diff --git a/docs/config/README.md b/docs/config/README.md index 61704656..64626ea3 100644 --- a/docs/config/README.md +++ b/docs/config/README.md @@ -122,6 +122,7 @@ prompt_order = [ "ruby", "rust", "terraform", + "zig", "nix_shell", "conda", "memory_usage", @@ -1363,6 +1364,31 @@ The module will be shown if any of the following conditions are met: disabled = true ``` + +## Zig + +The `zig` module shows the currently installed version of Zig. +The module will be shown if any of the following conditions are met: + +- The current directory contains a `.zig` file + +### Options + +| Variable | Default | Description | +| ---------- | ------------ | ------------------------------------------------------ | +| `symbol` | `"↯ "` | The symbol used before displaying the version of Zig. | +| `style` | `"bold yellow"` | The style for the module. | +| `disabled` | `false` | Disables the `zig` module. | + +### Example + +```toml +# ~/.config/starship.toml + +[zig] +symbol = "⚡️ " +``` + ## Custom commands The `custom` modules show the output of some arbitrary commands. diff --git a/src/configs/mod.rs b/src/configs/mod.rs index 5ee945ee..57521e52 100644 --- a/src/configs/mod.rs +++ b/src/configs/mod.rs @@ -38,5 +38,6 @@ mod starship_root; pub mod terraform; pub mod time; pub mod username; +pub mod zig; pub use starship_root::*; diff --git a/src/configs/starship_root.rs b/src/configs/starship_root.rs index d6ebdaa4..6d93cc46 100644 --- a/src/configs/starship_root.rs +++ b/src/configs/starship_root.rs @@ -46,6 +46,7 @@ impl<'a> RootModuleConfig<'a> for StarshipRootConfig<'a> { "ruby", "rust", "terraform", + "zig", // ↑ Toolchain version modules ↑ "nix_shell", "conda", diff --git a/src/configs/zig.rs b/src/configs/zig.rs new file mode 100644 index 00000000..af97b2c3 --- /dev/null +++ b/src/configs/zig.rs @@ -0,0 +1,23 @@ +use crate::config::{ModuleConfig, RootModuleConfig, SegmentConfig}; + +use ansi_term::{Color, Style}; +use starship_module_config_derive::ModuleConfig; + +#[derive(Clone, ModuleConfig)] +pub struct ZigConfig<'a> { + pub symbol: SegmentConfig<'a>, + pub version: SegmentConfig<'a>, + pub style: Style, + pub disabled: bool, +} + +impl<'a> RootModuleConfig<'a> for ZigConfig<'a> { + fn new() -> Self { + ZigConfig { + symbol: SegmentConfig::new("↯ "), + version: SegmentConfig::default(), + style: Color::Yellow.bold(), + disabled: false, + } + } +} diff --git a/src/module.rs b/src/module.rs index 8ea18024..89d7e508 100644 --- a/src/module.rs +++ b/src/module.rs @@ -50,6 +50,7 @@ pub const ALL_MODULES: &[&str] = &[ "singularity", "time", "username", + "zig", ]; /// A module is a collection of segments showing data for a single integration diff --git a/src/modules/mod.rs b/src/modules/mod.rs index 23f12bb2..39993de1 100644 --- a/src/modules/mod.rs +++ b/src/modules/mod.rs @@ -39,6 +39,7 @@ mod terraform; mod time; mod username; mod utils; +mod zig; #[cfg(feature = "battery")] mod battery; @@ -91,6 +92,7 @@ pub fn handle<'a>(module: &str, context: &'a Context) -> Option> { "time" => time::module(context), "crystal" => crystal::module(context), "username" => username::module(context), + "zig" => zig::module(context), _ => { eprintln!("Error: Unknown module {}. Use starship module --list to list out all supported modules.", module); None @@ -138,6 +140,7 @@ pub fn description(module: &str) -> &'static str { "terraform" => "The currently selected terraform workspace and version", "time" => "The current local time", "username" => "The active user's username", + "zig" => "The currently installed version of Zig", _ => "", } } diff --git a/src/modules/zig.rs b/src/modules/zig.rs new file mode 100644 index 00000000..6bf3e595 --- /dev/null +++ b/src/modules/zig.rs @@ -0,0 +1,63 @@ +use super::{Context, Module, RootModuleConfig}; + +use crate::configs::zig::ZigConfig; +use crate::utils; + +/// Creates a module with the current Zig version +/// +/// Will display the Zig version if any of the following criteria are met: +/// - The current directory contains a file with extension `.zig` +pub fn module<'a>(context: &'a Context) -> Option> { + let is_zig_project = context + .try_begin_scan()? + .set_extensions(&["zig"]) + .is_match(); + + if !is_zig_project { + return None; + } + + let zig_version_output = utils::exec_cmd("zig", &["version"])? + .stdout + .trim() + .to_string(); + let zig_version = format!("v{}", zig_version_output); + + let mut module = context.new_module("zig"); + let config = ZigConfig::try_load(module.config); + + module.set_style(config.style); + + module.create_segment("symbol", &config.symbol); + module.create_segment("version", &config.version.with_value(&zig_version)); + + Some(module) +} + +#[cfg(test)] +mod tests { + use crate::modules::utils::test::render_module; + use ansi_term::Color; + use std::fs::File; + use std::io; + + #[test] + fn folder_without_zig() -> io::Result<()> { + let dir = tempfile::tempdir()?; + File::create(dir.path().join("zig.txt"))?.sync_all()?; + let actual = render_module("zig", dir.path(), None); + let expected = None; + assert_eq!(expected, actual); + dir.close() + } + + #[test] + fn folder_with_zig_file() -> io::Result<()> { + let dir = tempfile::tempdir()?; + File::create(dir.path().join("main.zig"))?.sync_all()?; + let actual = render_module("zig", dir.path(), None); + let expected = Some(format!("via {} ", Color::Yellow.bold().paint("↯ v0.6.0"))); + assert_eq!(expected, actual); + dir.close() + } +} diff --git a/src/utils.rs b/src/utils.rs index fc5d81a2..606624f2 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -92,6 +92,10 @@ Elixir 1.10 (compiled with Erlang/OTP 22)", ), stderr: String::default(), }), + "zig version" => Some(CommandOutput { + stdout: String::from("0.6.0"), + stderr: String::default(), + }), s if s.starts_with("erl") => Some(CommandOutput { stdout: String::from("22.1.3"), stderr: String::default(),