summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorAndrew Dassonville <dassonville.andrew@gmail.com>2019-07-28 17:15:40 -0700
committerMatan Kushner <hello@matchai.me>2019-07-28 20:15:40 -0400
commit75e74e0d749db029a9b8da56bd33648ac959b70a (patch)
tree26abb4b5485b5d772b1501e9583462a7fc273b75 /src
parent0bc28c521df789d3aae5ceb541ee336aefa14340 (diff)
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.
Diffstat (limited to 'src')
-rw-r--r--src/modules/directory.rs73
1 files changed, 66 insertions, 7 deletions
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<Module<'a>> {
/// `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.
@@ -111,6 +130,46 @@ mod tests {
}
#[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";
let output = truncate(path.to_string(), 3);