fix(directory): improve truncation detection (#3266)

This commit is contained in:
David Knaack 2021-11-26 13:07:28 +01:00 committed by GitHub
parent 3a1f1c359f
commit e18c61cd68
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 30 additions and 26 deletions

View File

@ -21,7 +21,7 @@ pub fn module<'a>(context: &'a Context) -> Option<Module<'a>> {
return None; 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| { let parsed = StringFormatter::new(config.format).and_then(|formatter| {
formatter formatter

View File

@ -60,6 +60,8 @@ pub fn module<'a>(context: &'a Context) -> Option<Module<'a>> {
None None
}; };
let mut is_truncated = dir_string.is_some();
// the home directory if required. // the home directory if required.
let dir_string = let dir_string =
dir_string.unwrap_or_else(|| contract_path(display_dir, &home_dir, &home_symbol)); 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<Module<'a>> {
let dir_string = substitute_path(dir_string, &config.substitutions); let dir_string = substitute_path(dir_string, &config.substitutions);
// Truncate the dir string to the maximum number of path components // 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 // Substitutions could have changed the prefix, so don't allow them and
// fish-style path contraction together // fish-style path contraction together
if config.fish_style_pwd_dir_length > 0 && config.substitutions.is_empty() { 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 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 { fn is_readonly_dir(path: &Path) -> bool {
match directory_utils::is_write_allowed(path) { match directory_utils::is_write_allowed(path) {
Ok(res) => !res, Ok(res) => !res,
@ -755,11 +757,12 @@ mod tests {
}) })
.path(&dir) .path(&dir)
.collect(); .collect();
let dir_str = dir.to_slash_lossy();
let expected = Some(format!( let expected = Some(format!(
"{} ", "{} ",
Color::Cyan Color::Cyan
.bold() .bold()
.paint(truncate(dir.to_slash_lossy(), 100)) .paint(truncate(&dir_str, 100).unwrap_or(dir_str))
)); ));
assert_eq!(expected, actual); assert_eq!(expected, actual);

View File

@ -2,9 +2,10 @@
/// ///
/// Will truncate a path to only show the last `length` components in a path. /// 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. /// 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<String> {
if length == 0 { if length == 0 {
return dir_string; return None;
} }
let mut components = dir_string.split('/').collect::<Vec<&str>>(); let mut components = dir_string.split('/').collect::<Vec<&str>>();
@ -15,11 +16,11 @@ pub fn truncate(dir_string: String, length: usize) -> String {
} }
if components.len() <= length { if components.len() <= length {
return dir_string; return None;
} }
let truncated_components = &components[components.len() - length..]; let truncated_components = &components[components.len() - length..];
truncated_components.join("/") Some(truncated_components.join("/"))
} }
#[cfg(test)] #[cfg(test)]
@ -29,42 +30,42 @@ mod tests {
#[test] #[test]
fn truncate_smaller_path_than_provided_length() { fn truncate_smaller_path_than_provided_length() {
let path = "~/starship"; let path = "~/starship";
let output = truncate(path.to_string(), 3); let output = truncate(path, 3);
assert_eq!(output, "~/starship") assert_eq!(output, None)
} }
#[test] #[test]
fn truncate_same_path_as_provided_length() { fn truncate_same_path_as_provided_length() {
let path = "~/starship/engines"; let path = "~/starship/engines";
let output = truncate(path.to_string(), 3); let output = truncate(path, 3);
assert_eq!(output, "~/starship/engines") assert_eq!(output, None)
} }
#[test] #[test]
fn truncate_slightly_larger_path_than_provided_length() { fn truncate_slightly_larger_path_than_provided_length() {
let path = "~/starship/engines/booster"; let path = "~/starship/engines/booster";
let output = truncate(path.to_string(), 3); let output = truncate(path, 3);
assert_eq!(output, "starship/engines/booster") assert_eq!(output.as_deref(), Some("starship/engines/booster"))
} }
#[test] #[test]
fn truncate_larger_path_than_provided_length() { fn truncate_larger_path_than_provided_length() {
let path = "~/starship/engines/booster/rocket"; let path = "~/starship/engines/booster/rocket";
let output = truncate(path.to_string(), 3); let output = truncate(path, 3);
assert_eq!(output, "engines/booster/rocket") assert_eq!(output.as_deref(), Some("engines/booster/rocket"));
} }
#[test] #[test]
fn truncate_same_path_as_provided_length_from_root() { fn truncate_same_path_as_provided_length_from_root() {
let path = "/starship/engines/booster"; let path = "/starship/engines/booster";
let output = truncate(path.to_string(), 3); let output = truncate(path, 3);
assert_eq!(output, "/starship/engines/booster"); assert_eq!(output, None);
} }
#[test] #[test]
fn truncate_larger_path_than_provided_length_from_root() { fn truncate_larger_path_than_provided_length_from_root() {
let path = "/starship/engines/booster/rocket"; let path = "/starship/engines/booster/rocket";
let output = truncate(path.to_string(), 3); let output = truncate(path, 3);
assert_eq!(output, "engines/booster/rocket"); assert_eq!(output.as_deref(), Some("engines/booster/rocket"));
} }
} }