From 469e6d0a6904cd97ff5798008486ee89de531450 Mon Sep 17 00:00:00 2001 From: "andy.boot" Date: Sun, 2 Jan 2022 23:16:27 +0000 Subject: [PATCH] Fix: Bug: names may be shortened unnecessarily The code calculating the width of a row to use vs the width of the terminal wasn't quite right. If we had 2 long filepaths one at the top of the dir tree and one at the bottom the old code would shorten both equally. This doesn't make sense as the one at the shallowest part of the tree would have used less screen real estate and so should show a longer part of the filepath. --- src/display.rs | 43 +++++++++++++++++++++++--------------- tests/test_exact_output.rs | 4 ++-- tests/tests_symlinks.rs | 2 +- 3 files changed, 29 insertions(+), 20 deletions(-) diff --git a/src/display.rs b/src/display.rs index d904a7c..dcf1c8e 100644 --- a/src/display.rs +++ b/src/display.rs @@ -128,20 +128,21 @@ pub fn draw_it( } else { 5 // Under normal usage we need 5 chars to display the size of a directory }; + assert!( - terminal_width > 9 + num_chars_needed_on_left_most, + terminal_width > num_chars_needed_on_left_most + 2, "Not enough terminal width" ); - let terminal_width = terminal_width - 9 - num_chars_needed_on_left_most; + let t = terminal_width - num_chars_needed_on_left_most - 2; let num_indent_chars = 3; let longest_string_length = - find_longest_dir_name(&root_node, num_indent_chars, terminal_width, !use_full_path); + find_longest_dir_name(&root_node, num_indent_chars, t, !use_full_path); - let max_bar_length = if no_percents || longest_string_length >= terminal_width as usize { + let max_bar_length = if no_percents || longest_string_length + 7 >= t as usize { 0 } else { - terminal_width as usize - longest_string_length + t as usize - longest_string_length - 7 }; let first_size_bar = repeat(BLOCKS[0]).take(max_bar_length).collect::(); @@ -264,23 +265,31 @@ fn pad_or_trim_filename(node: &DisplayNode, indent: &str, display_data: &Display let indent_and_name = format!("{} {}", indent, name); let width = UnicodeWidthStr::width(&*indent_and_name); - assert!(display_data.longest_string_length >= width); + assert!( + display_data.longest_string_length >= width, + "Terminal width not wide enough to draw directory tree" + ); // Add spaces after the filename so we can draw the % used bar chart. let name_and_padding = name + " " - .repeat(display_data.longest_string_length - width) + .repeat((display_data.longest_string_length) - (width)) .as_str(); - maybe_trim_filename(name_and_padding, display_data) + name_and_padding } -fn maybe_trim_filename(name_in: String, display_data: &DisplayData) -> String { - if UnicodeWidthStr::width(&*name_in) > display_data.longest_string_length { - let name = name_in - .chars() - .take(display_data.longest_string_length - 2) - .collect::(); +fn maybe_trim_filename(name_in: String, indent: &str, display_data: &DisplayData) -> String { + let indent_length = UnicodeWidthStr::width(indent); + assert!( + display_data.longest_string_length >= indent_length + 2, + "Terminal width not wide enough to draw directory tree" + ); + + // println!("{} : {} : {}", UnicodeWidthStr::width(&*name_in) ,display_data.longest_string_length, indent_length); + let max_size = display_data.longest_string_length - indent_length; + if UnicodeWidthStr::width(&*name_in) > max_size { + let name = name_in.chars().take(max_size - 2).collect::(); name + ".." } else { name_in @@ -313,7 +322,7 @@ fn get_name_percent( (percents, name_and_padding) } else { let n = get_printable_name(&node.name, display_data.short_paths); - let name = maybe_trim_filename(n, display_data); + let name = maybe_trim_filename(n, indent, display_data); ("".into(), name) } } @@ -406,7 +415,7 @@ mod tests { indent, percent_bar, is_biggest, - &get_fake_display_data(6), + &get_fake_display_data(20), ); assert_eq!(s, " 4.0K ┌─┴ short"); } @@ -427,7 +436,7 @@ mod tests { let s = format_string(&n, indent, percent_bar, is_biggest, &dd); assert_eq!( s, - " 4.0K ┌─┴ very_long_name_longer_than_the_eighty_character_limit_very_lon.." + " 4.0K ┌─┴ very_long_name_longer_than_the_eighty_character_limit_very_.." ); } diff --git a/tests/test_exact_output.rs b/tests/test_exact_output.rs index 253a1c9..d67fe4a 100644 --- a/tests/test_exact_output.rs +++ b/tests/test_exact_output.rs @@ -141,7 +141,7 @@ pub fn test_substring_of_names_and_long_names() { fn no_substring_of_names_output() -> Vec { let ubuntu = " - 0B ┌── long_dir_name_what_a_very_long_dir_name_what_happens_when_this_g.. + 0B ┌── long_dir_name_what_a_very_long_dir_name_what_happens_when_this_goe.. 4.0K ├── dir_name_clash 4.0K │ ┌── hello 8.0K ├─┴ dir @@ -153,7 +153,7 @@ fn no_substring_of_names_output() -> Vec { .into(); let mac_and_some_linux = " - 0B ┌── long_dir_name_what_a_very_long_dir_name_what_happens_when_this_g.. + 0B ┌── long_dir_name_what_a_very_long_dir_name_what_happens_when_this_goe.. 4.0K │ ┌── hello 4.0K ├─┴ dir 4.0K ├── dir_name_clash diff --git a/tests/tests_symlinks.rs b/tests/tests_symlinks.rs index 6b1f08f..0ade925 100644 --- a/tests/tests_symlinks.rs +++ b/tests/tests_symlinks.rs @@ -24,7 +24,7 @@ fn get_width_of_terminal() -> u16 { // Mac test runners create tmp files with very long names, hence it may be shortened in the output fn get_file_name(name: String) -> String { - let terminal_plus_buffer = (get_width_of_terminal() - 14) as usize; + let terminal_plus_buffer = (get_width_of_terminal() - 12) as usize; if UnicodeWidthStr::width(&*name) > terminal_plus_buffer { let trimmed_name = name .chars()