Merge pull request #3544 from epage/trycmd

test: Switch completions/man to snapshot testing
This commit is contained in:
Ed Page 2022-03-07 14:45:21 -06:00 committed by GitHub
commit 9e3b661f08
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
76 changed files with 4340 additions and 2559 deletions

View file

@ -139,7 +139,7 @@ criterion = "0.3.2"
trybuild = "1.0.18" trybuild = "1.0.18"
rustversion = "1" rustversion = "1"
# Cutting out `filesystem` feature # Cutting out `filesystem` feature
trycmd = { version = "0.12", default-features = false, features = ["color-auto", "diff", "examples"] } trycmd = { version = "0.13", default-features = false, features = ["color-auto", "diff", "examples"] }
[[example]] [[example]]
name = "demo" name = "demo"

View file

@ -39,6 +39,7 @@ clap = { path = "../", version = "3.1.0", default-features = false, features = [
[dev-dependencies] [dev-dependencies]
pretty_assertions = "1.0" pretty_assertions = "1.0"
snapbox = { version = "0.2", features = ["diff"] }
clap = { path = "../", version = "3.1.0", default-features = false, features = ["std", "derive"] } clap = { path = "../", version = "3.1.0", default-features = false, features = ["std", "derive"] }
[features] [features]

View file

@ -0,0 +1,85 @@
mod common;
#[test]
fn basic() {
let name = "my-app";
let cmd = common::basic_command(name);
common::assert_matches_path(
"tests/snapshots/basic.bash.log",
clap_complete::shells::Bash,
cmd,
name,
);
}
#[test]
fn feature_sample() {
let name = "my-app";
let cmd = common::feature_sample_command(name);
common::assert_matches_path(
"tests/snapshots/feature_sample.bash.log",
clap_complete::shells::Bash,
cmd,
name,
);
}
#[test]
fn special_commands() {
let name = "my-app";
let cmd = common::special_commands_command(name);
common::assert_matches_path(
"tests/snapshots/special_commands.bash.log",
clap_complete::shells::Bash,
cmd,
name,
);
}
#[test]
fn quoting() {
let name = "my-app";
let cmd = common::quoting_command(name);
common::assert_matches_path(
"tests/snapshots/quoting.bash.log",
clap_complete::shells::Bash,
cmd,
name,
);
}
#[test]
fn aliases() {
let name = "my-app";
let cmd = common::aliases_command(name);
common::assert_matches_path(
"tests/snapshots/aliases.bash.log",
clap_complete::shells::Bash,
cmd,
name,
);
}
#[test]
fn sub_subcommands() {
let name = "my-app";
let cmd = common::sub_subcommands_command(name);
common::assert_matches_path(
"tests/snapshots/sub_subcommands.bash.log",
clap_complete::shells::Bash,
cmd,
name,
);
}
#[test]
fn value_hint() {
let name = "my-app";
let cmd = common::value_hint_command(name);
common::assert_matches_path(
"tests/snapshots/value_hint.bash.log",
clap_complete::shells::Bash,
cmd,
name,
);
}

View file

@ -0,0 +1,235 @@
pub fn basic_command(name: &'static str) -> clap::Command<'static> {
clap::Command::new(name)
.arg(clap::Arg::new("config").short('c').global(true))
.arg(clap::Arg::new("v").short('v').conflicts_with("config"))
.subcommand(
clap::Command::new("test")
.about("Subcommand")
.arg(clap::Arg::new("debug").short('d')),
)
}
pub fn feature_sample_command(name: &'static str) -> clap::Command<'static> {
clap::Command::new(name)
.version("3.0")
.propagate_version(true)
.about("Tests completions")
.arg(
clap::Arg::new("file")
.value_hint(clap::ValueHint::FilePath)
.help("some input file"),
)
.arg(
clap::Arg::new("config")
.help("some config file")
.short('c')
.visible_short_alias('C')
.long("config")
.visible_alias("conf"),
)
.arg(clap::Arg::new("choice").possible_values(["first", "second"]))
.subcommand(
clap::Command::new("test").about("tests things").arg(
clap::Arg::new("case")
.long("case")
.takes_value(true)
.help("the case to test"),
),
)
}
pub fn special_commands_command(name: &'static str) -> clap::Command<'static> {
feature_sample_command(name)
.subcommand(
clap::Command::new("some_cmd")
.about("tests other things")
.arg(
clap::Arg::new("config")
.long("--config")
.takes_value(true)
.help("the other case to test"),
),
)
.subcommand(clap::Command::new("some-cmd-with-hyphens").alias("hyphen"))
}
pub fn quoting_command(name: &'static str) -> clap::Command<'static> {
clap::Command::new(name)
.version("3.0")
.arg(
clap::Arg::new("single-quotes")
.long("single-quotes")
.help("Can be 'always', 'auto', or 'never'"),
)
.arg(
clap::Arg::new("double-quotes")
.long("double-quotes")
.help("Can be \"always\", \"auto\", or \"never\""),
)
.arg(
clap::Arg::new("backticks")
.long("backticks")
.help("For more information see `echo test`"),
)
.arg(
clap::Arg::new("backslash")
.long("backslash")
.help("Avoid '\\n'"),
)
.arg(
clap::Arg::new("brackets")
.long("brackets")
.help("List packages [filter]"),
)
.arg(
clap::Arg::new("expansions")
.long("expansions")
.help("Execute the shell command with $SHELL"),
)
.subcommands([
clap::Command::new("cmd-single-quotes").about("Can be 'always', 'auto', or 'never'"),
clap::Command::new("cmd-double-quotes")
.about("Can be \"always\", \"auto\", or \"never\""),
clap::Command::new("cmd-backticks").about("For more information see `echo test`"),
clap::Command::new("cmd-backslash").about("Avoid '\\n'"),
clap::Command::new("cmd-brackets").about("List packages [filter]"),
clap::Command::new("cmd-expansions").about("Execute the shell command with $SHELL"),
])
}
pub fn aliases_command(name: &'static str) -> clap::Command<'static> {
clap::Command::new(name)
.version("3.0")
.about("testing bash completions")
.arg(
clap::Arg::new("flag")
.short('f')
.visible_short_alias('F')
.long("flag")
.visible_alias("flg")
.help("cmd flag"),
)
.arg(
clap::Arg::new("option")
.short('o')
.visible_short_alias('O')
.long("option")
.visible_alias("opt")
.help("cmd option")
.takes_value(true),
)
.arg(clap::Arg::new("positional"))
}
pub fn sub_subcommands_command(name: &'static str) -> clap::Command<'static> {
feature_sample_command(name).subcommand(
clap::Command::new("some_cmd")
.about("top level subcommand")
.subcommand(
clap::Command::new("sub_cmd").about("sub-subcommand").arg(
clap::Arg::new("config")
.long("--config")
.takes_value(true)
.possible_values([clap::PossibleValue::new("Lest quotes aren't escaped.")])
.help("the other case to test"),
),
),
)
}
pub fn value_hint_command(name: &'static str) -> clap::Command<'static> {
clap::Command::new(name)
.trailing_var_arg(true)
.arg(
clap::Arg::new("choice")
.long("choice")
.possible_values(["bash", "fish", "zsh"]),
)
.arg(
clap::Arg::new("unknown")
.long("unknown")
.value_hint(clap::ValueHint::Unknown),
)
.arg(
clap::Arg::new("other")
.long("other")
.value_hint(clap::ValueHint::Other),
)
.arg(
clap::Arg::new("path")
.long("path")
.short('p')
.value_hint(clap::ValueHint::AnyPath),
)
.arg(
clap::Arg::new("file")
.long("file")
.short('f')
.value_hint(clap::ValueHint::FilePath),
)
.arg(
clap::Arg::new("dir")
.long("dir")
.short('d')
.value_hint(clap::ValueHint::DirPath),
)
.arg(
clap::Arg::new("exe")
.long("exe")
.short('e')
.value_hint(clap::ValueHint::ExecutablePath),
)
.arg(
clap::Arg::new("cmd_name")
.long("cmd-name")
.value_hint(clap::ValueHint::CommandName),
)
.arg(
clap::Arg::new("cmd")
.long("cmd")
.short('c')
.value_hint(clap::ValueHint::CommandString),
)
.arg(
clap::Arg::new("command_with_args")
.takes_value(true)
.multiple_values(true)
.value_hint(clap::ValueHint::CommandWithArguments),
)
.arg(
clap::Arg::new("user")
.short('u')
.long("user")
.value_hint(clap::ValueHint::Username),
)
.arg(
clap::Arg::new("host")
.short('h')
.long("host")
.value_hint(clap::ValueHint::Hostname),
)
.arg(
clap::Arg::new("url")
.long("url")
.value_hint(clap::ValueHint::Url),
)
.arg(
clap::Arg::new("email")
.long("email")
.value_hint(clap::ValueHint::EmailAddress),
)
}
pub fn assert_matches_path(
expected_path: impl AsRef<std::path::Path>,
gen: impl clap_complete::Generator,
mut cmd: clap::Command,
name: &str,
) {
let mut buf = vec![];
clap_complete::generate(gen, &mut cmd, name, &mut buf);
snapbox::Assert::new()
.action_env("SNAPSHOTS")
.matches_path(expected_path, buf);
}

View file

@ -1,331 +0,0 @@
use super::*;
fn build_app() -> Command<'static> {
build_app_with_name("myapp")
}
fn build_app_with_name(s: &'static str) -> Command<'static> {
Command::new(s)
.version("3.0")
.propagate_version(true)
.about("Tests completions")
.arg(
Arg::new("file")
.value_hint(ValueHint::FilePath)
.help("some input file"),
)
.arg(Arg::new("choice").possible_values(["first", "second"]))
.subcommand(
Command::new("test").about("tests things").arg(
Arg::new("case")
.long("case")
.takes_value(true)
.help("the case to test"),
),
)
}
#[test]
fn bash() {
let mut cmd = build_app();
common(Bash, &mut cmd, "myapp", BASH);
}
static BASH: &str = r#"_myapp() {
local i cur prev opts cmds
COMPREPLY=()
cur="${COMP_WORDS[COMP_CWORD]}"
prev="${COMP_WORDS[COMP_CWORD-1]}"
cmd=""
opts=""
for i in ${COMP_WORDS[@]}
do
case "${i}" in
"$1")
cmd="myapp"
;;
help)
cmd+="__help"
;;
test)
cmd+="__test"
;;
*)
;;
esac
done
case "${cmd}" in
myapp)
opts="-h -V --help --version <file> first second test help"
if [[ ${cur} == -* || ${COMP_CWORD} -eq 1 ]] ; then
COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
return 0
fi
case "${prev}" in
*)
COMPREPLY=()
;;
esac
COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
return 0
;;
myapp__help)
opts="<SUBCOMMAND>..."
if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then
COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
return 0
fi
case "${prev}" in
*)
COMPREPLY=()
;;
esac
COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
return 0
;;
myapp__test)
opts="-h -V --case --help --version"
if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then
COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
return 0
fi
case "${prev}" in
--case)
COMPREPLY=($(compgen -f "${cur}"))
return 0
;;
*)
COMPREPLY=()
;;
esac
COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
return 0
;;
esac
}
complete -F _myapp -o bashdefault -o default myapp
"#;
#[test]
fn bash_with_special_commands() {
let mut cmd = build_app_special_commands();
common(Bash, &mut cmd, "my_app", BASH_SPECIAL_CMDS);
}
fn build_app_special_commands() -> Command<'static> {
build_app_with_name("my_app")
.subcommand(
Command::new("some_cmd").about("tests other things").arg(
Arg::new("config")
.long("--config")
.takes_value(true)
.help("the other case to test"),
),
)
.subcommand(Command::new("some-cmd-with-hyphens").alias("hyphen"))
}
static BASH_SPECIAL_CMDS: &str = r#"_my_app() {
local i cur prev opts cmds
COMPREPLY=()
cur="${COMP_WORDS[COMP_CWORD]}"
prev="${COMP_WORDS[COMP_CWORD-1]}"
cmd=""
opts=""
for i in ${COMP_WORDS[@]}
do
case "${i}" in
"$1")
cmd="my_app"
;;
help)
cmd+="__help"
;;
some-cmd-with-hyphens)
cmd+="__some__cmd__with__hyphens"
;;
some_cmd)
cmd+="__some_cmd"
;;
test)
cmd+="__test"
;;
*)
;;
esac
done
case "${cmd}" in
my_app)
opts="-h -V --help --version <file> first second test some_cmd some-cmd-with-hyphens help"
if [[ ${cur} == -* || ${COMP_CWORD} -eq 1 ]] ; then
COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
return 0
fi
case "${prev}" in
*)
COMPREPLY=()
;;
esac
COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
return 0
;;
my_app__help)
opts="<SUBCOMMAND>..."
if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then
COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
return 0
fi
case "${prev}" in
*)
COMPREPLY=()
;;
esac
COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
return 0
;;
my_app__some__cmd__with__hyphens)
opts="-h -V --help --version"
if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then
COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
return 0
fi
case "${prev}" in
*)
COMPREPLY=()
;;
esac
COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
return 0
;;
my_app__some_cmd)
opts="-h -V --config --help --version"
if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then
COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
return 0
fi
case "${prev}" in
--config)
COMPREPLY=($(compgen -f "${cur}"))
return 0
;;
*)
COMPREPLY=()
;;
esac
COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
return 0
;;
my_app__test)
opts="-h -V --case --help --version"
if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then
COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
return 0
fi
case "${prev}" in
--case)
COMPREPLY=($(compgen -f "${cur}"))
return 0
;;
*)
COMPREPLY=()
;;
esac
COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
return 0
;;
esac
}
complete -F _my_app -o bashdefault -o default my_app
"#;
#[test]
fn bash_with_aliases() {
let mut cmd = build_app_with_aliases();
common(Bash, &mut cmd, "cmd", BASH_ALIASES);
}
fn build_app_with_aliases() -> Command<'static> {
Command::new("cmd")
.version("3.0")
.about("testing bash completions")
.arg(
Arg::new("flag")
.short('f')
.visible_short_alias('F')
.long("flag")
.visible_alias("flg")
.help("cmd flag"),
)
.arg(
Arg::new("option")
.short('o')
.visible_short_alias('O')
.long("option")
.visible_alias("opt")
.help("cmd option")
.takes_value(true),
)
.arg(Arg::new("positional"))
}
static BASH_ALIASES: &str = r#"_cmd() {
local i cur prev opts cmds
COMPREPLY=()
cur="${COMP_WORDS[COMP_CWORD]}"
prev="${COMP_WORDS[COMP_CWORD-1]}"
cmd=""
opts=""
for i in ${COMP_WORDS[@]}
do
case "${i}" in
"$1")
cmd="cmd"
;;
*)
;;
esac
done
case "${cmd}" in
cmd)
opts="-h -V -F -f -O -o --help --version --flg --flag --opt --option <positional>"
if [[ ${cur} == -* || ${COMP_CWORD} -eq 1 ]] ; then
COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
return 0
fi
case "${prev}" in
--option)
COMPREPLY=($(compgen -f "${cur}"))
return 0
;;
--opt)
COMPREPLY=($(compgen -f "${cur}"))
return 0
;;
-o)
COMPREPLY=($(compgen -f "${cur}"))
return 0
;;
-O)
COMPREPLY=($(compgen -f "${cur}"))
return 0
;;
*)
COMPREPLY=()
;;
esac
COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
return 0
;;
esac
}
complete -F _cmd -o bashdefault -o default cmd
"#;

View file

@ -1,215 +0,0 @@
use super::*;
fn build_app() -> Command<'static> {
build_app_with_name("myapp")
}
fn build_app_with_name(s: &'static str) -> Command<'static> {
Command::new(s)
.version("3.0")
.propagate_version(true)
.about("Tests completions")
.arg(
Arg::new("file")
.value_hint(ValueHint::FilePath)
.help("some input file"),
)
.subcommand(
Command::new("test").about("tests things").arg(
Arg::new("case")
.long("case")
.takes_value(true)
.help("the case to test"),
),
)
}
#[test]
fn elvish() {
let mut cmd = build_app();
common(Elvish, &mut cmd, "my_app", ELVISH);
}
static ELVISH: &str = r#"
use builtin;
use str;
set edit:completion:arg-completer[my_app] = {|@words|
fn spaces {|n|
builtin:repeat $n ' ' | str:join ''
}
fn cand {|text desc|
edit:complex-candidate $text &display=$text' '(spaces (- 14 (wcswidth $text)))$desc
}
var command = 'my_app'
for word $words[1..-1] {
if (str:has-prefix $word '-') {
break
}
set command = $command';'$word
}
var completions = [
&'my_app'= {
cand -h 'Print help information'
cand --help 'Print help information'
cand -V 'Print version information'
cand --version 'Print version information'
cand test 'tests things'
cand help 'Print this message or the help of the given subcommand(s)'
}
&'my_app;test'= {
cand --case 'the case to test'
cand -h 'Print help information'
cand --help 'Print help information'
cand -V 'Print version information'
cand --version 'Print version information'
}
&'my_app;help'= {
}
]
$completions[$command]
}
"#;
#[test]
fn elvish_with_special_commands() {
let mut cmd = build_app_special_commands();
common(Elvish, &mut cmd, "my_app", ELVISH_SPECIAL_CMDS);
}
fn build_app_special_commands() -> Command<'static> {
build_app_with_name("my_app")
.subcommand(
Command::new("some_cmd").about("tests other things").arg(
Arg::new("config")
.long("--config")
.takes_value(true)
.help("the other case to test"),
),
)
.subcommand(Command::new("some-cmd-with-hyphens").alias("hyphen"))
}
static ELVISH_SPECIAL_CMDS: &str = r#"
use builtin;
use str;
set edit:completion:arg-completer[my_app] = {|@words|
fn spaces {|n|
builtin:repeat $n ' ' | str:join ''
}
fn cand {|text desc|
edit:complex-candidate $text &display=$text' '(spaces (- 14 (wcswidth $text)))$desc
}
var command = 'my_app'
for word $words[1..-1] {
if (str:has-prefix $word '-') {
break
}
set command = $command';'$word
}
var completions = [
&'my_app'= {
cand -h 'Print help information'
cand --help 'Print help information'
cand -V 'Print version information'
cand --version 'Print version information'
cand test 'tests things'
cand some_cmd 'tests other things'
cand some-cmd-with-hyphens 'some-cmd-with-hyphens'
cand help 'Print this message or the help of the given subcommand(s)'
}
&'my_app;test'= {
cand --case 'the case to test'
cand -h 'Print help information'
cand --help 'Print help information'
cand -V 'Print version information'
cand --version 'Print version information'
}
&'my_app;some_cmd'= {
cand --config 'the other case to test'
cand -h 'Print help information'
cand --help 'Print help information'
cand -V 'Print version information'
cand --version 'Print version information'
}
&'my_app;some-cmd-with-hyphens'= {
cand -h 'Print help information'
cand --help 'Print help information'
cand -V 'Print version information'
cand --version 'Print version information'
}
&'my_app;help'= {
}
]
$completions[$command]
}
"#;
#[test]
fn elvish_with_aliases() {
let mut cmd = build_app_with_aliases();
common(Elvish, &mut cmd, "cmd", ELVISH_ALIASES);
}
fn build_app_with_aliases() -> Command<'static> {
Command::new("cmd")
.version("3.0")
.about("testing bash completions")
.arg(
Arg::new("flag")
.short('f')
.visible_short_alias('F')
.long("flag")
.visible_alias("flg")
.help("cmd flag"),
)
.arg(
Arg::new("option")
.short('o')
.visible_short_alias('O')
.long("option")
.visible_alias("opt")
.help("cmd option")
.takes_value(true),
)
.arg(Arg::new("positional"))
}
static ELVISH_ALIASES: &str = r#"
use builtin;
use str;
set edit:completion:arg-completer[cmd] = {|@words|
fn spaces {|n|
builtin:repeat $n ' ' | str:join ''
}
fn cand {|text desc|
edit:complex-candidate $text &display=$text' '(spaces (- 14 (wcswidth $text)))$desc
}
var command = 'cmd'
for word $words[1..-1] {
if (str:has-prefix $word '-') {
break
}
set command = $command';'$word
}
var completions = [
&'cmd'= {
cand -o 'cmd option'
cand -O 'cmd option'
cand --option 'cmd option'
cand --opt 'cmd option'
cand -h 'Print help information'
cand --help 'Print help information'
cand -V 'Print version information'
cand --version 'Print version information'
cand -f 'cmd flag'
cand -F 'cmd flag'
cand --flag 'cmd flag'
cand --flg 'cmd flag'
}
]
$completions[$command]
}
"#;

View file

