diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/configs/directory.rs | 3 | ||||
-rw-r--r-- | src/modules/directory.rs | 37 |
2 files changed, 37 insertions, 3 deletions
diff --git a/src/configs/directory.rs b/src/configs/directory.rs index 3d44b14dd..9c6aaf26e 100644 --- a/src/configs/directory.rs +++ b/src/configs/directory.rs @@ -1,4 +1,5 @@ use crate::config::{ModuleConfig, RootModuleConfig}; +use std::collections::HashMap; use ansi_term::{Color, Style}; use starship_module_config_derive::ModuleConfig; @@ -7,6 +8,7 @@ use starship_module_config_derive::ModuleConfig; pub struct DirectoryConfig<'a> { pub truncation_length: i64, pub truncate_to_repo: bool, + pub substitutions: HashMap<String, &'a str>, pub fish_style_pwd_dir_length: i64, pub use_logical_path: bool, pub prefix: &'a str, @@ -20,6 +22,7 @@ impl<'a> RootModuleConfig<'a> for DirectoryConfig<'a> { truncation_length: 3, truncate_to_repo: true, fish_style_pwd_dir_length: 0, + substitutions: HashMap::new(), use_logical_path: true, prefix: "in ", style: Color::Cyan.bold(), diff --git a/src/modules/directory.rs b/src/modules/directory.rs index 16cee2f39..464ef23b2 100644 --- a/src/modules/directory.rs +++ b/src/modules/directory.rs @@ -1,4 +1,5 @@ use path_slash::PathExt; +use std::collections::HashMap; use std::path::{Path, PathBuf}; use unicode_segmentation::UnicodeSegmentation; @@ -10,12 +11,15 @@ use crate::configs::directory::DirectoryConfig; /// Creates a module with the current directory /// -/// Will perform path contraction and truncation. +/// Will perform path contraction, substitution, and truncation. /// **Contraction** /// - Paths beginning with the home directory or with a git repo right /// inside the home directory will be contracted to `~` /// - Paths containing a git repo will contract to begin at the repo root /// +/// **Substitution** +/// Paths will undergo user-provided substitutions of substrings +/// /// **Truncation** /// Paths will be limited in length to `3` path components by default. pub fn module<'a>(context: &'a Context) -> Option<Module<'a>> { @@ -67,10 +71,14 @@ pub fn module<'a>(context: &'a Context) -> Option<Module<'a>> { _ => contract_path(current_dir, &home_dir, HOME_SYMBOL), }; + let substituted_dir = substitute_path(dir_string, &config.substitutions); + // Truncate the dir string to the maximum number of path components - let truncated_dir_string = truncate(dir_string, config.truncation_length as usize); + let truncated_dir_string = truncate(substituted_dir, config.truncation_length as usize); - if config.fish_style_pwd_dir_length > 0 { + // 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() { // If user is using fish style path, we need to add the segment first let contracted_home_dir = contract_path(¤t_dir, &home_dir, HOME_SYMBOL); let fish_style_dir = to_fish_style( @@ -126,6 +134,18 @@ fn contract_path(full_path: &Path, top_level_path: &Path, top_level_replacement: ) } +/// Perform a list of string substitutions on the path +/// +/// Given a list of (from, to) pairs, this will perform the string +/// substitutions, in order, on the path. Any non-pair of strings is ignored. +fn substitute_path(dir_string: String, substitutions: &HashMap<String, &str>) -> String { + let mut substituted_dir = dir_string; + for substitution_pair in substitutions.iter() { + substituted_dir = substituted_dir.replace(substitution_pair.0, substitution_pair.1); + } + substituted_dir +} + /// Takes part before contracted path and replaces it with fish style path /// /// Will take the first letter of each directory before the contracted path and @@ -224,6 +244,17 @@ mod tests { } #[test] + fn substitute_prefix_and_middle() { + let full_path = "/absolute/path/foo/bar/baz"; + let mut substitutions = HashMap::new(); + substitutions.insert("/absolute/path".to_string(), ""); + substitutions.insert("/bar/".to_string(), "/"); + + let output = substitute_path(full_path.to_string(), &substitutions); + assert_eq!(output, "/foo/baz"); + } + + #[test] fn fish_style_with_user_home_contracted_path() { let path = "~/starship/engines/booster/rocket"; let output = to_fish_style(1, path.to_string(), "engines/booster/rocket"); |