From 5dbf4381acd1fd8dbb2905828c3fcc6515d850cf Mon Sep 17 00:00:00 2001 From: Andrew Dassonville Date: Sun, 28 Jul 2019 18:05:13 -0700 Subject: [PATCH] feat: Allow directory truncation length to be configured (#120) This allows the directory truncation length to be configured. Previously, it was hard-coded to truncate to 3 parent directories. --- docs/config/README.md | 16 +++++++++--- src/config.rs | 34 ++++++++++++++++++++++++++ src/module.rs | 10 ++++++++ src/modules/directory.rs | 8 ++++-- tests/testsuite/directory.rs | 47 +++++++++++++++++++++++++++++++++++- 5 files changed, 109 insertions(+), 6 deletions(-) diff --git a/docs/config/README.md b/docs/config/README.md index fdcb07ae..bca949c5 100644 --- a/docs/config/README.md +++ b/docs/config/README.md @@ -116,9 +116,19 @@ git repo that you're currently in. ### Options -| Variable | Default | Description | -| ---------- | ------- | -------------------------------- | -| `disabled` | `false` | Disables the `directory` module. | +| Variable | Default | Description | +| ------------------- | ------- | -------------------------------------- | +| `truncation_length` | `3` | Truncates to this many parent folders. | +| `disabled` | `false` | Disables the `directory` module. | + +### Example + +```toml +# ~/.config/starship.toml + +[directory] +truncation_length = 8 +``` ## Git Branch diff --git a/src/config.rs b/src/config.rs index d5861b9f..c06541ee 100644 --- a/src/config.rs +++ b/src/config.rs @@ -12,6 +12,7 @@ pub trait Config { // Config accessor methods fn get_as_bool(&self, key: &str) -> Option; fn get_as_str(&self, key: &str) -> Option<&str>; + fn get_as_i64(&self, key: &str) -> Option; // Internal implementation for accessors fn get_config(&self, key: &str) -> Option<&toml::value::Value>; @@ -129,6 +130,23 @@ impl Config for Table { str_value } + + /// Get a key from a module's configuration as an integer + fn get_as_i64(&self, key: &str) -> Option { + let value = self.get_config(key)?; + let i64_value = value.as_integer(); + + if i64_value.is_none() { + log::debug!( + "Expected \"{}\" to be an integer. Instead received {} of type {}.", + key, + value, + value.type_str() + ); + } + + i64_value + } } mod tests { @@ -165,4 +183,20 @@ mod tests { table.insert(String::from("boolean"), toml::value::Value::Boolean(true)); assert_eq!(table.get_as_str("boolean"), None); } + + #[test] + fn table_get_as_i64() { + let mut table = toml::value::Table::new(); + + // Use with integer value + table.insert(String::from("integer"), toml::value::Value::Integer(82)); + assert_eq!(table.get_as_i64("integer"), Some(82)); + + // Use with string value + table.insert( + String::from("string"), + toml::value::Value::String(String::from("82")), + ); + assert_eq!(table.get_as_bool("string"), None); + } } diff --git a/src/module.rs b/src/module.rs index af985ea3..526345b9 100644 --- a/src/module.rs +++ b/src/module.rs @@ -99,6 +99,16 @@ impl<'a> Module<'a> { fn config_value(&self, key: &str) -> Option<&str> { self.config.and_then(|config| config.get_as_str(key)) } + + /// Get a module's config value as an int + pub fn config_value_i64(&self, key: &str) -> Option { + self.config.and_then(|config| config.get_as_i64(key)) + } + + /// Get a module's config value as a bool + pub fn config_value_bool(&self, key: &str) -> Option { + self.config.and_then(|config| config.get_as_bool(key)) + } } impl<'a> fmt::Display for Module<'a> { diff --git a/src/modules/directory.rs b/src/modules/directory.rs index 61937e75..a14f1c20 100644 --- a/src/modules/directory.rs +++ b/src/modules/directory.rs @@ -15,12 +15,16 @@ use super::{Context, Module}; /// Paths will be limited in length to `3` path components by default. pub fn module<'a>(context: &'a Context) -> Option> { const HOME_SYMBOL: &str = "~"; - const DIR_TRUNCATION_LENGTH: usize = 3; + const DIR_TRUNCATION_LENGTH: i64 = 3; let module_color = Color::Cyan.bold(); let mut module = context.new_module("directory")?; module.set_style(module_color); + let truncation_length = module + .config_value_i64("truncation_length") + .unwrap_or(DIR_TRUNCATION_LENGTH); + let current_dir = &context.current_dir; log::debug!("Current directory: {:?}", current_dir); @@ -38,7 +42,7 @@ pub fn module<'a>(context: &'a Context) -> Option> { } // Truncate the dir string to the maximum number of path components - let truncated_dir_string = truncate(dir_string, DIR_TRUNCATION_LENGTH); + let truncated_dir_string = truncate(dir_string, truncation_length as usize); module.new_segment("path", &truncated_dir_string); module.get_prefix().set_value("in "); diff --git a/tests/testsuite/directory.rs b/tests/testsuite/directory.rs index c2c81d52..1a5e67dd 100644 --- a/tests/testsuite/directory.rs +++ b/tests/testsuite/directory.rs @@ -6,7 +6,7 @@ use std::io; use std::path::Path; use tempfile::TempDir; -use crate::common; +use crate::common::{self, TestCommand}; #[test] fn home_directory() -> io::Result<()> { @@ -95,6 +95,51 @@ fn truncated_directory_in_root() -> io::Result<()> { Ok(()) } +#[test] +#[ignore] +fn truncated_directory_config_large() -> io::Result<()> { + let dir = Path::new("/tmp/starship/thrusters/rocket"); + fs::create_dir_all(&dir)?; + + let output = common::render_module("dir") + .use_config(toml::toml! { + [directory] + truncation_length = 100 + }) + .arg("--path") + .arg(dir) + .output()?; + let actual = String::from_utf8(output.stdout).unwrap(); + + let expected = format!( + "in {} ", + Color::Cyan.bold().paint("/tmp/starship/thrusters/rocket") + ); + assert_eq!(expected, actual); + Ok(()) +} + +#[test] +#[ignore] +fn truncated_directory_config_small() -> io::Result<()> { + let dir = Path::new("/tmp/starship/thrusters/rocket"); + fs::create_dir_all(&dir)?; + + let output = common::render_module("dir") + .use_config(toml::toml! { + [directory] + truncation_length = 2 + }) + .arg("--path") + .arg(dir) + .output()?; + let actual = String::from_utf8(output.stdout).unwrap(); + + let expected = format!("in {} ", Color::Cyan.bold().paint("thrusters/rocket")); + assert_eq!(expected, actual); + Ok(()) +} + #[test] #[ignore] fn git_repo_root() -> io::Result<()> {