From 75e74e0d749db029a9b8da56bd33648ac959b70a Mon Sep 17 00:00:00 2001 From: Andrew Dassonville Date: Sun, 28 Jul 2019 17:15:40 -0700 Subject: feat: Use Unix-style slash on Windows (#119) Prior to this change, starship would use inconsistent slashes when displaying the working directory. With this change, starship uses Unix-style slashes on all platforms. This is consistent with the Git Bash and Cygwin prompts on Windows. --- src/modules/directory.rs | 73 +++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 66 insertions(+), 7 deletions(-) (limited to 'src/modules/directory.rs') diff --git a/src/modules/directory.rs b/src/modules/directory.rs index bd9d8333b..61937e751 100644 --- a/src/modules/directory.rs +++ b/src/modules/directory.rs @@ -1,4 +1,5 @@ use ansi_term::Color; +use path_slash::PathExt; use std::path::Path; use super::{Context, Module}; @@ -51,25 +52,43 @@ pub fn module<'a>(context: &'a Context) -> Option> { /// `top_level_replacement`. fn contract_path(full_path: &Path, top_level_path: &Path, top_level_replacement: &str) -> String { if !full_path.starts_with(top_level_path) { - return full_path.to_str().unwrap().to_string(); + return replace_c_dir(full_path.to_slash().unwrap()); } if full_path == top_level_path { - return top_level_replacement.to_string(); + return replace_c_dir(top_level_replacement.to_string()); } format!( "{replacement}{separator}{path}", replacement = top_level_replacement, separator = "/", - path = full_path - .strip_prefix(top_level_path) - .unwrap() - .to_str() - .unwrap() + path = replace_c_dir( + full_path + .strip_prefix(top_level_path) + .unwrap() + .to_slash() + .unwrap() + ) ) } +/// Replaces "C://" with "/c/" within a Windows path +/// +/// On non-Windows OS, does nothing +#[cfg(target_os = "windows")] +fn replace_c_dir(path: String) -> String { + return path.replace("C:/", "/c"); +} + +/// Replaces "C://" with "/c/" within a Windows path +/// +/// On non-Windows OS, does nothing +#[cfg(not(target_os = "windows"))] +fn replace_c_dir(path: String) -> String { + return path; +} + /// Truncate a path to only have a set number of path components /// /// Will truncate a path to only show the last `length` components in a path. @@ -110,6 +129,46 @@ mod tests { assert_eq!(output, "rocket-controls/src"); } + #[test] + #[cfg(target_os = "windows")] + fn contract_windows_style_home_directory() { + let full_path = Path::new("C:\\Users\\astronaut\\schematics\\rocket"); + let home = Path::new("C:\\Users\\astronaut"); + + let output = contract_path(full_path, home, "~"); + assert_eq!(output, "~/schematics/rocket"); + } + + #[test] + #[cfg(target_os = "windows")] + fn contract_windows_style_repo_directory() { + let full_path = Path::new("C:\\Users\\astronaut\\dev\\rocket-controls\\src"); + let repo_root = Path::new("C:\\Users\\astronaut\\dev\\rocket-controls"); + + let output = contract_path(full_path, repo_root, "rocket-controls"); + assert_eq!(output, "rocket-controls/src"); + } + + #[test] + #[cfg(target_os = "windows")] + fn contract_windows_style_no_top_level_directory() { + let full_path = Path::new("C:\\Some\\Other\\Path"); + let top_level_path = Path::new("C:\\Users\\astronaut"); + + let output = contract_path(full_path, top_level_path, "~"); + assert_eq!(output, "/c/Some/Other/Path"); + } + + #[test] + #[cfg(target_os = "windows")] + fn contract_windows_style_root_directory() { + let full_path = Path::new("C:\\"); + let top_level_path = Path::new("C:\\Users\\astronaut"); + + let output = contract_path(full_path, top_level_path, "~"); + assert_eq!(output, "/c"); + } + #[test] fn truncate_smaller_path_than_provided_length() { let path = "~/starship"; -- cgit v1.2.3