@ -1,201 +0,0 @@
use clap::PossibleValue;
use super::*;
fn build_app() -> Command<'static> {
build_app_with_name("myapp")
}
fn build_app_with_name(s: &'static str) -> Command<'static> {
Command::new(s)
.version("3.0")
.propagate_version(true)
.about("Tests completions")
.arg(
Arg::new("file")
.value_hint(ValueHint::FilePath)
.help("some input file"),
)
.subcommand(
Command::new("test").about("tests things").arg(
Arg::new("case")
.long("case")
.takes_value(true)
.help("the case to test"),
),
)
}
#[test]
fn fish() {
let mut cmd = build_app();
common(Fish, &mut cmd, "myapp", FISH);
}
static FISH: &str = r#"complete -c myapp -n "__fish_use_subcommand" -s h -l help -d 'Print help information'
complete -c myapp -n "__fish_use_subcommand" -s V -l version -d 'Print version information'
complete -c myapp -n "__fish_use_subcommand" -f -a "test" -d 'tests things'
complete -c myapp -n "__fish_use_subcommand" -f -a "help" -d 'Print this message or the help of the given subcommand(s)'
complete -c myapp -n "__fish_seen_subcommand_from test" -l case -d 'the case to test' -r
complete -c myapp -n "__fish_seen_subcommand_from test" -s h -l help -d 'Print help information'
complete -c myapp -n "__fish_seen_subcommand_from test" -s V -l version -d 'Print version information'
"#;
#[test]
fn fish_with_special_commands() {
let mut cmd = build_app_special_commands();
common(Fish, &mut cmd, "my_app", FISH_SPECIAL_CMDS);
}
fn build_app_special_commands() -> Command<'static> {
build_app_with_name("my_app")
.subcommand(
Command::new("some_cmd").about("tests other things").arg(
Arg::new("config")
.long("--config")
.takes_value(true)
.help("the other case to test"),
),
)
.subcommand(Command::new("some-cmd-with-hyphens").alias("hyphen"))
}
static FISH_SPECIAL_CMDS: &str = r#"complete -c my_app -n "__fish_use_subcommand" -s h -l help -d 'Print help information'
complete -c my_app -n "__fish_use_subcommand" -s V -l version -d 'Print version information'
complete -c my_app -n "__fish_use_subcommand" -f -a "test" -d 'tests things'
complete -c my_app -n "__fish_use_subcommand" -f -a "some_cmd" -d 'tests other things'
complete -c my_app -n "__fish_use_subcommand" -f -a "some-cmd-with-hyphens"
complete -c my_app -n "__fish_use_subcommand" -f -a "help" -d 'Print this message or the help of the given subcommand(s)'
complete -c my_app -n "__fish_seen_subcommand_from test" -l case -d 'the case to test' -r
complete -c my_app -n "__fish_seen_subcommand_from test" -s h -l help -d 'Print help information'
complete -c my_app -n "__fish_seen_subcommand_from test" -s V -l version -d 'Print version information'
complete -c my_app -n "__fish_seen_subcommand_from some_cmd" -l config -d 'the other case to test' -r
complete -c my_app -n "__fish_seen_subcommand_from some_cmd" -s h -l help -d 'Print help information'
complete -c my_app -n "__fish_seen_subcommand_from some_cmd" -s V -l version -d 'Print version information'
complete -c my_app -n "__fish_seen_subcommand_from some-cmd-with-hyphens" -s h -l help -d 'Print help information'
complete -c my_app -n "__fish_seen_subcommand_from some-cmd-with-hyphens" -s V -l version -d 'Print version information'
"#;
#[test]
fn fish_with_special_help() {
let mut cmd = build_app_special_help();
common(Fish, &mut cmd, "my_app", FISH_SPECIAL_HELP);
}
fn build_app_special_help() -> Command<'static> {
Command::new("my_app")
.version("3.0")
.arg(
Arg::new("single-quotes")
.long("single-quotes")
.help("Can be 'always', 'auto', or 'never'"),
)
.arg(
Arg::new("double-quotes")
.long("double-quotes")
.help("Can be \"always\", \"auto\", or \"never\""),
)
.arg(
Arg::new("backticks")
.long("backticks")
.help("For more information see `echo test`"),
)
.arg(Arg::new("backslash").long("backslash").help("Avoid '\\n'"))
.arg(
Arg::new("brackets")
.long("brackets")
.help("List packages [filter]"),
)
.arg(
Arg::new("expansions")
.long("expansions")
.help("Execute the shell command with $SHELL"),
)
}
static FISH_SPECIAL_HELP: &str = r#"complete -c my_app -s h -l help -d 'Print help information'
complete -c my_app -s V -l version -d 'Print version information'
complete -c my_app -l single-quotes -d 'Can be \'always\', \'auto\', or \'never\''
complete -c my_app -l double-quotes -d 'Can be "always", "auto", or "never"'
complete -c my_app -l backticks -d 'For more information see `echo test`'
complete -c my_app -l backslash -d 'Avoid \'\\n\''
complete -c my_app -l brackets -d 'List packages [filter]'
complete -c my_app -l expansions -d 'Execute the shell command with $SHELL'
"#;
#[test]
fn fish_with_aliases() {
let mut cmd = build_app_with_aliases();
common(Fish, &mut cmd, "cmd", FISH_ALIASES);
}
fn build_app_with_aliases() -> Command<'static> {
Command::new("cmd")
.version("3.0")
.about("testing bash completions")
.arg(
Arg::new("flag")
.short('f')
.visible_short_alias('F')
.long("flag")
.visible_alias("flg")
.help("cmd flag"),
)
.arg(
Arg::new("option")
.short('o')
.visible_short_alias('O')
.long("option")
.visible_alias("opt")
.help("cmd option")
.takes_value(true),
)
.arg(Arg::new("positional"))
}
static FISH_ALIASES: &str = r#"complete -c cmd -s o -s O -l option -l opt -d 'cmd option' -r
complete -c cmd -s h -l help -d 'Print help information'
complete -c cmd -s V -l version -d 'Print version information'
complete -c cmd -s f -s F -l flag -l flg -d 'cmd flag'
"#;
#[test]
fn fish_with_sub_subcommands() {
let mut cmd = build_app_sub_subcommands();
common(Fish, &mut cmd, "my_app", FISH_SUB_SUBCMDS);
}
fn build_app_sub_subcommands() -> Command<'static> {
build_app_with_name("my_app").subcommand(
Command::new("some_cmd")
.about("top level subcommand")
.subcommand(
Command::new("sub_cmd").about("sub-subcommand").arg(
Arg::new("config")
.long("--config")
.takes_value(true)
.possible_values([PossibleValue::new("Lest quotes aren't escaped.")])
.help("the other case to test"),
),
),
)
}
static FISH_SUB_SUBCMDS: &str = r#"complete -c my_app -n "__fish_use_subcommand" -s h -l help -d 'Print help information'
complete -c my_app -n "__fish_use_subcommand" -s V -l version -d 'Print version information'
complete -c my_app -n "__fish_use_subcommand" -f -a "test" -d 'tests things'
complete -c my_app -n "__fish_use_subcommand" -f -a "some_cmd" -d 'top level subcommand'
complete -c my_app -n "__fish_use_subcommand" -f -a "help" -d 'Print this message or the help of the given subcommand(s)'
complete -c my_app -n "__fish_seen_subcommand_from test" -l case -d 'the case to test' -r
complete -c my_app -n "__fish_seen_subcommand_from test" -s h -l help -d 'Print help information'
complete -c my_app -n "__fish_seen_subcommand_from test" -s V -l version -d 'Print version information'
complete -c my_app -n "__fish_seen_subcommand_from some_cmd; and not __fish_seen_subcommand_from sub_cmd; and not __fish_seen_subcommand_from help" -s h -l help -d 'Print help information'
complete -c my_app -n "__fish_seen_subcommand_from some_cmd; and not __fish_seen_subcommand_from sub_cmd; and not __fish_seen_subcommand_from help" -s V -l version -d 'Print version information'
complete -c my_app -n "__fish_seen_subcommand_from some_cmd; and not __fish_seen_subcommand_from sub_cmd; and not __fish_seen_subcommand_from help" -f -a "sub_cmd" -d 'sub-subcommand'
complete -c my_app -n "__fish_seen_subcommand_from some_cmd; and not __fish_seen_subcommand_from sub_cmd; and not __fish_seen_subcommand_from help" -f -a "help" -d 'Print this message or the help of the given subcommand(s)'
complete -c my_app -n "__fish_seen_subcommand_from some_cmd; and __fish_seen_subcommand_from sub_cmd" -l config -d 'the other case to test' -r -f -a "{Lest quotes aren\'t escaped. }"
complete -c my_app -n "__fish_seen_subcommand_from some_cmd; and __fish_seen_subcommand_from sub_cmd" -s h -l help -d 'Print help information'
complete -c my_app -n "__fish_seen_subcommand_from some_cmd; and __fish_seen_subcommand_from sub_cmd" -s V -l version -d 'Print version information'
complete -c my_app -n "__fish_seen_subcommand_from some_cmd; and __fish_seen_subcommand_from help" -s h -l help -d 'Print help information'
complete -c my_app -n "__fish_seen_subcommand_from some_cmd; and __fish_seen_subcommand_from help" -s V -l version -d 'Print version information'
"#;

View file

@ -1,32 +0,0 @@
use clap::{Arg, Command, ValueHint};
use clap_complete::{generate, shells::*, Generator};
use std::fmt;
mod bash;
mod elvish;
mod fish;
mod powershell;
mod zsh;
#[derive(PartialEq, Eq)]
pub struct PrettyString<'a>(pub &'a str);
impl<'a> fmt::Debug for PrettyString<'a> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
f.write_str(self.0)
}
}
macro_rules! assert_eq {
($left:expr, $right:expr) => {
pretty_assertions::assert_eq!(PrettyString($left), PrettyString($right));
};
}
pub fn common<G: Generator>(gen: G, cmd: &mut Command, name: &str, fixture: &str) {
let mut buf = vec![];
generate(gen, cmd, name, &mut buf);
let string = String::from_utf8(buf).unwrap();
assert_eq!(&string, fixture);
}

View file

@ -1,255 +0,0 @@
use super::*;
fn build_app() -> Command<'static> {
build_app_with_name("myapp")
}
fn build_app_with_name(s: &'static str) -> Command<'static> {
Command::new(s)
.version("3.0")
.propagate_version(true)
.about("Tests completions")
.arg(
Arg::new("file")
.value_hint(ValueHint::FilePath)
.help("some input file"),
)
.arg(
Arg::new("config")
.help("some config file")
.short('c')
.visible_short_alias('C')
.long("config")
.visible_alias("conf"),
)
.subcommand(
Command::new("test").about("tests things").arg(
Arg::new("case")
.long("case")
.takes_value(true)
.help("the case to test"),
),
)
}
#[test]
fn powershell() {
let mut cmd = build_app();
common(PowerShell, &mut cmd, "my_app", POWERSHELL);
}
static POWERSHELL: &str = r#"
using namespace System.Management.Automation
using namespace System.Management.Automation.Language
Register-ArgumentCompleter -Native -CommandName 'my_app' -ScriptBlock {
param($wordToComplete, $commandAst, $cursorPosition)
$commandElements = $commandAst.CommandElements
$command = @(
'my_app'
for ($i = 1; $i -lt $commandElements.Count; $i++) {
$element = $commandElements[$i]
if ($element -isnot [StringConstantExpressionAst] -or
$element.StringConstantType -ne [StringConstantType]::BareWord -or
$element.Value.StartsWith('-') -or
$element.Value -eq $wordToComplete) {
break
}
$element.Value
}) -join ';'
$completions = @(switch ($command) {
'my_app' {
[CompletionResult]::new('-h', 'h', [CompletionResultType]::ParameterName, 'Print help information')
[CompletionResult]::new('--help', 'help', [CompletionResultType]::ParameterName, 'Print help information')
[CompletionResult]::new('-V', 'V', [CompletionResultType]::ParameterName, 'Print version information')
[CompletionResult]::new('--version', 'version', [CompletionResultType]::ParameterName, 'Print version information')
[CompletionResult]::new('-c', 'c', [CompletionResultType]::ParameterName, 'some config file')
[CompletionResult]::new('-C', 'C', [CompletionResultType]::ParameterName, 'some config file')
[CompletionResult]::new('--config', 'config', [CompletionResultType]::ParameterName, 'some config file')
[CompletionResult]::new('--conf', 'conf', [CompletionResultType]::ParameterName, 'some config file')
[CompletionResult]::new('test', 'test', [CompletionResultType]::ParameterValue, 'tests things')
[CompletionResult]::new('help', 'help', [CompletionResultType]::ParameterValue, 'Print this message or the help of the given subcommand(s)')
break
}
'my_app;test' {
[CompletionResult]::new('--case', 'case', [CompletionResultType]::ParameterName, 'the case to test')
[CompletionResult]::new('-h', 'h', [CompletionResultType]::ParameterName, 'Print help information')
[CompletionResult]::new('--help', 'help', [CompletionResultType]::ParameterName, 'Print help information')
[CompletionResult]::new('-V', 'V', [CompletionResultType]::ParameterName, 'Print version information')
[CompletionResult]::new('--version', 'version', [CompletionResultType]::ParameterName, 'Print version information')
break
}
'my_app;help' {
break
}
})
$completions.Where{ $_.CompletionText -like "$wordToComplete*" } |
Sort-Object -Property ListItemText
}
"#;
#[test]
fn powershell_with_special_commands() {
let mut cmd = build_app_special_commands();
common(PowerShell, &mut cmd, "my_app", POWERSHELL_SPECIAL_CMDS);
}
fn build_app_special_commands() -> Command<'static> {
build_app_with_name("my_app")
.subcommand(
Command::new("some_cmd").about("tests other things").arg(
Arg::new("config")
.long("--config")
.takes_value(true)
.help("the other case to test"),
),
)
.subcommand(Command::new("some-cmd-with-hyphens").alias("hyphen"))
}
static POWERSHELL_SPECIAL_CMDS: &str = r#"
using namespace System.Management.Automation
using namespace System.Management.Automation.Language
Register-ArgumentCompleter -Native -CommandName 'my_app' -ScriptBlock {
param($wordToComplete, $commandAst, $cursorPosition)
$commandElements = $commandAst.CommandElements
$command = @(
'my_app'
for ($i = 1; $i -lt $commandElements.Count; $i++) {
$element = $commandElements[$i]
if ($element -isnot [StringConstantExpressionAst] -or
$element.StringConstantType -ne [StringConstantType]::BareWord -or
$element.Value.StartsWith('-') -or
$element.Value -eq $wordToComplete) {
break
}
$element.Value
}) -join ';'
$completions = @(switch ($command) {
'my_app' {
[CompletionResult]::new('-h', 'h', [CompletionResultType]::ParameterName, 'Print help information')
[CompletionResult]::new('--help', 'help', [CompletionResultType]::ParameterName, 'Print help information')
[CompletionResult]::new('-V', 'V', [CompletionResultType]::ParameterName, 'Print version information')
[CompletionResult]::new('--version', 'version', [CompletionResultType]::ParameterName, 'Print version information')
[CompletionResult]::new('-c', 'c', [CompletionResultType]::ParameterName, 'some config file')
[CompletionResult]::new('-C', 'C', [CompletionResultType]::ParameterName, 'some config file')
[CompletionResult]::new('--config', 'config', [CompletionResultType]::ParameterName, 'some config file')
[CompletionResult]::new('--conf', 'conf', [CompletionResultType]::ParameterName, 'some config file')
[CompletionResult]::new('test', 'test', [CompletionResultType]::ParameterValue, 'tests things')
[CompletionResult]::new('some_cmd', 'some_cmd', [CompletionResultType]::ParameterValue, 'tests other things')
[CompletionResult]::new('some-cmd-with-hyphens', 'some-cmd-with-hyphens', [CompletionResultType]::ParameterValue, 'some-cmd-with-hyphens')
[CompletionResult]::new('help', 'help', [CompletionResultType]::ParameterValue, 'Print this message or the help of the given subcommand(s)')
break
}
'my_app;test' {
[CompletionResult]::new('--case', 'case', [CompletionResultType]::ParameterName, 'the case to test')
[CompletionResult]::new('-h', 'h', [CompletionResultType]::ParameterName, 'Print help information')
[CompletionResult]::new('--help', 'help', [CompletionResultType]::ParameterName, 'Print help information')
[CompletionResult]::new('-V', 'V', [CompletionResultType]::ParameterName, 'Print version information')
[CompletionResult]::new('--version', 'version', [CompletionResultType]::ParameterName, 'Print version information')
break
}
'my_app;some_cmd' {
[CompletionResult]::new('--config', 'config', [CompletionResultType]::ParameterName, 'the other case to test')
[CompletionResult]::new('-h', 'h', [CompletionResultType]::ParameterName, 'Print help information')
[CompletionResult]::new('--help', 'help', [CompletionResultType]::ParameterName, 'Print help information')
[CompletionResult]::new('-V', 'V', [CompletionResultType]::ParameterName, 'Print version information')
[CompletionResult]::new('--version', 'version', [CompletionResultType]::ParameterName, 'Print version information')
break
}
'my_app;some-cmd-with-hyphens' {
[CompletionResult]::new('-h', 'h', [CompletionResultType]::ParameterName, 'Print help information')
[CompletionResult]::new('--help', 'help', [CompletionResultType]::ParameterName, 'Print help information')
[CompletionResult]::new('-V', 'V', [CompletionResultType]::ParameterName, 'Print version information')
[CompletionResult]::new('--version', 'version', [CompletionResultType]::ParameterName, 'Print version information')
break
}
'my_app;help' {
break
}
})
$completions.Where{ $_.CompletionText -like "$wordToComplete*" } |
Sort-Object -Property ListItemText
}
"#;
#[test]
fn powershell_with_aliases() {
let mut cmd = build_app_with_aliases();
common(PowerShell, &mut cmd, "cmd", POWERSHELL_ALIASES);
}
fn build_app_with_aliases() -> Command<'static> {
Command::new("cmd")
.version("3.0")
.about("testing bash completions")
.arg(
Arg::new("flag")
.short('f')
.visible_short_alias('F')
.long("flag")
.visible_alias("flg")
.help("cmd flag"),
)
.arg(
Arg::new("option")
.short('o')
.visible_short_alias('O')
.long("option")
.visible_alias("opt")
.help("cmd option")
.takes_value(true),
)
.arg(Arg::new("positional"))
}
static POWERSHELL_ALIASES: &str = r#"
using namespace System.Management.Automation
using namespace System.Management.Automation.Language
Register-ArgumentCompleter -Native -CommandName 'cmd' -ScriptBlock {
param($wordToComplete, $commandAst, $cursorPosition)
$commandElements = $commandAst.CommandElements
$command = @(
'cmd'
for ($i = 1; $i -lt $commandElements.Count; $i++) {
$element = $commandElements[$i]
if ($element -isnot [StringConstantExpressionAst] -or
$element.StringConstantType -ne [StringConstantType]::BareWord -or
$element.Value.StartsWith('-') -or
$element.Value -eq $wordToComplete) {
break
}
$element.Value
}) -join ';'
$completions = @(switch ($command) {
'cmd' {
[CompletionResult]::new('-o', 'o', [CompletionResultType]::ParameterName, 'cmd option')
[CompletionResult]::new('-O', 'O', [CompletionResultType]::ParameterName, 'cmd option')
[CompletionResult]::new('--option', 'option', [CompletionResultType]::ParameterName, 'cmd option')
[CompletionResult]::new('--opt', 'opt', [CompletionResultType]::ParameterName, 'cmd option')
[CompletionResult]::new('-h', 'h', [CompletionResultType]::ParameterName, 'Print help information')
[CompletionResult]::new('--help', 'help', [CompletionResultType]::ParameterName, 'Print help information')
[CompletionResult]::new('-V', 'V', [CompletionResultType]::ParameterName, 'Print version information')
[CompletionResult]::new('--version', 'version', [CompletionResultType]::ParameterName, 'Print version information')
[CompletionResult]::new('-f', 'f', [CompletionResultType]::ParameterName, 'cmd flag')
[CompletionResult]::new('-F', 'F', [CompletionResultType]::ParameterName, 'cmd flag')
[CompletionResult]::new('--flag', 'flag', [CompletionResultType]::ParameterName, 'cmd flag')
[CompletionResult]::new('--flg', 'flg', [CompletionResultType]::ParameterName, 'cmd flag')
break
}
})
$completions.Where{ $_.CompletionText -like "$wordToComplete*" } |
Sort-Object -Property ListItemText
}
"#;

View file

