diff --git a/Cargo.lock b/Cargo.lock index 163867b..1888088 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -125,6 +125,7 @@ dependencies = [ "num_cpus 1.13.0 (registry+https://github.com/rust-lang/crates.io-index)", "tempfile 3.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "terminal_size 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)", + "thousands 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "unicode-width 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", "walkdir 2.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "winapi-util 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", @@ -359,6 +360,11 @@ dependencies = [ "unicode-width 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "thousands" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "thread_local" version = "1.0.1" @@ -475,6 +481,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum tempfile 3.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7a6e24d9338a0a5be79593e2fa15a648add6138caa803e2d5bc782c371732ca9" "checksum terminal_size 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)" = "9a14cd9f8c72704232f0bfc8455c0e861f0ad4eb60cc9ec8a170e231414c1e13" "checksum textwrap 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d326610f408c7a4eb6f51c37c330e496b08506c9457c9d34287ecc38809fb060" +"checksum thousands 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3bf63baf9f5039dadc247375c29eb13706706cfde997d0330d05aa63a77d8820" "checksum thread_local 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d40c6d1b69745a6ec6fb1ca717914848da4b44ae29d9b3080cbee91d72a69b14" "checksum treeline 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a7f741b240f1a48843f9b8e0444fb55fb2a4ff67293b50a9179dfd5ea67f8d41" "checksum unicode-width 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "9337591893a19b88d8d87f2cec1e73fad5cdfd10e5a6f349f498ad6ea2ffb1e3" diff --git a/Cargo.toml b/Cargo.toml index d2b0302..baafe8e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -30,6 +30,8 @@ unicode-width = "0.1" ignore="0.4" crossbeam-channel = "0.4" walkdir="2.3" +# todo use num_format instead +thousands="" [target.'cfg(windows)'.dependencies] winapi-util = "0.1" diff --git a/src/display.rs b/src/display.rs index f407284..3c964fc 100644 --- a/src/display.rs +++ b/src/display.rs @@ -14,6 +14,7 @@ use std::cmp::min; use std::fs; use std::iter::repeat; use std::path::Path; +use thousands::Separable; static UNITS: [char; 4] = ['T', 'G', 'M', 'K']; static BLOCKS: [char; 5] = ['█', '▓', '▒', '░', ' ']; @@ -23,6 +24,8 @@ pub struct DisplayData { pub short_paths: bool, pub is_reversed: bool, pub colors_on: bool, + pub by_filecount: bool, + pub num_chars_needed_on_left_most: usize, pub base_size: u64, pub longest_string_length: usize, pub ls_colors: LsColors, @@ -143,12 +146,20 @@ pub fn draw_it( is_reversed: bool, no_colors: bool, no_percents: bool, + by_filecount: bool, root_node: Node, ) { if !permissions { eprintln!("Did not have permissions for all directories"); } - let terminal_width = (get_width_of_terminal() - 14) as usize; + let num_chars_needed_on_left_most = if by_filecount { + let max_size = root_node.children.iter().map(|n| n.size).fold(0, max); + max_size.separate_with_commas().chars().count() + } else { + 5 // Under normal usage we need 5 chars to display the size of a directory + }; + + let terminal_width = get_width_of_terminal() as usize - 9 - num_chars_needed_on_left_most; let num_indent_chars = 3; let longest_string_length = root_node .children @@ -169,6 +180,8 @@ pub fn draw_it( short_paths: !use_full_path, is_reversed, colors_on: !no_colors, + by_filecount, + num_chars_needed_on_left_most, base_size: c.size, longest_string_length, ls_colors: LsColors::from_env().unwrap_or_default(), @@ -323,12 +336,26 @@ fn get_name_percent( ("".into(), name) } } + fn get_pretty_size(node: &Node, is_biggest: bool, display_data: &DisplayData) -> String { - let pretty_size = format!("{:>5}", human_readable_number(node.size)); - if is_biggest && display_data.colors_on { - format!("{}", Red.paint(pretty_size)) + if display_data.by_filecount { + let size_as_str = node.size.separate_with_commas(); + let spaces_to_add = + display_data.num_chars_needed_on_left_most - size_as_str.chars().count(); + let first_size_bar = size_as_str + &*repeat(' ').take(spaces_to_add).collect::(); + + if is_biggest && display_data.colors_on { + format!("{}", Red.paint(first_size_bar)) + } else { + first_size_bar + } } else { - pretty_size + let pretty_size = format!("{:>5}", human_readable_number(node.size)); + if is_biggest && display_data.colors_on { + format!("{}", Red.paint(pretty_size)) + } else { + pretty_size + } } } fn get_pretty_name(node: &Node, name_and_padding: String, display_data: &DisplayData) -> String { @@ -372,6 +399,8 @@ mod tests { short_paths: true, is_reversed: false, colors_on: false, + by_filecount: false, + num_chars_needed_on_left_most: 5, base_size: 1, longest_string_length: longest_string_length, ls_colors: LsColors::from_env().unwrap_or_default(), diff --git a/src/main.rs b/src/main.rs index ee68804..04efc7e 100644 --- a/src/main.rs +++ b/src/main.rs @@ -120,6 +120,13 @@ fn main() { .long("no-percent-bars") .help("No percent bars or percentages will be displayed"), ) + .arg( + Arg::with_name("by_filecount") + .short("f") + .long("filecount") + .help("Directory 'size' is number of child files/dirs not disk size"), + ) + .arg(Arg::with_name("inputs").multiple(true)) .get_matches(); @@ -157,6 +164,7 @@ fn main() { Some(i) => Some(i.map(PathBuf::from).collect()), None => None, }; + let by_filecount = options.is_present("by_filecount"); let simplified_dirs = simplify_dir_names(target_dirs); let (permissions, nodes) = get_dir_tree( @@ -164,6 +172,7 @@ fn main() { &ignore_directories, use_apparent_size, limit_filesystem, + by_filecount, depth, ); let sorted_data = sort(nodes); @@ -181,6 +190,7 @@ fn main() { !options.is_present("reverse"), no_colors, options.is_present("no_bars"), + by_filecount, tree, ); } diff --git a/src/utils/mod.rs b/src/utils/mod.rs index 9002008..651d354 100644 --- a/src/utils/mod.rs +++ b/src/utils/mod.rs @@ -109,6 +109,7 @@ pub fn get_dir_tree>( ignore_directories: &Option>, apparent_size: bool, limit_filesystem: bool, + by_filecount: bool, max_depth: Option, ) -> (bool, HashMap) { let (tx, rx) = channel::bounded::(1000); @@ -144,7 +145,8 @@ pub fn get_dir_tree>( match maybe_size_and_inode { Some(data) => { - let (size, inode_device) = data; + let (size, inode_device) = + if by_filecount { (1, data.1) } else { data }; txc.send((p.into_path(), size, inode_device)).unwrap(); } None => {