summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorRadu Butoi <rbutoi@users.noreply.github.com>2020-05-31 13:32:35 -0400
committerGitHub <noreply@github.com>2020-05-31 19:32:35 +0200
commitab1c3d1c5431a4fbc9a7e2d268feb28c0c2b8e5f (patch)
treef6951371ae8522531c02719de81c756221f02ada /src
parent329b3c791d321f95e484c1c62fc46b314016a309 (diff)
feat(directory): Add directory substitutions (#1183)
Adds an option to provide a table of strings to substitute in the directory string. Fixes #1065. Co-authored-by: Radu Butoi <butoi@google.com>
Diffstat (limited to 'src')
-rw-r--r--src/configs/directory.rs3
-rw-r--r--src/modules/directory.rs37
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(&current_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");