@ -1,572 +0,0 @@
use super::*;
fn build_app() -> Command<'static> {
build_app_with_name("myapp")
}
fn build_app_with_name(s: &'static str) -> Command<'static> {
Command::new(s)
.version("3.0")
.propagate_version(true)
.about("Test test's completions")
.arg(
Arg::new("file")
.value_hint(ValueHint::FilePath)
.help("some input's file"),
)
.subcommand(
Command::new("test").about("test test's things").arg(
Arg::new("case")
.long("case")
.takes_value(true)
.help("test's cases to test"),
),
)
}
#[test]
fn zsh() {
let mut cmd = build_app();
common(Zsh, &mut cmd, "myapp", ZSH);
}
static ZSH: &str = r#"#compdef myapp
autoload -U is-at-least
_myapp() {
typeset -A opt_args
typeset -a _arguments_options
local ret=1
if is-at-least 5.2; then
_arguments_options=(-s -S -C)
else
_arguments_options=(-s -C)
fi
local context curcontext="$curcontext" state line
_arguments "${_arguments_options[@]}" \
'-h[Print help information]' \
'--help[Print help information]' \
'-V[Print version information]' \
'--version[Print version information]' \
'::file -- some input'\''s file:_files' \
":: :_myapp_commands" \
"*::: :->myapp" \
&& ret=0
case $state in
(myapp)
words=($line[2] "${words[@]}")
(( CURRENT += 1 ))
curcontext="${curcontext%:*:*}:myapp-command-$line[2]:"
case $line[2] in
(test)
_arguments "${_arguments_options[@]}" \
'--case=[test'\''s cases to test]: : ' \
'-h[Print help information]' \
'--help[Print help information]' \
'-V[Print version information]' \
'--version[Print version information]' \
&& ret=0
;;
(help)
_arguments "${_arguments_options[@]}" \
'*::subcommand -- The subcommand whose help message to display:' \
&& ret=0
;;
esac
;;
esac
}
(( $+functions[_myapp_commands] )) ||
_myapp_commands() {
local commands; commands=(
'test:test test'\''s things' \
'help:Print this message or the help of the given subcommand(s)' \
)
_describe -t commands 'myapp commands' commands "$@"
}
(( $+functions[_myapp__help_commands] )) ||
_myapp__help_commands() {
local commands; commands=()
_describe -t commands 'myapp help commands' commands "$@"
}
(( $+functions[_myapp__test_commands] )) ||
_myapp__test_commands() {
local commands; commands=()
_describe -t commands 'myapp test commands' commands "$@"
}
_myapp "$@"
"#;
#[test]
fn zsh_with_special_commands() {
let mut cmd = build_app_special_commands();
common(Zsh, &mut cmd, "my_app", ZSH_SPECIAL_CMDS);
}
fn build_app_special_commands() -> Command<'static> {
build_app_with_name("my_app")
.subcommand(
Command::new("some_cmd").about("tests other things").arg(
Arg::new("config")
.long("--config")
.takes_value(true)
.help("the other case to test"),
),
)
.subcommand(Command::new("some-cmd-with-hypens").alias("hyphen"))
.subcommand(
Command::new("some_cmd_with_special_characters")
.about("This 'is' a \"special\" [character] string \\"),
)
}
static ZSH_SPECIAL_CMDS: &str = r#"#compdef my_app
autoload -U is-at-least
_my_app() {
typeset -A opt_args
typeset -a _arguments_options
local ret=1
if is-at-least 5.2; then
_arguments_options=(-s -S -C)
else
_arguments_options=(-s -C)
fi
local context curcontext="$curcontext" state line
_arguments "${_arguments_options[@]}" \
'-h[Print help information]' \
'--help[Print help information]' \
'-V[Print version information]' \
'--version[Print version information]' \
'::file -- some input'\''s file:_files' \
":: :_my_app_commands" \
"*::: :->my_app" \
&& ret=0
case $state in
(my_app)
words=($line[2] "${words[@]}")
(( CURRENT += 1 ))
curcontext="${curcontext%:*:*}:my_app-command-$line[2]:"
case $line[2] in
(test)
_arguments "${_arguments_options[@]}" \
'--case=[test'\''s cases to test]: : ' \
'-h[Print help information]' \
'--help[Print help information]' \
'-V[Print version information]' \
'--version[Print version information]' \
&& ret=0
;;
(some_cmd)
_arguments "${_arguments_options[@]}" \
'--config=[the other case to test]: : ' \
'-h[Print help information]' \
'--help[Print help information]' \
'-V[Print version information]' \
'--version[Print version information]' \
&& ret=0
;;
(some-cmd-with-hypens)
_arguments "${_arguments_options[@]}" \
'-h[Print help information]' \
'--help[Print help information]' \
'-V[Print version information]' \
'--version[Print version information]' \
&& ret=0
;;
(some_cmd_with_special_characters)
_arguments "${_arguments_options[@]}" \
'-h[Print help information]' \
'--help[Print help information]' \
'-V[Print version information]' \
'--version[Print version information]' \
&& ret=0
;;
(help)
_arguments "${_arguments_options[@]}" \
'*::subcommand -- The subcommand whose help message to display:' \
&& ret=0
;;
esac
;;
esac
}
(( $+functions[_my_app_commands] )) ||
_my_app_commands() {
local commands; commands=(
'test:test test'\''s things' \
'some_cmd:tests other things' \
'some-cmd-with-hypens:' \
'some_cmd_with_special_characters:This '\''is'\'' a "special" \[character\] string \\' \
'help:Print this message or the help of the given subcommand(s)' \
)
_describe -t commands 'my_app commands' commands "$@"
}
(( $+functions[_my_app__help_commands] )) ||
_my_app__help_commands() {
local commands; commands=()
_describe -t commands 'my_app help commands' commands "$@"
}
(( $+functions[_my_app__some-cmd-with-hypens_commands] )) ||
_my_app__some-cmd-with-hypens_commands() {
local commands; commands=()
_describe -t commands 'my_app some-cmd-with-hypens commands' commands "$@"
}
(( $+functions[_my_app__some_cmd_commands] )) ||
_my_app__some_cmd_commands() {
local commands; commands=()
_describe -t commands 'my_app some_cmd commands' commands "$@"
}
(( $+functions[_my_app__some_cmd_with_special_characters_commands] )) ||
_my_app__some_cmd_with_special_characters_commands() {
local commands; commands=()
_describe -t commands 'my_app some_cmd_with_special_characters commands' commands "$@"
}
(( $+functions[_my_app__test_commands] )) ||
_my_app__test_commands() {
local commands; commands=()
_describe -t commands 'my_app test commands' commands "$@"
}
_my_app "$@"
"#;
#[test]
fn zsh_with_special_help() {
let mut cmd = build_app_special_help();
common(Zsh, &mut cmd, "my_app", ZSH_SPECIAL_HELP);
}
fn build_app_special_help() -> Command<'static> {
Command::new("my_app")
.version("3.0")
.arg(
Arg::new("single-quotes")
.long("single-quotes")
.help("Can be 'always', 'auto', or 'never'"),
)
.arg(
Arg::new("double-quotes")
.long("double-quotes")
.help("Can be \"always\", \"auto\", or \"never\""),
)
.arg(
Arg::new("backticks")
.long("backticks")
.help("For more information see `echo test`"),
)
.arg(Arg::new("backslash").long("backslash").help("Avoid '\\n'"))
.arg(
Arg::new("brackets")
.long("brackets")
.help("List packages [filter]"),
)
.arg(
Arg::new("expansions")
.long("expansions")
.help("Execute the shell command with $SHELL"),
)
}
static ZSH_SPECIAL_HELP: &str = r#"#compdef my_app
autoload -U is-at-least
_my_app() {
typeset -A opt_args
typeset -a _arguments_options
local ret=1
if is-at-least 5.2; then
_arguments_options=(-s -S -C)
else
_arguments_options=(-s -C)
fi
local context curcontext="$curcontext" state line
_arguments "${_arguments_options[@]}" \
'-h[Print help information]' \
'--help[Print help information]' \
'-V[Print version information]' \
'--version[Print version information]' \
'--single-quotes[Can be '\''always'\'', '\''auto'\'', or '\''never'\'']' \
'--double-quotes[Can be "always", "auto", or "never"]' \
'--backticks[For more information see `echo test`]' \
'--backslash[Avoid '\''\\n'\'']' \
'--brackets[List packages \[filter\]]' \
'--expansions[Execute the shell command with $SHELL]' \
&& ret=0
}
(( $+functions[_my_app_commands] )) ||
_my_app_commands() {
local commands; commands=()
_describe -t commands 'my_app commands' commands "$@"
}
_my_app "$@"
"#;
#[test]
fn zsh_with_nested_subcommands() {
let mut cmd = build_app_nested_subcommands();
common(Zsh, &mut cmd, "my_app", ZSH_NESTED_SUBCOMMANDS);
}
fn build_app_nested_subcommands() -> Command<'static> {
Command::new("first")
.version("3.0")
.subcommand(Command::new("second").subcommand(Command::new("third")))
}
static ZSH_NESTED_SUBCOMMANDS: &str = r#"#compdef my_app
autoload -U is-at-least
_my_app() {
typeset -A opt_args
typeset -a _arguments_options
local ret=1
if is-at-least 5.2; then
_arguments_options=(-s -S -C)
else
_arguments_options=(-s -C)
fi
local context curcontext="$curcontext" state line
_arguments "${_arguments_options[@]}" \
'-h[Print help information]' \
'--help[Print help information]' \
'-V[Print version information]' \
'--version[Print version information]' \
":: :_my_app_commands" \
"*::: :->first" \
&& ret=0
case $state in
(first)
words=($line[1] "${words[@]}")
(( CURRENT += 1 ))
curcontext="${curcontext%:*:*}:my_app-command-$line[1]:"
case $line[1] in
(second)
_arguments "${_arguments_options[@]}" \
'-h[Print help information]' \
'--help[Print help information]' \
":: :_my_app__second_commands" \
"*::: :->second" \
&& ret=0
case $state in
(second)
words=($line[1] "${words[@]}")
(( CURRENT += 1 ))
curcontext="${curcontext%:*:*}:my_app-second-command-$line[1]:"
case $line[1] in
(third)
_arguments "${_arguments_options[@]}" \
'--version[Print version information]' \
'-h[Print help information]' \
'--help[Print help information]' \
&& ret=0
;;
(help)
_arguments "${_arguments_options[@]}" \
'--version[Print version information]' \
'-h[Print help information]' \
'--help[Print help information]' \
'*::subcommand -- The subcommand whose help message to display:' \
&& ret=0
;;
esac
;;
esac
;;
(help)
_arguments "${_arguments_options[@]}" \
'*::subcommand -- The subcommand whose help message to display:' \
&& ret=0
;;
esac
;;
esac
}
(( $+functions[_my_app_commands] )) ||
_my_app_commands() {
local commands; commands=(
'second:' \
'help:Print this message or the help of the given subcommand(s)' \
)
_describe -t commands 'my_app commands' commands "$@"
}
(( $+functions[_my_app__help_commands] )) ||
_my_app__help_commands() {
local commands; commands=()
_describe -t commands 'my_app help commands' commands "$@"
}
(( $+functions[_my_app__second__help_commands] )) ||
_my_app__second__help_commands() {
local commands; commands=()
_describe -t commands 'my_app second help commands' commands "$@"
}
(( $+functions[_my_app__second_commands] )) ||
_my_app__second_commands() {
local commands; commands=(
'third:' \
'help:Print this message or the help of the given subcommand(s)' \
)
_describe -t commands 'my_app second commands' commands "$@"
}
(( $+functions[_my_app__second__third_commands] )) ||
_my_app__second__third_commands() {
local commands; commands=()
_describe -t commands 'my_app second third commands' commands "$@"
}
_my_app "$@"
"#;
#[test]
fn zsh_with_aliases() {
let mut cmd = build_app_with_aliases();
common(Zsh, &mut cmd, "cmd", ZSH_ALIASES);
}
fn build_app_with_aliases() -> Command<'static> {
Command::new("cmd")
.version("3.0")
.about("testing bash completions")
.arg(
Arg::new("flag")
.short('f')
.visible_short_alias('F')
.long("flag")
.visible_alias("flg")
.help("cmd flag"),
)
.arg(
Arg::new("option")
.short('o')
.visible_short_alias('O')
.long("option")
.visible_alias("opt")
.help("cmd option")
.takes_value(true),
)
.arg(Arg::new("positional"))
}
static ZSH_ALIASES: &str = r#"#compdef cmd
autoload -U is-at-least
_cmd() {
typeset -A opt_args
typeset -a _arguments_options
local ret=1
if is-at-least 5.2; then
_arguments_options=(-s -S -C)
else
_arguments_options=(-s -C)
fi
local context curcontext="$curcontext" state line
_arguments "${_arguments_options[@]}" \
'-o+[cmd option]: : ' \
'-O+[cmd option]: : ' \
'--option=[cmd option]: : ' \
'--opt=[cmd option]: : ' \
'-h[Print help information]' \
'--help[Print help information]' \
'-V[Print version information]' \
'--version[Print version information]' \
'-f[cmd flag]' \
'-F[cmd flag]' \
'--flag[cmd flag]' \
'--flg[cmd flag]' \
'::positional:' \
&& ret=0
}
(( $+functions[_cmd_commands] )) ||
_cmd_commands() {
local commands; commands=()
_describe -t commands 'cmd commands' commands "$@"
}
_cmd "$@"
"#;
#[test]
fn zsh_with_files_and_dirs() {
let mut cmd = build_app_with_files_and_dirs();
common(Zsh, &mut cmd, "my_app", ZSH_PATHS);
}
fn build_app_with_files_and_dirs() -> Command<'static> {
Command::new("my_app")
.version("3.0")
.about("testing zsh completions")
.arg(
Arg::new("directory")
.long("dir")
.help("specify a directory")
.value_name("DIR")
.number_of_values(3)
.value_hint(ValueHint::DirPath),
)
.arg(
Arg::new("file")
.long("inputfiles")
.value_name("FILE")
.multiple_occurrences(true)
.help("specify a file")
.value_hint(ValueHint::FilePath),
)
}
static ZSH_PATHS: &str = r#"#compdef my_app
autoload -U is-at-least
_my_app() {
typeset -A opt_args
typeset -a _arguments_options
local ret=1
if is-at-least 5.2; then
_arguments_options=(-s -S -C)
else
_arguments_options=(-s -C)
fi
local context curcontext="$curcontext" state line
_arguments "${_arguments_options[@]}" \
'--dir=[specify a directory]:DIR:_files -/:DIR:_files -/:DIR:_files -/' \
'*--inputfiles=[specify a file]:FILE:_files' \
'-h[Print help information]' \
'--help[Print help information]' \
'-V[Print version information]' \
'--version[Print version information]' \
&& ret=0
}
(( $+functions[_my_app_commands] )) ||
_my_app_commands() {
local commands; commands=()
_describe -t commands 'my_app commands' commands "$@"
}
_my_app "$@"
"#;

View file

@ -0,0 +1,85 @@
mod common;
#[test]
fn basic() {
let name = "my-app";
let cmd = common::basic_command(name);
common::assert_matches_path(
"tests/snapshots/basic.elvish.log",
clap_complete::shells::Elvish,
cmd,
name,
);
}
#[test]
fn feature_sample() {
let name = "my-app";
let cmd = common::feature_sample_command(name);
common::assert_matches_path(
"tests/snapshots/feature_sample.elvish.log",
clap_complete::shells::Elvish,
cmd,
name,
);
}
#[test]
fn special_commands() {
let name = "my-app";
let cmd = common::special_commands_command(name);
common::assert_matches_path(
"tests/snapshots/special_commands.elvish.log",
clap_complete::shells::Elvish,
cmd,
name,
);
}
#[test]
fn quoting() {
let name = "my-app";
let cmd = common::quoting_command(name);
common::assert_matches_path(
"tests/snapshots/quoting.elvish.log",
clap_complete::shells::Elvish,
cmd,
name,
);
}
#[test]
fn aliases() {
let name = "my-app";
let cmd = common::aliases_command(name);
common::assert_matches_path(
"tests/snapshots/aliases.elvish.log",
clap_complete::shells::Elvish,
cmd,
name,
);
}
#[test]
fn sub_subcommands() {
let name = "my-app";
let cmd = common::sub_subcommands_command(name);
common::assert_matches_path(
"tests/snapshots/sub_subcommands.elvish.log",
clap_complete::shells::Elvish,
cmd,
name,
);
}
#[test]
fn value_hint() {
let name = "my-app";
let cmd = common::value_hint_command(name);
common::assert_matches_path(
"tests/snapshots/value_hint.elvish.log",
clap_complete::shells::Elvish,
cmd,
name,
);
}

View file

@ -0,0 +1,85 @@
mod common;
#[test]
fn basic() {
let name = "my-app";
let cmd = common::basic_command(name);
common::assert_matches_path(
"tests/snapshots/basic.fish.log",
clap_complete::shells::Fish,
cmd,
name,
);
}
#[test]
fn feature_sample() {
let name = "my-app";
let cmd = common::feature_sample_command(name);
common::assert_matches_path(
"tests/snapshots/feature_sample.fish.log",
clap_complete::shells::Fish,
cmd,
name,
);
}
#[test]
fn special_commands() {
let name = "my-app";
let cmd = common::special_commands_command(name);
common::assert_matches_path(
"tests/snapshots/special_commands.fish.log",
clap_complete::shells::Fish,
cmd,
name,
);
}
#[test]
fn quoting() {
let name = "my-app";
let cmd = common::quoting_command(name);
common::assert_matches_path(
"tests/snapshots/quoting.fish.log",
clap_complete::shells::Fish,
cmd,
name,
);
}
#[test]
fn aliases() {
let name = "my-app";
let cmd = common::aliases_command(name);
common::assert_matches_path(
"tests/snapshots/aliases.fish.log",
clap_complete::shells::Fish,
cmd,
name,
);
}
#[test]
fn sub_subcommands() {
let name = "my-app";
let cmd = common::sub_subcommands_command(name);
common::assert_matches_path(
"tests/snapshots/sub_subcommands.fish.log",
clap_complete::shells::Fish,
cmd,
name,
);
}
#[test]
fn value_hint() {
let name = "my-app";
let cmd = common::value_hint_command(name);
common::assert_matches_path(
"tests/snapshots/value_hint.fish.log",
clap_complete::shells::Fish,
cmd,
name,
);
}

View file

@ -1,23 +0,0 @@
use std::io;
use clap::{Arg, Command};
use clap_complete::{generate, shells::*};
#[test]
fn generate_completions() {
let mut cmd = Command::new("test_app")
.arg(Arg::new("config").short('c').global(true))
.arg(Arg::new("v").short('v').conflicts_with("config"))
.subcommand(
Command::new("test")
.about("Subcommand")
.arg(Arg::new("debug").short('d')),
);
generate(Bash, &mut cmd, "test_app", &mut io::sink());
generate(Fish, &mut cmd, "test_app", &mut io::sink());
generate(PowerShell, &mut cmd, "test_app", &mut io::sink());
generate(Elvish, &mut cmd, "test_app", &mut io::sink());
generate(Zsh, &mut cmd, "test_app", &mut io::sink());
}

View file

@ -0,0 +1,85 @@
mod common;
#[test]
fn basic() {
let name = "my-app";
let cmd = common::basic_command(name);
common::assert_matches_path(
"tests/snapshots/basic.powershell.log",
clap_complete::shells::PowerShell,
cmd,
name,
);
}
#[test]
fn feature_sample() {
let name = "my-app";
let cmd = common::feature_sample_command(name);
common::assert_matches_path(
"tests/snapshots/feature_sample.powershell.log",
clap_complete::shells::PowerShell,
cmd,
name,
);
}
#[test]
fn special_commands() {
let name = "my-app";
let cmd = common::special_commands_command(name);
common::assert_matches_path(
"tests/snapshots/special_commands.powershell.log",
clap_complete::shells::PowerShell,
cmd,
name,
);
}
#[test]
fn quoting() {
let name = "my-app";
let cmd = common::quoting_command(name);
common::assert_matches_path(
"tests/snapshots/quoting.powershell.log",
clap_complete::shells::PowerShell,
cmd,
name,
);
}
#[test]
fn aliases() {
let name = "my-app";
let cmd = common::aliases_command(name);
common::assert_matches_path(
"tests/snapshots/aliases.powershell.log",
clap_complete::shells::PowerShell,
cmd,
name,
);
}
#[test]
fn sub_subcommands() {
let name = "my-app";
let cmd = common::sub_subcommands_command(name);
common::assert_matches_path(
"tests/snapshots/sub_subcommands.powershell.log",
clap_complete::shells::PowerShell,
cmd,
name,
);
}
#[test]
fn value_hint() {
let name = "my-app";
let cmd = common::value_hint_command(name);
common::assert_matches_path(
"tests/snapshots/value_hint.powershell.log",
clap_complete::shells::PowerShell,
cmd,
name,
);
}

View file

@ -0,0 +1,54 @@
_my-app() {
local i cur prev opts cmds
COMPREPLY=()
cur="${COMP_WORDS[COMP_CWORD]}"
prev="${COMP_WORDS[COMP_CWORD-1]}"
cmd=""
opts=""
for i in ${COMP_WORDS[@]}
do
case "${i}" in
"$1")
cmd="my__app"
;;
*)
;;
esac
done
case "${cmd}" in
my__app)
opts="-h -V -F -f -O -o --help --version --flg --flag --opt --option <positional>"
if [[ ${cur} == -* || ${COMP_CWORD} -eq 1 ]] ; then
COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
return 0
fi
case "${prev}" in
--option)
COMPREPLY=($(compgen -f "${cur}"))
return 0
;;
--opt)
COMPREPLY=($(compgen -f "${cur}"))
return 0
;;
-o)
COMPREPLY=($(compgen -f "${cur}"))
return 0
;;
-O)
COMPREPLY=($(compgen -f "${cur}"))
return 0
;;
*)
COMPREPLY=()
;;
esac
COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
return 0
;;
esac
}
complete -F _my-app -o bashdefault -o default my-app

View file

@ -0,0 +1,36 @@
use builtin;
use str;
set edit:completion:arg-completer[my-app] = {|@words|
fn spaces {|n|
builtin:repeat $n ' ' | str:join ''
}
fn cand {|text desc|
edit:complex-candidate $text &display=$text' '(spaces (- 14 (wcswidth $text)))$desc
}
var command = 'my-app'
for word $words[1..-1] {
if (str:has-prefix $word '-') {
break
}
set command = $command';'$word
}
var completions = [
&'my-app'= {
cand -o 'cmd option'
cand -O 'cmd option'
cand --option 'cmd option'
cand --opt 'cmd option'
cand -h 'Print help information'
cand --help 'Print help information'
cand -V 'Print version information'
cand --version 'Print version information'
cand -f 'cmd flag'
cand -F 'cmd flag'
cand --flag 'cmd flag'
cand --flg 'cmd flag'
}
]
$completions[$command]
}

View file

@ -0,0 +1,4 @@
complete -c my-app -s o -s O -l option -l opt -d 'cmd option' -r
complete -c my-app -s h -l help -d 'Print help information'
complete -c my-app -s V -l version -d 'Print version information'
complete -c my-app -s f -s F -l flag -l flg -d 'cmd flag'

View file

@ -0,0 +1,42 @@
using namespace System.Management.Automation
using namespace System.Management.Automation.Language
Register-ArgumentCompleter -Native -CommandName 'my-app' -ScriptBlock {
param($wordToComplete, $commandAst, $cursorPosition)
$commandElements = $commandAst.CommandElements
$command = @(
'my-app'
for ($i = 1; $i -lt $commandElements.Count; $i++) {
$element = $commandElements[$i]
if ($element -isnot [StringConstantExpressionAst] -or
$element.StringConstantType -ne [StringConstantType]::BareWord -or
$element.Value.StartsWith('-') -or
$element.Value -eq $wordToComplete) {
break
}
$element.Value
}) -join ';'
$completions = @(switch ($command) {
'my-app' {
[CompletionResult]::new('-o', 'o', [CompletionResultType]::ParameterName, 'cmd option')
[CompletionResult]::new('-O', 'O', [CompletionResultType]::ParameterName, 'cmd option')
[CompletionResult]::new('--option', 'option', [CompletionResultType]::ParameterName, 'cmd option')
[CompletionResult]::new('--opt', 'opt', [CompletionResultType]::ParameterName, 'cmd option')
[CompletionResult]::new('-h', 'h', [CompletionResultType]::ParameterName, 'Print help information')
[CompletionResult]::new('--help', 'help', [CompletionResultType]::ParameterName, 'Print help information')
[CompletionResult]::new('-V', 'V', [CompletionResultType]::ParameterName, 'Print version information')
[CompletionResult]::new('--version', 'version', [CompletionResultType]::ParameterName, 'Print version information')
[CompletionResult]::new('-f', 'f', [CompletionResultType]::ParameterName, 'cmd flag')
[CompletionResult]::new('-F', 'F', [CompletionResultType]::ParameterName, 'cmd flag')
[CompletionResult]::new('--flag', 'flag', [CompletionResultType]::ParameterName, 'cmd flag')
[CompletionResult]::new('--flg', 'flg', [CompletionResultType]::ParameterName, 'cmd flag')
break
}
})
$completions.Where{ $_.CompletionText -like "$wordToComplete*" } |
Sort-Object -Property ListItemText
}

View file

@ -0,0 +1,40 @@
#compdef my-app
autoload -U is-at-least
_my-app() {
typeset -A opt_args
typeset -a _arguments_options
local ret=1
if is-at-least 5.2; then
_arguments_options=(-s -S -C)
else
_arguments_options=(-s -C)
fi
local context curcontext="$curcontext" state line
_arguments "${_arguments_options[@]}" /
'-o+[cmd option]: : ' /
'-O+[cmd option]: : ' /
'--option=[cmd option]: : ' /
'--opt=[cmd option]: : ' /
'-h[Print help information]' /
'--help[Print help information]' /
'-V[Print version information]' /
'--version[Print version information]' /
'-f[cmd flag]' /
'-F[cmd flag]' /
'--flag[cmd flag]' /
'--flg[cmd flag]' /
'::positional:' /
&& ret=0
}
(( $+functions[_my-app_commands] )) ||
_my-app_commands() {
local commands; commands=()
_describe -t commands 'my-app commands' commands "$@"
}
_my-app "$@"

View file

@ -0,0 +1,72 @@
_my-app() {
local i cur prev opts cmds
COMPREPLY=()
cur="${COMP_WORDS[COMP_CWORD]}"
prev="${COMP_WORDS[COMP_CWORD-1]}"
cmd=""
opts=""
for i in ${COMP_WORDS[@]}
do
case "${i}" in
"$1")
cmd="my__app"
;;
help)
cmd+="__help"
;;
test)
cmd+="__test"
;;
*)
;;
esac
done
case "${cmd}" in
my__app)
opts="-h -c -v --help test help"
if [[ ${cur} == -* || ${COMP_CWORD} -eq 1 ]] ; then
COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
return 0
fi
case "${prev}" in
*)
COMPREPLY=()
;;
esac
COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
return 0
;;
my__app__help)
opts="-c <SUBCOMMAND>..."
if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then
COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
return 0
fi
case "${prev}" in
*)
COMPREPLY=()
;;
esac
COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
return 0
;;
my__app__test)
opts="-d -h -c --help"
if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then
COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
return 0
fi
case "${prev}" in
*)
COMPREPLY=()
;;
esac
COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
return 0
;;
esac
}
complete -F _my-app -o bashdefault -o default my-app

View file

@ -0,0 +1,39 @@
use builtin;
use str;
set edit:completion:arg-completer[my-app] = {|@words|
fn spaces {|n|
builtin:repeat $n ' ' | str:join ''
}
fn cand {|text desc|
edit:complex-candidate $text &display=$text' '(spaces (- 14 (wcswidth $text)))$desc
}
var command = 'my-app'
for word $words[1..-1] {
if (str:has-prefix $word '-') {
break
}
set command = $command';'$word
}
var completions = [
&'my-app'= {
cand -h 'Print help information'
cand --help 'Print help information'
cand -c 'c'
cand -v 'v'
cand test 'Subcommand'
cand help 'Print this message or the help of the given subcommand(s)'
}
&'my-app;test'= {
cand -d 'd'
cand -h 'Print help information'
cand --help 'Print help information'
cand -c 'c'
}
&'my-app;help'= {
cand -c 'c'
}
]
$completions[$command]
}

View file

@ -0,0 +1,9 @@
complete -c my-app -n "__fish_use_subcommand" -s h -l help -d 'Print help information'
complete -c my-app -n "__fish_use_subcommand" -s c
complete -c my-app -n "__fish_use_subcommand" -s v
complete -c my-app -n "__fish_use_subcommand" -f -a "test" -d 'Subcommand'
complete -c my-app -n "__fish_use_subcommand" -f -a "help" -d 'Print this message or the help of the given subcommand(s)'
complete -c my-app -n "__fish_seen_subcommand_from test" -s d
complete -c my-app -n "__fish_seen_subcommand_from test" -s h -l help -d 'Print help information'
complete -c my-app -n "__fish_seen_subcommand_from test" -s c
complete -c my-app -n "__fish_seen_subcommand_from help" -s c

View file

