Skip to content

Commit

Permalink
restore clap descriptions
Browse files Browse the repository at this point in the history
  • Loading branch information
solidiquis committed May 2, 2023
1 parent 7e398a6 commit c593044
Show file tree
Hide file tree
Showing 6 changed files with 279 additions and 5 deletions.
9 changes: 4 additions & 5 deletions src/render/context/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -47,11 +47,10 @@ mod test;

/// Defines the CLI.
#[derive(Parser, Debug)]
#[command(name = env!("CARGO_PKG_NAME", "The Package Name is missing!"))]
#[command(author = env!("CARGO_PKG_AUTHORS", "The Author of the Package is missing!"))]
#[command(version = env!("CARGO_PKG_VERSION_MAJOR", "The Package version is missing!"))]
#[command(about = "erdtree (erd) is a cross-platform multi-threaded filesystem and disk usage analysis tool.",
long_about = env!("CARGO_PKG_DESCRIPTION", "The Long Package Description is missing!"))]
#[command(name = "erdtree")]
#[command(author = "Benjamin Nguyen. <[email protected]>")]
#[command(version = "2.0.0")]
#[command(about = "erdtree (erd) is a cross-platform multi-threaded filesystem and disk usage analysis tool.", long_about = None)]
pub struct Context {
/// Directory to traverse; defaults to current working directory
dir: Option<PathBuf>,
Expand Down
37 changes: 37 additions & 0 deletions src/render/display/flat.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
use crate::{
render::Engine,
tree::{count::FileCount, Tree},
};
use std::fmt::{self, Display};

pub struct Flat;

impl Display for Engine<Flat> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let ctx = self.context();
let tree = self.tree();
let arena = tree.arena();
let root_id = tree.root_id();
let max_depth = ctx.level();
let mut file_count_data = vec![];

let descendants = root_id.descendants(arena);

for node_id in descendants {
let node = arena[node_id].get();

if node.depth() > max_depth {
continue;
}

node.flat_display(f, ctx)?;
file_count_data.push(Tree::compute_file_count(node_id, arena));
}

if !file_count_data.is_empty() {
write!(f, "\n{}", FileCount::from(file_count_data))?;
}

Ok(())
}
}
92 changes: 92 additions & 0 deletions src/render/display/inverted.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
use crate::{
render::{Engine, theme},
styles,
tree::{count::FileCount, node::Node, Tree},
};
use indextree::NodeId;
use std::fmt::{self, Display};

pub struct Inverted;

impl Display for Engine<Inverted> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let ctx = self.context();
let tree = self.tree();

let root_id = tree.root_id();
let arena = tree.arena();
let level = ctx.level();
let mut file_count_data = vec![];

let mut descendants = root_id.descendants(arena).skip(1).peekable();

let mut display_node = |node_id: NodeId, node: &Node, prefix: &str| -> fmt::Result {
node.tree_display(f, prefix, ctx)?;
file_count_data.push(Tree::compute_file_count(node_id, arena));
writeln!(f)
};

display_node(root_id, arena[root_id].get(), "")?;

let mut get_theme = if ctx.follow {
theme::link_theme_getter()
} else {
theme::regular_theme_getter()
};

let mut base_prefix_components = vec![""];

while let Some(current_node_id) = descendants.next() {
let current_node = arena[current_node_id].get();

let current_depth = current_node.depth();

let mut siblings = current_node_id.following_siblings(arena).skip(1).peekable();

let last_sibling = siblings.peek().is_none();

let theme = get_theme(current_node);

if current_depth <= level {
let prefix_part = if last_sibling {
theme.get("uprt").unwrap()
} else {
theme.get("vtrt").unwrap()
};

let mut current_prefix_components = base_prefix_components.clone();

current_prefix_components.push(prefix_part);

let prefix = current_prefix_components.join("");

display_node(current_node_id, current_node, &prefix)?;
}

if let Some(next_id) = descendants.peek() {
let next_node = arena[*next_id].get();

let next_depth = next_node.depth();

if next_depth == current_depth + 1 {
if last_sibling {
base_prefix_components.push(styles::SEP);
} else {
let prefix = theme.get("vt").unwrap();
base_prefix_components.push(prefix);
}
} else if next_depth < current_depth {
let depth_delta = current_depth - next_depth;

base_prefix_components.truncate(base_prefix_components.len() - depth_delta);
}
}
}

