diff --git a/clap_complete/examples/exhaustive.rs b/clap_complete/examples/exhaustive.rs index 9ebdde62c88..f9110490e05 100644 --- a/clap_complete/examples/exhaustive.rs +++ b/clap_complete/examples/exhaustive.rs @@ -100,6 +100,7 @@ fn cli() -> clap::Command { clap::Command::new("cmd-brackets").about("List packages [filter]"), clap::Command::new("cmd-expansions") .about("Execute the shell command with $SHELL"), + clap::Command::new("escape-help").about("\\tab\t\"'\nNew Line"), ]), clap::Command::new("value").args([ clap::Arg::new("delim").long("delim").value_delimiter(','), diff --git a/clap_complete/src/dynamic/completer.rs b/clap_complete/src/dynamic/completer.rs index 327e557e14c..cb3b96bbbeb 100644 --- a/clap_complete/src/dynamic/completer.rs +++ b/clap_complete/src/dynamic/completer.rs @@ -1,6 +1,7 @@ use std::ffi::OsStr; use std::ffi::OsString; +use clap::builder::StyledStr; use clap_lex::OsStrExt as _; /// Shell-specific completions @@ -31,7 +32,7 @@ pub fn complete( args: Vec, arg_index: usize, current_dir: Option<&std::path::Path>, -) -> Result, std::io::Error> { +) -> Result)>, std::io::Error> { cmd.build(); let raw_args = clap_lex::RawArgs::new(args.into_iter()); @@ -90,7 +91,7 @@ fn complete_arg( current_dir: Option<&std::path::Path>, pos_index: usize, is_escaped: bool, -) -> Result, std::io::Error> { +) -> Result)>, std::io::Error> { debug!( "complete_arg: arg={:?}, cmd={:?}, current_dir={:?}, pos_index={}, is_escaped={}", arg, @@ -109,26 +110,24 @@ fn complete_arg( completions.extend( complete_arg_value(value.to_str().ok_or(value), arg, current_dir) .into_iter() - .map(|os| { + .map(|(os, help)| { // HACK: Need better `OsStr` manipulation - format!("--{}={}", flag, os.to_string_lossy()).into() + (format!("--{}={}", flag, os.to_string_lossy()).into(), help) }), ) } } else { - completions.extend( - crate::generator::utils::longs_and_visible_aliases(cmd) - .into_iter() - .filter_map(|f| f.starts_with(flag).then(|| format!("--{f}").into())), - ); + completions.extend(longs_and_visible_aliases(cmd).into_iter().filter_map( + |(f, help)| f.starts_with(flag).then(|| (format!("--{f}").into(), help)), + )); } } } else if arg.is_escape() || arg.is_stdio() || arg.is_empty() { // HACK: Assuming knowledge of is_escape / is_stdio completions.extend( - crate::generator::utils::longs_and_visible_aliases(cmd) + longs_and_visible_aliases(cmd) .into_iter() - .map(|f| format!("--{f}").into()), + .map(|(f, help)| (format!("--{f}").into(), help)), ); } @@ -140,10 +139,10 @@ fn complete_arg( }; // HACK: Assuming knowledge of is_stdio completions.extend( - crate::generator::utils::shorts_and_visible_aliases(cmd) + shorts_and_visible_aliases(cmd) .into_iter() // HACK: Need better `OsStr` manipulation - .map(|f| format!("{}{}", dash_or_arg, f).into()), + .map(|(f, help)| (format!("{}{}", dash_or_arg, f).into(), help)), ); } } @@ -166,15 +165,16 @@ fn complete_arg_value( value: Result<&str, &OsStr>, arg: &clap::Arg, current_dir: Option<&std::path::Path>, -) -> Vec { +) -> Vec<(OsString, Option)> { let mut values = Vec::new(); debug!("complete_arg_value: arg={arg:?}, value={value:?}"); - if let Some(possible_values) = crate::generator::utils::possible_values(arg) { + if let Some(possible_values) = possible_values(arg) { if let Ok(value) = value { values.extend(possible_values.into_iter().filter_map(|p| { let name = p.get_name(); - name.starts_with(value).then(|| name.into()) + name.starts_with(value) + .then(|| (name.into(), p.get_help().cloned())) })); } } else { @@ -223,7 +223,7 @@ fn complete_path( value_os: &OsStr, current_dir: Option<&std::path::Path>, is_wanted: impl Fn(&std::path::Path) -> bool, -) -> Vec { +) -> Vec<(OsString, Option)> { let mut completions = Vec::new(); let current_dir = match current_dir { @@ -255,12 +255,12 @@ fn complete_path( let path = entry.path(); let mut suggestion = pathdiff::diff_paths(&path, current_dir).unwrap_or(path); suggestion.push(""); // Ensure trailing `/` - completions.push(suggestion.as_os_str().to_owned()); + completions.push((suggestion.as_os_str().to_owned(), None)); } else { let path = entry.path(); if is_wanted(&path) { let suggestion = pathdiff::diff_paths(&path, current_dir).unwrap_or(path); - completions.push(suggestion.as_os_str().to_owned()); + completions.push((suggestion.as_os_str().to_owned(), None)); } } } @@ -268,19 +268,74 @@ fn complete_path( completions } -fn complete_subcommand(value: &str, cmd: &clap::Command) -> Vec { +fn complete_subcommand(value: &str, cmd: &clap::Command) -> Vec<(OsString, Option)> { debug!( "complete_subcommand: cmd={:?}, value={:?}", cmd.get_name(), value ); - let mut scs = crate::generator::utils::subcommands(cmd) + let mut scs = subcommands(cmd) .into_iter() .filter(|x| x.0.starts_with(value)) - .map(|x| OsString::from(&x.0)) + .map(|x| (OsString::from(&x.0), x.1)) .collect::>(); scs.sort(); scs.dedup(); scs } + +/// Gets all the long options, their visible aliases and flags of a [`clap::Command`]. +/// Includes `help` and `version` depending on the [`clap::Command`] settings. +fn longs_and_visible_aliases(p: &clap::Command) -> Vec<(String, Option)> { + debug!("longs: name={}", p.get_name()); + + p.get_arguments() + .filter_map(|a| { + a.get_long_and_visible_aliases().map(|longs| { + longs + .into_iter() + .map(|s| (s.to_string(), a.get_help().cloned())) + }) + }) + .flatten() + .collect() +} + +/// Gets all the short options, their visible aliases and flags of a [`clap::Command`]. +/// Includes `h` and `V` depending on the [`clap::Command`] settings. +fn shorts_and_visible_aliases(p: &clap::Command) -> Vec<(char, Option)> { + debug!("shorts: name={}", p.get_name()); + + p.get_arguments() + .filter_map(|a| { + a.get_short_and_visible_aliases() + .map(|shorts| shorts.into_iter().map(|s| (s, a.get_help().cloned()))) + }) + .flatten() + .collect() +} + +/// Get the possible values for completion +fn possible_values(a: &clap::Arg) -> Option> { + if !a.get_num_args().expect("built").takes_values() { + None + } else { + a.get_value_parser() + .possible_values() + .map(|pvs| pvs.collect()) + } +} + +/// Gets subcommands of [`clap::Command`] in the form of `("name", "bin_name")`. +/// +/// Subcommand `rustup toolchain install` would be converted to +/// `("install", "rustup toolchain install")`. +fn subcommands(p: &clap::Command) -> Vec<(String, Option)> { + debug!("subcommands: name={}", p.get_name()); + debug!("subcommands: Has subcommands...{:?}", p.has_subcommands()); + + p.get_subcommands() + .map(|sc| (sc.get_name().to_string(), sc.get_about().cloned())) + .collect() +} diff --git a/clap_complete/src/dynamic/shells/bash.rs b/clap_complete/src/dynamic/shells/bash.rs index ebc43c6910f..43c128e5b4e 100644 --- a/clap_complete/src/dynamic/shells/bash.rs +++ b/clap_complete/src/dynamic/shells/bash.rs @@ -73,7 +73,7 @@ complete -o nospace -o bashdefault -F _clap_complete_NAME BIN let ifs: Option = std::env::var("IFS").ok().and_then(|i| i.parse().ok()); let completions = crate::dynamic::complete(cmd, args, index, current_dir)?; - for (i, completion) in completions.iter().enumerate() { + for (i, (completion, _)) in completions.iter().enumerate() { if i != 0 { write!(buf, "{}", ifs.as_deref().unwrap_or("\n"))?; } diff --git a/clap_complete/src/dynamic/shells/fish.rs b/clap_complete/src/dynamic/shells/fish.rs index 79b8bda543d..9d7e8c6846b 100644 --- a/clap_complete/src/dynamic/shells/fish.rs +++ b/clap_complete/src/dynamic/shells/fish.rs @@ -30,8 +30,16 @@ impl crate::dynamic::Completer for Fish { let index = args.len() - 1; let completions = crate::dynamic::complete(cmd, args, index, current_dir)?; - for completion in completions { - writeln!(buf, "{}", completion.to_string_lossy())?; + for (completion, help) in completions { + write!(buf, "{}", completion.to_string_lossy())?; + if let Some(help) = help { + write!( + buf, + "\t{}", + help.to_string().lines().next().unwrap_or_default() + )?; + } + writeln!(buf)?; } Ok(()) } diff --git a/clap_complete/tests/snapshots/home/static/exhaustive/bash/.bashrc b/clap_complete/tests/snapshots/home/static/exhaustive/bash/.bashrc index 9ef12ac7edb..a843c90ee31 100644 --- a/clap_complete/tests/snapshots/home/static/exhaustive/bash/.bashrc +++ b/clap_complete/tests/snapshots/home/static/exhaustive/bash/.bashrc @@ -92,6 +92,9 @@ _exhaustive() { exhaustive__help__quote,cmd-single-quotes) cmd="exhaustive__help__quote__cmd__single__quotes" ;; + exhaustive__help__quote,escape-help) + cmd="exhaustive__help__quote__escape__help" + ;; exhaustive__pacman,help) cmd="exhaustive__pacman__help" ;; @@ -128,6 +131,9 @@ _exhaustive() { exhaustive__quote,cmd-single-quotes) cmd="exhaustive__quote__cmd__single__quotes" ;; + exhaustive__quote,escape-help) + cmd="exhaustive__quote__escape__help" + ;; exhaustive__quote,help) cmd="exhaustive__quote__help" ;; @@ -149,6 +155,9 @@ _exhaustive() { exhaustive__quote__help,cmd-single-quotes) cmd="exhaustive__quote__help__cmd__single__quotes" ;; + exhaustive__quote__help,escape-help) + cmd="exhaustive__quote__help__escape__help" + ;; exhaustive__quote__help,help) cmd="exhaustive__quote__help__help" ;; @@ -391,7 +400,7 @@ _exhaustive() { return 0 ;; exhaustive__help__quote) - opts="cmd-single-quotes cmd-double-quotes cmd-backticks cmd-backslash cmd-brackets cmd-expansions" + opts="cmd-single-quotes cmd-double-quotes cmd-backticks cmd-backslash cmd-brackets cmd-expansions escape-help" if [[ ${cur} == -* || ${COMP_CWORD} -eq 3 ]] ; then COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) return 0 @@ -488,6 +497,20 @@ _exhaustive() { COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) return 0 ;; + exhaustive__help__quote__escape__help) + opts="" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 4 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; exhaustive__help__value) opts="" if [[ ${cur} == -* || ${COMP_CWORD} -eq 3 ]] ; then @@ -709,7 +732,7 @@ _exhaustive() { return 0 ;; exhaustive__quote) - opts="-h -V --single-quotes --double-quotes --backticks --backslash --brackets --expansions --global --help --version cmd-single-quotes cmd-double-quotes cmd-backticks cmd-backslash cmd-brackets cmd-expansions help" + opts="-h -V --single-quotes --double-quotes --backticks --backslash --brackets --expansions --global --help --version cmd-single-quotes cmd-double-quotes cmd-backticks cmd-backslash cmd-brackets cmd-expansions escape-help help" if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) return 0 @@ -806,8 +829,22 @@ _exhaustive() { COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) return 0 ;; + exhaustive__quote__escape__help) + opts="-h -V --global --help --version" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 3 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; exhaustive__quote__help) - opts="cmd-single-quotes cmd-double-quotes cmd-backticks cmd-backslash cmd-brackets cmd-expansions help" + opts="cmd-single-quotes cmd-double-quotes cmd-backticks cmd-backslash cmd-brackets cmd-expansions escape-help help" if [[ ${cur} == -* || ${COMP_CWORD} -eq 3 ]] ; then COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) return 0 @@ -904,6 +941,20 @@ _exhaustive() { COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) return 0 ;; + exhaustive__quote__help__escape__help) + opts="" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 4 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; exhaustive__quote__help__help) opts="" if [[ ${cur} == -* || ${COMP_CWORD} -eq 4 ]] ; then diff --git a/clap_complete/tests/snapshots/home/static/exhaustive/elvish/elvish/rc.elv b/clap_complete/tests/snapshots/home/static/exhaustive/elvish/elvish/rc.elv index 8c0a4d62f71..3e596f7f242 100644 --- a/clap_complete/tests/snapshots/home/static/exhaustive/elvish/elvish/rc.elv +++ b/clap_complete/tests/snapshots/home/static/exhaustive/elvish/elvish/rc.elv @@ -65,6 +65,8 @@ set edit:completion:arg-completer[exhaustive] = {|@words| cand cmd-backslash 'Avoid ''\n''' cand cmd-brackets 'List packages [filter]' cand cmd-expansions 'Execute the shell command with $SHELL' + cand escape-help '\tab "'' +New Line' cand help 'Print this message or the help of the given subcommand(s)' } &'exhaustive;quote;cmd-single-quotes'= { @@ -109,6 +111,13 @@ set edit:completion:arg-completer[exhaustive] = {|@words| cand -V 'Print version' cand --version 'Print version' } + &'exhaustive;quote;escape-help'= { + cand --global 'everywhere' + cand -h 'Print help' + cand --help 'Print help' + cand -V 'Print version' + cand --version 'Print version' + } &'exhaustive;quote;help'= { cand cmd-single-quotes 'Can be ''always'', ''auto'', or ''never''' cand cmd-double-quotes 'Can be "always", "auto", or "never"' @@ -116,6 +125,8 @@ set edit:completion:arg-completer[exhaustive] = {|@words| cand cmd-backslash 'Avoid ''\n''' cand cmd-brackets 'List packages [filter]' cand cmd-expansions 'Execute the shell command with $SHELL' + cand escape-help '\tab "'' +New Line' cand help 'Print this message or the help of the given subcommand(s)' } &'exhaustive;quote;help;cmd-single-quotes'= { @@ -130,6 +141,8 @@ set edit:completion:arg-completer[exhaustive] = {|@words| } &'exhaustive;quote;help;cmd-expansions'= { } + &'exhaustive;quote;help;escape-help'= { + } &'exhaustive;quote;help;help'= { } &'exhaustive;value'= { @@ -255,6 +268,8 @@ set edit:completion:arg-completer[exhaustive] = {|@words| cand cmd-backslash 'Avoid ''\n''' cand cmd-brackets 'List packages [filter]' cand cmd-expansions 'Execute the shell command with $SHELL' + cand escape-help '\tab "'' +New Line' } &'exhaustive;help;quote;cmd-single-quotes'= { } @@ -268,6 +283,8 @@ set edit:completion:arg-completer[exhaustive] = {|@words| } &'exhaustive;help;quote;cmd-expansions'= { } + &'exhaustive;help;quote;escape-help'= { + } &'exhaustive;help;value'= { } &'exhaustive;help;pacman'= { diff --git a/clap_complete/tests/snapshots/home/static/exhaustive/fish/fish/completions/exhaustive.fish b/clap_complete/tests/snapshots/home/static/exhaustive/fish/fish/completions/exhaustive.fish index 77cfddd8e0c..47b42f4a4d4 100644 --- a/clap_complete/tests/snapshots/home/static/exhaustive/fish/fish/completions/exhaustive.fish +++ b/clap_complete/tests/snapshots/home/static/exhaustive/fish/fish/completions/exhaustive.fish @@ -18,22 +18,24 @@ complete -c exhaustive -n "__fish_seen_subcommand_from action" -l count -d 'numb complete -c exhaustive -n "__fish_seen_subcommand_from action" -l global -d 'everywhere' complete -c exhaustive -n "__fish_seen_subcommand_from action" -s h -l help -d 'Print help' complete -c exhaustive -n "__fish_seen_subcommand_from action" -s V -l version -d 'Print version' -complete -c exhaustive -n "__fish_seen_subcommand_from quote; and not __fish_seen_subcommand_from cmd-single-quotes; and not __fish_seen_subcommand_from cmd-double-quotes; and not __fish_seen_subcommand_from cmd-backticks; and not __fish_seen_subcommand_from cmd-backslash; and not __fish_seen_subcommand_from cmd-brackets; and not __fish_seen_subcommand_from cmd-expansions; and not __fish_seen_subcommand_from help" -l single-quotes -d 'Can be \'always\', \'auto\', or \'never\'' -complete -c exhaustive -n "__fish_seen_subcommand_from quote; and not __fish_seen_subcommand_from cmd-single-quotes; and not __fish_seen_subcommand_from cmd-double-quotes; and not __fish_seen_subcommand_from cmd-backticks; and not __fish_seen_subcommand_from cmd-backslash; and not __fish_seen_subcommand_from cmd-brackets; and not __fish_seen_subcommand_from cmd-expansions; and not __fish_seen_subcommand_from help" -l double-quotes -d 'Can be "always", "auto", or "never"' -complete -c exhaustive -n "__fish_seen_subcommand_from quote; and not __fish_seen_subcommand_from cmd-single-quotes; and not __fish_seen_subcommand_from cmd-double-quotes; and not __fish_seen_subcommand_from cmd-backticks; and not __fish_seen_subcommand_from cmd-backslash; and not __fish_seen_subcommand_from cmd-brackets; and not __fish_seen_subcommand_from cmd-expansions; and not __fish_seen_subcommand_from help" -l backticks -d 'For more information see `echo test`' -complete -c exhaustive -n "__fish_seen_subcommand_from quote; and not __fish_seen_subcommand_from cmd-single-quotes; and not __fish_seen_subcommand_from cmd-double-quotes; and not __fish_seen_subcommand_from cmd-backticks; and not __fish_seen_subcommand_from cmd-backslash; and not __fish_seen_subcommand_from cmd-brackets; and not __fish_seen_subcommand_from cmd-expansions; and not __fish_seen_subcommand_from help" -l backslash -d 'Avoid \'\\n\'' -complete -c exhaustive -n "__fish_seen_subcommand_from quote; and not __fish_seen_subcommand_from cmd-single-quotes; and not __fish_seen_subcommand_from cmd-double-quotes; and not __fish_seen_subcommand_from cmd-backticks; and not __fish_seen_subcommand_from cmd-backslash; and not __fish_seen_subcommand_from cmd-brackets; and not __fish_seen_subcommand_from cmd-expansions; and not __fish_seen_subcommand_from help" -l brackets -d 'List packages [filter]' -complete -c exhaustive -n "__fish_seen_subcommand_from quote; and not __fish_seen_subcommand_from cmd-single-quotes; and not __fish_seen_subcommand_from cmd-double-quotes; and not __fish_seen_subcommand_from cmd-backticks; and not __fish_seen_subcommand_from cmd-backslash; and not __fish_seen_subcommand_from cmd-brackets; and not __fish_seen_subcommand_from cmd-expansions; and not __fish_seen_subcommand_from help" -l expansions -d 'Execute the shell command with $SHELL' -complete -c exhaustive -n "__fish_seen_subcommand_from quote; and not __fish_seen_subcommand_from cmd-single-quotes; and not __fish_seen_subcommand_from cmd-double-quotes; and not __fish_seen_subcommand_from cmd-backticks; and not __fish_seen_subcommand_from cmd-backslash; and not __fish_seen_subcommand_from cmd-brackets; and not __fish_seen_subcommand_from cmd-expansions; and not __fish_seen_subcommand_from help" -l global -d 'everywhere' -complete -c exhaustive -n "__fish_seen_subcommand_from quote; and not __fish_seen_subcommand_from cmd-single-quotes; and not __fish_seen_subcommand_from cmd-double-quotes; and not __fish_seen_subcommand_from cmd-backticks; and not __fish_seen_subcommand_from cmd-backslash; and not __fish_seen_subcommand_from cmd-brackets; and not __fish_seen_subcommand_from cmd-expansions; and not __fish_seen_subcommand_from help" -s h -l help -d 'Print help' -complete -c exhaustive -n "__fish_seen_subcommand_from quote; and not __fish_seen_subcommand_from cmd-single-quotes; and not __fish_seen_subcommand_from cmd-double-quotes; and not __fish_seen_subcommand_from cmd-backticks; and not __fish_seen_subcommand_from cmd-backslash; and not __fish_seen_subcommand_from cmd-brackets; and not __fish_seen_subcommand_from cmd-expansions; and not __fish_seen_subcommand_from help" -s V -l version -d 'Print version' -complete -c exhaustive -n "__fish_seen_subcommand_from quote; and not __fish_seen_subcommand_from cmd-single-quotes; and not __fish_seen_subcommand_from cmd-double-quotes; and not __fish_seen_subcommand_from cmd-backticks; and not __fish_seen_subcommand_from cmd-backslash; and not __fish_seen_subcommand_from cmd-brackets; and not __fish_seen_subcommand_from cmd-expansions; and not __fish_seen_subcommand_from help" -f -a "cmd-single-quotes" -d 'Can be \'always\', \'auto\', or \'never\'' -complete -c exhaustive -n "__fish_seen_subcommand_from quote; and not __fish_seen_subcommand_from cmd-single-quotes; and not __fish_seen_subcommand_from cmd-double-quotes; and not __fish_seen_subcommand_from cmd-backticks; and not __fish_seen_subcommand_from cmd-backslash; and not __fish_seen_subcommand_from cmd-brackets; and not __fish_seen_subcommand_from cmd-expansions; and not __fish_seen_subcommand_from help" -f -a "cmd-double-quotes" -d 'Can be "always", "auto", or "never"' -complete -c exhaustive -n "__fish_seen_subcommand_from quote; and not __fish_seen_subcommand_from cmd-single-quotes; and not __fish_seen_subcommand_from cmd-double-quotes; and not __fish_seen_subcommand_from cmd-backticks; and not __fish_seen_subcommand_from cmd-backslash; and not __fish_seen_subcommand_from cmd-brackets; and not __fish_seen_subcommand_from cmd-expansions; and not __fish_seen_subcommand_from help" -f -a "cmd-backticks" -d 'For more information see `echo test`' -complete -c exhaustive -n "__fish_seen_subcommand_from quote; and not __fish_seen_subcommand_from cmd-single-quotes; and not __fish_seen_subcommand_from cmd-double-quotes; and not __fish_seen_subcommand_from cmd-backticks; and not __fish_seen_subcommand_from cmd-backslash; and not __fish_seen_subcommand_from cmd-brackets; and not __fish_seen_subcommand_from cmd-expansions; and not __fish_seen_subcommand_from help" -f -a "cmd-backslash" -d 'Avoid \'\\n\'' -complete -c exhaustive -n "__fish_seen_subcommand_from quote; and not __fish_seen_subcommand_from cmd-single-quotes; and not __fish_seen_subcommand_from cmd-double-quotes; and not __fish_seen_subcommand_from cmd-backticks; and not __fish_seen_subcommand_from cmd-backslash; and not __fish_seen_subcommand_from cmd-brackets; and not __fish_seen_subcommand_from cmd-expansions; and not __fish_seen_subcommand_from help" -f -a "cmd-brackets" -d 'List packages [filter]' -complete -c exhaustive -n "__fish_seen_subcommand_from quote; and not __fish_seen_subcommand_from cmd-single-quotes; and not __fish_seen_subcommand_from cmd-double-quotes; and not __fish_seen_subcommand_from cmd-backticks; and not __fish_seen_subcommand_from cmd-backslash; and not __fish_seen_subcommand_from cmd-brackets; and not __fish_seen_subcommand_from cmd-expansions; and not __fish_seen_subcommand_from help" -f -a "cmd-expansions" -d 'Execute the shell command with $SHELL' -complete -c exhaustive -n "__fish_seen_subcommand_from quote; and not __fish_seen_subcommand_from cmd-single-quotes; and not __fish_seen_subcommand_from cmd-double-quotes; and not __fish_seen_subcommand_from cmd-backticks; and not __fish_seen_subcommand_from cmd-backslash; and not __fish_seen_subcommand_from cmd-brackets; and not __fish_seen_subcommand_from cmd-expansions; and not __fish_seen_subcommand_from help" -f -a "help" -d 'Print this message or the help of the given subcommand(s)' +complete -c exhaustive -n "__fish_seen_subcommand_from quote; and not __fish_seen_subcommand_from cmd-single-quotes; and not __fish_seen_subcommand_from cmd-double-quotes; and not __fish_seen_subcommand_from cmd-backticks; and not __fish_seen_subcommand_from cmd-backslash; and not __fish_seen_subcommand_from cmd-brackets; and not __fish_seen_subcommand_from cmd-expansions; and not __fish_seen_subcommand_from escape-help; and not __fish_seen_subcommand_from help" -l single-quotes -d 'Can be \'always\', \'auto\', or \'never\'' +complete -c exhaustive -n "__fish_seen_subcommand_from quote; and not __fish_seen_subcommand_from cmd-single-quotes; and not __fish_seen_subcommand_from cmd-double-quotes; and not __fish_seen_subcommand_from cmd-backticks; and not __fish_seen_subcommand_from cmd-backslash; and not __fish_seen_subcommand_from cmd-brackets; and not __fish_seen_subcommand_from cmd-expansions; and not __fish_seen_subcommand_from escape-help; and not __fish_seen_subcommand_from help" -l double-quotes -d 'Can be "always", "auto", or "never"' +complete -c exhaustive -n "__fish_seen_subcommand_from quote; and not __fish_seen_subcommand_from cmd-single-quotes; and not __fish_seen_subcommand_from cmd-double-quotes; and not __fish_seen_subcommand_from cmd-backticks; and not __fish_seen_subcommand_from cmd-backslash; and not __fish_seen_subcommand_from cmd-brackets; and not __fish_seen_subcommand_from cmd-expansions; and not __fish_seen_subcommand_from escape-help; and not __fish_seen_subcommand_from help" -l backticks -d 'For more information see `echo test`' +complete -c exhaustive -n "__fish_seen_subcommand_from quote; and not __fish_seen_subcommand_from cmd-single-quotes; and not __fish_seen_subcommand_from cmd-double-quotes; and not __fish_seen_subcommand_from cmd-backticks; and not __fish_seen_subcommand_from cmd-backslash; and not __fish_seen_subcommand_from cmd-brackets; and not __fish_seen_subcommand_from cmd-expansions; and not __fish_seen_subcommand_from escape-help; and not __fish_seen_subcommand_from help" -l backslash -d 'Avoid \'\\n\'' +complete -c exhaustive -n "__fish_seen_subcommand_from quote; and not __fish_seen_subcommand_from cmd-single-quotes; and not __fish_seen_subcommand_from cmd-double-quotes; and not __fish_seen_subcommand_from cmd-backticks; and not __fish_seen_subcommand_from cmd-backslash; and not __fish_seen_subcommand_from cmd-brackets; and not __fish_seen_subcommand_from cmd-expansions; and not __fish_seen_subcommand_from escape-help; and not __fish_seen_subcommand_from help" -l brackets -d 'List packages [filter]' +complete -c exhaustive -n "__fish_seen_subcommand_from quote; and not __fish_seen_subcommand_from cmd-single-quotes; and not __fish_seen_subcommand_from cmd-double-quotes; and not __fish_seen_subcommand_from cmd-backticks; and not __fish_seen_subcommand_from cmd-backslash; and not __fish_seen_subcommand_from cmd-brackets; and not __fish_seen_subcommand_from cmd-expansions; and not __fish_seen_subcommand_from escape-help; and not __fish_seen_subcommand_from help" -l expansions -d 'Execute the shell command with $SHELL' +complete -c exhaustive -n "__fish_seen_subcommand_from quote; and not __fish_seen_subcommand_from cmd-single-quotes; and not __fish_seen_subcommand_from cmd-double-quotes; and not __fish_seen_subcommand_from cmd-backticks; and not __fish_seen_subcommand_from cmd-backslash; and not __fish_seen_subcommand_from cmd-brackets; and not __fish_seen_subcommand_from cmd-expansions; and not __fish_seen_subcommand_from escape-help; and not __fish_seen_subcommand_from help" -l global -d 'everywhere' +complete -c exhaustive -n "__fish_seen_subcommand_from quote; and not __fish_seen_subcommand_from cmd-single-quotes; and not __fish_seen_subcommand_from cmd-double-quotes; and not __fish_seen_subcommand_from cmd-backticks; and not __fish_seen_subcommand_from cmd-backslash; and not __fish_seen_subcommand_from cmd-brackets; and not __fish_seen_subcommand_from cmd-expansions; and not __fish_seen_subcommand_from escape-help; and not __fish_seen_subcommand_from help" -s h -l help -d 'Print help' +complete -c exhaustive -n "__fish_seen_subcommand_from quote; and not __fish_seen_subcommand_from cmd-single-quotes; and not __fish_seen_subcommand_from cmd-double-quotes; and not __fish_seen_subcommand_from cmd-backticks; and not __fish_seen_subcommand_from cmd-backslash; and not __fish_seen_subcommand_from cmd-brackets; and not __fish_seen_subcommand_from cmd-expansions; and not __fish_seen_subcommand_from escape-help; and not __fish_seen_subcommand_from help" -s V -l version -d 'Print version' +complete -c exhaustive -n "__fish_seen_subcommand_from quote; and not __fish_seen_subcommand_from cmd-single-quotes; and not __fish_seen_subcommand_from cmd-double-quotes; and not __fish_seen_subcommand_from cmd-backticks; and not __fish_seen_subcommand_from cmd-backslash; and not __fish_seen_subcommand_from cmd-brackets; and not __fish_seen_subcommand_from cmd-expansions; and not __fish_seen_subcommand_from escape-help; and not __fish_seen_subcommand_from help" -f -a "cmd-single-quotes" -d 'Can be \'always\', \'auto\', or \'never\'' +complete -c exhaustive -n "__fish_seen_subcommand_from quote; and not __fish_seen_subcommand_from cmd-single-quotes; and not __fish_seen_subcommand_from cmd-double-quotes; and not __fish_seen_subcommand_from cmd-backticks; and not __fish_seen_subcommand_from cmd-backslash; and not __fish_seen_subcommand_from cmd-brackets; and not __fish_seen_subcommand_from cmd-expansions; and not __fish_seen_subcommand_from escape-help; and not __fish_seen_subcommand_from help" -f -a "cmd-double-quotes" -d 'Can be "always", "auto", or "never"' +complete -c exhaustive -n "__fish_seen_subcommand_from quote; and not __fish_seen_subcommand_from cmd-single-quotes; and not __fish_seen_subcommand_from cmd-double-quotes; and not __fish_seen_subcommand_from cmd-backticks; and not __fish_seen_subcommand_from cmd-backslash; and not __fish_seen_subcommand_from cmd-brackets; and not __fish_seen_subcommand_from cmd-expansions; and not __fish_seen_subcommand_from escape-help; and not __fish_seen_subcommand_from help" -f -a "cmd-backticks" -d 'For more information see `echo test`' +complete -c exhaustive -n "__fish_seen_subcommand_from quote; and not __fish_seen_subcommand_from cmd-single-quotes; and not __fish_seen_subcommand_from cmd-double-quotes; and not __fish_seen_subcommand_from cmd-backticks; and not __fish_seen_subcommand_from cmd-backslash; and not __fish_seen_subcommand_from cmd-brackets; and not __fish_seen_subcommand_from cmd-expansions; and not __fish_seen_subcommand_from escape-help; and not __fish_seen_subcommand_from help" -f -a "cmd-backslash" -d 'Avoid \'\\n\'' +complete -c exhaustive -n "__fish_seen_subcommand_from quote; and not __fish_seen_subcommand_from cmd-single-quotes; and not __fish_seen_subcommand_from cmd-double-quotes; and not __fish_seen_subcommand_from cmd-backticks; and not __fish_seen_subcommand_from cmd-backslash; and not __fish_seen_subcommand_from cmd-brackets; and not __fish_seen_subcommand_from cmd-expansions; and not __fish_seen_subcommand_from escape-help; and not __fish_seen_subcommand_from help" -f -a "cmd-brackets" -d 'List packages [filter]' +complete -c exhaustive -n "__fish_seen_subcommand_from quote; and not __fish_seen_subcommand_from cmd-single-quotes; and not __fish_seen_subcommand_from cmd-double-quotes; and not __fish_seen_subcommand_from cmd-backticks; and not __fish_seen_subcommand_from cmd-backslash; and not __fish_seen_subcommand_from cmd-brackets; and not __fish_seen_subcommand_from cmd-expansions; and not __fish_seen_subcommand_from escape-help; and not __fish_seen_subcommand_from help" -f -a "cmd-expansions" -d 'Execute the shell command with $SHELL' +complete -c exhaustive -n "__fish_seen_subcommand_from quote; and not __fish_seen_subcommand_from cmd-single-quotes; and not __fish_seen_subcommand_from cmd-double-quotes; and not __fish_seen_subcommand_from cmd-backticks; and not __fish_seen_subcommand_from cmd-backslash; and not __fish_seen_subcommand_from cmd-brackets; and not __fish_seen_subcommand_from cmd-expansions; and not __fish_seen_subcommand_from escape-help; and not __fish_seen_subcommand_from help" -f -a "escape-help" -d '\\tab "\' +New Line' +complete -c exhaustive -n "__fish_seen_subcommand_from quote; and not __fish_seen_subcommand_from cmd-single-quotes; and not __fish_seen_subcommand_from cmd-double-quotes; and not __fish_seen_subcommand_from cmd-backticks; and not __fish_seen_subcommand_from cmd-backslash; and not __fish_seen_subcommand_from cmd-brackets; and not __fish_seen_subcommand_from cmd-expansions; and not __fish_seen_subcommand_from escape-help; and not __fish_seen_subcommand_from help" -f -a "help" -d 'Print this message or the help of the given subcommand(s)' complete -c exhaustive -n "__fish_seen_subcommand_from quote; and __fish_seen_subcommand_from cmd-single-quotes" -l global -d 'everywhere' complete -c exhaustive -n "__fish_seen_subcommand_from quote; and __fish_seen_subcommand_from cmd-single-quotes" -s h -l help -d 'Print help' complete -c exhaustive -n "__fish_seen_subcommand_from quote; and __fish_seen_subcommand_from cmd-single-quotes" -s V -l version -d 'Print version' @@ -52,13 +54,18 @@ complete -c exhaustive -n "__fish_seen_subcommand_from quote; and __fish_seen_su complete -c exhaustive -n "__fish_seen_subcommand_from quote; and __fish_seen_subcommand_from cmd-expansions" -l global -d 'everywhere' complete -c exhaustive -n "__fish_seen_subcommand_from quote; and __fish_seen_subcommand_from cmd-expansions" -s h -l help -d 'Print help' complete -c exhaustive -n "__fish_seen_subcommand_from quote; and __fish_seen_subcommand_from cmd-expansions" -s V -l version -d 'Print version' -complete -c exhaustive -n "__fish_seen_subcommand_from quote; and __fish_seen_subcommand_from help; and not __fish_seen_subcommand_from cmd-single-quotes; and not __fish_seen_subcommand_from cmd-double-quotes; and not __fish_seen_subcommand_from cmd-backticks; and not __fish_seen_subcommand_from cmd-backslash; and not __fish_seen_subcommand_from cmd-brackets; and not __fish_seen_subcommand_from cmd-expansions; and not __fish_seen_subcommand_from help" -f -a "cmd-single-quotes" -d 'Can be \'always\', \'auto\', or \'never\'' -complete -c exhaustive -n "__fish_seen_subcommand_from quote; and __fish_seen_subcommand_from help; and not __fish_seen_subcommand_from cmd-single-quotes; and not __fish_seen_subcommand_from cmd-double-quotes; and not __fish_seen_subcommand_from cmd-backticks; and not __fish_seen_subcommand_from cmd-backslash; and not __fish_seen_subcommand_from cmd-brackets; and not __fish_seen_subcommand_from cmd-expansions; and not __fish_seen_subcommand_from help" -f -a "cmd-double-quotes" -d 'Can be "always", "auto", or "never"' -complete -c exhaustive -n "__fish_seen_subcommand_from quote; and __fish_seen_subcommand_from help; and not __fish_seen_subcommand_from cmd-single-quotes; and not __fish_seen_subcommand_from cmd-double-quotes; and not __fish_seen_subcommand_from cmd-backticks; and not __fish_seen_subcommand_from cmd-backslash; and not __fish_seen_subcommand_from cmd-brackets; and not __fish_seen_subcommand_from cmd-expansions; and not __fish_seen_subcommand_from help" -f -a "cmd-backticks" -d 'For more information see `echo test`' -complete -c exhaustive -n "__fish_seen_subcommand_from quote; and __fish_seen_subcommand_from help; and not __fish_seen_subcommand_from cmd-single-quotes; and not __fish_seen_subcommand_from cmd-double-quotes; and not __fish_seen_subcommand_from cmd-backticks; and not __fish_seen_subcommand_from cmd-backslash; and not __fish_seen_subcommand_from cmd-brackets; and not __fish_seen_subcommand_from cmd-expansions; and not __fish_seen_subcommand_from help" -f -a "cmd-backslash" -d 'Avoid \'\\n\'' -complete -c exhaustive -n "__fish_seen_subcommand_from quote; and __fish_seen_subcommand_from help; and not __fish_seen_subcommand_from cmd-single-quotes; and not __fish_seen_subcommand_from cmd-double-quotes; and not __fish_seen_subcommand_from cmd-backticks; and not __fish_seen_subcommand_from cmd-backslash; and not __fish_seen_subcommand_from cmd-brackets; and not __fish_seen_subcommand_from cmd-expansions; and not __fish_seen_subcommand_from help" -f -a "cmd-brackets" -d 'List packages [filter]' -complete -c exhaustive -n "__fish_seen_subcommand_from quote; and __fish_seen_subcommand_from help; and not __fish_seen_subcommand_from cmd-single-quotes; and not __fish_seen_subcommand_from cmd-double-quotes; and not __fish_seen_subcommand_from cmd-backticks; and not __fish_seen_subcommand_from cmd-backslash; and not __fish_seen_subcommand_from cmd-brackets; and not __fish_seen_subcommand_from cmd-expansions; and not __fish_seen_subcommand_from help" -f -a "cmd-expansions" -d 'Execute the shell command with $SHELL' -complete -c exhaustive -n "__fish_seen_subcommand_from quote; and __fish_seen_subcommand_from help; and not __fish_seen_subcommand_from cmd-single-quotes; and not __fish_seen_subcommand_from cmd-double-quotes; and not __fish_seen_subcommand_from cmd-backticks; and not __fish_seen_subcommand_from cmd-backslash; and not __fish_seen_subcommand_from cmd-brackets; and not __fish_seen_subcommand_from cmd-expansions; and not __fish_seen_subcommand_from help" -f -a "help" -d 'Print this message or the help of the given subcommand(s)' +complete -c exhaustive -n "__fish_seen_subcommand_from quote; and __fish_seen_subcommand_from escape-help" -l global -d 'everywhere' +complete -c exhaustive -n "__fish_seen_subcommand_from quote; and __fish_seen_subcommand_from escape-help" -s h -l help -d 'Print help' +complete -c exhaustive -n "__fish_seen_subcommand_from quote; and __fish_seen_subcommand_from escape-help" -s V -l version -d 'Print version' +complete -c exhaustive -n "__fish_seen_subcommand_from quote; and __fish_seen_subcommand_from help; and not __fish_seen_subcommand_from cmd-single-quotes; and not __fish_seen_subcommand_from cmd-double-quotes; and not __fish_seen_subcommand_from cmd-backticks; and not __fish_seen_subcommand_from cmd-backslash; and not __fish_seen_subcommand_from cmd-brackets; and not __fish_seen_subcommand_from cmd-expansions; and not __fish_seen_subcommand_from escape-help; and not __fish_seen_subcommand_from help" -f -a "cmd-single-quotes" -d 'Can be \'always\', \'auto\', or \'never\'' +complete -c exhaustive -n "__fish_seen_subcommand_from quote; and __fish_seen_subcommand_from help; and not __fish_seen_subcommand_from cmd-single-quotes; and not __fish_seen_subcommand_from cmd-double-quotes; and not __fish_seen_subcommand_from cmd-backticks; and not __fish_seen_subcommand_from cmd-backslash; and not __fish_seen_subcommand_from cmd-brackets; and not __fish_seen_subcommand_from cmd-expansions; and not __fish_seen_subcommand_from escape-help; and not __fish_seen_subcommand_from help" -f -a "cmd-double-quotes" -d 'Can be "always", "auto", or "never"' +complete -c exhaustive -n "__fish_seen_subcommand_from quote; and __fish_seen_subcommand_from help; and not __fish_seen_subcommand_from cmd-single-quotes; and not __fish_seen_subcommand_from cmd-double-quotes; and not __fish_seen_subcommand_from cmd-backticks; and not __fish_seen_subcommand_from cmd-backslash; and not __fish_seen_subcommand_from cmd-brackets; and not __fish_seen_subcommand_from cmd-expansions; and not __fish_seen_subcommand_from escape-help; and not __fish_seen_subcommand_from help" -f -a "cmd-backticks" -d 'For more information see `echo test`' +complete -c exhaustive -n "__fish_seen_subcommand_from quote; and __fish_seen_subcommand_from help; and not __fish_seen_subcommand_from cmd-single-quotes; and not __fish_seen_subcommand_from cmd-double-quotes; and not __fish_seen_subcommand_from cmd-backticks; and not __fish_seen_subcommand_from cmd-backslash; and not __fish_seen_subcommand_from cmd-brackets; and not __fish_seen_subcommand_from cmd-expansions; and not __fish_seen_subcommand_from escape-help; and not __fish_seen_subcommand_from help" -f -a "cmd-backslash" -d 'Avoid \'\\n\'' +complete -c exhaustive -n "__fish_seen_subcommand_from quote; and __fish_seen_subcommand_from help; and not __fish_seen_subcommand_from cmd-single-quotes; and not __fish_seen_subcommand_from cmd-double-quotes; and not __fish_seen_subcommand_from cmd-backticks; and not __fish_seen_subcommand_from cmd-backslash; and not __fish_seen_subcommand_from cmd-brackets; and not __fish_seen_subcommand_from cmd-expansions; and not __fish_seen_subcommand_from escape-help; and not __fish_seen_subcommand_from help" -f -a "cmd-brackets" -d 'List packages [filter]' +complete -c exhaustive -n "__fish_seen_subcommand_from quote; and __fish_seen_subcommand_from help; and not __fish_seen_subcommand_from cmd-single-quotes; and not __fish_seen_subcommand_from cmd-double-quotes; and not __fish_seen_subcommand_from cmd-backticks; and not __fish_seen_subcommand_from cmd-backslash; and not __fish_seen_subcommand_from cmd-brackets; and not __fish_seen_subcommand_from cmd-expansions; and not __fish_seen_subcommand_from escape-help; and not __fish_seen_subcommand_from help" -f -a "cmd-expansions" -d 'Execute the shell command with $SHELL' +complete -c exhaustive -n "__fish_seen_subcommand_from quote; and __fish_seen_subcommand_from help; and not __fish_seen_subcommand_from cmd-single-quotes; and not __fish_seen_subcommand_from cmd-double-quotes; and not __fish_seen_subcommand_from cmd-backticks; and not __fish_seen_subcommand_from cmd-backslash; and not __fish_seen_subcommand_from cmd-brackets; and not __fish_seen_subcommand_from cmd-expansions; and not __fish_seen_subcommand_from escape-help; and not __fish_seen_subcommand_from help" -f -a "escape-help" -d '\\tab "\' +New Line' +complete -c exhaustive -n "__fish_seen_subcommand_from quote; and __fish_seen_subcommand_from help; and not __fish_seen_subcommand_from cmd-single-quotes; and not __fish_seen_subcommand_from cmd-double-quotes; and not __fish_seen_subcommand_from cmd-backticks; and not __fish_seen_subcommand_from cmd-backslash; and not __fish_seen_subcommand_from cmd-brackets; and not __fish_seen_subcommand_from cmd-expansions; and not __fish_seen_subcommand_from escape-help; and not __fish_seen_subcommand_from help" -f -a "help" -d 'Print this message or the help of the given subcommand(s)' complete -c exhaustive -n "__fish_seen_subcommand_from value" -l delim -r complete -c exhaustive -n "__fish_seen_subcommand_from value" -l tuple -r complete -c exhaustive -n "__fish_seen_subcommand_from value" -l require-eq -r @@ -118,11 +125,13 @@ complete -c exhaustive -n "__fish_seen_subcommand_from help; and not __fish_seen complete -c exhaustive -n "__fish_seen_subcommand_from help; and not __fish_seen_subcommand_from action; and not __fish_seen_subcommand_from quote; and not __fish_seen_subcommand_from value; and not __fish_seen_subcommand_from pacman; and not __fish_seen_subcommand_from last; and not __fish_seen_subcommand_from alias; and not __fish_seen_subcommand_from hint; and not __fish_seen_subcommand_from complete; and not __fish_seen_subcommand_from help" -f -a "hint" complete -c exhaustive -n "__fish_seen_subcommand_from help; and not __fish_seen_subcommand_from action; and not __fish_seen_subcommand_from quote; and not __fish_seen_subcommand_from value; and not __fish_seen_subcommand_from pacman; and not __fish_seen_subcommand_from last; and not __fish_seen_subcommand_from alias; and not __fish_seen_subcommand_from hint; and not __fish_seen_subcommand_from complete; and not __fish_seen_subcommand_from help" -f -a "complete" -d 'Register shell completions for this program' complete -c exhaustive -n "__fish_seen_subcommand_from help; and not __fish_seen_subcommand_from action; and not __fish_seen_subcommand_from quote; and not __fish_seen_subcommand_from value; and not __fish_seen_subcommand_from pacman; and not __fish_seen_subcommand_from last; and not __fish_seen_subcommand_from alias; and not __fish_seen_subcommand_from hint; and not __fish_seen_subcommand_from complete; and not __fish_seen_subcommand_from help" -f -a "help" -d 'Print this message or the help of the given subcommand(s)' -complete -c exhaustive -n "__fish_seen_subcommand_from help; and __fish_seen_subcommand_from quote; and not __fish_seen_subcommand_from cmd-single-quotes; and not __fish_seen_subcommand_from cmd-double-quotes; and not __fish_seen_subcommand_from cmd-backticks; and not __fish_seen_subcommand_from cmd-backslash; and not __fish_seen_subcommand_from cmd-brackets; and not __fish_seen_subcommand_from cmd-expansions" -f -a "cmd-single-quotes" -d 'Can be \'always\', \'auto\', or \'never\'' -complete -c exhaustive -n "__fish_seen_subcommand_from help; and __fish_seen_subcommand_from quote; and not __fish_seen_subcommand_from cmd-single-quotes; and not __fish_seen_subcommand_from cmd-double-quotes; and not __fish_seen_subcommand_from cmd-backticks; and not __fish_seen_subcommand_from cmd-backslash; and not __fish_seen_subcommand_from cmd-brackets; and not __fish_seen_subcommand_from cmd-expansions" -f -a "cmd-double-quotes" -d 'Can be "always", "auto", or "never"' -complete -c exhaustive -n "__fish_seen_subcommand_from help; and __fish_seen_subcommand_from quote; and not __fish_seen_subcommand_from cmd-single-quotes; and not __fish_seen_subcommand_from cmd-double-quotes; and not __fish_seen_subcommand_from cmd-backticks; and not __fish_seen_subcommand_from cmd-backslash; and not __fish_seen_subcommand_from cmd-brackets; and not __fish_seen_subcommand_from cmd-expansions" -f -a "cmd-backticks" -d 'For more information see `echo test`' -complete -c exhaustive -n "__fish_seen_subcommand_from help; and __fish_seen_subcommand_from quote; and not __fish_seen_subcommand_from cmd-single-quotes; and not __fish_seen_subcommand_from cmd-double-quotes; and not __fish_seen_subcommand_from cmd-backticks; and not __fish_seen_subcommand_from cmd-backslash; and not __fish_seen_subcommand_from cmd-brackets; and not __fish_seen_subcommand_from cmd-expansions" -f -a "cmd-backslash" -d 'Avoid \'\\n\'' -complete -c exhaustive -n "__fish_seen_subcommand_from help; and __fish_seen_subcommand_from quote; and not __fish_seen_subcommand_from cmd-single-quotes; and not __fish_seen_subcommand_from cmd-double-quotes; and not __fish_seen_subcommand_from cmd-backticks; and not __fish_seen_subcommand_from cmd-backslash; and not __fish_seen_subcommand_from cmd-brackets; and not __fish_seen_subcommand_from cmd-expansions" -f -a "cmd-brackets" -d 'List packages [filter]' -complete -c exhaustive -n "__fish_seen_subcommand_from help; and __fish_seen_subcommand_from quote; and not __fish_seen_subcommand_from cmd-single-quotes; and not __fish_seen_subcommand_from cmd-double-quotes; and not __fish_seen_subcommand_from cmd-backticks; and not __fish_seen_subcommand_from cmd-backslash; and not __fish_seen_subcommand_from cmd-brackets; and not __fish_seen_subcommand_from cmd-expansions" -f -a "cmd-expansions" -d 'Execute the shell command with $SHELL' +complete -c exhaustive -n "__fish_seen_subcommand_from help; and __fish_seen_subcommand_from quote; and not __fish_seen_subcommand_from cmd-single-quotes; and not __fish_seen_subcommand_from cmd-double-quotes; and not __fish_seen_subcommand_from cmd-backticks; and not __fish_seen_subcommand_from cmd-backslash; and not __fish_seen_subcommand_from cmd-brackets; and not __fish_seen_subcommand_from cmd-expansions; and not __fish_seen_subcommand_from escape-help" -f -a "cmd-single-quotes" -d 'Can be \'always\', \'auto\', or \'never\'' +complete -c exhaustive -n "__fish_seen_subcommand_from help; and __fish_seen_subcommand_from quote; and not __fish_seen_subcommand_from cmd-single-quotes; and not __fish_seen_subcommand_from cmd-double-quotes; and not __fish_seen_subcommand_from cmd-backticks; and not __fish_seen_subcommand_from cmd-backslash; and not __fish_seen_subcommand_from cmd-brackets; and not __fish_seen_subcommand_from cmd-expansions; and not __fish_seen_subcommand_from escape-help" -f -a "cmd-double-quotes" -d 'Can be "always", "auto", or "never"' +complete -c exhaustive -n "__fish_seen_subcommand_from help; and __fish_seen_subcommand_from quote; and not __fish_seen_subcommand_from cmd-single-quotes; and not __fish_seen_subcommand_from cmd-double-quotes; and not __fish_seen_subcommand_from cmd-backticks; and not __fish_seen_subcommand_from cmd-backslash; and not __fish_seen_subcommand_from cmd-brackets; and not __fish_seen_subcommand_from cmd-expansions; and not __fish_seen_subcommand_from escape-help" -f -a "cmd-backticks" -d 'For more information see `echo test`' +complete -c exhaustive -n "__fish_seen_subcommand_from help; and __fish_seen_subcommand_from quote; and not __fish_seen_subcommand_from cmd-single-quotes; and not __fish_seen_subcommand_from cmd-double-quotes; and not __fish_seen_subcommand_from cmd-backticks; and not __fish_seen_subcommand_from cmd-backslash; and not __fish_seen_subcommand_from cmd-brackets; and not __fish_seen_subcommand_from cmd-expansions; and not __fish_seen_subcommand_from escape-help" -f -a "cmd-backslash" -d 'Avoid \'\\n\'' +complete -c exhaustive -n "__fish_seen_subcommand_from help; and __fish_seen_subcommand_from quote; and not __fish_seen_subcommand_from cmd-single-quotes; and not __fish_seen_subcommand_from cmd-double-quotes; and not __fish_seen_subcommand_from cmd-backticks; and not __fish_seen_subcommand_from cmd-backslash; and not __fish_seen_subcommand_from cmd-brackets; and not __fish_seen_subcommand_from cmd-expansions; and not __fish_seen_subcommand_from escape-help" -f -a "cmd-brackets" -d 'List packages [filter]' +complete -c exhaustive -n "__fish_seen_subcommand_from help; and __fish_seen_subcommand_from quote; and not __fish_seen_subcommand_from cmd-single-quotes; and not __fish_seen_subcommand_from cmd-double-quotes; and not __fish_seen_subcommand_from cmd-backticks; and not __fish_seen_subcommand_from cmd-backslash; and not __fish_seen_subcommand_from cmd-brackets; and not __fish_seen_subcommand_from cmd-expansions; and not __fish_seen_subcommand_from escape-help" -f -a "cmd-expansions" -d 'Execute the shell command with $SHELL' +complete -c exhaustive -n "__fish_seen_subcommand_from help; and __fish_seen_subcommand_from quote; and not __fish_seen_subcommand_from cmd-single-quotes; and not __fish_seen_subcommand_from cmd-double-quotes; and not __fish_seen_subcommand_from cmd-backticks; and not __fish_seen_subcommand_from cmd-backslash; and not __fish_seen_subcommand_from cmd-brackets; and not __fish_seen_subcommand_from cmd-expansions; and not __fish_seen_subcommand_from escape-help" -f -a "escape-help" -d '\\tab "\' +New Line' complete -c exhaustive -n "__fish_seen_subcommand_from help; and __fish_seen_subcommand_from pacman; and not __fish_seen_subcommand_from one; and not __fish_seen_subcommand_from two" -f -a "one" complete -c exhaustive -n "__fish_seen_subcommand_from help; and __fish_seen_subcommand_from pacman; and not __fish_seen_subcommand_from one; and not __fish_seen_subcommand_from two" -f -a "two" diff --git a/clap_complete/tests/snapshots/home/static/exhaustive/zsh/zsh/_exhaustive b/clap_complete/tests/snapshots/home/static/exhaustive/zsh/zsh/_exhaustive index 6548aa0e6bc..2c8b30e6c61 100644 --- a/clap_complete/tests/snapshots/home/static/exhaustive/zsh/zsh/_exhaustive +++ b/clap_complete/tests/snapshots/home/static/exhaustive/zsh/zsh/_exhaustive @@ -120,6 +120,15 @@ _arguments "${_arguments_options[@]}" \ '--version[Print version]' \ && ret=0 ;; +(escape-help) +_arguments "${_arguments_options[@]}" \ +'--global[everywhere]' \ +'-h[Print help]' \ +'--help[Print help]' \ +'-V[Print version]' \ +'--version[Print version]' \ +&& ret=0 +;; (help) _arguments "${_arguments_options[@]}" \ ":: :_exhaustive__quote__help_commands" \ @@ -156,6 +165,10 @@ _arguments "${_arguments_options[@]}" \ _arguments "${_arguments_options[@]}" \ && ret=0 ;; +(escape-help) +_arguments "${_arguments_options[@]}" \ +&& ret=0 +;; (help) _arguments "${_arguments_options[@]}" \ && ret=0 @@ -370,6 +383,10 @@ _arguments "${_arguments_options[@]}" \ (cmd-expansions) _arguments "${_arguments_options[@]}" \ && ret=0 +;; +(escape-help) +_arguments "${_arguments_options[@]}" \ +&& ret=0 ;; esac ;; @@ -567,6 +584,21 @@ _exhaustive__help__complete_commands() { local commands; commands=() _describe -t commands 'exhaustive help complete commands' commands "$@" } +(( $+functions[_exhaustive__help__quote__escape-help_commands] )) || +_exhaustive__help__quote__escape-help_commands() { + local commands; commands=() + _describe -t commands 'exhaustive help quote escape-help commands' commands "$@" +} +(( $+functions[_exhaustive__quote__escape-help_commands] )) || +_exhaustive__quote__escape-help_commands() { + local commands; commands=() + _describe -t commands 'exhaustive quote escape-help commands' commands "$@" +} +(( $+functions[_exhaustive__quote__help__escape-help_commands] )) || +_exhaustive__quote__help__escape-help_commands() { + local commands; commands=() + _describe -t commands 'exhaustive quote help escape-help commands' commands "$@" +} (( $+functions[_exhaustive__help_commands] )) || _exhaustive__help_commands() { local commands; commands=( @@ -610,6 +642,8 @@ _exhaustive__quote__help_commands() { 'cmd-backslash:Avoid '\''\\n'\''' \ 'cmd-brackets:List packages \[filter\]' \ 'cmd-expansions:Execute the shell command with \$SHELL' \ +'escape-help:\\tab "'\'' +New Line' \ 'help:Print this message or the help of the given subcommand(s)' \ ) _describe -t commands 'exhaustive quote help commands' commands "$@" @@ -680,6 +714,8 @@ _exhaustive__help__quote_commands() { 'cmd-backslash:Avoid '\''\\n'\''' \ 'cmd-brackets:List packages \[filter\]' \ 'cmd-expansions:Execute the shell command with \$SHELL' \ +'escape-help:\\tab "'\'' +New Line' \ ) _describe -t commands 'exhaustive help quote commands' commands "$@" } @@ -692,6 +728,8 @@ _exhaustive__quote_commands() { 'cmd-backslash:Avoid '\''\\n'\''' \ 'cmd-brackets:List packages \[filter\]' \ 'cmd-expansions:Execute the shell command with \$SHELL' \ +'escape-help:\\tab "'\'' +New Line' \ 'help:Print this message or the help of the given subcommand(s)' \ ) _describe -t commands 'exhaustive quote commands' commands "$@" diff --git a/clap_complete/tests/testsuite/dynamic.rs b/clap_complete/tests/testsuite/dynamic.rs index 8ab7461d033..2755f33bd4c 100644 --- a/clap_complete/tests/testsuite/dynamic.rs +++ b/clap_complete/tests/testsuite/dynamic.rs @@ -1,34 +1,38 @@ #![cfg(feature = "unstable-dynamic")] +use std::path::Path; + +use clap::{builder::PossibleValue, Command}; + +macro_rules! complete { + ($cmd:expr, $input:expr$(, current_dir = $current_dir:expr)? $(,)?) => { + { + #[allow(unused)] + let current_dir = None; + $(let current_dir = $current_dir;)? + complete(&mut $cmd, $input, current_dir) + } + } +} + #[test] fn suggest_subcommand_subset() { - let name = "exhaustive"; - let mut cmd = clap::Command::new(name) - .subcommand(clap::Command::new("hello-world")) - .subcommand(clap::Command::new("hello-moon")) - .subcommand(clap::Command::new("goodbye-world")); - - let args = [name, "he"]; - let arg_index = 1; - let args = IntoIterator::into_iter(args) - .map(std::ffi::OsString::from) - .collect::>(); - let current_dir = None; - - let completions = - clap_complete::dynamic::complete(&mut cmd, args, arg_index, current_dir).unwrap(); - let completions = completions - .into_iter() - .map(|s| s.to_string_lossy().into_owned()) - .collect::>(); - - assert_eq!(completions, ["hello-moon", "hello-world", "help"]); + let mut cmd = Command::new("exhaustive") + .subcommand(Command::new("hello-world")) + .subcommand(Command::new("hello-moon")) + .subcommand(Command::new("goodbye-world")); + + snapbox::assert_eq( + "hello-moon +hello-world +help\tPrint this message or the help of the given subcommand(s)", + complete!(cmd, "he"), + ); } #[test] fn suggest_long_flag_subset() { - let name = "exhaustive"; - let mut cmd = clap::Command::new(name) + let mut cmd = Command::new("exhaustive") .arg( clap::Arg::new("hello-world") .long("hello-world") @@ -45,53 +49,33 @@ fn suggest_long_flag_subset() { .action(clap::ArgAction::Count), ); - let args = [name, "--he"]; - let arg_index = 1; - let args = IntoIterator::into_iter(args) - .map(std::ffi::OsString::from) - .collect::>(); - let current_dir = None; - - let completions = - clap_complete::dynamic::complete(&mut cmd, args, arg_index, current_dir).unwrap(); - let completions = completions - .into_iter() - .map(|s| s.to_string_lossy().into_owned()) - .collect::>(); - - assert_eq!(completions, ["--hello-world", "--hello-moon", "--help"]); + snapbox::assert_eq( + "--hello-world +--hello-moon +--help\tPrint help", + complete!(cmd, "--he"), + ); } #[test] fn suggest_possible_value_subset() { let name = "exhaustive"; - let mut cmd = clap::Command::new(name).arg(clap::Arg::new("hello-world").value_parser([ - "hello-world", - "hello-moon", - "goodbye-world", + let mut cmd = Command::new(name).arg(clap::Arg::new("hello-world").value_parser([ + PossibleValue::new("hello-world").help("Say hello to the world"), + "hello-moon".into(), + "goodbye-world".into(), ])); - let args = [name, "hello"]; - let arg_index = 1; - let args = IntoIterator::into_iter(args) - .map(std::ffi::OsString::from) - .collect::>(); - let current_dir = None; - - let completions = - clap_complete::dynamic::complete(&mut cmd, args, arg_index, current_dir).unwrap(); - let completions = completions - .into_iter() - .map(|s| s.to_string_lossy().into_owned()) - .collect::>(); - - assert_eq!(completions, ["hello-world", "hello-moon"]); + snapbox::assert_eq( + "hello-world\tSay hello to the world +hello-moon", + complete!(cmd, "hello"), + ); } #[test] fn suggest_additional_short_flags() { - let name = "exhaustive"; - let mut cmd = clap::Command::new(name) + let mut cmd = Command::new("exhaustive") .arg( clap::Arg::new("a") .short('a') @@ -108,19 +92,47 @@ fn suggest_additional_short_flags() { .action(clap::ArgAction::Count), ); - let args = [name, "-a"]; - let arg_index = 1; - let args = IntoIterator::into_iter(args) - .map(std::ffi::OsString::from) - .collect::>(); - let current_dir = None; + snapbox::assert_eq( + "-aa +-ab +-ac +-ah\tPrint help", + complete!(cmd, "-a"), + ); +} - let completions = - clap_complete::dynamic::complete(&mut cmd, args, arg_index, current_dir).unwrap(); - let completions = completions +fn complete(cmd: &mut Command, args: impl AsRef, current_dir: Option<&Path>) -> String { + let input = args.as_ref(); + let mut args = vec![std::ffi::OsString::from(cmd.get_name())]; + let arg_index; + + if let Some((prior, after)) = input.split_once("[TAB]") { + args.extend(prior.split_whitespace().map(From::from)); + if prior.ends_with(char::is_whitespace) { + args.push(std::ffi::OsString::default()) + } + arg_index = args.len() - 1; + // HACK: this cannot handle in-word '[TAB]' + args.extend(after.split_whitespace().map(From::from)); + } else { + args.extend(input.split_whitespace().map(From::from)); + if input.ends_with(char::is_whitespace) { + args.push(std::ffi::OsString::default()) + } + arg_index = args.len() - 1; + } + + clap_complete::dynamic::complete(cmd, args, arg_index, current_dir) + .unwrap() .into_iter() - .map(|s| s.to_string_lossy().into_owned()) - .collect::>(); - - assert_eq!(completions, ["-aa", "-ab", "-ac", "-ah"]); + .map(|(compl, help)| { + let compl = compl.to_str().unwrap(); + if let Some(help) = help { + format!("{compl}\t{help}") + } else { + compl.to_owned() + } + }) + .collect::>() + .join("\n") } diff --git a/clap_complete/tests/testsuite/fish.rs b/clap_complete/tests/testsuite/fish.rs index 6e2bbeb46fe..49656a5cb47 100644 --- a/clap_complete/tests/testsuite/fish.rs +++ b/clap_complete/tests/testsuite/fish.rs @@ -162,9 +162,35 @@ fn complete_dynamic() { let input = "exhaustive \t"; let expected = r#"% exhaustive -action help pacman -h --global -alias hint quote -V --help -complete last value --generate --version"#; +action last -V (Print version) +alias pacman --generate (generate) +complete (Register shell completions for this program) quote --global (everywhere) +help (Print this message or the help of the given subcommand(s)) value --help (Print help) +hint -h (Print help) --version (Print version)"#; + let actual = runtime.complete(input, &term).unwrap(); + snapbox::assert_eq(expected, actual); + + let input = "exhaustive quote \t"; + let expected = r#"% exhaustive quote +cmd-backslash (Avoid '\n') +cmd-backticks (For more information see `echo test`) +cmd-brackets (List packages [filter]) +cmd-double-quotes (Can be "always", "auto", or "never") +cmd-expansions (Execute the shell command with $SHELL) +cmd-single-quotes (Can be 'always', 'auto', or 'never') +escape-help (\tab "') +help (Print this message or the help of the given subcommand(s)) +-h (Print help) +-V (Print version) +--backslash (Avoid '\n') +--backticks (For more information see `echo test`) +--brackets (List packages [filter]) +--double-quotes (Can be "always", "auto", or "never") +--expansions (Execute the shell command with $SHELL) +--global (everywhere) +--help (Print help) +--single-quotes (Can be 'always', 'auto', or 'never') +--version (Print version)"#; let actual = runtime.complete(input, &term).unwrap(); snapbox::assert_eq(expected, actual); }