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.
This commit is contained in:
andy.boot
2022-01-02 23:16:27 +00:00
parent 2d58609d54
commit 469e6d0a69
3 changed files with 29 additions and 20 deletions

View File

@@ -128,20 +128,21 @@ pub fn draw_it(
} else { } else {
5 // Under normal usage we need 5 chars to display the size of a directory 5 // Under normal usage we need 5 chars to display the size of a directory
}; };
assert!( assert!(
terminal_width > 9 + num_chars_needed_on_left_most, terminal_width > num_chars_needed_on_left_most + 2,
"Not enough terminal width" "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 num_indent_chars = 3;
let longest_string_length = 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 0
} else { } 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::<String>(); let first_size_bar = repeat(BLOCKS[0]).take(max_bar_length).collect::<String>();
@@ -264,23 +265,31 @@ fn pad_or_trim_filename(node: &DisplayNode, indent: &str, display_data: &Display
let indent_and_name = format!("{} {}", indent, name); let indent_and_name = format!("{} {}", indent, name);
let width = UnicodeWidthStr::width(&*indent_and_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. // Add spaces after the filename so we can draw the % used bar chart.
let name_and_padding = name let name_and_padding = name
+ " " + " "
.repeat(display_data.longest_string_length - width) .repeat((display_data.longest_string_length) - (width))
.as_str(); .as_str();
maybe_trim_filename(name_and_padding, display_data) name_and_padding
} }
fn maybe_trim_filename(name_in: String, display_data: &DisplayData) -> String { fn maybe_trim_filename(name_in: String, indent: &str, display_data: &DisplayData) -> String {
if UnicodeWidthStr::width(&*name_in) > display_data.longest_string_length { let indent_length = UnicodeWidthStr::width(indent);
let name = name_in assert!(
.chars() display_data.longest_string_length >= indent_length + 2,
.take(display_data.longest_string_length - 2) "Terminal width not wide enough to draw directory tree"
.collect::<String>(); );
// 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::<String>();
name + ".." name + ".."
} else { } else {
name_in name_in
@@ -313,7 +322,7 @@ fn get_name_percent(
(percents, name_and_padding) (percents, name_and_padding)
} else { } else {
let n = get_printable_name(&node.name, display_data.short_paths); 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) ("".into(), name)
} }
} }
@@ -406,7 +415,7 @@ mod tests {
indent, indent,
percent_bar, percent_bar,
is_biggest, is_biggest,
&get_fake_display_data(6), &get_fake_display_data(20),
); );
assert_eq!(s, " 4.0K ┌─┴ short"); assert_eq!(s, " 4.0K ┌─┴ short");
} }
@@ -427,7 +436,7 @@ mod tests {
let s = format_string(&n, indent, percent_bar, is_biggest, &dd); let s = format_string(&n, indent, percent_bar, is_biggest, &dd);
assert_eq!( assert_eq!(
s, 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_.."
); );
} }

View File

@@ -141,7 +141,7 @@ pub fn test_substring_of_names_and_long_names() {
fn no_substring_of_names_output() -> Vec<String> { fn no_substring_of_names_output() -> Vec<String> {
let ubuntu = " 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 ├── dir_name_clash
4.0K │ ┌── hello 4.0K │ ┌── hello
8.0K ├─┴ dir 8.0K ├─┴ dir
@@ -153,7 +153,7 @@ fn no_substring_of_names_output() -> Vec<String> {
.into(); .into();
let mac_and_some_linux = " 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 │ ┌── hello
4.0K ├─┴ dir 4.0K ├─┴ dir
4.0K ├── dir_name_clash 4.0K ├── dir_name_clash

View File

@@ -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 // 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 { 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 { if UnicodeWidthStr::width(&*name) > terminal_plus_buffer {
let trimmed_name = name let trimmed_name = name
.chars() .chars()