if !file_count_data.is_empty() {
write!(f, "\n{}", FileCount::from(file_count_data))?;
}

Ok(())
}
}
5 changes: 5 additions & 0 deletions src/render/display/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
pub mod regular;

pub mod flat;

pub mod inverted;
104 changes: 104 additions & 0 deletions src/render/display/regular.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
use crate::{
render::{Engine, theme},
styles,
tree::{count::FileCount, node::Node, Tree},
};
use indextree::{NodeEdge, NodeId};
use std::fmt::{self, Display};

pub struct Regular;

impl Display for Engine<Regular> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let ctx = self.context();
let tree = self.tree();
let root_id = tree.root_id();
let arena = tree.arena();
let max_depth = ctx.level();
let mut file_count_data = vec![];

let mut display_node = |node_id: NodeId, node: &Node, prefix: &str| -> fmt::Result {
node.tree_display(f, prefix, ctx)?;
file_count_data.push(Tree::compute_file_count(node_id, arena));
writeln!(f)
};

let mut get_theme = if ctx.follow {
theme::link_theme_getter()
} else {
theme::regular_theme_getter()
};

let mut base_prefix_components = vec![""];

let mut tree_edges = root_id.reverse_traverse(arena).skip(1).peekable();

while let Some(node_edge) = tree_edges.next() {
let current_node_id = match node_edge {
NodeEdge::Start(id) => id,

NodeEdge::End(id) => {
let current_node = arena[id].get();

if !current_node.is_dir() || id.children(arena).count() == 0 {
continue;
}

let theme = get_theme(current_node);

let topmost_sibling = id.following_siblings(arena).nth(1).is_none();

if topmost_sibling {
base_prefix_components.push(styles::SEP);
} else {
base_prefix_components.push(theme.get("vt").unwrap());
}

continue;
}
};

let current_node = arena[current_node_id].get();

let node_depth = current_node.depth();

let topmost_sibling = current_node_id.following_siblings(arena).nth(1).is_none();

let theme = get_theme(current_node);

if node_depth <= max_depth {
if node_depth == 0 {
display_node(current_node_id, current_node, "")?;
} else {
let prefix_part = if topmost_sibling {
theme.get("drt").unwrap()
} else {
theme.get("vtrt").unwrap()
};

let mut current_prefix_components = base_prefix_components.clone();

current_prefix_components.push(prefix_part);

let prefix = current_prefix_components.join("");

display_node(current_node_id, current_node, &prefix)?;
}
}

if let Some(NodeEdge::Start(next_id)) = tree_edges.peek() {
let next_node = arena[*next_id].get();

if next_node.depth() < node_depth {
base_prefix_components.pop();
}
}
}

if !file_count_data.is_empty() {
write!(f, "\n{}", FileCount::from(file_count_data))?;
}

Ok(())
}
}
37 changes: 37 additions & 0 deletions src/render/theme.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
use crate::{
styles::{self, ThemesMap},
tree::node::Node,
};

type Theme = Box<dyn FnMut(&Node) -> &'static ThemesMap>;

/// Returns a closure that retrieves the regular theme.
pub fn regular_theme_getter() -> Theme {
Box::new(|_node: &Node| styles::get_tree_theme().unwrap())
}

/// Returns a closure that can smartly determine when a symlink is being followed and when it is
/// not being followed. When a symlink is being followed, all of its descendents should have tree
/// branches that are colored differently.
pub fn link_theme_getter() -> Theme {
let mut link_depth = None;

Box::new(move |node: &Node| {
let current_depth = node.depth();

if let Some(ldepth) = link_depth {
if current_depth == ldepth {
link_depth = None;
}
}

if link_depth.is_some() || node.is_symlink() {
if node.is_dir() && link_depth.is_none() {
link_depth = Some(current_depth);
}
styles::get_link_theme().unwrap()
} else {
styles::get_tree_theme().unwrap()
}
})
}

0 comments on commit c593044

Please sign in to comment.