From 15dc486e7263fbf354e57a814880667a719122f0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gr=C3=A9goire=20Geis?= Date: Sat, 11 Apr 2020 18:37:24 +0200 Subject: [PATCH] Add support for custom modules. (#916) --- Cargo.lock | 10 ++ Cargo.toml | 2 +- docs/config/README.md | 54 +++++++ src/config.rs | 20 +++ src/configs/custom.rs | 96 ++++++++++++ src/configs/mod.rs | 1 + src/configs/starship_root.rs | 1 + src/context.rs | 9 ++ src/modules/custom.rs | 288 +++++++++++++++++++++++++++++++++++ src/modules/mod.rs | 1 + src/print.rs | 87 ++++++++++- 11 files changed, 561 insertions(+), 8 deletions(-) create mode 100644 src/configs/custom.rs create mode 100644 src/modules/custom.rs diff --git a/Cargo.lock b/Cargo.lock index f1fb3ad2..be2df1ce 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -412,6 +412,14 @@ dependencies = [ "unicode-normalization 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "indexmap" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "autocfg 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "itoa" version = "0.4.5" @@ -1135,6 +1143,7 @@ name = "toml" version = "0.5.6" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ + "indexmap 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.105 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1325,6 +1334,7 @@ dependencies = [ "checksum http 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b708cc7f06493459026f53b9a61a7a121a5d1ec6238dee58ea4941132b30156b" "checksum humantime 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "df004cfca50ef23c36850aaaa59ad52cc70d0e90243c3c7737a4dd32dc7a3c4f" "checksum idna 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "02e2673c30ee86b5b96a9cb52ad15718aa1f966f5ab9ad54a8b95d5ca33120a9" +"checksum indexmap 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "076f042c5b7b98f31d205f1249267e12a6518c1481e9dae9764af19b707d2292" "checksum itoa 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)" = "b8b7a7c0c47db5545ed3fef7468ee7bb5b74691498139e4b3f6a20685dc6dd8e" "checksum jobserver 0.1.21 (registry+https://github.com/rust-lang/crates.io-index)" = "5c71313ebb9439f74b00d9d2dcec36440beaf57a6aa0623068441dd7cd81a7f2" "checksum kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d" diff --git a/Cargo.toml b/Cargo.toml index f3785a89..288b2aa0 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -32,7 +32,7 @@ clap = "2.33.0" ansi_term = "0.12.1" dirs = "2.0.2" git2 = { version = "0.13.1", default-features = false, features = [] } -toml = "0.5.6" +toml = { version = "0.5.6", features = ["preserve_order"] } serde_json = "1.0.51" rayon = "1.3.0" pretty_env_logger = "0.4.0" diff --git a/docs/config/README.md b/docs/config/README.md index 64869269..5a87152c 100644 --- a/docs/config/README.md +++ b/docs/config/README.md @@ -122,6 +122,7 @@ prompt_order = [ "env_var", "crystal", "cmd_duration", + "custom", "line_break", "jobs", "battery", @@ -1299,3 +1300,56 @@ The module will be shown if any of the following conditions are met: [username] disabled = true ``` + +## Custom commands + +The `custom` modules show the output of some arbitrary commands. + +These modules will be shown if any of the following conditions are met: +- The current directory contains a file whose name is in `files` +- The current directory contains a directory whose name is in `directories` +- The current directory contains a file whose extension is in `extensions` +- The `when` command returns 0 + +::: tip + +Multiple custom modules can be defined by using a `.`. + +::: + +::: tip + +The order in which custom modules are shown can be individually set +by setting `custom.foo` in `prompt_order`. By default, the `custom` module +will simply show all custom modules in the order they were defined. + +::: + +### Options + +| Variable | Default | Description | +| ------------- | ------------------- | ---------------------------------------------------------------------------- | +| `command` | | The command whose output should be printed. | +| `when` | | A shell command used as a condition to show the module. The module will be shown if the command returns a `0` status code. | +| `shell` | | The path to the shell to use to execute the command. If unset, it will fallback to STARSHIP_SHELL and then to "sh". | +| `description` | `""` | The description of the module that is shown when running `starship explain`. | +| `files` | `[]` | The files that will be searched in the working directory for a match. | +| `directories` | `[]` | The directories that will be searched in the working directory for a match. | +| `extensions` | `[]` | The extensions that will be searched in the working directory for a match. | +| `symbol` | `""` | The symbol used before displaying the command output. | +| `style` | `"bold green"` | The style for the module. | +| `prefix` | `""` | Prefix to display immediately before the command output. | +| `suffix` | `""` | Suffix to display immediately after the command output. | +| `disabled` | `false` | Disables this `custom` module. | + +### Example + +```toml +# ~/.config/starship.toml + +[custom.foo] +command = "echo foo" # shows output of command +files = ["foo"] # can specify filters +when = """ test "$HOME" == "$PWD" """ +prefix = " transcending " +``` diff --git a/src/config.rs b/src/config.rs index 23535155..50456093 100644 --- a/src/config.rs +++ b/src/config.rs @@ -218,6 +218,26 @@ impl StarshipConfig { module_config } + /// Get the subset of the table for a custom module by its name + pub fn get_custom_module_config(&self, module_name: &str) -> Option<&Value> { + let module_config = self.get_custom_modules()?.get(module_name); + if module_config.is_some() { + log::debug!( + "Custom config found for \"{}\": \n{:?}", + &module_name, + &module_config + ); + } else { + log::trace!("No custom config found for \"{}\"", &module_name); + } + module_config + } + + /// Get the table of all the registered custom modules, if any + pub fn get_custom_modules(&self) -> Option<&toml::value::Table> { + self.config.as_ref()?.as_table()?.get("custom")?.as_table() + } + pub fn get_root_config(&self) -> StarshipRootConfig { if let Some(root_config) = &self.config { StarshipRootConfig::load(root_config) diff --git a/src/configs/custom.rs b/src/configs/custom.rs new file mode 100644 index 00000000..89d4c67d --- /dev/null +++ b/src/configs/custom.rs @@ -0,0 +1,96 @@ +use crate::config::{ModuleConfig, RootModuleConfig, SegmentConfig}; + +use ansi_term::Style; +use starship_module_config_derive::ModuleConfig; + +#[derive(Clone, Default, PartialEq)] +pub struct Files<'a>(pub Vec<&'a str>); + +#[derive(Clone, Default, PartialEq)] +pub struct Extensions<'a>(pub Vec<&'a str>); + +#[derive(Clone, Default, PartialEq)] +pub struct Directories<'a>(pub Vec<&'a str>); + +#[derive(Clone, ModuleConfig)] +pub struct CustomConfig<'a> { + pub symbol: Option>, + pub command: &'a str, + pub when: Option<&'a str>, + pub shell: Option<&'a str>, + pub description: &'a str, + pub style: Option