summaryrefslogtreecommitdiffstats
path: root/vendor/clap_complete/src/shells/shell.rs
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/clap_complete/src/shells/shell.rs')
-rw-r--r--vendor/clap_complete/src/shells/shell.rs80
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,
+ }
+}