Skip to content

Commit

Permalink
Support listing directories by number of files
Browse files Browse the repository at this point in the history
Based of #104

Idea is to allow users to find the number of files in each directory
instead of size.
  • Loading branch information
bootandy committed Aug 30, 2020
1 parent 82237c6 commit 4ea8d93
Show file tree
Hide file tree
Showing 5 changed files with 56 additions and 6 deletions.
7 changes: 7 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions Cargo.toml
Expand Up @@ -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"
Expand Down
39 changes: 34 additions & 5 deletions src/display.rs
Expand Up @@ -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] = ['█', '▓', '▒', '░', ' '];
Expand All @@ -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,
Expand Down Expand Up @@ -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
Expand All @@ -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(),
Expand Down Expand Up @@ -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::<String>();

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 {
Expand Down Expand Up @@ -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(),
Expand Down
10 changes: 10 additions & 0 deletions src/main.rs
Expand Up @@ -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();

Expand Down Expand Up @@ -157,13 +164,15 @@ 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(
&simplified_dirs,
&ignore_directories,
use_apparent_size,
limit_filesystem,
by_filecount,
depth,
);
let sorted_data = sort(nodes);
Expand All @@ -181,6 +190,7 @@ fn main() {
!options.is_present("reverse"),
no_colors,
options.is_present("no_bars"),
by_filecount,
tree,
);
}
Expand Down
4 changes: 3 additions & 1 deletion src/utils/mod.rs
Expand Up @@ -109,6 +109,7 @@ pub fn get_dir_tree<P: AsRef<Path>>(
ignore_directories: &Option<Vec<PathBuf>>,
apparent_size: bool,
limit_filesystem: bool,
by_filecount: bool,
max_depth: Option<usize>,
) -> (bool, HashMap<PathBuf, u64>) {
let (tx, rx) = channel::bounded::<PathData>(1000);
Expand Down Expand Up @@ -144,7 +145,8 @@ pub fn get_dir_tree<P: AsRef<Path>>(

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 => {
Expand Down

0 comments on commit 4ea8d93

Please sign in to comment.