@ -0,0 +1,47 @@
using namespace System.Management.Automation
using namespace System.Management.Automation.Language
Register-ArgumentCompleter -Native -CommandName 'my-app' -ScriptBlock {
param($wordToComplete, $commandAst, $cursorPosition)
$commandElements = $commandAst.CommandElements
$command = @(
'my-app'
for ($i = 1; $i -lt $commandElements.Count; $i++) {
$element = $commandElements[$i]
if ($element -isnot [StringConstantExpressionAst] -or
$element.StringConstantType -ne [StringConstantType]::BareWord -or
$element.Value.StartsWith('-') -or
$element.Value -eq $wordToComplete) {
break
}
$element.Value
}) -join ';'
$completions = @(switch ($command) {
'my-app' {
[CompletionResult]::new('-h', 'h', [CompletionResultType]::ParameterName, 'Print help information')
[CompletionResult]::new('--help', 'help', [CompletionResultType]::ParameterName, 'Print help information')
[CompletionResult]::new('-c', 'c', [CompletionResultType]::ParameterName, 'c')
[CompletionResult]::new('-v', 'v', [CompletionResultType]::ParameterName, 'v')
[CompletionResult]::new('test', 'test', [CompletionResultType]::ParameterValue, 'Subcommand')
[CompletionResult]::new('help', 'help', [CompletionResultType]::ParameterValue, 'Print this message or the help of the given subcommand(s)')
break
}
'my-app;test' {
[CompletionResult]::new('-d', 'd', [CompletionResultType]::ParameterName, 'd')
[CompletionResult]::new('-h', 'h', [CompletionResultType]::ParameterName, 'Print help information')
[CompletionResult]::new('--help', 'help', [CompletionResultType]::ParameterName, 'Print help information')
[CompletionResult]::new('-c', 'c', [CompletionResultType]::ParameterName, 'c')
break
}
'my-app;help' {
[CompletionResult]::new('-c', 'c', [CompletionResultType]::ParameterName, 'c')
break
}
})
$completions.Where{ $_.CompletionText -like "$wordToComplete*" } |
Sort-Object -Property ListItemText
}

View file

@ -0,0 +1,69 @@
#compdef my-app
autoload -U is-at-least
_my-app() {
typeset -A opt_args
typeset -a _arguments_options
local ret=1
if is-at-least 5.2; then
_arguments_options=(-s -S -C)
else
_arguments_options=(-s -C)
fi
local context curcontext="$curcontext" state line
_arguments "${_arguments_options[@]}" /
'-h[Print help information]' /
'--help[Print help information]' /
'-c[]' /
'(-c)-v[]' /
":: :_my-app_commands" /
"*::: :->my-app" /
&& ret=0
case $state in
(my-app)
words=($line[1] "${words[@]}")
(( CURRENT += 1 ))
curcontext="${curcontext%:*:*}:my-app-command-$line[1]:"
case $line[1] in
(test)
_arguments "${_arguments_options[@]}" /
'-d[]' /
'-h[Print help information]' /
'--help[Print help information]' /
'-c[]' /
&& ret=0
;;
(help)
_arguments "${_arguments_options[@]}" /
'-c[]' /
'*::subcommand -- The subcommand whose help message to display:' /
&& ret=0
;;
esac
;;
esac
}
(( $+functions[_my-app_commands] )) ||
_my-app_commands() {
local commands; commands=(
'test:Subcommand' /
'help:Print this message or the help of the given subcommand(s)' /
)
_describe -t commands 'my-app commands' commands "$@"
}
(( $+functions[_my-app__help_commands] )) ||
_my-app__help_commands() {
local commands; commands=()
_describe -t commands 'my-app help commands' commands "$@"
}
(( $+functions[_my-app__test_commands] )) ||
_my-app__test_commands() {
local commands; commands=()
_describe -t commands 'my-app test commands' commands "$@"
}
_my-app "$@"

View file

@ -0,0 +1,76 @@
_my-app() {
local i cur prev opts cmds
COMPREPLY=()
cur="${COMP_WORDS[COMP_CWORD]}"
prev="${COMP_WORDS[COMP_CWORD-1]}"
cmd=""
opts=""
for i in ${COMP_WORDS[@]}
do
case "${i}" in
"$1")
cmd="my__app"
;;
help)
cmd+="__help"
;;
test)
cmd+="__test"
;;
*)
;;
esac
done
case "${cmd}" in
my__app)
opts="-h -V -C -c --help --version --conf --config <file> first second test help"
if [[ ${cur} == -* || ${COMP_CWORD} -eq 1 ]] ; then
COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
return 0
fi
case "${prev}" in
*)
COMPREPLY=()
;;
esac
COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
return 0
;;
my__app__help)
opts="<SUBCOMMAND>..."
if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then
COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
return 0
fi
case "${prev}" in
*)
COMPREPLY=()
;;
esac
COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
return 0
;;
my__app__test)
opts="-h -V --case --help --version"
if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then
COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
return 0
fi
case "${prev}" in
--case)
COMPREPLY=($(compgen -f "${cur}"))
return 0
;;
*)
COMPREPLY=()
;;
esac
COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
return 0
;;
esac
}
complete -F _my-app -o bashdefault -o default my-app

View file

@ -0,0 +1,43 @@
use builtin;
use str;
set edit:completion:arg-completer[my-app] = {|@words|
fn spaces {|n|
builtin:repeat $n ' ' | str:join ''
}
fn cand {|text desc|
edit:complex-candidate $text &display=$text' '(spaces (- 14 (wcswidth $text)))$desc
}
var command = 'my-app'
for word $words[1..-1] {
if (str:has-prefix $word '-') {
break
}
set command = $command';'$word
}
var completions = [
&'my-app'= {
cand -h 'Print help information'
cand --help 'Print help information'
cand -V 'Print version information'
cand --version 'Print version information'
cand -c 'some config file'
cand -C 'some config file'
cand --config 'some config file'
cand --conf 'some config file'
cand test 'tests things'
cand help 'Print this message or the help of the given subcommand(s)'
}
&'my-app;test'= {
cand --case 'the case to test'
cand -h 'Print help information'
cand --help 'Print help information'
cand -V 'Print version information'
cand --version 'Print version information'
}
&'my-app;help'= {
}
]
$completions[$command]
}

View file

@ -0,0 +1,8 @@
complete -c my-app -n "__fish_use_subcommand" -s h -l help -d 'Print help information'
complete -c my-app -n "__fish_use_subcommand" -s V -l version -d 'Print version information'
complete -c my-app -n "__fish_use_subcommand" -s c -s C -l config -l conf -d 'some config file'
complete -c my-app -n "__fish_use_subcommand" -f -a "test" -d 'tests things'
complete -c my-app -n "__fish_use_subcommand" -f -a "help" -d 'Print this message or the help of the given subcommand(s)'
complete -c my-app -n "__fish_seen_subcommand_from test" -l case -d 'the case to test' -r
complete -c my-app -n "__fish_seen_subcommand_from test" -s h -l help -d 'Print help information'
complete -c my-app -n "__fish_seen_subcommand_from test" -s V -l version -d 'Print version information'

View file

@ -0,0 +1,51 @@
using namespace System.Management.Automation
using namespace System.Management.Automation.Language
Register-ArgumentCompleter -Native -CommandName 'my-app' -ScriptBlock {
param($wordToComplete, $commandAst, $cursorPosition)
$commandElements = $commandAst.CommandElements
$command = @(
'my-app'
for ($i = 1; $i -lt $commandElements.Count; $i++) {
$element = $commandElements[$i]
if ($element -isnot [StringConstantExpressionAst] -or
$element.StringConstantType -ne [StringConstantType]::BareWord -or
$element.Value.StartsWith('-') -or
$element.Value -eq $wordToComplete) {
break
}
$element.Value
}) -join ';'
$completions = @(switch ($command) {
'my-app' {
[CompletionResult]::new('-h', 'h', [CompletionResultType]::ParameterName, 'Print help information')
[CompletionResult]::new('--help', 'help', [CompletionResultType]::ParameterName, 'Print help information')
[CompletionResult]::new('-V', 'V', [CompletionResultType]::ParameterName, 'Print version information')
[CompletionResult]::new('--version', 'version', [CompletionResultType]::ParameterName, 'Print version information')
[CompletionResult]::new('-c', 'c', [CompletionResultType]::ParameterName, 'some config file')
[CompletionResult]::new('-C', 'C', [CompletionResultType]::ParameterName, 'some config file')
[CompletionResult]::new('--config', 'config', [CompletionResultType]::ParameterName, 'some config file')
[CompletionResult]::new('--conf', 'conf', [CompletionResultType]::ParameterName, 'some config file')
[CompletionResult]::new('test', 'test', [CompletionResultType]::ParameterValue, 'tests things')
[CompletionResult]::new('help', 'help', [CompletionResultType]::ParameterValue, 'Print this message or the help of the given subcommand(s)')
break
}
'my-app;test' {
[CompletionResult]::new('--case', 'case', [CompletionResultType]::ParameterName, 'the case to test')
[CompletionResult]::new('-h', 'h', [CompletionResultType]::ParameterName, 'Print help information')
[CompletionResult]::new('--help', 'help', [CompletionResultType]::ParameterName, 'Print help information')
[CompletionResult]::new('-V', 'V', [CompletionResultType]::ParameterName, 'Print version information')
[CompletionResult]::new('--version', 'version', [CompletionResultType]::ParameterName, 'Print version information')
break
}
'my-app;help' {
break
}
})
$completions.Where{ $_.CompletionText -like "$wordToComplete*" } |
Sort-Object -Property ListItemText
}

View file

@ -0,0 +1,75 @@
#compdef my-app
autoload -U is-at-least
_my-app() {
typeset -A opt_args
typeset -a _arguments_options
local ret=1
if is-at-least 5.2; then
_arguments_options=(-s -S -C)
else
_arguments_options=(-s -C)
fi
local context curcontext="$curcontext" state line
_arguments "${_arguments_options[@]}" /
'-h[Print help information]' /
'--help[Print help information]' /
'-V[Print version information]' /
'--version[Print version information]' /
'-c[some config file]' /
'-C[some config file]' /
'--config[some config file]' /
'--conf[some config file]' /
'::file -- some input file:_files' /
'::choice:(first second)' /
":: :_my-app_commands" /
"*::: :->my-app" /
&& ret=0
case $state in
(my-app)
words=($line[3] "${words[@]}")
(( CURRENT += 1 ))
curcontext="${curcontext%:*:*}:my-app-command-$line[3]:"
case $line[3] in
(test)
_arguments "${_arguments_options[@]}" /
'--case=[the case to test]: : ' /
'-h[Print help information]' /
'--help[Print help information]' /
'-V[Print version information]' /
'--version[Print version information]' /
&& ret=0
;;
(help)
_arguments "${_arguments_options[@]}" /
'*::subcommand -- The subcommand whose help message to display:' /
&& ret=0
;;
esac
;;
esac
}
(( $+functions[_my-app_commands] )) ||
_my-app_commands() {
local commands; commands=(
'test:tests things' /
'help:Print this message or the help of the given subcommand(s)' /
)
_describe -t commands 'my-app commands' commands "$@"
}
(( $+functions[_my-app__help_commands] )) ||
_my-app__help_commands() {
local commands; commands=()
_describe -t commands 'my-app help commands' commands "$@"
}
(( $+functions[_my-app__test_commands] )) ||
_my-app__test_commands() {
local commands; commands=()
_describe -t commands 'my-app test commands' commands "$@"
}
_my-app "$@"

View file

@ -0,0 +1,157 @@
_my-app() {
local i cur prev opts cmds
COMPREPLY=()
cur="${COMP_WORDS[COMP_CWORD]}"
prev="${COMP_WORDS[COMP_CWORD-1]}"
cmd=""
opts=""
for i in ${COMP_WORDS[@]}
do
case "${i}" in
"$1")
cmd="my__app"
;;
cmd-backslash)
cmd+="__cmd__backslash"
;;
cmd-backticks)
cmd+="__cmd__backticks"
;;
cmd-brackets)
cmd+="__cmd__brackets"
;;
cmd-double-quotes)
cmd+="__cmd__double__quotes"
;;
cmd-expansions)
cmd+="__cmd__expansions"
;;
cmd-single-quotes)
cmd+="__cmd__single__quotes"
;;
help)
cmd+="__help"
;;
*)
;;
esac
done
case "${cmd}" in
my__app)
opts="-h -V --help --version --single-quotes --double-quotes --backticks --backslash --brackets --expansions cmd-single-quotes cmd-double-quotes cmd-backticks cmd-backslash cmd-brackets cmd-expansions help"
if [[ ${cur} == -* || ${COMP_CWORD} -eq 1 ]] ; then
COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
return 0
fi
case "${prev}" in
*)
COMPREPLY=()
;;
esac
COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
return 0
;;
my__app__cmd__backslash)
opts="-h --help"
if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then
COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
return 0
fi
case "${prev}" in
*)
COMPREPLY=()
;;
esac
COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
return 0
;;
my__app__cmd__backticks)
opts="-h --help"
if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then
COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
return 0
fi
case "${prev}" in
*)
COMPREPLY=()
;;
esac
COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
return 0
;;
my__app__cmd__brackets)
opts="-h --help"
if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then
COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
return 0
fi
case "${prev}" in
*)
COMPREPLY=()
;;
esac
COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
return 0
;;
my__app__cmd__double__quotes)
opts="-h --help"
if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then
COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
return 0
fi
case "${prev}" in
*)
COMPREPLY=()
;;
esac
COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
return 0
;;
my__app__cmd__expansions)
opts="-h --help"
if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then
COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
return 0
fi
case "${prev}" in
*)
COMPREPLY=()
;;
esac
COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
return 0
;;
my__app__cmd__single__quotes)
opts="-h --help"
if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then
COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
return 0
fi
case "${prev}" in
*)
COMPREPLY=()
;;
esac
COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
return 0
;;
my__app__help)
opts="<SUBCOMMAND>..."
if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then
COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
return 0
fi
case "${prev}" in
*)
COMPREPLY=()
;;
esac
COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
return 0
;;
esac
}
complete -F _my-app -o bashdefault -o default my-app

View file

@ -0,0 +1,67 @@
use builtin;
use str;
set edit:completion:arg-completer[my-app] = {|@words|
fn spaces {|n|
builtin:repeat $n ' ' | str:join ''
}
fn cand {|text desc|
edit:complex-candidate $text &display=$text' '(spaces (- 14 (wcswidth $text)))$desc
}
var command = 'my-app'
for word $words[1..-1] {
if (str:has-prefix $word '-') {
break
}
set command = $command';'$word
}
var completions = [
&'my-app'= {
cand -h 'Print help information'
cand --help 'Print help information'
cand -V 'Print version information'
cand --version 'Print version information'
cand --single-quotes 'Can be ''always'', ''auto'', or ''never'''
cand --double-quotes 'Can be "always", "auto", or "never"'
cand --backticks 'For more information see `echo test`'
cand --backslash 'Avoid ''/n'''
cand --brackets 'List packages [filter]'
cand --expansions 'Execute the shell command with $SHELL'
cand cmd-single-quotes 'Can be ''always'', ''auto'', or ''never'''
cand cmd-double-quotes 'Can be "always", "auto", or "never"'
cand cmd-backticks 'For more information see `echo test`'
cand cmd-backslash 'Avoid ''/n'''
cand cmd-brackets 'List packages [filter]'
cand cmd-expansions 'Execute the shell command with $SHELL'
cand help 'Print this message or the help of the given subcommand(s)'
}
&'my-app;cmd-single-quotes'= {
cand -h 'Print help information'
cand --help 'Print help information'
}
&'my-app;cmd-double-quotes'= {
cand -h 'Print help information'
cand --help 'Print help information'
}
&'my-app;cmd-backticks'= {
cand -h 'Print help information'
cand --help 'Print help information'
}
&'my-app;cmd-backslash'= {
cand -h 'Print help information'
cand --help 'Print help information'
}
&'my-app;cmd-brackets'= {
cand -h 'Print help information'
cand --help 'Print help information'
}
&'my-app;cmd-expansions'= {
cand -h 'Print help information'
cand --help 'Print help information'
}
&'my-app;help'= {
}
]
$completions[$command]
}

View file

@ -0,0 +1,21 @@
complete -c my-app -n "__fish_use_subcommand" -s h -l help -d 'Print help information'
complete -c my-app -n "__fish_use_subcommand" -s V -l version -d 'Print version information'
complete -c my-app -n "__fish_use_subcommand" -l single-quotes -d 'Can be /'always/', /'auto/', or /'never/''
complete -c my-app -n "__fish_use_subcommand" -l double-quotes -d 'Can be "always", "auto", or "never"'
complete -c my-app -n "__fish_use_subcommand" -l backticks -d 'For more information see `echo test`'
complete -c my-app -n "__fish_use_subcommand" -l backslash -d 'Avoid /'//n/''
complete -c my-app -n "__fish_use_subcommand" -l brackets -d 'List packages [filter]'
complete -c my-app -n "__fish_use_subcommand" -l expansions -d 'Execute the shell command with $SHELL'
complete -c my-app -n "__fish_use_subcommand" -f -a "cmd-single-quotes" -d 'Can be /'always/', /'auto/', or /'never/''
complete -c my-app -n "__fish_use_subcommand" -f -a "cmd-double-quotes" -d 'Can be "always", "auto", or "never"'
complete -c my-app -n "__fish_use_subcommand" -f -a "cmd-backticks" -d 'For more information see `echo test`'
complete -c my-app -n "__fish_use_subcommand" -f -a "cmd-backslash" -d 'Avoid /'//n/''
complete -c my-app -n "__fish_use_subcommand" -f -a "cmd-brackets" -d 'List packages [filter]'
complete -c my-app -n "__fish_use_subcommand" -f -a "cmd-expansions" -d 'Execute the shell command with $SHELL'
complete -c my-app -n "__fish_use_subcommand" -f -a "help" -d 'Print this message or the help of the given subcommand(s)'
complete -c my-app -n "__fish_seen_subcommand_from cmd-single-quotes" -s h -l help -d 'Print help information'
complete -c my-app -n "__fish_seen_subcommand_from cmd-double-quotes" -s h -l help -d 'Print help information'
complete -c my-app -n "__fish_seen_subcommand_from cmd-backticks" -s h -l help -d 'Print help information'
complete -c my-app -n "__fish_seen_subcommand_from cmd-backslash" -s h -l help -d 'Print help information'
complete -c my-app -n "__fish_seen_subcommand_from cmd-brackets" -s h -l help -d 'Print help information'
complete -c my-app -n "__fish_seen_subcommand_from cmd-expansions" -s h -l help -d 'Print help information'

View file

@ -0,0 +1,80 @@
using namespace System.Management.Automation
using namespace System.Management.Automation.Language
Register-ArgumentCompleter -Native -CommandName 'my-app' -ScriptBlock {
param($wordToComplete, $commandAst, $cursorPosition)
$commandElements = $commandAst.CommandElements
$command = @(
'my-app'
for ($i = 1; $i -lt $commandElements.Count; $i++) {
$element = $commandElements[$i]
if ($element -isnot [StringConstantExpressionAst] -or
$element.StringConstantType -ne [StringConstantType]::BareWord -or
$element.Value.StartsWith('-') -or
$element.Value -eq $wordToComplete) {
break
}
$element.Value
}) -join ';'
$completions = @(switch ($command) {
'my-app' {
[CompletionResult]::new('-h', 'h', [CompletionResultType]::ParameterName, 'Print help information')
[CompletionResult]::new('--help', 'help', [CompletionResultType]::ParameterName, 'Print help information')
[CompletionResult]::new('-V', 'V', [CompletionResultType]::ParameterName, 'Print version information')
[CompletionResult]::new('--version', 'version', [CompletionResultType]::ParameterName, 'Print version information')
[CompletionResult]::new('--single-quotes', 'single-quotes', [CompletionResultType]::ParameterName, 'Can be ''always'', ''auto'', or ''never''')
[CompletionResult]::new('--double-quotes', 'double-quotes', [CompletionResultType]::ParameterName, 'Can be "always", "auto", or "never"')
[CompletionResult]::new('--backticks', 'backticks', [CompletionResultType]::ParameterName, 'For more information see `echo test`')
[CompletionResult]::new('--backslash', 'backslash', [CompletionResultType]::ParameterName, 'Avoid ''/n''')
[CompletionResult]::new('--brackets', 'brackets', [CompletionResultType]::ParameterName, 'List packages [filter]')
[CompletionResult]::new('--expansions', 'expansions', [CompletionResultType]::ParameterName, 'Execute the shell command with $SHELL')
[CompletionResult]::new('cmd-single-quotes', 'cmd-single-quotes', [CompletionResultType]::ParameterValue, 'Can be ''always'', ''auto'', or ''never''')
[CompletionResult]::new('cmd-double-quotes', 'cmd-double-quotes', [CompletionResultType]::ParameterValue, 'Can be "always", "auto", or "never"')
[CompletionResult]::new('cmd-backticks', 'cmd-backticks', [CompletionResultType]::ParameterValue, 'For more information see `echo test`')
[CompletionResult]::new('cmd-backslash', 'cmd-backslash', [CompletionResultType]::ParameterValue, 'Avoid ''/n''')
[CompletionResult]::new('cmd-brackets', 'cmd-brackets', [CompletionResultType]::ParameterValue, 'List packages [filter]')
[CompletionResult]::new('cmd-expansions', 'cmd-expansions', [CompletionResultType]::ParameterValue, 'Execute the shell command with $SHELL')
[CompletionResult]::new('help', 'help', [CompletionResultType]::ParameterValue, 'Print this message or the help of the given subcommand(s)')
break
}
'my-app;cmd-single-quotes' {
[CompletionResult]::new('-h', 'h', [CompletionResultType]::ParameterName, 'Print help information')
[CompletionResult]::new('--help', 'help', [CompletionResultType]::ParameterName, 'Print help information')
break
}
'my-app;cmd-double-quotes' {
[CompletionResult]::new('-h', 'h', [CompletionResultType]::ParameterName, 'Print help information')
[CompletionResult]::new('--help', 'help', [CompletionResultType]::ParameterName, 'Print help information')
break
}
'my-app;cmd-backticks' {
[CompletionResult]::new('-h', 'h', [CompletionResultType]::ParameterName, 'Print help information')
[CompletionResult]::new('--help', 'help', [CompletionResultType]::ParameterName, 'Print help information')
break
}
'my-app;cmd-backslash' {
[CompletionResult]::new('-h', 'h', [CompletionResultType]::ParameterName, 'Print help information')
[CompletionResult]::new('--help', 'help', [CompletionResultType]::ParameterName, 'Print help information')
break
}
'my-app;cmd-brackets' {
[CompletionResult]::new('-h', 'h', [CompletionResultType]::ParameterName, 'Print help information')
[CompletionResult]::new('--help', 'help', [CompletionResultType]::ParameterName, 'Print help information')
break
}
'my-app;cmd-expansions' {
[CompletionResult]::new('-h', 'h', [CompletionResultType]::ParameterName, 'Print help information')
[CompletionResult]::new('--help', 'help', [CompletionResultType]::ParameterName, 'Print help information')
break
}
'my-app;help' {
break
}
})
$completions.Where{ $_.CompletionText -like "$wordToComplete*" } |
Sort-Object -Property ListItemText
}

View file

