diff --git a/docs/config/README.md b/docs/config/README.md index c852aae0..a752a5f1 100644 --- a/docs/config/README.md +++ b/docs/config/README.md @@ -189,6 +189,7 @@ $hostname\ $shlvl\ $kubernetes\ $directory\ +$vcsh\ $git_branch\ $git_commit\ $git_state\ @@ -2717,6 +2718,39 @@ By default the module will be shown if any of the following conditions are met: format = "via [⍱ $version](bold white) " ``` +## VCSH + +The `vcsh` module displays the current active VCSH repository. +The module will be shown only if a repository is currently in use. + +### Options + +| Option | Default | Description | +| ---------- | -------------------------------- | -------------------------------------------------------| +| `symbol` | | The symbol used before displaying the repository name. | +| `style` | `"bold yellow"` | The style for the module. | +| `format` | `"vcsh [$symbol$repo]($style) "` | The format for the module. | +| `disabled` | `false` | Disables the `vcsh` module. | + +### Variables + +| Variable | Example | Description | +| -------- | ------------------------------------------- | -------------------------------------| +| repo | `dotfiles` if in a VCSH repo named dotfiles | The active repository name | +| symbol | | Mirrors the value of option `symbol` | +| style\* | `black bold dimmed` | Mirrors the value of option `style` | + +\*: This variable can only be used as a part of a style string + +### Example + +```toml +# ~/.config/starship.toml + +[vcsh] +format = "[🆅 $repo](bold blue) " +``` + ## Zig By default the the `zig` module shows the currently installed version of Zig. diff --git a/src/configs/mod.rs b/src/configs/mod.rs index 4ad15699..7f5ebf50 100644 --- a/src/configs/mod.rs +++ b/src/configs/mod.rs @@ -53,6 +53,7 @@ pub mod terraform; pub mod time; pub mod username; pub mod vagrant; +pub mod vcsh; pub mod zig; pub use starship_root::*; diff --git a/src/configs/starship_root.rs b/src/configs/starship_root.rs index 6b8bdf56..6bb913d4 100644 --- a/src/configs/starship_root.rs +++ b/src/configs/starship_root.rs @@ -20,6 +20,7 @@ pub const PROMPT_ORDER: &[&str] = &[ "singularity", "kubernetes", "directory", + "vcsh", "git_branch", "git_commit", "git_state", diff --git a/src/configs/vcsh.rs b/src/configs/vcsh.rs new file mode 100644 index 00000000..9d3a0e14 --- /dev/null +++ b/src/configs/vcsh.rs @@ -0,0 +1,22 @@ +use crate::config::ModuleConfig; + +use starship_module_config_derive::ModuleConfig; + +#[derive(Clone, ModuleConfig)] +pub struct VcshConfig<'a> { + pub symbol: &'a str, + pub style: &'a str, + pub format: &'a str, + pub disabled: bool, +} + +impl<'a> Default for VcshConfig<'a> { + fn default() -> Self { + VcshConfig { + symbol: "", + style: "bold yellow", + format: "vcsh [$symbol$repo]($style) ", + disabled: false, + } + } +} diff --git a/src/module.rs b/src/module.rs index c5ca928e..63eaef4d 100644 --- a/src/module.rs +++ b/src/module.rs @@ -63,6 +63,7 @@ pub const ALL_MODULES: &[&str] = &[ "status", "time", "username", + "vcsh", "vagrant", "zig", ]; diff --git a/src/modules/mod.rs b/src/modules/mod.rs index 35dd4f37..39e3b86d 100644 --- a/src/modules/mod.rs +++ b/src/modules/mod.rs @@ -54,6 +54,7 @@ mod time; mod username; mod utils; mod vagrant; +mod vcsh; mod zig; #[cfg(feature = "battery")] @@ -126,6 +127,7 @@ pub fn handle<'a>(module: &str, context: &'a Context) -> Option> { "crystal" => crystal::module(context), "username" => username::module(context), "vagrant" => vagrant::module(context), + "vcsh" => vcsh::module(context), "zig" => zig::module(context), _ => { eprintln!("Error: Unknown module {}. Use starship module --list to list out all supported modules.", module); @@ -203,6 +205,7 @@ pub fn description(module: &str) -> &'static str { "time" => "The current local time", "username" => "The active user's username", "vagrant" => "The currently installed version of Vagrant", + "vcsh" => "The currently active VCSH repository", "zig" => "The currently installed version of Zig", _ => "", } diff --git a/src/modules/vcsh.rs b/src/modules/vcsh.rs new file mode 100644 index 00000000..d115fc04 --- /dev/null +++ b/src/modules/vcsh.rs @@ -0,0 +1,74 @@ +use super::{Context, Module}; + +use crate::config::RootModuleConfig; +use crate::configs::vcsh::VcshConfig; +use crate::formatter::StringFormatter; + +/// Creates a module that displays VCSH repository currently in use +/// +/// Will display the name of the current VCSH repository if one is active. +pub fn module<'a>(context: &'a Context) -> Option> { + let repo = context.get_env("VCSH_REPO_NAME").unwrap_or_default(); + if repo.trim().is_empty() { + return None; + } + + let mut module = context.new_module("vcsh"); + let config: VcshConfig = VcshConfig::try_load(module.config); + + let parsed = StringFormatter::new(config.format).and_then(|formatter| { + formatter + .map_meta(|var, _| match var { + "symbol" => Some(config.symbol), + _ => None, + }) + .map_style(|variable| match variable { + "style" => Some(Ok(config.style)), + _ => None, + }) + .map(|variable| match variable { + "repo" => Some(Ok(&repo)), + _ => None, + }) + .parse(None) + }); + + module.set_segments(match parsed { + Ok(segments) => segments, + Err(error) => { + log::warn!("Error in module `vcsh`:\n{}", error); + return None; + } + }); + + Some(module) +} + +#[cfg(test)] +mod tests { + use crate::test::ModuleRenderer; + use ansi_term::Color; + + #[test] + fn not_in_env() { + let actual = ModuleRenderer::new("vcsh").collect(); + + let expected = None; + + assert_eq!(expected, actual); + } + + #[test] + fn env_set() { + let actual = ModuleRenderer::new("vcsh") + .env("VCSH_REPO_NAME", "astronauts") + .collect(); + + let expected = Some(format!( + "vcsh {} ", + Color::Yellow.bold().paint("astronauts") + )); + + assert_eq!(expected, actual); + } +}