From be2d5cf1cd23d2b33892445f5d73dda5b165e7a7 Mon Sep 17 00:00:00 2001 From: Zhenhui Xie Date: Tue, 15 Oct 2019 19:34:48 +0800 Subject: [PATCH] refactor: Rewrite cmd_duration, directory and env_var module to use module config (#460) This PR is a batched rewrite of the following modules: - cmd_duration - directory - env_var --- docs/config/README.md | 2 +- src/configs/cmd_duration.rs | 23 +++++++++++++++++++ src/configs/directory.rs | 27 ++++++++++++++++++++++ src/configs/env_var.rs | 29 +++++++++++++++++++++++ src/configs/mod.rs | 3 +++ src/modules/cmd_duration.rs | 25 ++++++++------------ src/modules/directory.rs | 46 +++++++++++++++++++------------------ src/modules/env_var.rs | 31 +++++++++++++------------ 8 files changed, 132 insertions(+), 54 deletions(-) create mode 100644 src/configs/cmd_duration.rs create mode 100644 src/configs/directory.rs create mode 100644 src/configs/env_var.rs diff --git a/docs/config/README.md b/docs/config/README.md index 81c19cea..89c4f16a 100644 --- a/docs/config/README.md +++ b/docs/config/README.md @@ -264,7 +264,7 @@ running `eval $(starship init $0)`, and then proceed as normal. | Variable | Default | Description | | ---------- | --------------- | ---------------------------------------------------------- | | `min_time` | `2` | Shortest duration to show time for. | -| `prefix` | `took` | Prefix to display immediately before the command duration. | +| `prefix` | `took ` | Prefix to display immediately before the command duration. | | `style` | `"bold yellow"` | The style for the module. | | `disabled` | `false` | Disables the `cmd_duration` module. | diff --git a/src/configs/cmd_duration.rs b/src/configs/cmd_duration.rs new file mode 100644 index 00000000..2cf7a85a --- /dev/null +++ b/src/configs/cmd_duration.rs @@ -0,0 +1,23 @@ +use crate::config::{ModuleConfig, RootModuleConfig}; + +use ansi_term::{Color, Style}; +use starship_module_config_derive::ModuleConfig; + +#[derive(Clone, ModuleConfig)] +pub struct CmdDurationConfig<'a> { + pub min_time: i64, + pub prefix: &'a str, + pub style: Style, + pub disabled: bool, +} + +impl<'a> RootModuleConfig<'a> for CmdDurationConfig<'a> { + fn new() -> Self { + CmdDurationConfig { + min_time: 2, + prefix: "took ", + style: Color::Yellow.bold(), + disabled: false, + } + } +} diff --git a/src/configs/directory.rs b/src/configs/directory.rs new file mode 100644 index 00000000..40574fd1 --- /dev/null +++ b/src/configs/directory.rs @@ -0,0 +1,27 @@ +use crate::config::{ModuleConfig, RootModuleConfig}; + +use ansi_term::{Color, Style}; +use starship_module_config_derive::ModuleConfig; + +#[derive(Clone, ModuleConfig)] +pub struct DirectoryConfig { + pub truncation_length: i64, + pub truncate_to_repo: bool, + pub fish_style_pwd_dir_length: i64, + pub use_logical_path: bool, + pub style: Style, + pub disabled: bool, +} + +impl<'a> RootModuleConfig<'a> for DirectoryConfig { + fn new() -> Self { + DirectoryConfig { + truncation_length: 3, + truncate_to_repo: true, + fish_style_pwd_dir_length: 0, + use_logical_path: true, + style: Color::Cyan.bold(), + disabled: false, + } + } +} diff --git a/src/configs/env_var.rs b/src/configs/env_var.rs new file mode 100644 index 00000000..fc4e6533 --- /dev/null +++ b/src/configs/env_var.rs @@ -0,0 +1,29 @@ +use crate::config::{ModuleConfig, RootModuleConfig, SegmentConfig}; + +use ansi_term::{Color, Style}; +use starship_module_config_derive::ModuleConfig; + +#[derive(Clone, ModuleConfig)] +pub struct EnvVarConfig<'a> { + pub symbol: Option>, + pub variable: Option<&'a str>, + pub default: Option<&'a str>, + pub prefix: &'a str, + pub suffix: &'a str, + pub style: Style, + pub disabled: bool, +} + +impl<'a> RootModuleConfig<'a> for EnvVarConfig<'a> { + fn new() -> Self { + EnvVarConfig { + symbol: None, + variable: None, + default: None, + prefix: "", + suffix: "", + style: Color::Black.bold().dimmed(), + disabled: false, + } + } +} diff --git a/src/configs/mod.rs b/src/configs/mod.rs index 40ed6293..b26c1ebf 100644 --- a/src/configs/mod.rs +++ b/src/configs/mod.rs @@ -1,8 +1,11 @@ pub mod aws; pub mod battery; pub mod character; +pub mod cmd_duration; pub mod conda; +pub mod directory; pub mod dotnet; +pub mod env_var; pub mod go; pub mod hostname; pub mod jobs; diff --git a/src/modules/cmd_duration.rs b/src/modules/cmd_duration.rs index 8d481639..a0340cb0 100644 --- a/src/modules/cmd_duration.rs +++ b/src/modules/cmd_duration.rs @@ -1,13 +1,15 @@ -use ansi_term::Color; - use super::{Context, Module}; +use crate::config::RootModuleConfig; +use crate::configs::cmd_duration::CmdDurationConfig; + /// Outputs the time it took the last command to execute /// /// Will only print if last command took more than a certain amount of time to /// execute. Default is two seconds, but can be set by config option `min_time`. pub fn module<'a>(context: &'a Context) -> Option> { let mut module = context.new_module("cmd_duration"); + let config: CmdDurationConfig = CmdDurationConfig::try_load(module.config); let arguments = &context.arguments; let elapsed = arguments @@ -16,36 +18,27 @@ pub fn module<'a>(context: &'a Context) -> Option> { .parse::() .ok()?; - let prefix = module - .config_value_str("prefix") - .unwrap_or("took ") - .to_owned(); - - let signed_config_min = module.config_value_i64("min_time").unwrap_or(2); - /* TODO: Once error handling is implemented, warn the user if their config min time is nonsensical */ - if signed_config_min < 0 { + if config.min_time < 0 { log::debug!( "[WARN]: min_time in [cmd_duration] ({}) was less than zero", - signed_config_min + config.min_time ); return None; } - let config_min = signed_config_min as u64; + let config_min = config.min_time as u64; let module_color = match elapsed { time if time < config_min => return None, - _ => module - .config_value_style("style") - .unwrap_or_else(|| Color::Yellow.bold()), + _ => config.style, }; module.set_style(module_color); module.new_segment( "cmd_duration", - &format!("{}{}", prefix, render_time(elapsed)), + &format!("{}{}", config.prefix, render_time(elapsed)), ); module.get_prefix().set_value(""); diff --git a/src/modules/directory.rs b/src/modules/directory.rs index 46968b6d..1a3a209c 100644 --- a/src/modules/directory.rs +++ b/src/modules/directory.rs @@ -1,9 +1,11 @@ -use ansi_term::Color; use path_slash::PathExt; use std::path::Path; use super::{Context, Module}; +use crate::config::{RootModuleConfig, SegmentConfig}; +use crate::configs::directory::DirectoryConfig; + /// Creates a module with the current directory /// /// Will perform path contraction and truncation. @@ -16,27 +18,15 @@ 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: i64 = 3; - const FISH_STYLE_PWD_DIR_LENGTH: i64 = 0; let mut module = context.new_module("directory"); - let module_color = module - .config_value_style("style") - .unwrap_or_else(|| Color::Cyan.bold()); - module.set_style(module_color); + let config: DirectoryConfig = DirectoryConfig::try_load(module.config); - let truncation_length = module - .config_value_i64("truncation_length") - .unwrap_or(DIR_TRUNCATION_LENGTH); - let truncate_to_repo = module.config_value_bool("truncate_to_repo").unwrap_or(true); - let fish_style_pwd_dir_length = module - .config_value_i64("fish_style_pwd_dir_length") - .unwrap_or(FISH_STYLE_PWD_DIR_LENGTH); + module.set_style(config.style); // Using environment PWD is the standard approach for determining logical path - let use_logical_path = module.config_value_bool("use_logical_path").unwrap_or(true); // If this is None for any reason, we fall back to reading the os-provided path - let logical_current_dir = if use_logical_path { + let logical_current_dir = if config.use_logical_path { match std::env::var("PWD") { Ok(x) => Some(x), Err(_) => { @@ -58,7 +48,7 @@ pub fn module<'a>(context: &'a Context) -> Option> { let repo = &context.get_repo().ok()?; let dir_string = match &repo.root { - Some(repo_root) if truncate_to_repo && (repo_root != &home_dir) => { + Some(repo_root) if config.truncate_to_repo && (repo_root != &home_dir) => { let repo_folder_name = repo_root.file_name().unwrap().to_str().unwrap(); // Contract the path to the git repo root @@ -69,21 +59,33 @@ 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, truncation_length as usize); + let truncated_dir_string = truncate(dir_string, config.truncation_length as usize); - if fish_style_pwd_dir_length > 0 { + if config.fish_style_pwd_dir_length > 0 { // 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( - fish_style_pwd_dir_length as usize, + config.fish_style_pwd_dir_length as usize, contracted_home_dir, &truncated_dir_string, ); - module.new_segment("path", &fish_style_dir); + module.create_segment( + "path", + &SegmentConfig { + value: &fish_style_dir, + style: None, + }, + ); } - module.new_segment("path", &truncated_dir_string); + module.create_segment( + "path", + &SegmentConfig { + value: &truncated_dir_string, + style: None, + }, + ); module.get_prefix().set_value("in "); diff --git a/src/modules/env_var.rs b/src/modules/env_var.rs index bb46456a..f4905fda 100644 --- a/src/modules/env_var.rs +++ b/src/modules/env_var.rs @@ -1,8 +1,10 @@ -use ansi_term::Color; use std::env; use super::{Context, Module}; +use crate::config::RootModuleConfig; +use crate::configs::env_var::EnvVarConfig; + /// Creates a module with the value of the chosen environment variable /// /// Will display the environment variable's value if all of the following criteria are met: @@ -11,23 +13,22 @@ use super::{Context, Module}; /// - a variable named as the value of env_var.variable is defined pub fn module<'a>(context: &'a Context) -> Option> { let mut module = context.new_module("env_var"); - let module_style = module - .config_value_style("style") - .unwrap_or_else(|| Color::Black.bold().dimmed()); + let config: EnvVarConfig = EnvVarConfig::try_load(module.config); - let env_name = module.config_value_str("variable")?; + let env_value = get_env_value(config.variable?, config.default)?; - let default_value = module.config_value_str("default"); - - let env_value = get_env_value(env_name, default_value)?; - - let prefix = module.config_value_str("prefix").unwrap_or("").to_owned(); - let suffix = module.config_value_str("suffix").unwrap_or("").to_owned(); - - module.set_style(module_style); + module.set_style(config.style); module.get_prefix().set_value("with "); - module.new_segment_if_config_exists("symbol"); - module.new_segment("env_var", &format!("{}{}{}", prefix, env_value, suffix)); + + if let Some(symbol) = config.symbol { + module.create_segment("symbol", &symbol); + } + + // TODO: Use native prefix and suffix instead of stacking custom ones together with env_value. + module.new_segment( + "env_var", + &format!("{}{}{}", config.prefix, env_value, config.suffix), + ); Some(module) }