@ -0,0 +1,132 @@
#compdef my-app
autoload -U is-at-least
_my-app() {
typeset -A opt_args
typeset -a _arguments_options
local ret=1
if is-at-least 5.2; then
_arguments_options=(-s -S -C)
else
_arguments_options=(-s -C)
fi
local context curcontext="$curcontext" state line
_arguments "${_arguments_options[@]}" /
'-h[Print help information]' /
'--help[Print help information]' /
'-V[Print version information]' /
'--version[Print version information]' /
'--single-quotes[Can be '/''always'/'', '/''auto'/'', or '/''never'/'']' /
'--double-quotes[Can be "always", "auto", or "never"]' /
'--backticks[For more information see `echo test`]' /
'--backslash[Avoid '/''//n'/'']' /
'--brackets[List packages /[filter/]]' /
'--expansions[Execute the shell command with $SHELL]' /
":: :_my-app_commands" /
"*::: :->my-app" /
&& ret=0
case $state in
(my-app)
words=($line[1] "${words[@]}")
(( CURRENT += 1 ))
curcontext="${curcontext%:*:*}:my-app-command-$line[1]:"
case $line[1] in
(cmd-single-quotes)
_arguments "${_arguments_options[@]}" /
'-h[Print help information]' /
'--help[Print help information]' /
&& ret=0
;;
(cmd-double-quotes)
_arguments "${_arguments_options[@]}" /
'-h[Print help information]' /
'--help[Print help information]' /
&& ret=0
;;
(cmd-backticks)
_arguments "${_arguments_options[@]}" /
'-h[Print help information]' /
'--help[Print help information]' /
&& ret=0
;;
(cmd-backslash)
_arguments "${_arguments_options[@]}" /
'-h[Print help information]' /
'--help[Print help information]' /
&& ret=0
;;
(cmd-brackets)
_arguments "${_arguments_options[@]}" /
'-h[Print help information]' /
'--help[Print help information]' /
&& ret=0
;;
(cmd-expansions)
_arguments "${_arguments_options[@]}" /
'-h[Print help information]' /
'--help[Print help information]' /
&& ret=0
;;
(help)
_arguments "${_arguments_options[@]}" /
'*::subcommand -- The subcommand whose help message to display:' /
&& ret=0
;;
esac
;;
esac
}
(( $+functions[_my-app_commands] )) ||
_my-app_commands() {
local commands; commands=(
'cmd-single-quotes:Can be '/''always'/'', '/''auto'/'', or '/''never'/''' /
'cmd-double-quotes:Can be "always", "auto", or "never"' /
'cmd-backticks:For more information see `echo test`' /
'cmd-backslash:Avoid '/''//n'/''' /
'cmd-brackets:List packages /[filter/]' /
'cmd-expansions:Execute the shell command with $SHELL' /
'help:Print this message or the help of the given subcommand(s)' /
)
_describe -t commands 'my-app commands' commands "$@"
}
(( $+functions[_my-app__cmd-backslash_commands] )) ||
_my-app__cmd-backslash_commands() {
local commands; commands=()
_describe -t commands 'my-app cmd-backslash commands' commands "$@"
}
(( $+functions[_my-app__cmd-backticks_commands] )) ||
_my-app__cmd-backticks_commands() {
local commands; commands=()
_describe -t commands 'my-app cmd-backticks commands' commands "$@"
}
(( $+functions[_my-app__cmd-brackets_commands] )) ||
_my-app__cmd-brackets_commands() {
local commands; commands=()
_describe -t commands 'my-app cmd-brackets commands' commands "$@"
}
(( $+functions[_my-app__cmd-double-quotes_commands] )) ||
_my-app__cmd-double-quotes_commands() {
local commands; commands=()
_describe -t commands 'my-app cmd-double-quotes commands' commands "$@"
}
(( $+functions[_my-app__cmd-expansions_commands] )) ||
_my-app__cmd-expansions_commands() {
local commands; commands=()
_describe -t commands 'my-app cmd-expansions commands' commands "$@"
}
(( $+functions[_my-app__cmd-single-quotes_commands] )) ||
_my-app__cmd-single-quotes_commands() {
local commands; commands=()
_describe -t commands 'my-app cmd-single-quotes commands' commands "$@"
}
(( $+functions[_my-app__help_commands] )) ||
_my-app__help_commands() {
local commands; commands=()
_describe -t commands 'my-app help commands' commands "$@"
}
_my-app "$@"

View file

@ -0,0 +1,114 @@
_my-app() {
local i cur prev opts cmds
COMPREPLY=()
cur="${COMP_WORDS[COMP_CWORD]}"
prev="${COMP_WORDS[COMP_CWORD-1]}"
cmd=""
opts=""
for i in ${COMP_WORDS[@]}
do
case "${i}" in
"$1")
cmd="my__app"
;;
help)
cmd+="__help"
;;
some-cmd-with-hyphens)
cmd+="__some__cmd__with__hyphens"
;;
some_cmd)
cmd+="__some_cmd"
;;
test)
cmd+="__test"
;;
*)
;;
esac
done
case "${cmd}" in
my__app)
opts="-h -V -C -c --help --version --conf --config <file> first second test some_cmd some-cmd-with-hyphens help"
if [[ ${cur} == -* || ${COMP_CWORD} -eq 1 ]] ; then
COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
return 0
fi
case "${prev}" in
*)
COMPREPLY=()
;;
esac
COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
return 0
;;
my__app__help)
opts="<SUBCOMMAND>..."
if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then
COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
return 0
fi
case "${prev}" in
*)
COMPREPLY=()
;;
esac
COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
return 0
;;
my__app__some__cmd__with__hyphens)
opts="-h -V --help --version"
if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then
COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
return 0
fi
case "${prev}" in
*)
COMPREPLY=()
;;
esac
COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
return 0
;;
my__app__some_cmd)
opts="-h -V --config --help --version"
if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then
COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
return 0
fi
case "${prev}" in
--config)
COMPREPLY=($(compgen -f "${cur}"))
return 0
;;
*)
COMPREPLY=()
;;
esac
COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
return 0
;;
my__app__test)
opts="-h -V --case --help --version"
if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then
COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
return 0
fi
case "${prev}" in
--case)
COMPREPLY=($(compgen -f "${cur}"))
return 0
;;
*)
COMPREPLY=()
;;
esac
COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
return 0
;;
esac
}
complete -F _my-app -o bashdefault -o default my-app

View file

@ -0,0 +1,58 @@
use builtin;
use str;
set edit:completion:arg-completer[my-app] = {|@words|
fn spaces {|n|
builtin:repeat $n ' ' | str:join ''
}
fn cand {|text desc|
edit:complex-candidate $text &display=$text' '(spaces (- 14 (wcswidth $text)))$desc
}
var command = 'my-app'
for word $words[1..-1] {
if (str:has-prefix $word '-') {
break
}
set command = $command';'$word
}
var completions = [
&'my-app'= {
cand -h 'Print help information'
cand --help 'Print help information'
cand -V 'Print version information'
cand --version 'Print version information'
cand -c 'some config file'
cand -C 'some config file'
cand --config 'some config file'
cand --conf 'some config file'
cand test 'tests things'
cand some_cmd 'tests other things'
cand some-cmd-with-hyphens 'some-cmd-with-hyphens'
cand help 'Print this message or the help of the given subcommand(s)'
}
&'my-app;test'= {
cand --case 'the case to test'
cand -h 'Print help information'
cand --help 'Print help information'
cand -V 'Print version information'
cand --version 'Print version information'
}
&'my-app;some_cmd'= {
cand --config 'the other case to test'
cand -h 'Print help information'
cand --help 'Print help information'
cand -V 'Print version information'
cand --version 'Print version information'
}
&'my-app;some-cmd-with-hyphens'= {
cand -h 'Print help information'
cand --help 'Print help information'
cand -V 'Print version information'
cand --version 'Print version information'
}
&'my-app;help'= {
}
]
$completions[$command]
}

View file

@ -0,0 +1,15 @@
complete -c my-app -n "__fish_use_subcommand" -s h -l help -d 'Print help information'
complete -c my-app -n "__fish_use_subcommand" -s V -l version -d 'Print version information'
complete -c my-app -n "__fish_use_subcommand" -s c -s C -l config -l conf -d 'some config file'
complete -c my-app -n "__fish_use_subcommand" -f -a "test" -d 'tests things'
complete -c my-app -n "__fish_use_subcommand" -f -a "some_cmd" -d 'tests other things'
complete -c my-app -n "__fish_use_subcommand" -f -a "some-cmd-with-hyphens"
complete -c my-app -n "__fish_use_subcommand" -f -a "help" -d 'Print this message or the help of the given subcommand(s)'
complete -c my-app -n "__fish_seen_subcommand_from test" -l case -d 'the case to test' -r
complete -c my-app -n "__fish_seen_subcommand_from test" -s h -l help -d 'Print help information'
complete -c my-app -n "__fish_seen_subcommand_from test" -s V -l version -d 'Print version information'
complete -c my-app -n "__fish_seen_subcommand_from some_cmd" -l config -d 'the other case to test' -r
complete -c my-app -n "__fish_seen_subcommand_from some_cmd" -s h -l help -d 'Print help information'
complete -c my-app -n "__fish_seen_subcommand_from some_cmd" -s V -l version -d 'Print version information'
complete -c my-app -n "__fish_seen_subcommand_from some-cmd-with-hyphens" -s h -l help -d 'Print help information'
complete -c my-app -n "__fish_seen_subcommand_from some-cmd-with-hyphens" -s V -l version -d 'Print version information'

View file

@ -0,0 +1,68 @@
using namespace System.Management.Automation
using namespace System.Management.Automation.Language
Register-ArgumentCompleter -Native -CommandName 'my-app' -ScriptBlock {
param($wordToComplete, $commandAst, $cursorPosition)
$commandElements = $commandAst.CommandElements
$command = @(
'my-app'
for ($i = 1; $i -lt $commandElements.Count; $i++) {
$element = $commandElements[$i]
if ($element -isnot [StringConstantExpressionAst] -or
$element.StringConstantType -ne [StringConstantType]::BareWord -or
$element.Value.StartsWith('-') -or
$element.Value -eq $wordToComplete) {
break
}
$element.Value
}) -join ';'
$completions = @(switch ($command) {
'my-app' {
[CompletionResult]::new('-h', 'h', [CompletionResultType]::ParameterName, 'Print help information')
[CompletionResult]::new('--help', 'help', [CompletionResultType]::ParameterName, 'Print help information')
[CompletionResult]::new('-V', 'V', [CompletionResultType]::ParameterName, 'Print version information')
[CompletionResult]::new('--version', 'version', [CompletionResultType]::ParameterName, 'Print version information')
[CompletionResult]::new('-c', 'c', [CompletionResultType]::ParameterName, 'some config file')
[CompletionResult]::new('-C', 'C', [CompletionResultType]::ParameterName, 'some config file')
[CompletionResult]::new('--config', 'config', [CompletionResultType]::ParameterName, 'some config file')
[CompletionResult]::new('--conf', 'conf', [CompletionResultType]::ParameterName, 'some config file')
[CompletionResult]::new('test', 'test', [CompletionResultType]::ParameterValue, 'tests things')
[CompletionResult]::new('some_cmd', 'some_cmd', [CompletionResultType]::ParameterValue, 'tests other things')
[CompletionResult]::new('some-cmd-with-hyphens', 'some-cmd-with-hyphens', [CompletionResultType]::ParameterValue, 'some-cmd-with-hyphens')
[CompletionResult]::new('help', 'help', [CompletionResultType]::ParameterValue, 'Print this message or the help of the given subcommand(s)')
break
}
'my-app;test' {
[CompletionResult]::new('--case', 'case', [CompletionResultType]::ParameterName, 'the case to test')
[CompletionResult]::new('-h', 'h', [CompletionResultType]::ParameterName, 'Print help information')
[CompletionResult]::new('--help', 'help', [CompletionResultType]::ParameterName, 'Print help information')
[CompletionResult]::new('-V', 'V', [CompletionResultType]::ParameterName, 'Print version information')
[CompletionResult]::new('--version', 'version', [CompletionResultType]::ParameterName, 'Print version information')
break
}
'my-app;some_cmd' {
[CompletionResult]::new('--config', 'config', [CompletionResultType]::ParameterName, 'the other case to test')
[CompletionResult]::new('-h', 'h', [CompletionResultType]::ParameterName, 'Print help information')
[CompletionResult]::new('--help', 'help', [CompletionResultType]::ParameterName, 'Print help information')
[CompletionResult]::new('-V', 'V', [CompletionResultType]::ParameterName, 'Print version information')
[CompletionResult]::new('--version', 'version', [CompletionResultType]::ParameterName, 'Print version information')
break
}
'my-app;some-cmd-with-hyphens' {
[CompletionResult]::new('-h', 'h', [CompletionResultType]::ParameterName, 'Print help information')
[CompletionResult]::new('--help', 'help', [CompletionResultType]::ParameterName, 'Print help information')
[CompletionResult]::new('-V', 'V', [CompletionResultType]::ParameterName, 'Print version information')
[CompletionResult]::new('--version', 'version', [CompletionResultType]::ParameterName, 'Print version information')
break
}
'my-app;help' {
break
}
})
$completions.Where{ $_.CompletionText -like "$wordToComplete*" } |
Sort-Object -Property ListItemText
}

View file

@ -0,0 +1,104 @@
#compdef my-app
autoload -U is-at-least
_my-app() {
typeset -A opt_args
typeset -a _arguments_options
local ret=1
if is-at-least 5.2; then
_arguments_options=(-s -S -C)
else
_arguments_options=(-s -C)
fi
local context curcontext="$curcontext" state line
_arguments "${_arguments_options[@]}" /
'-h[Print help information]' /
'--help[Print help information]' /
'-V[Print version information]' /
'--version[Print version information]' /
'-c[some config file]' /
'-C[some config file]' /
'--config[some config file]' /
'--conf[some config file]' /
'::file -- some input file:_files' /
'::choice:(first second)' /
":: :_my-app_commands" /
"*::: :->my-app" /
&& ret=0
case $state in
(my-app)
words=($line[3] "${words[@]}")
(( CURRENT += 1 ))
curcontext="${curcontext%:*:*}:my-app-command-$line[3]:"
case $line[3] in
(test)
_arguments "${_arguments_options[@]}" /
'--case=[the case to test]: : ' /
'-h[Print help information]' /
'--help[Print help information]' /
'-V[Print version information]' /
'--version[Print version information]' /
&& ret=0
;;
(some_cmd)
_arguments "${_arguments_options[@]}" /
'--config=[the other case to test]: : ' /
'-h[Print help information]' /
'--help[Print help information]' /
'-V[Print version information]' /
'--version[Print version information]' /
&& ret=0
;;
(some-cmd-with-hyphens)
_arguments "${_arguments_options[@]}" /
'-h[Print help information]' /
'--help[Print help information]' /
'-V[Print version information]' /
'--version[Print version information]' /
&& ret=0
;;
(help)
_arguments "${_arguments_options[@]}" /
'*::subcommand -- The subcommand whose help message to display:' /
&& ret=0
;;
esac
;;
esac
}
(( $+functions[_my-app_commands] )) ||
_my-app_commands() {
local commands; commands=(
'test:tests things' /
'some_cmd:tests other things' /
'some-cmd-with-hyphens:' /
'help:Print this message or the help of the given subcommand(s)' /
)
_describe -t commands 'my-app commands' commands "$@"
}
(( $+functions[_my-app__help_commands] )) ||
_my-app__help_commands() {
local commands; commands=()
_describe -t commands 'my-app help commands' commands "$@"
}
(( $+functions[_my-app__some-cmd-with-hyphens_commands] )) ||
_my-app__some-cmd-with-hyphens_commands() {
local commands; commands=()
_describe -t commands 'my-app some-cmd-with-hyphens commands' commands "$@"
}
(( $+functions[_my-app__some_cmd_commands] )) ||
_my-app__some_cmd_commands() {
local commands; commands=()
_describe -t commands 'my-app some_cmd commands' commands "$@"
}
(( $+functions[_my-app__test_commands] )) ||
_my-app__test_commands() {
local commands; commands=()
_describe -t commands 'my-app test commands' commands "$@"
}
_my-app "$@"

View file

@ -0,0 +1,128 @@
_my-app() {
local i cur prev opts cmds
COMPREPLY=()
cur="${COMP_WORDS[COMP_CWORD]}"
prev="${COMP_WORDS[COMP_CWORD-1]}"
cmd=""
opts=""
for i in ${COMP_WORDS[@]}
do
case "${i}" in
"$1")
cmd="my__app"
;;
help)
cmd+="__help"
;;
some_cmd)
cmd+="__some_cmd"
;;
sub_cmd)
cmd+="__sub_cmd"
;;
test)
cmd+="__test"
;;
*)
;;
esac
done
case "${cmd}" in
my__app)
opts="-h -V -C -c --help --version --conf --config <file> first second test some_cmd help"
if [[ ${cur} == -* || ${COMP_CWORD} -eq 1 ]] ; then
COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
return 0
fi
case "${prev}" in
*)
COMPREPLY=()
;;
esac
COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
return 0
;;
my__app__help)
opts="<SUBCOMMAND>..."
if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then
COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
return 0
fi
case "${prev}" in
*)
COMPREPLY=()
;;
esac
COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
return 0
;;
my__app__some_cmd)
opts="-h -V --help --version sub_cmd help"
if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then
COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
return 0
fi
case "${prev}" in
*)
COMPREPLY=()
;;
esac
COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
return 0
;;
my__app__some_cmd__help)
opts="-h -V --help --version <SUBCOMMAND>..."
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
;;
my__app__some_cmd__sub_cmd)
opts="-h -V --config --help --version"
if [[ ${cur} == -* || ${COMP_CWORD} -eq 3 ]] ; then
COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
return 0
fi
case "${prev}" in
--config)
COMPREPLY=($(compgen -W "" -- "${cur}"))
return 0
;;
*)
COMPREPLY=()
;;
esac
COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
return 0
;;
my__app__test)
opts="-h -V --case --help --version"
if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then
COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
return 0
fi
case "${prev}" in
--case)
COMPREPLY=($(compgen -f "${cur}"))
return 0
;;
*)
COMPREPLY=()
;;
esac
COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
return 0
;;
esac
}
complete -F _my-app -o bashdefault -o default my-app

View file

@ -0,0 +1,65 @@
use builtin;
use str;
set edit:completion:arg-completer[my-app] = {|@words|
fn spaces {|n|
builtin:repeat $n ' ' | str:join ''
}
fn cand {|text desc|
edit:complex-candidate $text &display=$text' '(spaces (- 14 (wcswidth $text)))$desc
}
var command = 'my-app'
for word $words[1..-1] {
if (str:has-prefix $word '-') {
break
}
set command = $command';'$word
}
var completions = [
&'my-app'= {
cand -h 'Print help information'
cand --help 'Print help information'
cand -V 'Print version information'
cand --version 'Print version information'
cand -c 'some config file'
cand -C 'some config file'
cand --config 'some config file'
cand --conf 'some config file'
cand test 'tests things'
cand some_cmd 'top level subcommand'
cand help 'Print this message or the help of the given subcommand(s)'
}
&'my-app;test'= {
cand --case 'the case to test'
cand -h 'Print help information'
cand --help 'Print help information'
cand -V 'Print version information'
cand --version 'Print version information'
}
&'my-app;some_cmd'= {
cand -h 'Print help information'
cand --help 'Print help information'
cand -V 'Print version information'
cand --version 'Print version information'
cand sub_cmd 'sub-subcommand'
cand help 'Print this message or the help of the given subcommand(s)'
}
&'my-app;some_cmd;sub_cmd'= {
cand --config 'the other case to test'
cand -h 'Print help information'
cand --help 'Print help information'
cand -V 'Print version information'
cand --version 'Print version information'
}
&'my-app;some_cmd;help'= {
cand -h 'Print help information'
cand --help 'Print help information'
cand -V 'Print version information'
cand --version 'Print version information'
}
&'my-app;help'= {
}
]
$completions[$command]
}

View file

@ -0,0 +1,18 @@
complete -c my-app -n "__fish_use_subcommand" -s h -l help -d 'Print help information'
complete -c my-app -n "__fish_use_subcommand" -s V -l version -d 'Print version information'
complete -c my-app -n "__fish_use_subcommand" -s c -s C -l config -l conf -d 'some config file'
complete -c my-app -n "__fish_use_subcommand" -f -a "test" -d 'tests things'
complete -c my-app -n "__fish_use_subcommand" -f -a "some_cmd" -d 'top level subcommand'
complete -c my-app -n "__fish_use_subcommand" -f -a "help" -d 'Print this message or the help of the given subcommand(s)'
complete -c my-app -n "__fish_seen_subcommand_from test" -l case -d 'the case to test' -r
complete -c my-app -n "__fish_seen_subcommand_from test" -s h -l help -d 'Print help information'
complete -c my-app -n "__fish_seen_subcommand_from test" -s V -l version -d 'Print version information'
complete -c my-app -n "__fish_seen_subcommand_from some_cmd; and not __fish_seen_subcommand_from sub_cmd; and not __fish_seen_subcommand_from help" -s h -l help -d 'Print help information'
complete -c my-app -n "__fish_seen_subcommand_from some_cmd; and not __fish_seen_subcommand_from sub_cmd; and not __fish_seen_subcommand_from help" -s V -l version -d 'Print version information'
complete -c my-app -n "__fish_seen_subcommand_from some_cmd; and not __fish_seen_subcommand_from sub_cmd; and not __fish_seen_subcommand_from help" -f -a "sub_cmd" -d 'sub-subcommand'
complete -c my-app -n "__fish_seen_subcommand_from some_cmd; and not __fish_seen_subcommand_from sub_cmd; and not __fish_seen_subcommand_from help" -f -a "help" -d 'Print this message or the help of the given subcommand(s)'
complete -c my-app -n "__fish_seen_subcommand_from some_cmd; and __fish_seen_subcommand_from sub_cmd" -l config -d 'the other case to test' -r -f -a "{Lest quotes aren/'t escaped. }"
complete -c my-app -n "__fish_seen_subcommand_from some_cmd; and __fish_seen_subcommand_from sub_cmd" -s h -l help -d 'Print help information'
complete -c my-app -n "__fish_seen_subcommand_from some_cmd; and __fish_seen_subcommand_from sub_cmd" -s V -l version -d 'Print version information'
complete -c my-app -n "__fish_seen_subcommand_from some_cmd; and __fish_seen_subcommand_from help" -s h -l help -d 'Print help information'
complete -c my-app -n "__fish_seen_subcommand_from some_cmd; and __fish_seen_subcommand_from help" -s V -l version -d 'Print version information'

View file

