diff --git a/README.md b/README.md index 563539b9..bd14f3f7 100644 --- a/README.md +++ b/README.md @@ -88,6 +88,7 @@ The prompt shows information you need while you're working, while staying sleek ## 🍬 Features - Prompt character turns red if the last command exits with non-zero code +- Current Elm version (`🌳`) - Current Go version (`🐹`) - Current Haskell version (`λ`) - Current Java version(`☕`) diff --git a/docs/config/README.md b/docs/config/README.md index 2f26cc38..68c37e87 100644 --- a/docs/config/README.md +++ b/docs/config/README.md @@ -102,6 +102,7 @@ prompt_order = [ "hg_branch", "package", "dotnet", + "elm", "golang", "haskell", "java", @@ -405,6 +406,34 @@ style = "green" heuristic = false ``` +## Elm + +The `elm` module shows the currently installed version of Elm version. +The module will be shown if any of the following conditions are met: + +- The current directory contains a `elm.json` file +- The current directory contains a `elm-package.json` file +- The current directory contains a `elm-stuff` folder +- The current directory contains a `*.elm` files + +### Options + +| Variable | Default | Description | +| ---------- | ------------- | --------------------------------------------------------- | +| `symbol` | `"🌳 "` | The symbol used before displaying the version of Elm. | +| `style` | `"bold cyan"` | The style for the module. | +| `disabled` | `false` | Disables the `elm` module. | + + +### Example + +```toml +# ~/.config/starship.toml + +[elm] +symbol = "λx.x " +``` + ## Environment Variable The `env_var` module displays the current value of a selected environment variable. diff --git a/src/configs/elm.rs b/src/configs/elm.rs new file mode 100644 index 00000000..5c8e9a96 --- /dev/null +++ b/src/configs/elm.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 ElmConfig<'a> { + pub symbol: SegmentConfig<'a>, + pub version: SegmentConfig<'a>, + pub style: Style, + pub disabled: bool, +} + +impl<'a> RootModuleConfig<'a> for ElmConfig<'a> { + fn new() -> Self { + ElmConfig { + symbol: SegmentConfig::new("🌳 "), + version: SegmentConfig::default(), + style: Color::Cyan.bold(), + disabled: false, + } + } +} diff --git a/src/configs/mod.rs b/src/configs/mod.rs index b3950b50..d3c6d4f3 100644 --- a/src/configs/mod.rs +++ b/src/configs/mod.rs @@ -6,6 +6,7 @@ pub mod conda; pub mod crystal; pub mod directory; pub mod dotnet; +pub mod elm; pub mod env_var; pub mod git_branch; pub mod git_commit; diff --git a/src/configs/starship_root.rs b/src/configs/starship_root.rs index 14f17179..db024df7 100644 --- a/src/configs/starship_root.rs +++ b/src/configs/starship_root.rs @@ -30,6 +30,7 @@ impl<'a> RootModuleConfig<'a> for StarshipRootConfig<'a> { // ↓ Toolchain version modules ↓ // (Let's keep these sorted alphabetically) "dotnet", + "elm", "golang", "haskell", "java", diff --git a/src/module.rs b/src/module.rs index c3d283d8..60108d47 100644 --- a/src/module.rs +++ b/src/module.rs @@ -17,6 +17,7 @@ pub const ALL_MODULES: &[&str] = &[ "conda", "directory", "dotnet", + "elm", "env_var", "git_branch", "git_commit", diff --git a/src/modules/elm.rs b/src/modules/elm.rs new file mode 100644 index 00000000..2acc87ac --- /dev/null +++ b/src/modules/elm.rs @@ -0,0 +1,95 @@ +use super::{Context, Module, RootModuleConfig, SegmentConfig}; + +use crate::configs::elm::ElmConfig; +use crate::utils; + +/// Creates a module with the current Elm version +/// +/// Will display the Elm version if any of the following criteria are met: +/// - The current directory contains a `elm.json` file +/// - The current directory contains a `elm-package.json` file +/// - The current directory contains a `elm-stuff` folder +/// - The current directory contains a `*.elm` files +pub fn module<'a>(context: &'a Context) -> Option> { + let is_elm_project = context + .try_begin_scan()? + .set_files(&["elm.json", "elm-package.json"]) + .set_extensions(&["elm"]) + .set_folders(&["elm-stuff"]) + .is_match(); + + if !is_elm_project { + return None; + } + + let elm_version = utils::exec_cmd("elm", &["--version"])?.stdout; + let formatted_version = Some(format!("v{}", elm_version.trim()))?; + + let mut module = context.new_module("elm"); + let config: ElmConfig = ElmConfig::try_load(module.config); + module.set_style(config.style); + + module.create_segment("symbol", &config.symbol); + module.create_segment("version", &SegmentConfig::new(&formatted_version)); + + Some(module) +} + +#[cfg(test)] +mod tests { + use crate::modules::utils::test::render_module; + use ansi_term::Color; + use std::fs::{self, File}; + use std::io; + use tempfile; + + #[test] + fn folder_without_elm() -> io::Result<()> { + let dir = tempfile::tempdir()?; + let actual = render_module("elm", dir.path()); + let expected = None; + assert_eq!(expected, actual); + Ok(()) + } + + #[test] + fn folder_with_elm_json() -> io::Result<()> { + let dir = tempfile::tempdir()?; + File::create(dir.path().join("elm.json"))?.sync_all()?; + let actual = render_module("elm", dir.path()); + let expected = Some(format!("via {} ", Color::Cyan.bold().paint("🌳 v0.19.1"))); + assert_eq!(expected, actual); + Ok(()) + } + + #[test] + fn folder_with_elm_package_json() -> io::Result<()> { + let dir = tempfile::tempdir()?; + File::create(dir.path().join("elm-package.json"))?.sync_all()?; + let actual = render_module("elm", dir.path()); + let expected = Some(format!("via {} ", Color::Cyan.bold().paint("🌳 v0.19.1"))); + assert_eq!(expected, actual); + Ok(()) + } + + #[test] + fn folder_with_elm_stuff_directory() -> io::Result<()> { + let dir = tempfile::tempdir()?; + let elmstuff = dir.path().join("elm-stuff"); + fs::create_dir_all(&elmstuff)?; + let actual = render_module("elm", dir.path()); + let expected = Some(format!("via {} ", Color::Cyan.bold().paint("🌳 v0.19.1"))); + assert_eq!(expected, actual); + Ok(()) + } + + #[test] + fn folder_with_elm_file() -> io::Result<()> { + let dir = tempfile::tempdir()?; + File::create(dir.path().join("main.elm"))?.sync_all()?; + let actual = render_module("elm", dir.path()); + let expected = Some(format!("via {} ", Color::Cyan.bold().paint("🌳 v0.19.1"))); + assert_eq!(expected, actual); + Ok(()) + } +} diff --git a/src/modules/mod.rs b/src/modules/mod.rs index 2852d169..a1a5d192 100644 --- a/src/modules/mod.rs +++ b/src/modules/mod.rs @@ -6,6 +6,7 @@ mod conda; mod crystal; mod directory; mod dotnet; +mod elm; mod env_var; mod git_branch; mod git_commit; @@ -51,6 +52,7 @@ pub fn handle<'a>(module: &str, context: &'a Context) -> Option> { "conda" => conda::module(context), "directory" => directory::module(context), "dotnet" => dotnet::module(context), + "elm" => elm::module(context), "env_var" => env_var::module(context), "git_branch" => git_branch::module(context), "git_commit" => git_commit::module(context), diff --git a/src/utils.rs b/src/utils.rs index 01039093..d9bd2963 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -37,6 +37,10 @@ pub fn exec_cmd(cmd: &str, args: &[&str]) -> Option { _ => format!("{} {}", cmd, args.join(" ")), }; match command.as_str() { + "elm --version" => Some(CommandOutput { + stdout: String::from("0.19.1"), + stderr: String::default(), + }), "node --version" => Some(CommandOutput { stdout: String::from("v12.0.0"), stderr: String::default(),