summaryrefslogtreecommitdiffstats
path: root/vendor/clap_complete/src/shells
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/clap_complete/src/shells')
-rw-r--r--vendor/clap_complete/src/shells/bash.rs76
-rw-r--r--vendor/clap_complete/src/shells/elvish.rs16
-rw-r--r--vendor/clap_complete/src/shells/fish.rs29
-rw-r--r--vendor/clap_complete/src/shells/powershell.rs16
-rw-r--r--vendor/clap_complete/src/shells/shell.rs80
-rw-r--r--vendor/clap_complete/src/shells/zsh.rs45
6 files changed, 169 insertions, 93 deletions
diff --git a/vendor/clap_complete/src/shells/bash.rs b/vendor/clap_complete/src/shells/bash.rs
index 08bf1190c..e110537e5 100644
--- a/vendor/clap_complete/src/shells/bash.rs
+++ b/vendor/clap_complete/src/shells/bash.rs
@@ -31,8 +31,8 @@ impl Generator for Bash {
for i in ${{COMP_WORDS[@]}}
do
- case \"${{i}}\" in
- \"$1\")
+ case \"${{cmd}},${{i}}\" in
+ \",$1\")
cmd=\"{cmd}\"
;;{subcmds}
*)
@@ -75,26 +75,52 @@ complete -F _{name} -o bashdefault -o default {name}
fn all_subcommands(cmd: &Command) -> String {
debug!("all_subcommands");
- let mut subcmds = vec![String::new()];
- let mut scs = utils::all_subcommands(cmd)
- .iter()
- .map(|x| x.0.clone())
- .collect::<Vec<_>>();
-
- scs.sort();
- scs.dedup();
+ fn add_command(
+ parent_fn_name: &str,
+ cmd: &Command,
+ subcmds: &mut Vec<(String, String, String)>,
+ ) {
+ let fn_name = format!(
+ "{parent_fn_name}__{cmd_name}",
+ parent_fn_name = parent_fn_name,
+ cmd_name = cmd.get_name().to_string().replace('-', "__")
+ );
+ subcmds.push((
+ parent_fn_name.to_string(),
+ cmd.get_name().to_string(),
+ fn_name.clone(),
+ ));
+ for alias in cmd.get_visible_aliases() {
+ subcmds.push((
+ parent_fn_name.to_string(),
+ alias.to_string(),
+ fn_name.clone(),
+ ));
+ }
+ for subcmd in cmd.get_subcommands() {
+ add_command(&fn_name, subcmd, subcmds);
+ }
+ }
+ let mut subcmds = vec![];
+ let fn_name = cmd.get_name().replace('-', "__");
+ for subcmd in cmd.get_subcommands() {
+ add_command(&fn_name, subcmd, &mut subcmds);
+ }
+ subcmds.sort();
- subcmds.extend(scs.iter().map(|sc| {
- format!(
- "{name})
- cmd+=\"__{fn_name}\"
+ let mut cases = vec![String::new()];
+ for (parent_fn_name, name, fn_name) in subcmds {
+ cases.push(format!(
+ "{parent_fn_name},{name})
+ cmd=\"{fn_name}\"
;;",
- name = sc,
- fn_name = sc.replace('-', "__")
- )
- }));
+ parent_fn_name = parent_fn_name,
+ name = name,
+ fn_name = fn_name,
+ ));
+ }
- subcmds.join("\n ")
+ cases.join("\n ")
}
fn subcommand_details(cmd: &Command) -> String {
@@ -125,9 +151,9 @@ fn subcommand_details(cmd: &Command) -> String {
return 0
;;",
subcmd = sc.replace('-', "__"),
- sc_opts = all_options_for_path(cmd, &*sc),
+ sc_opts = all_options_for_path(cmd, sc),
level = sc.split("__").map(|_| 1).sum::<u64>(),
- opts_details = option_details_for_path(cmd, &*sc)
+ opts_details = option_details_for_path(cmd, sc)
)
}));
@@ -174,12 +200,12 @@ fn option_details_for_path(cmd: &Command, path: &str) -> String {
fn vals_for(o: &Arg) -> String {
debug!("vals_for: o={}", o.get_id());
- if let Some(vals) = o.get_possible_values() {
+ if let Some(vals) = crate::generator::utils::possible_values(o) {
format!(
"$(compgen -W \"{}\" -- \"${{cur}}\")",
vals.iter()
- .filter(|pv| pv.is_hide_set())
- .map(PossibleValue::get_name)
+ .filter(|pv| !pv.is_hide_set())
+ .map(|n| n.get_name())
.collect::<Vec<_>>()
.join(" ")
)
@@ -201,7 +227,7 @@ fn all_options_for_path(cmd: &Command, path: &str) -> String {
write!(&mut opts, "--{} ", long).unwrap();
}
for pos in p.get_positionals() {
- if let Some(vals) = pos.get_possible_values() {
+ if let Some(vals) = utils::possible_values(pos) {
for value in vals {
write!(&mut opts, "{} ", value.get_name()).unwrap();
}
diff --git a/vendor/clap_complete/src/shells/elvish.rs b/vendor/clap_complete/src/shells/elvish.rs
index 959372087..07da28348 100644
--- a/vendor/clap_complete/src/shells/elvish.rs
+++ b/vendor/clap_complete/src/shells/elvish.rs
@@ -1,5 +1,6 @@
use std::io::Write;
+use clap::builder::StyledStr;
use clap::*;
use crate::generator::{utils, Generator};
@@ -19,8 +20,7 @@ impl Generator for Elvish {
.get_bin_name()
.expect("crate::generate should have set the bin_name");
- let mut names = vec![];
- let subcommands_cases = generate_inner(cmd, "", &mut names);
+ let subcommands_cases = generate_inner(cmd, "");
let result = format!(
r#"
@@ -59,18 +59,14 @@ fn escape_string(string: &str) -> String {
string.replace('\'', "''")
}
-fn get_tooltip<T: ToString>(help: Option<&str>, data: T) -> String {
+fn get_tooltip<T: ToString>(help: Option<&StyledStr>, data: T) -> String {
match help {
- Some(help) => escape_string(help),
+ Some(help) => escape_string(&help.to_string()),
_ => data.to_string(),
}
}
-fn generate_inner<'help>(
- p: &Command<'help>,
- previous_command_name: &str,
- names: &mut Vec<&'help str>,
-) -> String {
+fn generate_inner(p: &Command, previous_command_name: &str) -> String {
debug!("generate_inner");
let command_name = if previous_command_name.is_empty() {
@@ -134,7 +130,7 @@ fn generate_inner<'help>(
);
for subcommand in p.get_subcommands() {
- let subcommand_subcommands_cases = generate_inner(subcommand, &command_name, names);
+ let subcommand_subcommands_cases = generate_inner(subcommand, &command_name);
subcommands_cases.push_str(&subcommand_subcommands_cases);
}
diff --git a/vendor/clap_complete/src/shells/fish.rs b/vendor/clap_complete/src/shells/fish.rs
index 9b516084b..fd2f3a4f8 100644
--- a/vendor/clap_complete/src/shells/fish.rs
+++ b/vendor/clap_complete/src/shells/fish.rs
@@ -27,8 +27,13 @@ impl Generator for Fish {
}
// Escape string inside single quotes
-fn escape_string(string: &str) -> String {
- string.replace('\\', "\\\\").replace('\'', "\\'")
+fn escape_string(string: &str, escape_comma: bool) -> String {
+ let string = string.replace('\\', "\\\\").replace('\'', "\\'");
+ if escape_comma {
+ string.replace(',', "\\,")
+ } else {
+ string
+ }
}
fn gen_fish_inner(
@@ -88,12 +93,13 @@ fn gen_fish_inner(
if let Some(longs) = option.get_long_and_visible_aliases() {
for long in longs {
- template.push_str(format!(" -l {}", escape_string(long)).as_str());
+ template.push_str(format!(" -l {}", escape_string(long, false)).as_str());
}
}
if let Some(data) = option.get_help() {
- template.push_str(format!(" -d '{}'", escape_string(data)).as_str());
+ template
+ .push_str(format!(" -d '{}'", escape_string(&data.to_string(), false)).as_str());
}
template.push_str(value_completion(option).as_str());
@@ -113,12 +119,13 @@ fn gen_fish_inner(
if let Some(longs) = flag.get_long_and_visible_aliases() {
for long in longs {
- template.push_str(format!(" -l {}", escape_string(long)).as_str());
+ template.push_str(format!(" -l {}", escape_string(long, false)).as_str());
}
}
if let Some(data) = flag.get_help() {
- template.push_str(format!(" -d '{}'", escape_string(data)).as_str());
+ template
+ .push_str(format!(" -d '{}'", escape_string(&data.to_string(), false)).as_str());
}
buffer.push_str(template.as_str());
@@ -132,7 +139,7 @@ fn gen_fish_inner(
template.push_str(format!(" -a \"{}\"", &subcommand.get_name()).as_str());
if let Some(data) = subcommand.get_about() {
- template.push_str(format!(" -d '{}'", escape_string(data)).as_str())
+ template.push_str(format!(" -d '{}'", escape_string(&data.to_string(), false)).as_str())
}
buffer.push_str(template.as_str());
@@ -148,11 +155,11 @@ fn gen_fish_inner(
}
fn value_completion(option: &Arg) -> String {
- if !option.is_takes_value_set() {
+ if !option.get_num_args().expect("built").takes_values() {
return "".to_string();
}
- if let Some(data) = option.get_possible_values() {
+ if let Some(data) = crate::generator::utils::possible_values(option) {
// We return the possible values with their own empty description e.g. {a\t,b\t}
// this makes sure that a and b don't get the description of the option or argument
format!(
@@ -163,8 +170,8 @@ fn value_completion(option: &Arg) -> String {
} else {
Some(format!(
"{}\t{}",
- escape_string(value.get_name()).as_str(),
- escape_string(value.get_help().unwrap_or_default()).as_str()
+ escape_string(value.get_name(), true).as_str(),
+ escape_string(&value.get_help().unwrap_or_default().to_string(), true)
))
})
.collect::<Vec<_>>()
diff --git a/vendor/clap_complete/src/shells/powershell.rs b/vendor/clap_complete/src/shells/powershell.rs
index d35e61c7d..0d3a2a55f 100644
--- a/vendor/clap_complete/src/shells/powershell.rs
+++ b/vendor/clap_complete/src/shells/powershell.rs
@@ -1,5 +1,6 @@
use std::io::Write;
+use clap::builder::StyledStr;
use clap::*;
use crate::generator::{utils, Generator};
@@ -19,8 +20,7 @@ impl Generator for PowerShell {
.get_bin_name()
.expect("crate::generate should have set the bin_name");
- let mut names = vec![];
- let subcommands_cases = generate_inner(cmd, "", &mut names);
+ let subcommands_cases = generate_inner(cmd, "");
let result = format!(
r#"
@@ -64,18 +64,14 @@ fn escape_string(string: &str) -> String {
string.replace('\'', "''")
}
-fn get_tooltip<T: ToString>(help: Option<&str>, data: T) -> String {
+fn get_tooltip<T: ToString>(help: Option<&StyledStr>, data: T) -> String {
match help {
- Some(help) => escape_string(help),
+ Some(help) => escape_string(&help.to_string()),
_ => data.to_string(),
}
}
-fn generate_inner<'help>(
- p: &Command<'help>,
- previous_command_name: &str,
- names: &mut Vec<&'help str>,
-) -> String {
+fn generate_inner(p: &Command, previous_command_name: &str) -> String {
debug!("generate_inner");
let command_name = if previous_command_name.is_empty() {
@@ -170,7 +166,7 @@ fn generate_inner<'help>(
);
for subcommand in p.get_subcommands() {
- let subcommand_subcommands_cases = generate_inner(subcommand, &command_name, names);
+ let subcommand_subcommands_cases = generate_inner(subcommand, &command_name);
subcommands_cases.push_str(&subcommand_subcommands_cases);
}
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,
+ }
+}
diff --git a/vendor/clap_complete/src/shells/zsh.rs b/vendor/clap_complete/src/shells/zsh.rs
index 2b64739ce..580de77a2 100644
--- a/vendor/clap_complete/src/shells/zsh.rs
+++ b/vendor/clap_complete/src/shells/zsh.rs
@@ -153,12 +153,10 @@ fn subcommands_of(p: &Command) -> String {
let text = format!(
"'{name}:{help}' \\",
name = name,
- help = escape_help(subcommand.get_about().unwrap_or(""))
+ help = escape_help(&subcommand.get_about().unwrap_or_default().to_string())
);
- if !text.is_empty() {
- ret.push(text);
- }
+ ret.push(text);
}
// The subcommands
@@ -234,7 +232,7 @@ fn get_subcommands_of(parent: &Command) -> String {
);
let mut segments = vec![format!("({})", name)];
let subcommand_args = get_args_of(
- parser_of(parent, &*bin_name).expect(INTERNAL_ERROR_MSG),
+ parser_of(parent, bin_name).expect(INTERNAL_ERROR_MSG),
Some(parent),
);
@@ -243,7 +241,7 @@ fn get_subcommands_of(parent: &Command) -> String {
}
// Get the help text of all child subcommands.
- let children = get_subcommands_of(parser_of(parent, &*bin_name).expect(INTERNAL_ERROR_MSG));
+ let children = get_subcommands_of(parser_of(parent, bin_name).expect(INTERNAL_ERROR_MSG));
if !children.is_empty() {
segments.push(children);
@@ -280,13 +278,10 @@ esac",
//
// Given the bin_name "a b c" and the Command for "a" this returns the "c" Command.
// Given the bin_name "a b c" and the Command for "b" this returns the "c" Command.
-fn parser_of<'help, 'cmd>(
- parent: &'cmd Command<'help>,
- bin_name: &str,
-) -> Option<&'cmd Command<'help>> {
+fn parser_of<'cmd>(parent: &'cmd Command, bin_name: &str) -> Option<&'cmd Command> {
debug!("parser_of: p={}, bin_name={}", parent.get_name(), bin_name);
- if bin_name == parent.get_bin_name().unwrap_or(&String::new()) {
+ if bin_name == parent.get_bin_name().unwrap_or_default() {
return Some(parent);
}
@@ -359,7 +354,7 @@ fn get_args_of(parent: &Command, p_global: Option<&Command>) -> String {
// Uses either `possible_vals` or `value_hint` to give hints about possible argument values
fn value_completion(arg: &Arg) -> Option<String> {
- if let Some(values) = &arg.get_possible_values() {
+ if let Some(values) = crate::generator::utils::possible_values(arg) {
if values
.iter()
.any(|value| !value.is_hide_set() && value.get_help().is_some())
@@ -375,7 +370,8 @@ fn value_completion(arg: &Arg) -> Option<String> {
Some(format!(
r#"{name}\:"{tooltip}""#,
name = escape_value(value.get_name()),
- tooltip = value.get_help().map(escape_help).unwrap_or_default()
+ tooltip =
+ escape_help(&value.get_help().unwrap_or_default().to_string()),
))
}
})
@@ -388,7 +384,7 @@ fn value_completion(arg: &Arg) -> Option<String> {
values
.iter()
.filter(|pv| !pv.is_hide_set())
- .map(PossibleValue::get_name)
+ .map(|n| n.get_name())
.collect::<Vec<_>>()
.join(" ")
))
@@ -448,10 +444,10 @@ fn write_opts_of(p: &Command, p_global: Option<&Command>) -> String {
for o in p.get_opts() {
debug!("write_opts_of:iter: o={}", o.get_id());
- let help = o.get_help().map_or(String::new(), escape_help);
+ let help = escape_help(&o.get_help().unwrap_or_default().to_string());
let conflicts = arg_conflicts(p, o, p_global);
- let multiple = if o.is_multiple_occurrences_set() {
+ let multiple = if let ArgAction::Count | ArgAction::Append = o.get_action() {
"*"
} else {
""
@@ -465,10 +461,7 @@ fn write_opts_of(p: &Command, p_global: Option<&Command>) -> String {
Some(val) => format!(":{}:{}", vn, val),
None => format!(":{}: ", vn),
};
- let vc = match o.get_num_vals() {
- Some(num_vals) => vc.repeat(num_vals),
- None => vc,
- };
+ let vc = vc.repeat(o.get_num_args().expect("built").min_values());
if let Some(shorts) = o.get_short_and_visible_aliases() {
for short in shorts {
@@ -551,10 +544,10 @@ fn write_flags_of(p: &Command, p_global: Option<&Command>) -> String {
for f in utils::flags(p) {
debug!("write_flags_of:iter: f={}", f.get_id());
- let help = f.get_help().map_or(String::new(), escape_help);
+ let help = escape_help(&f.get_help().unwrap_or_default().to_string());
let conflicts = arg_conflicts(p, &f, p_global);
- let multiple = if f.is_multiple_occurrences_set() {
+ let multiple = if let ArgAction::Count | ArgAction::Append = f.get_action() {
"*"
} else {
""
@@ -632,7 +625,8 @@ fn write_positionals_of(p: &Command) -> String {
for arg in p.get_positionals() {
debug!("write_positionals_of:iter: arg={}", arg.get_id());
- let cardinality = if arg.is_multiple_values_set() || arg.is_multiple_occurrences_set() {
+ let num_args = arg.get_num_args().expect("built");
+ let cardinality = if num_args.max_values() > 1 {
"*:"
} else if !arg.is_required_set() {
":"
@@ -646,12 +640,13 @@ fn write_positionals_of(p: &Command) -> String {
name = arg.get_id(),
help = arg
.get_help()
- .map_or("".to_owned(), |v| " -- ".to_owned() + v)
+ .map(|s| s.to_string())
+ .map_or("".to_owned(), |v| " -- ".to_owned() + &v)
.replace('[', "\\[")
.replace(']', "\\]")
.replace('\'', "'\\''")
.replace(':', "\\:"),
- value_completion = value_completion(arg).unwrap_or_else(|| "".to_string())
+ value_completion = value_completion(arg).unwrap_or_default()
);
debug!("write_positionals_of:iter: Wrote...{}", a);