@ -0,0 +1,76 @@
using namespace System.Management.Automation
using namespace System.Management.Automation.Language
Register-ArgumentCompleter -Native -CommandName 'my-app' -ScriptBlock {
param($wordToComplete, $commandAst, $cursorPosition)
$commandElements = $commandAst.CommandElements
$command = @(
'my-app'
for ($i = 1; $i -lt $commandElements.Count; $i++) {
$element = $commandElements[$i]
if ($element -isnot [StringConstantExpressionAst] -or
$element.StringConstantType -ne [StringConstantType]::BareWord -or
$element.Value.StartsWith('-') -or
$element.Value -eq $wordToComplete) {
break
}
$element.Value
}) -join ';'
$completions = @(switch ($command) {
'my-app' {
[CompletionResult]::new('-h', 'h', [CompletionResultType]::ParameterName, 'Print help information')
[CompletionResult]::new('--help', 'help', [CompletionResultType]::ParameterName, 'Print help information')
[CompletionResult]::new('-V', 'V', [CompletionResultType]::ParameterName, 'Print version information')
[CompletionResult]::new('--version', 'version', [CompletionResultType]::ParameterName, 'Print version information')
[CompletionResult]::new('-c', 'c', [CompletionResultType]::ParameterName, 'some config file')
[CompletionResult]::new('-C', 'C', [CompletionResultType]::ParameterName, 'some config file')
[CompletionResult]::new('--config', 'config', [CompletionResultType]::ParameterName, 'some config file')
[CompletionResult]::new('--conf', 'conf', [CompletionResultType]::ParameterName, 'some config file')
[CompletionResult]::new('test', 'test', [CompletionResultType]::ParameterValue, 'tests things')
[CompletionResult]::new('some_cmd', 'some_cmd', [CompletionResultType]::ParameterValue, 'top level subcommand')
[CompletionResult]::new('help', 'help', [CompletionResultType]::ParameterValue, 'Print this message or the help of the given subcommand(s)')
break
}
'my-app;test' {
[CompletionResult]::new('--case', 'case', [CompletionResultType]::ParameterName, 'the case to test')
[CompletionResult]::new('-h', 'h', [CompletionResultType]::ParameterName, 'Print help information')
[CompletionResult]::new('--help', 'help', [CompletionResultType]::ParameterName, 'Print help information')
[CompletionResult]::new('-V', 'V', [CompletionResultType]::ParameterName, 'Print version information')
[CompletionResult]::new('--version', 'version', [CompletionResultType]::ParameterName, 'Print version information')
break
}
'my-app;some_cmd' {
[CompletionResult]::new('-h', 'h', [CompletionResultType]::ParameterName, 'Print help information')
[CompletionResult]::new('--help', 'help', [CompletionResultType]::ParameterName, 'Print help information')
[CompletionResult]::new('-V', 'V', [CompletionResultType]::ParameterName, 'Print version information')
[CompletionResult]::new('--version', 'version', [CompletionResultType]::ParameterName, 'Print version information')
[CompletionResult]::new('sub_cmd', 'sub_cmd', [CompletionResultType]::ParameterValue, 'sub-subcommand')
[CompletionResult]::new('help', 'help', [CompletionResultType]::ParameterValue, 'Print this message or the help of the given subcommand(s)')
break
}
'my-app;some_cmd;sub_cmd' {
[CompletionResult]::new('--config', 'config', [CompletionResultType]::ParameterName, 'the other case to test')
[CompletionResult]::new('-h', 'h', [CompletionResultType]::ParameterName, 'Print help information')
[CompletionResult]::new('--help', 'help', [CompletionResultType]::ParameterName, 'Print help information')
[CompletionResult]::new('-V', 'V', [CompletionResultType]::ParameterName, 'Print version information')
[CompletionResult]::new('--version', 'version', [CompletionResultType]::ParameterName, 'Print version information')
break
}
'my-app;some_cmd;help' {
[CompletionResult]::new('-h', 'h', [CompletionResultType]::ParameterName, 'Print help information')
[CompletionResult]::new('--help', 'help', [CompletionResultType]::ParameterName, 'Print help information')
[CompletionResult]::new('-V', 'V', [CompletionResultType]::ParameterName, 'Print version information')
[CompletionResult]::new('--version', 'version', [CompletionResultType]::ParameterName, 'Print version information')
break
}
'my-app;help' {
break
}
})
$completions.Where{ $_.CompletionText -like "$wordToComplete*" } |
Sort-Object -Property ListItemText
}

View file

@ -0,0 +1,132 @@
#compdef my-app
autoload -U is-at-least
_my-app() {
typeset -A opt_args
typeset -a _arguments_options
local ret=1
if is-at-least 5.2; then
_arguments_options=(-s -S -C)
else
_arguments_options=(-s -C)
fi
local context curcontext="$curcontext" state line
_arguments "${_arguments_options[@]}" /
'-h[Print help information]' /
'--help[Print help information]' /
'-V[Print version information]' /
'--version[Print version information]' /
'-c[some config file]' /
'-C[some config file]' /
'--config[some config file]' /
'--conf[some config file]' /
'::file -- some input file:_files' /
'::choice:(first second)' /
":: :_my-app_commands" /
"*::: :->my-app" /
&& ret=0
case $state in
(my-app)
words=($line[3] "${words[@]}")
(( CURRENT += 1 ))
curcontext="${curcontext%:*:*}:my-app-command-$line[3]:"
case $line[3] in
(test)
_arguments "${_arguments_options[@]}" /
'--case=[the case to test]: : ' /
'-h[Print help information]' /
'--help[Print help information]' /
'-V[Print version information]' /
'--version[Print version information]' /
&& ret=0
;;
(some_cmd)
_arguments "${_arguments_options[@]}" /
'-h[Print help information]' /
'--help[Print help information]' /
'-V[Print version information]' /
'--version[Print version information]' /
":: :_my-app__some_cmd_commands" /
"*::: :->some_cmd" /
&& ret=0
case $state in
(some_cmd)
words=($line[1] "${words[@]}")
(( CURRENT += 1 ))
curcontext="${curcontext%:*:*}:my-app-some_cmd-command-$line[1]:"
case $line[1] in
(sub_cmd)
_arguments "${_arguments_options[@]}" /
'--config=[the other case to test]: :(Lest quotes aren't escaped.)' /
'-h[Print help information]' /
'--help[Print help information]' /
'-V[Print version information]' /
'--version[Print version information]' /
&& ret=0
;;
(help)
_arguments "${_arguments_options[@]}" /
'-h[Print help information]' /
'--help[Print help information]' /
'-V[Print version information]' /
'--version[Print version information]' /
'*::subcommand -- The subcommand whose help message to display:' /
&& ret=0
;;
esac
;;
esac
;;
(help)
_arguments "${_arguments_options[@]}" /
'*::subcommand -- The subcommand whose help message to display:' /
&& ret=0
;;
esac
;;
esac
}
(( $+functions[_my-app_commands] )) ||
_my-app_commands() {
local commands; commands=(
'test:tests things' /
'some_cmd:top level subcommand' /
'help:Print this message or the help of the given subcommand(s)' /
)
_describe -t commands 'my-app commands' commands "$@"
}
(( $+functions[_my-app__help_commands] )) ||
_my-app__help_commands() {
local commands; commands=()
_describe -t commands 'my-app help commands' commands "$@"
}
(( $+functions[_my-app__some_cmd__help_commands] )) ||
_my-app__some_cmd__help_commands() {
local commands; commands=()
_describe -t commands 'my-app some_cmd help commands' commands "$@"
}
(( $+functions[_my-app__some_cmd_commands] )) ||
_my-app__some_cmd_commands() {
local commands; commands=(
'sub_cmd:sub-subcommand' /
'help:Print this message or the help of the given subcommand(s)' /
)
_describe -t commands 'my-app some_cmd commands' commands "$@"
}
(( $+functions[_my-app__some_cmd__sub_cmd_commands] )) ||
_my-app__some_cmd__sub_cmd_commands() {
local commands; commands=()
_describe -t commands 'my-app some_cmd sub_cmd commands' commands "$@"
}
(( $+functions[_my-app__test_commands] )) ||
_my-app__test_commands() {
local commands; commands=()
_describe -t commands 'my-app test commands' commands "$@"
}
_my-app "$@"

View file

@ -0,0 +1,118 @@
_my-app() {
local i cur prev opts cmds
COMPREPLY=()
cur="${COMP_WORDS[COMP_CWORD]}"
prev="${COMP_WORDS[COMP_CWORD-1]}"
cmd=""
opts=""
for i in ${COMP_WORDS[@]}
do
case "${i}" in
"$1")
cmd="my__app"
;;
*)
;;
esac
done
case "${cmd}" in
my__app)
opts="-p -f -d -e -c -u -h --help --choice --unknown --other --path --file --dir --exe --cmd-name --cmd --user --host --url --email <command_with_args>..."
if [[ ${cur} == -* || ${COMP_CWORD} -eq 1 ]] ; then
COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
return 0
fi
case "${prev}" in
--choice)
COMPREPLY=($(compgen -W "" -- "${cur}"))
return 0
;;
--unknown)
COMPREPLY=($(compgen -f "${cur}"))
return 0
;;
--other)
COMPREPLY=($(compgen -f "${cur}"))
return 0
;;
--path)
COMPREPLY=($(compgen -f "${cur}"))
return 0
;;
-p)
COMPREPLY=($(compgen -f "${cur}"))
return 0
;;
--file)
COMPREPLY=($(compgen -f "${cur}"))
return 0
;;
-f)
COMPREPLY=($(compgen -f "${cur}"))
return 0
;;
--dir)
COMPREPLY=($(compgen -f "${cur}"))
return 0
;;
-d)
COMPREPLY=($(compgen -f "${cur}"))
return 0
;;
--exe)
COMPREPLY=($(compgen -f "${cur}"))
return 0
;;
-e)
COMPREPLY=($(compgen -f "${cur}"))
return 0
;;
--cmd-name)
COMPREPLY=($(compgen -f "${cur}"))
return 0
;;
--cmd)
COMPREPLY=($(compgen -f "${cur}"))
return 0
;;
-c)
COMPREPLY=($(compgen -f "${cur}"))
return 0
;;
--user)
COMPREPLY=($(compgen -f "${cur}"))
return 0
;;
-u)
COMPREPLY=($(compgen -f "${cur}"))
return 0
;;
--host)
COMPREPLY=($(compgen -f "${cur}"))
return 0
;;
-h)
COMPREPLY=($(compgen -f "${cur}"))
return 0
;;
--url)
COMPREPLY=($(compgen -f "${cur}"))
return 0
;;
--email)
COMPREPLY=($(compgen -f "${cur}"))
return 0
;;
*)
COMPREPLY=()
;;
esac
COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
return 0
;;
esac
}
complete -F _my-app -o bashdefault -o default my-app

View file

@ -0,0 +1,45 @@
use builtin;
use str;
set edit:completion:arg-completer[my-app] = {|@words|
fn spaces {|n|
builtin:repeat $n ' ' | str:join ''
}
fn cand {|text desc|
edit:complex-candidate $text &display=$text' '(spaces (- 14 (wcswidth $text)))$desc
}
var command = 'my-app'
for word $words[1..-1] {
if (str:has-prefix $word '-') {
break
}
set command = $command';'$word
}
var completions = [
&'my-app'= {
cand --choice 'choice'
cand --unknown 'unknown'
cand --other 'other'
cand -p 'p'
cand --path 'path'
cand -f 'f'
cand --file 'file'
cand -d 'd'
cand --dir 'dir'
cand -e 'e'
cand --exe 'exe'
cand --cmd-name 'cmd-name'
cand -c 'c'
cand --cmd 'cmd'
cand -u 'u'
cand --user 'user'
cand -h 'h'
cand --host 'host'
cand --url 'url'
cand --email 'email'
cand --help 'Print help information'
}
]
$completions[$command]
}

View file

@ -0,0 +1,14 @@
complete -c my-app -l choice -r -f -a "{bash ,fish ,zsh }"
complete -c my-app -l unknown -r
complete -c my-app -l other -r -f
complete -c my-app -s p -l path -r -F
complete -c my-app -s f -l file -r -F
complete -c my-app -s d -l dir -r -f -a "(__fish_complete_directories)"
complete -c my-app -s e -l exe -r -F
complete -c my-app -l cmd-name -r -f -a "(__fish_complete_command)"
complete -c my-app -s c -l cmd -r -f -a "(__fish_complete_command)"
complete -c my-app -s u -l user -r -f -a "(__fish_complete_users)"
complete -c my-app -s h -l host -r -f -a "(__fish_print_hostnames)"
complete -c my-app -l url -r -f
complete -c my-app -l email -r -f
complete -c my-app -l help -d 'Print help information'

View file

@ -0,0 +1,51 @@
using namespace System.Management.Automation
using namespace System.Management.Automation.Language
Register-ArgumentCompleter -Native -CommandName 'my-app' -ScriptBlock {
param($wordToComplete, $commandAst, $cursorPosition)
$commandElements = $commandAst.CommandElements
$command = @(
'my-app'
for ($i = 1; $i -lt $commandElements.Count; $i++) {
$element = $commandElements[$i]
if ($element -isnot [StringConstantExpressionAst] -or
$element.StringConstantType -ne [StringConstantType]::BareWord -or
$element.Value.StartsWith('-') -or
$element.Value -eq $wordToComplete) {
break
}
$element.Value
}) -join ';'
$completions = @(switch ($command) {
'my-app' {
[CompletionResult]::new('--choice', 'choice', [CompletionResultType]::ParameterName, 'choice')
[CompletionResult]::new('--unknown', 'unknown', [CompletionResultType]::ParameterName, 'unknown')
[CompletionResult]::new('--other', 'other', [CompletionResultType]::ParameterName, 'other')
[CompletionResult]::new('-p', 'p', [CompletionResultType]::ParameterName, 'p')
[CompletionResult]::new('--path', 'path', [CompletionResultType]::ParameterName, 'path')
[CompletionResult]::new('-f', 'f', [CompletionResultType]::ParameterName, 'f')
[CompletionResult]::new('--file', 'file', [CompletionResultType]::ParameterName, 'file')
[CompletionResult]::new('-d', 'd', [CompletionResultType]::ParameterName, 'd')
[CompletionResult]::new('--dir', 'dir', [CompletionResultType]::ParameterName, 'dir')
[CompletionResult]::new('-e', 'e', [CompletionResultType]::ParameterName, 'e')
[CompletionResult]::new('--exe', 'exe', [CompletionResultType]::ParameterName, 'exe')
[CompletionResult]::new('--cmd-name', 'cmd-name', [CompletionResultType]::ParameterName, 'cmd-name')
[CompletionResult]::new('-c', 'c', [CompletionResultType]::ParameterName, 'c')
[CompletionResult]::new('--cmd', 'cmd', [CompletionResultType]::ParameterName, 'cmd')
[CompletionResult]::new('-u', 'u', [CompletionResultType]::ParameterName, 'u')
[CompletionResult]::new('--user', 'user', [CompletionResultType]::ParameterName, 'user')
[CompletionResult]::new('-h', 'h', [CompletionResultType]::ParameterName, 'h')
[CompletionResult]::new('--host', 'host', [CompletionResultType]::ParameterName, 'host')
[CompletionResult]::new('--url', 'url', [CompletionResultType]::ParameterName, 'url')
[CompletionResult]::new('--email', 'email', [CompletionResultType]::ParameterName, 'email')
[CompletionResult]::new('--help', 'help', [CompletionResultType]::ParameterName, 'Print help information')
break
}
})
$completions.Where{ $_.CompletionText -like "$wordToComplete*" } |
Sort-Object -Property ListItemText
}

View file

@ -0,0 +1,49 @@
#compdef my-app
autoload -U is-at-least
_my-app() {
typeset -A opt_args
typeset -a _arguments_options
local ret=1
if is-at-least 5.2; then
_arguments_options=(-s -S -C)
else
_arguments_options=(-s -C)
fi
local context curcontext="$curcontext" state line
_arguments "${_arguments_options[@]}" /
'--choice=[]: :(bash fish zsh)' /
'--unknown=[]: : ' /
'--other=[]: :( )' /
'-p+[]: :_files' /
'--path=[]: :_files' /
'-f+[]: :_files' /
'--file=[]: :_files' /
'-d+[]: :_files -/' /
'--dir=[]: :_files -/' /
'-e+[]: :_absolute_command_paths' /
'--exe=[]: :_absolute_command_paths' /
'--cmd-name=[]: :_command_names -e' /
'-c+[]: :_cmdstring' /
'--cmd=[]: :_cmdstring' /
'-u+[]: :_users' /
'--user=[]: :_users' /
'-h+[]: :_hosts' /
'--host=[]: :_hosts' /
'--url=[]: :_urls' /
'--email=[]: :_email_addresses' /
'--help[Print help information]' /
'*::command_with_args:_cmdambivalent' /
&& ret=0
}
(( $+functions[_my-app_commands] )) ||
_my-app_commands() {
local commands; commands=()
_describe -t commands 'my-app commands' commands "$@"
}
_my-app "$@"

View file

@ -1,160 +0,0 @@
mod completions;
use clap::{Arg, Command, ValueHint};
use clap_complete::shells::*;
use completions::common;
pub fn build_app_with_value_hints() -> Command<'static> {
Command::new("my_app")
.trailing_var_arg(true)
.arg(
Arg::new("choice")
.long("choice")
.possible_values(["bash", "fish", "zsh"]),
)
.arg(
Arg::new("unknown")
.long("unknown")
.value_hint(ValueHint::Unknown),
)
.arg(Arg::new("other").long("other").value_hint(ValueHint::Other))
.arg(
Arg::new("path")
.long("path")
.short('p')
.value_hint(ValueHint::AnyPath),
)
.arg(
Arg::new("file")
.long("file")
.short('f')
.value_hint(ValueHint::FilePath),
)
.arg(
Arg::new("dir")
.long("dir")
.short('d')
.value_hint(ValueHint::DirPath),
)
.arg(
Arg::new("exe")
.long("exe")
.short('e')
.value_hint(ValueHint::ExecutablePath),
)
.arg(
Arg::new("cmd_name")
.long("cmd-name")
.value_hint(ValueHint::CommandName),
)
.arg(
Arg::new("cmd")
.long("cmd")
.short('c')
.value_hint(ValueHint::CommandString),
)
.arg(
Arg::new("command_with_args")
.takes_value(true)
.multiple_values(true)
.value_hint(ValueHint::CommandWithArguments),
)
.arg(
Arg::new("user")
.short('u')
.long("user")
.value_hint(ValueHint::Username),
)
.arg(
Arg::new("host")
.short('h')
.long("host")
.value_hint(ValueHint::Hostname),
)
.arg(Arg::new("url").long("url").value_hint(ValueHint::Url))
.arg(
Arg::new("email")
.long("email")
.value_hint(ValueHint::EmailAddress),
)
}
static ZSH_VALUE_HINTS: &str = r#"#compdef my_app
autoload -U is-at-least
_my_app() {
typeset -A opt_args
typeset -a _arguments_options
local ret=1
if is-at-least 5.2; then
_arguments_options=(-s -S -C)
else
_arguments_options=(-s -C)
fi
local context curcontext="$curcontext" state line
_arguments "${_arguments_options[@]}" \
'--choice=[]: :(bash fish zsh)' \
'--unknown=[]: : ' \
'--other=[]: :( )' \
'-p+[]: :_files' \
'--path=[]: :_files' \
'-f+[]: :_files' \
'--file=[]: :_files' \
'-d+[]: :_files -/' \
'--dir=[]: :_files -/' \
'-e+[]: :_absolute_command_paths' \
'--exe=[]: :_absolute_command_paths' \
'--cmd-name=[]: :_command_names -e' \
'-c+[]: :_cmdstring' \
'--cmd=[]: :_cmdstring' \
'-u+[]: :_users' \
'--user=[]: :_users' \
'-h+[]: :_hosts' \
'--host=[]: :_hosts' \
'--url=[]: :_urls' \
'--email=[]: :_email_addresses' \
'--help[Print help information]' \
'*::command_with_args:_cmdambivalent' \
&& ret=0
}
(( $+functions[_my_app_commands] )) ||
_my_app_commands() {
local commands; commands=()
_describe -t commands 'my_app commands' commands "$@"
}
_my_app "$@"
"#;
static FISH_VALUE_HINTS: &str = r#"complete -c my_app -l choice -r -f -a "{bash ,fish ,zsh }"
complete -c my_app -l unknown -r
complete -c my_app -l other -r -f
complete -c my_app -s p -l path -r -F
complete -c my_app -s f -l file -r -F
complete -c my_app -s d -l dir -r -f -a "(__fish_complete_directories)"
complete -c my_app -s e -l exe -r -F
complete -c my_app -l cmd-name -r -f -a "(__fish_complete_command)"
complete -c my_app -s c -l cmd -r -f -a "(__fish_complete_command)"
complete -c my_app -s u -l user -r -f -a "(__fish_complete_users)"
complete -c my_app -s h -l host -r -f -a "(__fish_print_hostnames)"
complete -c my_app -l url -r -f
complete -c my_app -l email -r -f
complete -c my_app -l help -d 'Print help information'
"#;
#[test]
fn zsh_with_value_hints() {
let mut cmd = build_app_with_value_hints();
common(Zsh, &mut cmd, "my_app", ZSH_VALUE_HINTS);
}
#[test]
fn fish_with_value_hints() {
let mut cmd = build_app_with_value_hints();
common(Fish, &mut cmd, "my_app", FISH_VALUE_HINTS);
}

View file

@ -0,0 +1,85 @@
mod common;
#[test]
fn basic() {
let name = "my-app";
let cmd = common::basic_command(name);
common::assert_matches_path(
"tests/snapshots/basic.zsh.log",
clap_complete::shells::Zsh,
cmd,
name,
);
}
#[test]
fn feature_sample() {
let name = "my-app";
let cmd = common::feature_sample_command(name);
common::assert_matches_path(
"tests/snapshots/feature_sample.zsh.log",
clap_complete::shells::Zsh,
cmd,
name,
);
}
#[test]
fn special_commands() {
let name = "my-app";
let cmd = common::special_commands_command(name);
common::assert_matches_path(
"tests/snapshots/special_commands.zsh.log",
clap_complete::shells::Zsh,
cmd,
name,
);
}
#[test]
fn quoting() {
let name = "my-app";
let cmd = common::quoting_command(name);
common::assert_matches_path(
"tests/snapshots/quoting.zsh.log",
clap_complete::shells::Zsh,
cmd,
name,
);
}
#[test]
fn aliases() {
let name = "my-app";
let cmd = common::aliases_command(name);
common::assert_matches_path(
"tests/snapshots/aliases.zsh.log",
clap_complete::shells::Zsh,
cmd,
name,
);
}
#[test]
fn sub_subcommands() {
let name = "my-app";
let cmd = common::sub_subcommands_command(name);
common::assert_matches_path(
"tests/snapshots/sub_subcommands.zsh.log",
clap_complete::shells::Zsh,
cmd,
name,
);
}
#[test]
fn value_hint() {
let name = "my-app";
let cmd = common::value_hint_command(name);
common::assert_matches_path(
"tests/snapshots/value_hint.zsh.log",
clap_complete::shells::Zsh,
cmd,
name,
);
}

View file

