mirror of
https://github.com/clap-rs/clap
synced 2024-12-13 22:32:33 +00:00
feat(complete): Support getting shell from env
Add functions for getting the Shell from a path and for getting the current shell form environment variables. Closes: #4446
This commit is contained in:
parent
033438eb4b
commit
86db119153
1 changed files with 64 additions and 0 deletions
|
@ -1,4 +1,5 @@
|
|||
use std::fmt::Display;
|
||||
use std::path::Path;
|
||||
use std::str::FromStr;
|
||||
|
||||
use clap::builder::PossibleValue;
|
||||
|
@ -89,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,
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue