diff --git a/docs/config/README.md b/docs/config/README.md index a5fb3421..5a07afc7 100644 --- a/docs/config/README.md +++ b/docs/config/README.md @@ -1420,7 +1420,7 @@ will simply show all custom modules in the order they were defined. | ------------- | ------------------- | ---------------------------------------------------------------------------- | | `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". | +| `shell` | | [See below](#custom-command-shell) | | `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. | @@ -1431,6 +1431,22 @@ will simply show all custom modules in the order they were defined. | `suffix` | `""` | Suffix to display immediately after the command output. | | `disabled` | `false` | Disables this `custom` module. | +#### Custom command shell + +`shell` accepts a non-empty list of strings, where: +- The first string is the path to the shell to use to execute the command. +- Other following arguments are passed to the shell. + +If unset, it will fallback to STARSHIP_SHELL and then to "sh" on Linux, and "cmd /C" on Windows. + +If `shell` is not given or only contains one element and Starship detects PowerShell will be used, +the following arguments will automatically be added: `-NoProfile -Command -`. +This behavior can be avoided by explicitly passing arguments to the shell, e.g. + +```toml +shell = ["pwsh", "-Command", "-"] +``` + ### Example ```toml diff --git a/src/config.rs b/src/config.rs index ab86a6ef..f940a8d0 100644 --- a/src/config.rs +++ b/src/config.rs @@ -153,6 +153,30 @@ where } } +/// A wrapper around `Vec` that implements `ModuleConfig`, and either +/// accepts a value of type `T` or a list of values of type `T`. +#[derive(Clone, Default)] +pub struct VecOr(pub Vec); + +impl<'a, T> ModuleConfig<'a> for VecOr +where + T: ModuleConfig<'a> + Sized, +{ + fn from_config(config: &'a Value) -> Option { + if let Some(item) = T::from_config(config) { + return Some(VecOr(vec![item])); + } + + let vec = config + .as_array()? + .iter() + .map(|value| T::from_config(value)) + .collect::>>()?; + + Some(VecOr(vec)) + } +} + /// Root config of starship. pub struct StarshipConfig { pub config: Option, diff --git a/src/configs/custom.rs b/src/configs/custom.rs index 89d4c67d..621b3980 100644 --- a/src/configs/custom.rs +++ b/src/configs/custom.rs @@ -1,4 +1,4 @@ -use crate::config::{ModuleConfig, RootModuleConfig, SegmentConfig}; +use crate::config::{ModuleConfig, RootModuleConfig, SegmentConfig, VecOr}; use ansi_term::Style; use starship_module_config_derive::ModuleConfig; @@ -17,7 +17,7 @@ pub struct CustomConfig<'a> { pub symbol: Option>, pub command: &'a str, pub when: Option<&'a str>, - pub shell: Option<&'a str>, + pub shell: VecOr<&'a str>, pub description: &'a str, pub style: Option