From e18c61cd684f77b13c65647065304f5fdc6a4080 Mon Sep 17 00:00:00 2001 From: David Knaack Date: Fri, 26 Nov 2021 13:07:28 +0100 Subject: [PATCH] fix(directory): improve truncation detection (#3266) --- src/modules/conda.rs | 2 +- src/modules/directory.rs | 21 ++++++++++++--------- src/modules/utils/directory.rs | 33 +++++++++++++++++---------------- 3 files changed, 30 insertions(+), 26 deletions(-) diff --git a/src/modules/conda.rs b/src/modules/conda.rs index d90355f0..2491420b 100644 --- a/src/modules/conda.rs +++ b/src/modules/conda.rs @@ -21,7 +21,7 @@ pub fn module<'a>(context: &'a Context) -> Option> { return None; } - let conda_env = truncate(conda_env, config.truncation_length); + let conda_env = truncate(&conda_env, config.truncation_length).unwrap_or(conda_env); let parsed = StringFormatter::new(config.format).and_then(|formatter| { formatter diff --git a/src/modules/directory.rs b/src/modules/directory.rs index 3f481070..7c2e733d 100644 --- a/src/modules/directory.rs +++ b/src/modules/directory.rs @@ -60,6 +60,8 @@ pub fn module<'a>(context: &'a Context) -> Option> { None }; + let mut is_truncated = dir_string.is_some(); + // the home directory if required. let dir_string = dir_string.unwrap_or_else(|| contract_path(display_dir, &home_dir, &home_symbol)); @@ -71,9 +73,15 @@ pub fn module<'a>(context: &'a Context) -> Option> { let dir_string = substitute_path(dir_string, &config.substitutions); // Truncate the dir string to the maximum number of path components - let dir_string = truncate(dir_string, config.truncation_length as usize); + let dir_string = + if let Some(truncated) = truncate(&dir_string, config.truncation_length as usize) { + is_truncated = true; + truncated + } else { + dir_string + }; - let prefix = if is_truncated(&dir_string, &home_symbol) { + let prefix = if is_truncated { // Substitutions could have changed the prefix, so don't allow them and // fish-style path contraction together if config.fish_style_pwd_dir_length > 0 && config.substitutions.is_empty() { @@ -170,12 +178,6 @@ fn remove_extended_path_prefix(path: String) -> String { path } -fn is_truncated(path: &str, home_symbol: &str) -> bool { - !(path.starts_with(&home_symbol) - || PathBuf::from(path).has_root() - || (cfg!(target_os = "windows") && PathBuf::from(String::from(path) + r"\").has_root())) -} - fn is_readonly_dir(path: &Path) -> bool { match directory_utils::is_write_allowed(path) { Ok(res) => !res, @@ -755,11 +757,12 @@ mod tests { }) .path(&dir) .collect(); + let dir_str = dir.to_slash_lossy(); let expected = Some(format!( "{} ", Color::Cyan .bold() - .paint(truncate(dir.to_slash_lossy(), 100)) + .paint(truncate(&dir_str, 100).unwrap_or(dir_str)) )); assert_eq!(expected, actual); diff --git a/src/modules/utils/directory.rs b/src/modules/utils/directory.rs index c6b0f221..5fd884d1 100644 --- a/src/modules/utils/directory.rs +++ b/src/modules/utils/directory.rs @@ -2,9 +2,10 @@ /// /// Will truncate a path to only show the last `length` components in a path. /// If a length of `0` is provided, the path will not be truncated. -pub fn truncate(dir_string: String, length: usize) -> String { +/// A value will only be returned if the path has been truncated. +pub fn truncate(dir_string: &str, length: usize) -> Option { if length == 0 { - return dir_string; + return None; } let mut components = dir_string.split('/').collect::>(); @@ -15,11 +16,11 @@ pub fn truncate(dir_string: String, length: usize) -> String { } if components.len() <= length { - return dir_string; + return None; } let truncated_components = &components[components.len() - length..]; - truncated_components.join("/") + Some(truncated_components.join("/")) } #[cfg(test)] @@ -29,42 +30,42 @@ mod tests { #[test] fn truncate_smaller_path_than_provided_length() { let path = "~/starship"; - let output = truncate(path.to_string(), 3); - assert_eq!(output, "~/starship") + let output = truncate(path, 3); + assert_eq!(output, None) } #[test] fn truncate_same_path_as_provided_length() { let path = "~/starship/engines"; - let output = truncate(path.to_string(), 3); - assert_eq!(output, "~/starship/engines") + let output = truncate(path, 3); + assert_eq!(output, None) } #[test] fn truncate_slightly_larger_path_than_provided_length() { let path = "~/starship/engines/booster"; - let output = truncate(path.to_string(), 3); - assert_eq!(output, "starship/engines/booster") + let output = truncate(path, 3); + assert_eq!(output.as_deref(), Some("starship/engines/booster")) } #[test] fn truncate_larger_path_than_provided_length() { let path = "~/starship/engines/booster/rocket"; - let output = truncate(path.to_string(), 3); - assert_eq!(output, "engines/booster/rocket") + let output = truncate(path, 3); + assert_eq!(output.as_deref(), Some("engines/booster/rocket")); } #[test] fn truncate_same_path_as_provided_length_from_root() { let path = "/starship/engines/booster"; - let output = truncate(path.to_string(), 3); - assert_eq!(output, "/starship/engines/booster"); + let output = truncate(path, 3); + assert_eq!(output, None); } #[test] fn truncate_larger_path_than_provided_length_from_root() { let path = "/starship/engines/booster/rocket"; - let output = truncate(path.to_string(), 3); - assert_eq!(output, "engines/booster/rocket"); + let output = truncate(path, 3); + assert_eq!(output.as_deref(), Some("engines/booster/rocket")); } }