@ -42,4 +42,4 @@ clap = { path = "../", version = "3.1.0", default-features = false, features = [
clap_complete = { path = "../clap_complete", version = "3.1.0" } clap_complete = { path = "../clap_complete", version = "3.1.0" }
[dev-dependencies] [dev-dependencies]
pretty_assertions = "1.0" snapbox = { version = "0.2", features = ["diff"] }

View file

@ -0,0 +1,235 @@
pub fn basic_command(name: &'static str) -> clap::Command<'static> {
clap::Command::new(name)
.arg(clap::Arg::new("config").short('c').global(true))
.arg(clap::Arg::new("v").short('v').conflicts_with("config"))
.subcommand(
clap::Command::new("test")
.about("Subcommand")
.arg(clap::Arg::new("debug").short('d')),
)
}
pub fn feature_sample_command(name: &'static str) -> clap::Command<'static> {
clap::Command::new(name)
.version("3.0")
.propagate_version(true)
.about("Tests completions")
.arg(
clap::Arg::new("file")
.value_hint(clap::ValueHint::FilePath)
.help("some input file"),
)
.arg(
clap::Arg::new("config")
.help("some config file")
.short('c')
.visible_short_alias('C')
.long("config")
.visible_alias("conf"),
)
.arg(clap::Arg::new("choice").possible_values(["first", "second"]))
.subcommand(
clap::Command::new("test").about("tests things").arg(
clap::Arg::new("case")
.long("case")
.takes_value(true)
.help("the case to test"),
),
)
}
pub fn special_commands_command(name: &'static str) -> clap::Command<'static> {
feature_sample_command(name)
.subcommand(
clap::Command::new("some_cmd")
.about("tests other things")
.arg(
clap::Arg::new("config")
.long("--config")
.takes_value(true)
.help("the other case to test"),
),
)
.subcommand(clap::Command::new("some-cmd-with-hyphens").alias("hyphen"))
}
pub fn quoting_command(name: &'static str) -> clap::Command<'static> {
clap::Command::new(name)
.version("3.0")
.arg(
clap::Arg::new("single-quotes")
.long("single-quotes")
.help("Can be 'always', 'auto', or 'never'"),
)
.arg(
clap::Arg::new("double-quotes")
.long("double-quotes")
.help("Can be \"always\", \"auto\", or \"never\""),
)
.arg(
clap::Arg::new("backticks")
.long("backticks")
.help("For more information see `echo test`"),
)
.arg(
clap::Arg::new("backslash")
.long("backslash")
.help("Avoid '\\n'"),
)
.arg(
clap::Arg::new("brackets")
.long("brackets")
.help("List packages [filter]"),
)
.arg(
clap::Arg::new("expansions")
.long("expansions")
.help("Execute the shell command with $SHELL"),
)
.subcommands([
clap::Command::new("cmd-single-quotes").about("Can be 'always', 'auto', or 'never'"),
clap::Command::new("cmd-double-quotes")
.about("Can be \"always\", \"auto\", or \"never\""),
clap::Command::new("cmd-backticks").about("For more information see `echo test`"),
clap::Command::new("cmd-backslash").about("Avoid '\\n'"),
clap::Command::new("cmd-brackets").about("List packages [filter]"),
clap::Command::new("cmd-expansions").about("Execute the shell command with $SHELL"),
])
}
pub fn aliases_command(name: &'static str) -> clap::Command<'static> {
clap::Command::new(name)
.version("3.0")
.about("testing bash completions")
.arg(
clap::Arg::new("flag")
.short('f')
.visible_short_alias('F')
.long("flag")
.visible_alias("flg")
.help("cmd flag"),
)
.arg(
clap::Arg::new("option")
.short('o')
.visible_short_alias('O')
.long("option")
.visible_alias("opt")
.help("cmd option")
.takes_value(true),
)
.arg(clap::Arg::new("positional"))
}
pub fn sub_subcommands_command(name: &'static str) -> clap::Command<'static> {
feature_sample_command(name).subcommand(
clap::Command::new("some_cmd")
.about("top level subcommand")
.subcommand(
clap::Command::new("sub_cmd").about("sub-subcommand").arg(
clap::Arg::new("config")
.long("--config")
.takes_value(true)
.possible_values([clap::PossibleValue::new("Lest quotes aren't escaped.")])
.help("the other case to test"),
),
),
)
}
pub fn value_hint_command(name: &'static str) -> clap::Command<'static> {
clap::Command::new(name)
.trailing_var_arg(true)
.arg(
clap::Arg::new("choice")
.long("choice")
.possible_values(["bash", "fish", "zsh"]),
)
.arg(
clap::Arg::new("unknown")
.long("unknown")
.value_hint(clap::ValueHint::Unknown),
)
.arg(
clap::Arg::new("other")
.long("other")
.value_hint(clap::ValueHint::Other),
)
.arg(
clap::Arg::new("path")
.long("path")
.short('p')
.value_hint(clap::ValueHint::AnyPath),
)
.arg(
clap::Arg::new("file")
.long("file")
.short('f')
.value_hint(clap::ValueHint::FilePath),
)
.arg(
clap::Arg::new("dir")
.long("dir")
.short('d')
.value_hint(clap::ValueHint::DirPath),
)
.arg(
clap::Arg::new("exe")
.long("exe")
.short('e')
.value_hint(clap::ValueHint::ExecutablePath),
)
.arg(
clap::Arg::new("cmd_name")
.long("cmd-name")
.value_hint(clap::ValueHint::CommandName),
)
.arg(
clap::Arg::new("cmd")
.long("cmd")
.short('c')
.value_hint(clap::ValueHint::CommandString),
)
.arg(
clap::Arg::new("command_with_args")
.takes_value(true)
.multiple_values(true)
.value_hint(clap::ValueHint::CommandWithArguments),
)
.arg(
clap::Arg::new("user")
.short('u')
.long("user")
.value_hint(clap::ValueHint::Username),
)
.arg(
clap::Arg::new("host")
.short('h')
.long("host")
.value_hint(clap::ValueHint::Hostname),
)
.arg(
clap::Arg::new("url")
.long("url")
.value_hint(clap::ValueHint::Url),
)
.arg(
clap::Arg::new("email")
.long("email")
.value_hint(clap::ValueHint::EmailAddress),
)
}
pub fn assert_matches_path(
expected_path: impl AsRef<std::path::Path>,
gen: impl clap_complete::Generator,
mut cmd: clap::Command,
name: &str,
) {
let mut buf = vec![];
clap_complete::generate(gen, &mut cmd, name, &mut buf);
snapbox::Assert::new()
.action_env("SNAPSHOTS")
.matches_path(expected_path, buf);
}

View file

@ -1,477 +0,0 @@
use super::*;
use crate::Fig;
fn build_app() -> Command<'static> {
build_app_with_name("myapp")
}
fn build_app_with_name(s: &'static str) -> Command<'static> {
Command::new(s)
.version("3.0")
.propagate_version(true)
.about("Tests completions")
.arg(
Arg::new("file")
.value_hint(ValueHint::FilePath)
.help("some input file"),
)
.subcommand(
Command::new("test").about("tests things").arg(
Arg::new("case")
.long("case")
.takes_value(true)
.help("the case to test"),
),
)
}
#[test]
fn fig() {
let mut cmd = build_app();
common(Fig, &mut cmd, "myapp", FIG);
}
static FIG: &str = r#"const completion: Fig.Spec = {
name: "myapp",
description: "Tests completions",
subcommands: [
{
name: "test",
description: "tests things",
options: [
{
name: "--case",
description: "the case to test",
args: {
name: "case",
isOptional: true,
},
},
{
name: ["-h", "--help"],
description: "Print help information",
},
{
name: ["-V", "--version"],
description: "Print version information",
},
],
},
{
name: "help",
description: "Print this message or the help of the given subcommand(s)",
options: [
],
args: {
name: "subcommand",
isOptional: true,
},
},
],
options: [
{
name: ["-h", "--help"],
description: "Print help information",
},
{
name: ["-V", "--version"],
description: "Print version information",
},
],
args: {
name: "file",
isOptional: true,
template: "filepaths",
},
};
export default completion;
"#;
#[test]
fn fig_with_special_commands() {
let mut cmd = build_app_special_commands();
common(Fig, &mut cmd, "my_app", FIG_SPECIAL_CMDS);
}
fn build_app_special_commands() -> Command<'static> {
build_app_with_name("my_app")
.subcommand(
Command::new("some_cmd").about("tests other things").arg(
Arg::new("config")
.long("--config")
.takes_value(true)
.help("the other case to test"),
),
)
.subcommand(Command::new("some-cmd-with-hyphens").alias("hyphen"))
}
static FIG_SPECIAL_CMDS: &str = r#"const completion: Fig.Spec = {
name: "my_app",
description: "Tests completions",
subcommands: [
{
name: "test",
description: "tests things",
options: [
{
name: "--case",
description: "the case to test",
args: {
name: "case",
isOptional: true,
},
},
{
name: ["-h", "--help"],
description: "Print help information",
},
{
name: ["-V", "--version"],
description: "Print version information",
},
],
},
{
name: "some_cmd",
description: "tests other things",
options: [
{
name: "--config",
description: "the other case to test",
args: {
name: "config",
isOptional: true,
},
},
{
name: ["-h", "--help"],
description: "Print help information",
},
{
name: ["-V", "--version"],
description: "Print version information",
},
],
},
{
name: "some-cmd-with-hyphens",
options: [
{
name: ["-h", "--help"],
description: "Print help information",
},
{
name: ["-V", "--version"],
description: "Print version information",
},
],
},
{
name: "help",
description: "Print this message or the help of the given subcommand(s)",
options: [
],
args: {
name: "subcommand",
isOptional: true,
},
},
],
options: [
{
name: ["-h", "--help"],
description: "Print help information",
},
{
name: ["-V", "--version"],
description: "Print version information",
},
],
args: {
name: "file",
isOptional: true,
template: "filepaths",
},
};
export default completion;
"#;
#[test]
fn fig_with_special_help() {
let mut cmd = build_app_special_help();
common(Fig, &mut cmd, "my_app", FIG_SPECIAL_HELP);
}
fn build_app_special_help() -> Command<'static> {
Command::new("my_app")
.version("3.0")
.arg(
Arg::new("single-quotes")
.long("single-quotes")
.help("Can be 'always', 'auto', or 'never'"),
)
.arg(
Arg::new("double-quotes")
.long("double-quotes")
.help("Can be \"always\", \"auto\", or \"never\""),
)
.arg(
Arg::new("backticks")
.long("backticks")
.help("For more information see `echo test`"),
)
.arg(Arg::new("backslash").long("backslash").help("Avoid '\\n'"))
.arg(
Arg::new("brackets")
.long("brackets")
.help("List packages [filter]"),
)
.arg(
Arg::new("expansions")
.long("expansions")
.help("Execute the shell command with $SHELL"),
)
}
static FIG_SPECIAL_HELP: &str = r#"const completion: Fig.Spec = {
name: "my_app",
description: "",
options: [
{
name: ["-h", "--help"],
description: "Print help information",
},
{
name: ["-V", "--version"],
description: "Print version information",
},
{
name: "--single-quotes",
description: "Can be 'always', 'auto', or 'never'",
},
{
name: "--double-quotes",
description: "Can be \"always\", \"auto\", or \"never\"",
},
{
name: "--backticks",
description: "For more information see `echo test`",
},
{
name: "--backslash",
description: "Avoid '\\n'",
},
{
name: "--brackets",
description: "List packages [filter]",
},
{
name: "--expansions",
description: "Execute the shell command with $SHELL",
},
],
};
export default completion;
"#;
#[test]
fn fig_with_aliases() {
let mut cmd = build_app_with_aliases();
common(Fig, &mut cmd, "cmd", FIG_ALIASES);
}
fn build_app_with_aliases() -> Command<'static> {
Command::new("cmd")
.version("3.0")
.about("testing bash completions")
.arg(
Arg::new("flag")
.short('f')
.visible_short_alias('F')
.long("flag")
.visible_alias("flg")
.help("cmd flag"),
)
.arg(
Arg::new("option")
.short('o')
.visible_short_alias('O')
.long("option")
.visible_alias("opt")
.help("cmd option")
.takes_value(true),
)
.arg(Arg::new("positional"))
}
static FIG_ALIASES: &str = r#"const completion: Fig.Spec = {
name: "cmd",
description: "testing bash completions",
options: [
{
name: ["-o", "-O", "--option", "--opt"],
description: "cmd option",
args: {
name: "option",
isOptional: true,
},
},
{
name: ["-h", "--help"],
description: "Print help information",
},
{
name: ["-V", "--version"],
description: "Print version information",
},
{
name: ["-f", "-F", "--flag", "--flg"],
description: "cmd flag",
},
],
args: {
name: "positional",
isOptional: true,
},
};
export default completion;
"#;
#[test]
fn fig_with_sub_subcommands() {
let mut cmd = build_app_sub_subcommands();
common(Fig, &mut cmd, "my_app", FIG_SUB_SUBCMDS);
}
fn build_app_sub_subcommands() -> Command<'static> {
build_app_with_name("my_app").subcommand(
Command::new("some_cmd")
.about("top level subcommand")
.subcommand(
Command::new("sub_cmd").about("sub-subcommand").arg(
Arg::new("config")
.long("--config")
.takes_value(true)
.help("the other case to test"),
),
),
)
}
static FIG_SUB_SUBCMDS: &str = r#"const completion: Fig.Spec = {
name: "my_app",
description: "Tests completions",
subcommands: [
{
name: "test",
description: "tests things",
options: [
{
name: "--case",
description: "the case to test",
args: {
name: "case",
isOptional: true,
},
},
{
name: ["-h", "--help"],
description: "Print help information",
},
{
name: ["-V", "--version"],
description: "Print version information",
},
],
},
{
name: "some_cmd",
description: "top level subcommand",
subcommands: [
{
name: "sub_cmd",
description: "sub-subcommand",
options: [
{
name: "--config",
description: "the other case to test",
args: {
name: "config",
isOptional: true,
},
},
{
name: ["-h", "--help"],
description: "Print help information",
},
{
name: ["-V", "--version"],
description: "Print version information",
},
],
},
{
name: "help",
description: "Print this message or the help of the given subcommand(s)",
options: [
{
name: ["-h", "--help"],
description: "Print help information",
},
{
name: ["-V", "--version"],
description: "Print version information",
},
],
args: {
name: "subcommand",
isOptional: true,
},
},
],
options: [
{
name: ["-h", "--help"],
description: "Print help information",
},
{
name: ["-V", "--version"],
description: "Print version information",
},
],
},
{
name: "help",
description: "Print this message or the help of the given subcommand(s)",
options: [
],
args: {
name: "subcommand",
isOptional: true,
},
},
],
options: [
{
name: ["-h", "--help"],
description: "Print help information",
},
{
name: ["-V", "--version"],
description: "Print version information",
},
],
args: {
name: "file",
isOptional: true,
template: "filepaths",
},
};
export default completion;
"#;

View file

@ -1,28 +0,0 @@
use clap::{Arg, Command, ValueHint};
use clap_complete::{generate, Generator};
use std::fmt;
mod fig;
#[derive(PartialEq, Eq)]
pub struct PrettyString<'a>(pub &'a str);
impl<'a> fmt::Debug for PrettyString<'a> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
f.write_str(self.0)
}
}
macro_rules! assert_eq {
($left:expr, $right:expr) => {
pretty_assertions::assert_eq!(PrettyString($left), PrettyString($right));
};
}
pub fn common<G: Generator>(gen: G, cmd: &mut Command, name: &str, fixture: &str) {
let mut buf = vec![];
generate(gen, cmd, name, &mut buf);
let string = String::from_utf8(buf).unwrap();
assert_eq!(&string, fixture);
}

View file

@ -0,0 +1,85 @@
mod common;
#[test]
fn basic() {
let name = "my-app";
let cmd = common::basic_command(name);
common::assert_matches_path(
"tests/snapshots/basic.fig.js",
clap_complete_fig::Fig,
cmd,
name,
);
}
#[test]
fn feature_sample() {
let name = "my-app";
let cmd = common::feature_sample_command(name);
common::assert_matches_path(
"tests/snapshots/feature_sample.fig.js",
clap_complete_fig::Fig,
cmd,
name,
);
}
#[test]
fn special_commands() {
let name = "my-app";
let cmd = common::special_commands_command(name);
common::assert_matches_path(
"tests/snapshots/special_commands.fig.js",
clap_complete_fig::Fig,
cmd,
name,
);
}
#[test]
fn quoting() {
let name = "my-app";
let cmd = common::quoting_command(name);
common::assert_matches_path(
"tests/snapshots/quoting.fig.js",
clap_complete_fig::Fig,
cmd,
name,
);
}
#[test]
fn aliases() {
let name = "my-app";
let cmd = common::aliases_command(name);
common::assert_matches_path(
"tests/snapshots/aliases.fig.js",
clap_complete_fig::Fig,
cmd,
name,
);
}
#[test]
fn sub_subcommands() {
let name = "my-app";
let cmd = common::sub_subcommands_command(name);
common::assert_matches_path(
"tests/snapshots/sub_subcommands.fig.js",
clap_complete_fig::Fig,
cmd,
name,
);
}
#[test]
fn value_hint() {
let name = "my-app";
let cmd = common::value_hint_command(name);
common::assert_matches_path(
"tests/snapshots/value_hint.fig.js",
clap_complete_fig::Fig,
cmd,
name,
);
}

View file

@ -1,18 +0,0 @@
use clap::{Arg, Command};
use clap_complete::generate;
use clap_complete_fig::Fig;
use std::io;
#[test]
fn generate_completions() {
let mut cmd = Command::new("test_app")
.arg(Arg::new("config").short('c').global(true))
.arg(Arg::new("v").short('v').conflicts_with("config"))
.subcommand(
Command::new("test")
.about("Subcommand")
.arg(Arg::new("debug").short('d')),
);
generate(Fig, &mut cmd, "test_app", &mut io::sink());
}

View file

@ -0,0 +1,32 @@
const completion: Fig.Spec = {
name: "my-app",
description: "testing bash completions",
options: [
{
name: ["-o", "-O", "--option", "--opt"],
description: "cmd option",
args: {
name: "option",
isOptional: true,
},
},
{
name: ["-h", "--help"],
description: "Print help information",
},
{
name: ["-V", "--version"],
description: "Print version information",
},
{
name: ["-f", "-F", "--flag", "--flg"],
description: "cmd flag",
},
],
args: {
name: "positional",
isOptional: true,
},
};
export default completion;

View file

@ -0,0 +1,49 @@
const completion: Fig.Spec = {
name: "my-app",
description: "",
subcommands: [
{
name: "test",
description: "Subcommand",
options: [
{
name: "-d",
},
{
name: ["-h", "--help"],
description: "Print help information",
},
{
name: "-c",
},
],
},
{
name: "help",
description: "Print this message or the help of the given subcommand(s)",
options: [
{
name: "-c",
},
],
args: {
name: "subcommand",
isOptional: true,
},
},
],
options: [
{
name: ["-h", "--help"],
description: "Print help information",
},
{
name: "-c",
},
{
name: "-v",
},
],
};
export default completion;

View file

@ -0,0 +1,73 @@
const completion: Fig.Spec = {
name: "my-app",
description: "Tests completions",
subcommands: [
{
name: "test",
description: "tests things",
options: [
{
name: "--case",
description: "the case to test",
args: {
name: "case",
isOptional: true,
},
},
{
name: ["-h", "--help"],
description: "Print help information",
},
{
name: ["-V", "--version"],
description: "Print version information",
},
],
},
{
name: "help",
description: "Print this message or the help of the given subcommand(s)",
options: [
],
args: {
name: "subcommand",
isOptional: true,
},
},
],
options: [
{
name: ["-h", "--help"],
description: "Print help information",
},
{
name: ["-V", "--version"],
description: "Print version information",
},
{
name: ["-c", "-C", "--config", "--conf"],
description: "some config file",
},
],
args: [
{
name: "file",
isOptional: true,
template: "filepaths",
},
{
name: "choice",
isOptional: true,
suggestions: [
{
name: "first",
},
{
name: "second",
},
]
},
]
};
export default completion;

View file

@ -0,0 +1,112 @@
const completion: Fig.Spec = {
name: "my-app",
description: "",
subcommands: [
{
name: "cmd-single-quotes",
description: "Can be 'always', 'auto', or 'never'",
options: [
{
name: ["-h", "--help"],
description: "Print help information",
},
],
},
{
name: "cmd-double-quotes",
description: "Can be /"always/", /"auto/", or /"never/"",
options: [
{
name: ["-h", "--help"],
description: "Print help information",
},
],
},
{
name: "cmd-backticks",
description: "For more information see `echo test`",
options: [
{
name: ["-h", "--help"],
description: "Print help information",
},
],
},
{
name: "cmd-backslash",
description: "Avoid '//n'",
options: [
{
name: ["-h", "--help"],
description: "Print help information",
},
],
},
{
name: "cmd-brackets",
description: "List packages [filter]",
options: [
{
name: ["-h", "--help"],
description: "Print help information",
},
],
},
{
name: "cmd-expansions",
description: "Execute the shell command with $SHELL",
options: [
{
name: ["-h", "--help"],
description: "Print help information",
},
],
},
{
name: "help",
description: "Print this message or the help of the given subcommand(s)",
options: [
],
args: {
name: "subcommand",
isOptional: true,
},
},
],
options: [
{
name: ["-h", "--help"],
description: "Print help information",
},
{
name: ["-V", "--version"],
description: "Print version information",
},
{
name: "--single-quotes",
description: "Can be 'always', 'auto', or 'never'",
},
{
name: "--double-quotes",
description: "Can be /"always/", /"auto/", or /"never/"",
},
{
name: "--backticks",
description: "For more information see `echo test`",
},
{
name: "--backslash",
description: "Avoid '//n'",
},
{
name: "--brackets",
description: "List packages [filter]",
},
{
name: "--expansions",
description: "Execute the shell command with $SHELL",
},
],
};
export default completion;

View file

@ -0,0 +1,108 @@
const completion: Fig.Spec = {
name: "my-app",
description: "Tests completions",
subcommands: [
{
name: "test",
description: "tests things",
options: [
{
name: "--case",
description: "the case to test",
args: {
name: "case",
isOptional: true,
},
},
{
name: ["-h", "--help"],
description: "Print help information",
},
{
name: ["-V", "--version"],
description: "Print version information",
},
],
},
{
name: "some_cmd",
description: "tests other things",
options: [
{
name: "--config",
description: "the other case to test",
args: {
name: "config",
isOptional: true,
},
},
{
name: ["-h", "--help"],
description: "Print help information",
},
{
name: ["-V", "--version"],
description: "Print version information",
},
],
},
{
name: "some-cmd-with-hyphens",
options: [
{
name: ["-h", "--help"],
description: "Print help information",
},
{
name: ["-V", "--version"],
description: "Print version information",
},
],
},
{
name: "help",
description: "Print this message or the help of the given subcommand(s)",
options: [
],
args: {
name: "subcommand",
isOptional: true,
},
},
],
options: [
{
name: ["-h", "--help"],
description: "Print help information",
},
{
name: ["-V", "--version"],
description: "Print version information",
},
{
name: ["-c", "-C", "--config", "--conf"],
description: "some config file",
},
],
args: [
{
name: "file",
isOptional: true,
template: "filepaths",
},
{
name: "choice",
isOptional: true,
suggestions: [
{
name: "first",
},
{
name: "second",
},
]
},
]
};
export default completion;

View file

@ -0,0 +1,134 @@
const completion: Fig.Spec = {
name: "my-app",
description: "Tests completions",
subcommands: [
{
name: "test",
description: "tests things",
options: [
{
name: "--case",
description: "the case to test",
args: {
name: "case",
isOptional: true,
},
},
{
name: ["-h", "--help"],
description: "Print help information",
},
{
name: ["-V", "--version"],
description: "Print version information",
},
],
},
{
name: "some_cmd",
description: "top level subcommand",
subcommands: [
{
name: "sub_cmd",
description: "sub-subcommand",
options: [
{
name: "--config",
description: "the other case to test",
args: {
name: "config",
isOptional: true,
suggestions: [
{
name: "Lest quotes aren't escaped.",
},
]
},
},
{
name: ["-h", "--help"],
description: "Print help information",
},
{
name: ["-V", "--version"],
description: "Print version information",
},
],
},
{
name: "help",
description: "Print this message or the help of the given subcommand(s)",
options: [
{
name: ["-h", "--help"],
description: "Print help information",
},
{
name: ["-V", "--version"],
description: "Print version information",
},
],
args: {
name: "subcommand",
isOptional: true,
},
},
],
options: [
{
name: ["-h", "--help"],
description: "Print help information",
},
{
name: ["-V", "--version"],
description: "Print version information",
},
],
},
{
name: "help",
description: "Print this message or the help of the given subcommand(s)",
options: [
],
args: {
name: "subcommand",
isOptional: true,
},
},
],
options: [
{
name: ["-h", "--help"],
description: "Print help information",
},
{
name: ["-V", "--version"],
description: "Print version information",
},
{
name: ["-c", "-C", "--config", "--conf"],
description: "some config file",
},
],
args: [
{
name: "file",
isOptional: true,
template: "filepaths",
},
{
name: "choice",
isOptional: true,
suggestions: [
{
name: "first",
},
{
name: "second",
},
]
},
]
};
export default completion;

