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.
This commit is contained in:
Andrew Dassonville 2019-07-28 18:05:13 -07:00 committed by Matan Kushner
parent ab46710fc4
commit 5dbf4381ac
5 changed files with 109 additions and 6 deletions

View File

@ -116,9 +116,19 @@ git repo that you're currently in.
### Options ### Options
| Variable | Default | Description | | Variable | Default | Description |
| ---------- | ------- | -------------------------------- | | ------------------- | ------- | -------------------------------------- |
| `disabled` | `false` | Disables the `directory` module. | | `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 ## Git Branch

View File

@ -12,6 +12,7 @@ pub trait Config {
// Config accessor methods // Config accessor methods
fn get_as_bool(&self, key: &str) -> Option<bool>; fn get_as_bool(&self, key: &str) -> Option<bool>;
fn get_as_str(&self, key: &str) -> Option<&str>; fn get_as_str(&self, key: &str) -> Option<&str>;
fn get_as_i64(&self, key: &str) -> Option<i64>;
// Internal implementation for accessors // Internal implementation for accessors
fn get_config(&self, key: &str) -> Option<&toml::value::Value>; fn get_config(&self, key: &str) -> Option<&toml::value::Value>;
@ -129,6 +130,23 @@ impl Config for Table {
str_value str_value
} }
/// Get a key from a module's configuration as an integer
fn get_as_i64(&self, key: &str) -> Option<i64> {
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 { mod tests {
@ -165,4 +183,20 @@ mod tests {
table.insert(String::from("boolean"), toml::value::Value::Boolean(true)); table.insert(String::from("boolean"), toml::value::Value::Boolean(true));
assert_eq!(table.get_as_str("boolean"), None); 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);
}
} }

View File

@ -99,6 +99,16 @@ impl<'a> Module<'a> {
fn config_value(&self, key: &str) -> Option<&str> { fn config_value(&self, key: &str) -> Option<&str> {
self.config.and_then(|config| config.get_as_str(key)) 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<i64> {
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<bool> {
self.config.and_then(|config| config.get_as_bool(key))
}
} }
impl<'a> fmt::Display for Module<'a> { impl<'a> fmt::Display for Module<'a> {

View File

@ -15,12 +15,16 @@ use super::{Context, Module};
/// Paths will be limited in length to `3` path components by default. /// Paths will be limited in length to `3` path components by default.
pub fn module<'a>(context: &'a Context) -> Option<Module<'a>> { pub fn module<'a>(context: &'a Context) -> Option<Module<'a>> {
const HOME_SYMBOL: &str = "~"; const HOME_SYMBOL: &str = "~";
const DIR_TRUNCATION_LENGTH: usize = 3; const DIR_TRUNCATION_LENGTH: i64 = 3;
let module_color = Color::Cyan.bold(); let module_color = Color::Cyan.bold();
let mut module = context.new_module("directory")?; let mut module = context.new_module("directory")?;
module.set_style(module_color); 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; let current_dir = &context.current_dir;
log::debug!("Current directory: {:?}", current_dir); log::debug!("Current directory: {:?}", current_dir);
@ -38,7 +42,7 @@ pub fn module<'a>(context: &'a Context) -> Option<Module<'a>> {
} }
// Truncate the dir string to the maximum number of path components // 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.new_segment("path", &truncated_dir_string);
module.get_prefix().set_value("in "); module.get_prefix().set_value("in ");

View File

@ -6,7 +6,7 @@ use std::io;
use std::path::Path; use std::path::Path;
use tempfile::TempDir; use tempfile::TempDir;
use crate::common; use crate::common::{self, TestCommand};
#[test] #[test]
fn home_directory() -> io::Result<()> { fn home_directory() -> io::Result<()> {
@ -95,6 +95,51 @@ fn truncated_directory_in_root() -> io::Result<()> {
Ok(()) 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] #[test]
#[ignore] #[ignore]
fn git_repo_root() -> io::Result<()> { fn git_repo_root() -> io::Result<()> {