diff options
Diffstat (limited to 'vendor/clap_complete/src/shells/shell.rs')
-rw-r--r-- | vendor/clap_complete/src/shells/shell.rs | 80 |
1 files changed, 68 insertions, 12 deletions
diff --git a/vendor/clap_complete/src/shells/shell.rs b/vendor/clap_complete/src/shells/shell.rs index 63063bb7c..f6e70f575 100644 --- a/vendor/clap_complete/src/shells/shell.rs +++ b/vendor/clap_complete/src/shells/shell.rs @@ -1,7 +1,9 @@ use std::fmt::Display; +use std::path::Path; use std::str::FromStr; -use clap::{ArgEnum, PossibleValue}; +use clap::builder::PossibleValue; +use clap::ValueEnum; use crate::shells; use crate::Generator; @@ -22,15 +24,6 @@ pub enum Shell { Zsh, } -impl Shell { - /// Report all `possible_values` - pub fn possible_values() -> impl Iterator<Item = PossibleValue<'static>> { - Shell::value_variants() - .iter() - .filter_map(ArgEnum::to_possible_value) - } -} - impl Display for Shell { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { self.to_possible_value() @@ -54,7 +47,7 @@ impl FromStr for Shell { } // Hand-rolled so it can work even when `derive` feature is disabled -impl ArgEnum for Shell { +impl ValueEnum for Shell { fn value_variants<'a>() -> &'a [Self] { &[ Shell::Bash, @@ -65,7 +58,7 @@ impl ArgEnum for Shell { ] } - fn to_possible_value<'a>(&self) -> Option<PossibleValue<'a>> { + fn to_possible_value<'a>(&self) -> Option<PossibleValue> { Some(match self { Shell::Bash => PossibleValue::new("bash"), Shell::Elvish => PossibleValue::new("elvish"), @@ -97,3 +90,66 @@ impl Generator for Shell { } } } + +impl Shell { + /// Parse a shell from a path to the executable for the shell + /// + /// # Examples + /// + /// ``` + /// use clap_complete::shells::Shell; + /// + /// assert_eq!(Shell::from_shell_path("/bin/bash"), Some(Shell::Bash)); + /// assert_eq!(Shell::from_shell_path("/usr/bin/zsh"), Some(Shell::Zsh)); + /// assert_eq!(Shell::from_shell_path("/opt/my_custom_shell"), None); + /// ``` + pub fn from_shell_path<P: AsRef<Path>>(path: P) -> Option<Shell> { + parse_shell_from_path(path.as_ref()) + } + + /// Determine the user's current shell from the environment + /// + /// This will read the SHELL environment variable and try to determine which shell is in use + /// from that. + /// + /// If SHELL is not set, then on windows, it will default to powershell, and on + /// other OSes it will return `None`. + /// + /// If SHELL is set, but contains a value that doesn't correspond to one of the supported shell + /// types, then return `None`. + /// + /// # Example: + /// + /// ```no_run + /// # use clap::Command; + /// use clap_complete::{generate, shells::Shell}; + /// # fn build_cli() -> Command { + /// # Command::new("compl") + /// # } + /// let mut cmd = build_cli(); + /// generate(Shell::from_env().unwrap_or(Shell::Bash), &mut cmd, "myapp", &mut std::io::stdout()); + /// ``` + pub fn from_env() -> Option<Shell> { + if let Some(env_shell) = std::env::var_os("SHELL") { + Shell::from_shell_path(env_shell) + } else if cfg!(windows) { + Some(Shell::PowerShell) + } else { + None + } + } +} + +// use a separate function to avoid having to monomorphize the entire function due +// to from_shell_path being generic +fn parse_shell_from_path(path: &Path) -> Option<Shell> { + let name = path.file_stem()?.to_str()?; + match name { + "bash" => Some(Shell::Bash), + "zsh" => Some(Shell::Zsh), + "fish" => Some(Shell::Fish), + "elvish" => Some(Shell::Elvish), + "powershell" | "powershell_ise" => Some(Shell::PowerShell), + _ => None, + } +} |