View file

@ -0,0 +1,126 @@
const completion: Fig.Spec = {
name: "my-app",
description: "",
options: [
{
name: "--choice",
args: {
name: "choice",
isOptional: true,
suggestions: [
{
name: "bash",
},
{
name: "fish",
},
{
name: "zsh",
},
]
},
},
{
name: "--unknown",
args: {
name: "unknown",
isOptional: true,
},
},
{
name: "--other",
args: {
name: "other",
isOptional: true,
},
},
{
name: ["-p", "--path"],
args: {
name: "path",
isOptional: true,
template: "filepaths",
},
},
{
name: ["-f", "--file"],
args: {
name: "file",
isOptional: true,
template: "filepaths",
},
},
{
name: ["-d", "--dir"],
args: {
name: "dir",
isOptional: true,
template: "folders",
},
},
{
name: ["-e", "--exe"],
args: {
name: "exe",
isOptional: true,
template: "filepaths",
},
},
{
name: "--cmd-name",
args: {
name: "cmd_name",
isOptional: true,
isCommand: true,
},
},
{
name: ["-c", "--cmd"],
args: {
name: "cmd",
isOptional: true,
isCommand: true,
},
},
{
name: ["-u", "--user"],
args: {
name: "user",
isOptional: true,
},
},
{
name: ["-h", "--host"],
args: {
name: "host",
isOptional: true,
},
},
{
name: "--url",
args: {
name: "url",
isOptional: true,
},
},
{
name: "--email",
args: {
name: "email",
isOptional: true,
},
},
{
name: "--help",
description: "Print help information",
},
],
args: {
name: "command_with_args",
isVariadic: true,
isOptional: true,
isCommand: true,
},
};
export default completion;

View file

@ -1,215 +0,0 @@
use clap::{Arg, Command, ValueHint};
use clap_complete_fig::Fig;
use completions::common;
mod completions;
pub fn build_app_with_value_hints() -> Command<'static> {
Command::new("my_app")
.disable_version_flag(true)
.trailing_var_arg(true)
.arg(
Arg::new("choice")
.long("choice")
.possible_values(["bash", "fish", "zsh"]),
)
.arg(
Arg::new("unknown")
.long("unknown")
.value_hint(ValueHint::Unknown),
)
.arg(Arg::new("other").long("other").value_hint(ValueHint::Other))
.arg(
Arg::new("path")
.long("path")
.short('p')
.value_hint(ValueHint::AnyPath),
)
.arg(
Arg::new("file")
.long("file")
.short('f')
.value_hint(ValueHint::FilePath),
)
.arg(
Arg::new("dir")
.long("dir")
.short('d')
.value_hint(ValueHint::DirPath),
)
.arg(
Arg::new("exe")
.long("exe")
.short('e')
.value_hint(ValueHint::ExecutablePath),
)
.arg(
Arg::new("cmd_name")
.long("cmd-name")
.value_hint(ValueHint::CommandName),
)
.arg(
Arg::new("cmd")
.long("cmd")
.short('c')
.value_hint(ValueHint::CommandString),
)
.arg(
Arg::new("command_with_args")
.takes_value(true)
.multiple_values(true)
.value_hint(ValueHint::CommandWithArguments),
)
.arg(
Arg::new("user")
.short('u')
.long("user")
.value_hint(ValueHint::Username),
)
.arg(
Arg::new("host")
.short('h')
.long("host")
.value_hint(ValueHint::Hostname),
)
.arg(Arg::new("url").long("url").value_hint(ValueHint::Url))
.arg(
Arg::new("email")
.long("email")
.value_hint(ValueHint::EmailAddress),
)
}
static FIG_VALUE_HINTS: &str = r#"const completion: Fig.Spec = {
name: "my_app",
description: "",
options: [
{
name: "--choice",
args: {
name: "choice",
isOptional: true,
suggestions: [
{
name: "bash",
},
{
name: "fish",
},
{
name: "zsh",
},
]
},
},
{
name: "--unknown",
args: {
name: "unknown",
isOptional: true,
},
},
{
name: "--other",
args: {
name: "other",
isOptional: true,
},
},
{
name: ["-p", "--path"],
args: {
name: "path",
isOptional: true,
template: "filepaths",
},
},
{
name: ["-f", "--file"],
args: {
name: "file",
isOptional: true,
template: "filepaths",
},
},
{
name: ["-d", "--dir"],
args: {
name: "dir",
isOptional: true,
template: "folders",
},
},
{
name: ["-e", "--exe"],
args: {
name: "exe",
isOptional: true,
template: "filepaths",
},
},
{
name: "--cmd-name",
args: {
name: "cmd_name",
isOptional: true,
isCommand: true,
},
},
{
name: ["-c", "--cmd"],
args: {
name: "cmd",
isOptional: true,
isCommand: true,
},
},
{
name: ["-u", "--user"],
args: {
name: "user",
isOptional: true,
},
},
{
name: ["-h", "--host"],
args: {
name: "host",
isOptional: true,
},
},
{
name: "--url",
args: {
name: "url",
isOptional: true,
},
},
{
name: "--email",
args: {
name: "email",
isOptional: true,
},
},
{
name: "--help",
description: "Print help information",
},
],
args: {
name: "command_with_args",
isVariadic: true,
isOptional: true,
isCommand: true,
},
};
export default completion;
"#;
#[test]
fn fig_with_value_hints() {
let mut cmd = build_app_with_value_hints();
common(Fig, &mut cmd, "my_app", FIG_VALUE_HINTS);
}

View file

@ -39,7 +39,7 @@ roff = "0.2.1"
clap = { path = "../", version = "3.1", default-features = false, features = ["std", "env"] } clap = { path = "../", version = "3.1", default-features = false, features = ["std", "env"] }
[dev-dependencies] [dev-dependencies]
pretty_assertions = "1.0" snapbox = { version = "0.2", features = ["diff"] }
clap = { path = "../", version = "3.1", default-features = false, features = ["std"] } clap = { path = "../", version = "3.1", default-features = false, features = ["std"] }
[features] [features]

230
clap_mangen/tests/common.rs Normal file
View file

@ -0,0 +1,230 @@
pub fn basic_command(name: &'static str) -> clap::Command<'static> {
clap::Command::new(name)
.arg(clap::Arg::new("config").short('c').global(true))
.arg(clap::Arg::new("v").short('v').conflicts_with("config"))
.subcommand(
clap::Command::new("test")
.about("Subcommand")
.arg(clap::Arg::new("debug").short('d')),
)
}
pub fn feature_sample_command(name: &'static str) -> clap::Command<'static> {
clap::Command::new(name)
.version("3.0")
.propagate_version(true)
.about("Tests completions")
.arg(
clap::Arg::new("file")
.value_hint(clap::ValueHint::FilePath)
.help("some input file"),
)
.arg(
clap::Arg::new("config")
.help("some config file")
.short('c')
.visible_short_alias('C')
.long("config")
.visible_alias("conf"),
)
.arg(clap::Arg::new("choice").possible_values(["first", "second"]))
.subcommand(
clap::Command::new("test").about("tests things").arg(
clap::Arg::new("case")
.long("case")
.takes_value(true)
.help("the case to test"),
),
)
}
pub fn special_commands_command(name: &'static str) -> clap::Command<'static> {
feature_sample_command(name)
.subcommand(
clap::Command::new("some_cmd")
.about("tests other things")
.arg(
clap::Arg::new("config")
.long("--config")
.takes_value(true)
.help("the other case to test"),
),
)
.subcommand(clap::Command::new("some-cmd-with-hyphens").alias("hyphen"))
}
pub fn quoting_command(name: &'static str) -> clap::Command<'static> {
clap::Command::new(name)
.version("3.0")
.arg(
clap::Arg::new("single-quotes")
.long("single-quotes")
.help("Can be 'always', 'auto', or 'never'"),
)
.arg(
clap::Arg::new("double-quotes")
.long("double-quotes")
.help("Can be \"always\", \"auto\", or \"never\""),
)
.arg(
clap::Arg::new("backticks")
.long("backticks")
.help("For more information see `echo test`"),
)
.arg(
clap::Arg::new("backslash")
.long("backslash")
.help("Avoid '\\n'"),
)
.arg(
clap::Arg::new("brackets")
.long("brackets")
.help("List packages [filter]"),
)
.arg(
clap::Arg::new("expansions")
.long("expansions")
.help("Execute the shell command with $SHELL"),
)
.subcommands([
clap::Command::new("cmd-single-quotes").about("Can be 'always', 'auto', or 'never'"),
clap::Command::new("cmd-double-quotes")
.about("Can be \"always\", \"auto\", or \"never\""),
clap::Command::new("cmd-backticks").about("For more information see `echo test`"),
clap::Command::new("cmd-backslash").about("Avoid '\\n'"),
clap::Command::new("cmd-brackets").about("List packages [filter]"),
clap::Command::new("cmd-expansions").about("Execute the shell command with $SHELL"),
])
}
pub fn aliases_command(name: &'static str) -> clap::Command<'static> {
clap::Command::new(name)
.version("3.0")
.about("testing bash completions")
.arg(
clap::Arg::new("flag")
.short('f')
.visible_short_alias('F')
.long("flag")
.visible_alias("flg")
.help("cmd flag"),
)
.arg(
clap::Arg::new("option")
.short('o')
.visible_short_alias('O')
.long("option")
.visible_alias("opt")
.help("cmd option")
.takes_value(true),
)
.arg(clap::Arg::new("positional"))
}
pub fn sub_subcommands_command(name: &'static str) -> clap::Command<'static> {
feature_sample_command(name).subcommand(
clap::Command::new("some_cmd")
.about("top level subcommand")
.subcommand(
clap::Command::new("sub_cmd").about("sub-subcommand").arg(
clap::Arg::new("config")
.long("--config")
.takes_value(true)
.possible_values([clap::PossibleValue::new("Lest quotes aren't escaped.")])
.help("the other case to test"),
),
),
)
}
pub fn value_hint_command(name: &'static str) -> clap::Command<'static> {
clap::Command::new(name)
.trailing_var_arg(true)
.arg(
clap::Arg::new("choice")
.long("choice")
.possible_values(["bash", "fish", "zsh"]),
)
.arg(
clap::Arg::new("unknown")
.long("unknown")
.value_hint(clap::ValueHint::Unknown),
)
.arg(
clap::Arg::new("other")
.long("other")
.value_hint(clap::ValueHint::Other),
)
.arg(
clap::Arg::new("path")
.long("path")
.short('p')
.value_hint(clap::ValueHint::AnyPath),
)
.arg(
clap::Arg::new("file")
.long("file")
.short('f')
.value_hint(clap::ValueHint::FilePath),
)
.arg(
clap::Arg::new("dir")
.long("dir")
.short('d')
.value_hint(clap::ValueHint::DirPath),
)
.arg(
clap::Arg::new("exe")
.long("exe")
.short('e')
.value_hint(clap::ValueHint::ExecutablePath),
)
.arg(
clap::Arg::new("cmd_name")
.long("cmd-name")
.value_hint(clap::ValueHint::CommandName),
)
.arg(
clap::Arg::new("cmd")
.long("cmd")
.short('c')
.value_hint(clap::ValueHint::CommandString),
)
.arg(
clap::Arg::new("command_with_args")
.takes_value(true)
.multiple_values(true)
.value_hint(clap::ValueHint::CommandWithArguments),
)
.arg(
clap::Arg::new("user")
.short('u')
.long("user")
.value_hint(clap::ValueHint::Username),
)
.arg(
clap::Arg::new("host")
.short('h')
.long("host")
.value_hint(clap::ValueHint::Hostname),
)
.arg(
clap::Arg::new("url")
.long("url")
.value_hint(clap::ValueHint::Url),
)
.arg(
clap::Arg::new("email")
.long("email")
.value_hint(clap::ValueHint::EmailAddress),
)
}
pub fn assert_matches_path(expected_path: impl AsRef<std::path::Path>, cmd: clap::Command) {
let mut buf = vec![];
clap_mangen::Man::new(cmd).render(&mut buf).unwrap();
snapbox::Assert::new()
.action_env("SNAPSHOTS")
.matches_path(expected_path, buf);
}

View file

@ -1,29 +0,0 @@
use clap::{arg, Command};
use clap_mangen::Man;
use std::io;
#[test]
fn render_manpage() {
let cmd = Command::new("myapp")
.version("1.0")
.author("Kevin K. <kbknapp@gmail.com>")
.about("Does awesome things")
.long_about("With a longer description to help clarify some things.")
.after_help("This is an extra section added to the end of the manpage.")
.after_long_help("With even more text added.")
.arg(
arg!(-c --config <FILE> "Sets a custom config file")
.long_help("Some more text about how to set a custom config file")
.required(false)
.takes_value(true),
)
.arg(arg!([output] "Sets an optional output file").index(1))
.arg(arg!(-d --debug ... "Turn debugging information on"))
.subcommand(
Command::new("test")
.about("does testing things")
.arg(arg!(-l --list "Lists test values")),
);
Man::new(cmd).render(&mut io::sink()).unwrap();
}

50
clap_mangen/tests/roff.rs Normal file
View file

@ -0,0 +1,50 @@
mod common;
#[test]
fn basic() {
let name = "my-app";
let cmd = common::basic_command(name);
common::assert_matches_path("tests/snapshots/basic.bash.roff", cmd);
}
#[test]
fn feature_sample() {
let name = "my-app";
let cmd = common::feature_sample_command(name);
common::assert_matches_path("tests/snapshots/feature_sample.bash.roff", cmd);
}
#[test]
fn special_commands() {
let name = "my-app";
let cmd = common::special_commands_command(name);
common::assert_matches_path("tests/snapshots/special_commands.bash.roff", cmd);
}
#[test]
fn quoting() {
let name = "my-app";
let cmd = common::quoting_command(name);
common::assert_matches_path("tests/snapshots/quoting.bash.roff", cmd);
}
#[test]
fn aliases() {
let name = "my-app";
let cmd = common::aliases_command(name);
common::assert_matches_path("tests/snapshots/aliases.bash.roff", cmd);
}
#[test]
fn sub_subcommands() {
let name = "my-app";
let cmd = common::sub_subcommands_command(name);
common::assert_matches_path("tests/snapshots/sub_subcommands.bash.roff", cmd);
}
#[test]
fn value_hint() {
let name = "my-app";
let cmd = common::value_hint_command(name);
common::assert_matches_path("tests/snapshots/value_hint.bash.roff", cmd);
}

View file

@ -0,0 +1,26 @@
.ie /n(.g .ds Aq /(aq
.el .ds Aq '
.TH my-app 1 "my-app 3.0"
.SH NAME
my/-app /- testing bash completions
.SH SYNOPSIS
/fBmy/-app/fR [/fB/-h/fR|/fB/-/-help/fR] [/fB/-V/fR|/fB/-/-version/fR] [/fB/-f/fR|/fB/-/-flag/fR] [/fB/-o/fR|/fB/-/-option/fR] [/fIpositional/fR]
.SH DESCRIPTION
testing bash completions
.SH OPTIONS
.TP
/fB/-h/fR, /fB/-/-help/fR
Print help information
.TP
/fB/-V/fR, /fB/-/-version/fR
Print version information
.TP
/fB/-f/fR, /fB/-/-flag/fR
cmd flag
.TP
/fB/-o/fR, /fB/-/-option/fR
cmd option
.TP
.SH VERSION
v3.0

View file

@ -0,0 +1,25 @@
.ie /n(.g .ds Aq /(aq
.el .ds Aq '
.TH my-app 1 "my-app "
.SH NAME
my/-app
.SH SYNOPSIS
/fBmy/-app/fR [/fB/-h/fR|/fB/-/-help/fR] [/fB/-c /fR] [/fB/-v /fR] [/fIsubcommands/fR]
.SH DESCRIPTION
.SH OPTIONS
.TP
/fB/-h/fR, /fB/-/-help/fR
Print help information
.TP
/fB/-c/fR
.TP
/fB/-v/fR
.SH SUBCOMMANDS
.TP
my/-app/-test(1)
Subcommand
.TP
my/-app/-help(1)
Print this message or the help of the given subcommand(s)

View file

@ -0,0 +1,32 @@
.ie /n(.g .ds Aq /(aq
.el .ds Aq '
.TH my-app 1 "my-app 3.0"
.SH NAME
my/-app /- Tests completions
.SH SYNOPSIS
/fBmy/-app/fR [/fB/-h/fR|/fB/-/-help/fR] [/fB/-V/fR|/fB/-/-version/fR] [/fB/-c/fR|/fB/-/-config/fR] [/fIfile/fR] [/fIchoice/fR] [/fIsubcommands/fR]
.SH DESCRIPTION
Tests completions
.SH OPTIONS
.TP
/fB/-h/fR, /fB/-/-help/fR
Print help information
.TP
/fB/-V/fR, /fB/-/-version/fR
Print version information
.TP
/fB/-c/fR, /fB/-/-config/fR
some config file
.TP
some input file
.TP
.SH SUBCOMMANDS
.TP
my/-app/-test(1)
tests things
.TP
my/-app/-help(1)
Print this message or the help of the given subcommand(s)
.SH VERSION
v3.0

View file

@ -0,0 +1,57 @@
.ie /n(.g .ds Aq /(aq
.el .ds Aq '
.TH my-app 1 "my-app 3.0"
.SH NAME
my/-app
.SH SYNOPSIS
/fBmy/-app/fR [/fB/-h/fR|/fB/-/-help/fR] [/fB/-V/fR|/fB/-/-version/fR] [/fB/-/-single/-quotes/fR] [/fB/-/-double/-quotes/fR] [/fB/-/-backticks/fR] [/fB/-/-backslash/fR] [/fB/-/-brackets/fR] [/fB/-/-expansions/fR] [/fIsubcommands/fR]
.SH DESCRIPTION
.SH OPTIONS
.TP
/fB/-h/fR, /fB/-/-help/fR
Print help information
.TP
/fB/-V/fR, /fB/-/-version/fR
Print version information
.TP
/fB/-/-single/-quotes/fR
Can be /*(Aqalways/*(Aq, /*(Aqauto/*(Aq, or /*(Aqnever/*(Aq
.TP
/fB/-/-double/-quotes/fR
Can be "always", "auto", or "never"
.TP
/fB/-/-backticks/fR
For more information see `echo test`
.TP
/fB/-/-backslash/fR
Avoid /*(Aq//n/*(Aq
.TP
/fB/-/-brackets/fR
List packages [filter]
.TP
/fB/-/-expansions/fR
Execute the shell command with $SHELL
.SH SUBCOMMANDS
.TP
my/-app/-cmd/-single/-quotes(1)
Can be /*(Aqalways/*(Aq, /*(Aqauto/*(Aq, or /*(Aqnever/*(Aq
.TP
my/-app/-cmd/-double/-quotes(1)
Can be "always", "auto", or "never"
.TP
my/-app/-cmd/-backticks(1)
For more information see `echo test`
.TP
my/-app/-cmd/-backslash(1)
Avoid /*(Aq//n/*(Aq
.TP
my/-app/-cmd/-brackets(1)
List packages [filter]
.TP
my/-app/-cmd/-expansions(1)
Execute the shell command with $SHELL
.TP
my/-app/-help(1)
Print this message or the help of the given subcommand(s)
.SH VERSION
v3.0

View file

@ -0,0 +1,37 @@
.ie /n(.g .ds Aq /(aq
.el .ds Aq '
.TH my-app 1 "my-app 3.0"
.SH NAME
my/-app /- Tests completions
.SH SYNOPSIS
/fBmy/-app/fR [/fB/-h/fR|/fB/-/-help/fR] [/fB/-V/fR|/fB/-/-version/fR] [/fB/-c/fR|/fB/-/-config/fR] [/fIfile/fR] [/fIchoice/fR] [/fIsubcommands/fR]
.SH DESCRIPTION
Tests completions
.SH OPTIONS
.TP
/fB/-h/fR, /fB/-/-help/fR
Print help information
.TP
/fB/-V/fR, /fB/-/-version/fR
Print version information
.TP
/fB/-c/fR, /fB/-/-config/fR
some config file
.TP
some input file
.TP
.SH SUBCOMMANDS
.TP
my/-app/-test(1)
tests things
.TP
my/-app/-some_cmd(1)
tests other things
.TP
my/-app/-some/-cmd/-with/-hyphens(1)
.TP
my/-app/-help(1)
Print this message or the help of the given subcommand(s)
.SH VERSION
v3.0

View file

@ -0,0 +1,35 @@
.ie /n(.g .ds Aq /(aq
.el .ds Aq '
.TH my-app 1 "my-app 3.0"
.SH NAME
my/-app /- Tests completions
.SH SYNOPSIS
/fBmy/-app/fR [/fB/-h/fR|/fB/-/-help/fR] [/fB/-V/fR|/fB/-/-version/fR] [/fB/-c/fR|/fB/-/-config/fR] [/fIfile/fR] [/fIchoice/fR] [/fIsubcommands/fR]
.SH DESCRIPTION
Tests completions
.SH OPTIONS
.TP
/fB/-h/fR, /fB/-/-help/fR
Print help information
.TP
/fB/-V/fR, /fB/-/-version/fR
Print version information
.TP
/fB/-c/fR, /fB/-/-config/fR
some config file
.TP
some input file
.TP
.SH SUBCOMMANDS
.TP
my/-app/-test(1)
tests things
.TP
my/-app/-some_cmd(1)
top level subcommand
.TP
my/-app/-help(1)
Print this message or the help of the given subcommand(s)
.SH VERSION
v3.0

View file

@ -0,0 +1,53 @@
.ie /n(.g .ds Aq /(aq
.el .ds Aq '
.TH my-app 1 "my-app "
.SH NAME
my/-app
.SH SYNOPSIS
/fBmy/-app/fR [/fB/-/-help/fR] [/fB/-/-choice/fR] [/fB/-/-unknown/fR] [/fB/-/-other/fR] [/fB/-p/fR|/fB/-/-path/fR] [/fB/-f/fR|/fB/-/-file/fR] [/fB/-d/fR|/fB/-/-dir/fR] [/fB/-e/fR|/fB/-/-exe/fR] [/fB/-/-cmd/-name/fR] [/fB/-c/fR|/fB/-/-cmd/fR] [/fB/-u/fR|/fB/-/-user/fR] [/fB/-h/fR|/fB/-/-host/fR] [/fB/-/-url/fR] [/fB/-/-email/fR] [/fIcommand_with_args/fR]
.SH DESCRIPTION
.SH OPTIONS
.TP
/fB/-/-help/fR
Print help information
.TP
/fB/-/-choice/fR
.TP
/fB/-/-unknown/fR
.TP
/fB/-/-other/fR
.TP
/fB/-p/fR, /fB/-/-path/fR
.TP
/fB/-f/fR, /fB/-/-file/fR
.TP
/fB/-d/fR, /fB/-/-dir/fR
.TP
/fB/-e/fR, /fB/-/-exe/fR
.TP
/fB/-/-cmd/-name/fR
.TP
/fB/-c/fR, /fB/-/-cmd/fR
.TP
/fB/-u/fR, /fB/-/-user/fR
.TP
/fB/-h/fR, /fB/-/-host/fR
.TP
/fB/-/-url/fR
.TP
/fB/-/-email/fR
.TP