mirror of
https://github.com/clap-rs/clap
synced 2025-01-18 23:53:54 +00:00
Merge pull request #5256 from Serock3/master
fix(clap_complete): Use bin name instead of package name for bash completions in subcommands
This commit is contained in:
commit
e1c3575044
11 changed files with 393 additions and 5 deletions
|
@ -18,6 +18,8 @@ impl Generator for Bash {
|
|||
.get_bin_name()
|
||||
.expect("crate::generate should have set the bin_name");
|
||||
|
||||
let fn_name = bin_name.replace('-', "__");
|
||||
|
||||
w!(
|
||||
buf,
|
||||
format!(
|
||||
|
@ -65,10 +67,10 @@ else
|
|||
fi
|
||||
",
|
||||
name = bin_name,
|
||||
cmd = bin_name.replace('-', "__"),
|
||||
cmd = fn_name,
|
||||
name_opts = all_options_for_path(cmd, bin_name),
|
||||
name_opts_details = option_details_for_path(cmd, bin_name),
|
||||
subcmds = all_subcommands(cmd),
|
||||
subcmds = all_subcommands(cmd, &fn_name),
|
||||
subcmd_details = subcommand_details(cmd)
|
||||
)
|
||||
.as_bytes()
|
||||
|
@ -76,7 +78,7 @@ fi
|
|||
}
|
||||
}
|
||||
|
||||
fn all_subcommands(cmd: &Command) -> String {
|
||||
fn all_subcommands(cmd: &Command, parent_fn_name: &str) -> String {
|
||||
debug!("all_subcommands");
|
||||
|
||||
fn add_command(
|
||||
|
@ -106,9 +108,8 @@ fn all_subcommands(cmd: &Command) -> String {
|
|||
}
|
||||
}
|
||||
let mut subcmds = vec![];
|
||||
let fn_name = cmd.get_name().replace('-', "__");
|
||||
for subcmd in cmd.get_subcommands() {
|
||||
add_command(&fn_name, subcmd, &mut subcmds);
|
||||
add_command(parent_fn_name, subcmd, &mut subcmds);
|
||||
}
|
||||
subcmds.sort();
|
||||
|
||||
|
|
110
clap_complete/tests/snapshots/custom_bin_name.bash
Normal file
110
clap_complete/tests/snapshots/custom_bin_name.bash
Normal file
|
@ -0,0 +1,110 @@
|
|||
_bin-name() {
|
||||
local i cur prev opts cmd
|
||||
COMPREPLY=()
|
||||
cur="${COMP_WORDS[COMP_CWORD]}"
|
||||
prev="${COMP_WORDS[COMP_CWORD-1]}"
|
||||
cmd=""
|
||||
opts=""
|
||||
|
||||
for i in ${COMP_WORDS[@]}
|
||||
do
|
||||
case "${cmd},${i}" in
|
||||
",$1")
|
||||
cmd="bin__name"
|
||||
;;
|
||||
bin__name,help)
|
||||
cmd="bin__name__help"
|
||||
;;
|
||||
bin__name,test)
|
||||
cmd="bin__name__test"
|
||||
;;
|
||||
bin__name__help,help)
|
||||
cmd="bin__name__help__help"
|
||||
;;
|
||||
bin__name__help,test)
|
||||
cmd="bin__name__help__test"
|
||||
;;
|
||||
*)
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
case "${cmd}" in
|
||||
bin__name)
|
||||
opts="-c -v -h --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
|
||||
;;
|
||||
bin__name__help)
|
||||
opts="test 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
|
||||
;;
|
||||
bin__name__help__help)
|
||||
opts=""
|
||||
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
|
||||
;;
|
||||
bin__name__help__test)
|
||||
opts=""
|
||||
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
|
||||
;;
|
||||
bin__name__test)
|
||||
opts="-d -c -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
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
if [[ "${BASH_VERSINFO[0]}" -eq 4 && "${BASH_VERSINFO[1]}" -ge 4 || "${BASH_VERSINFO[0]}" -gt 4 ]]; then
|
||||
complete -F _bin-name -o nosort -o bashdefault -o default bin-name
|
||||
else
|
||||
complete -F _bin-name -o bashdefault -o default bin-name
|
||||
fi
|
44
clap_complete/tests/snapshots/custom_bin_name.elvish
Normal file
44
clap_complete/tests/snapshots/custom_bin_name.elvish
Normal file
|
@ -0,0 +1,44 @@
|
|||
|
||||
use builtin;
|
||||
use str;
|
||||
|
||||
set edit:completion:arg-completer[bin-name] = {|@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 = 'bin-name'
|
||||
for word $words[1..-1] {
|
||||
if (str:has-prefix $word '-') {
|
||||
break
|
||||
}
|
||||
set command = $command';'$word
|
||||
}
|
||||
var completions = [
|
||||
&'bin-name'= {
|
||||
cand -c 'c'
|
||||
cand -v 'v'
|
||||
cand -h 'Print help'
|
||||
cand --help 'Print help'
|
||||
cand test 'Subcommand'
|
||||
cand help 'Print this message or the help of the given subcommand(s)'
|
||||
}
|
||||
&'bin-name;test'= {
|
||||
cand -d 'd'
|
||||
cand -c 'c'
|
||||
cand -h 'Print help'
|
||||
cand --help 'Print help'
|
||||
}
|
||||
&'bin-name;help'= {
|
||||
cand test 'Subcommand'
|
||||
cand help 'Print this message or the help of the given subcommand(s)'
|
||||
}
|
||||
&'bin-name;help;test'= {
|
||||
}
|
||||
&'bin-name;help;help'= {
|
||||
}
|
||||
]
|
||||
$completions[$command]
|
||||
}
|
10
clap_complete/tests/snapshots/custom_bin_name.fish
Normal file
10
clap_complete/tests/snapshots/custom_bin_name.fish
Normal file
|
@ -0,0 +1,10 @@
|
|||
complete -c bin-name -n "__fish_use_subcommand" -s c
|
||||
complete -c bin-name -n "__fish_use_subcommand" -s v
|
||||
complete -c bin-name -n "__fish_use_subcommand" -s h -l help -d 'Print help'
|
||||
complete -c bin-name -n "__fish_use_subcommand" -f -a "test" -d 'Subcommand'
|
||||
complete -c bin-name -n "__fish_use_subcommand" -f -a "help" -d 'Print this message or the help of the given subcommand(s)'
|
||||
complete -c bin-name -n "__fish_seen_subcommand_from test" -s d
|
||||
complete -c bin-name -n "__fish_seen_subcommand_from test" -s c
|
||||
complete -c bin-name -n "__fish_seen_subcommand_from test" -s h -l help -d 'Print help'
|
||||
complete -c bin-name -n "__fish_seen_subcommand_from help; and not __fish_seen_subcommand_from test; and not __fish_seen_subcommand_from help" -f -a "test" -d 'Subcommand'
|
||||
complete -c bin-name -n "__fish_seen_subcommand_from help; and not __fish_seen_subcommand_from test; and not __fish_seen_subcommand_from help" -f -a "help" -d 'Print this message or the help of the given subcommand(s)'
|
54
clap_complete/tests/snapshots/custom_bin_name.ps1
Normal file
54
clap_complete/tests/snapshots/custom_bin_name.ps1
Normal file
|
@ -0,0 +1,54 @@
|
|||
|
||||
using namespace System.Management.Automation
|
||||
using namespace System.Management.Automation.Language
|
||||
|
||||
Register-ArgumentCompleter -Native -CommandName 'bin-name' -ScriptBlock {
|
||||
param($wordToComplete, $commandAst, $cursorPosition)
|
||||
|
||||
$commandElements = $commandAst.CommandElements
|
||||
$command = @(
|
||||
'bin-name'
|
||||
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) {
|
||||
'bin-name' {
|
||||
[CompletionResult]::new('-c', 'c', [CompletionResultType]::ParameterName, 'c')
|
||||
[CompletionResult]::new('-v', 'v', [CompletionResultType]::ParameterName, 'v')
|
||||
[CompletionResult]::new('-h', 'h', [CompletionResultType]::ParameterName, 'Print help')
|
||||
[CompletionResult]::new('--help', 'help', [CompletionResultType]::ParameterName, 'Print help')
|
||||
[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
|
||||
}
|
||||
'bin-name;test' {
|
||||
[CompletionResult]::new('-d', 'd', [CompletionResultType]::ParameterName, 'd')
|
||||
[CompletionResult]::new('-c', 'c', [CompletionResultType]::ParameterName, 'c')
|
||||
[CompletionResult]::new('-h', 'h', [CompletionResultType]::ParameterName, 'Print help')
|
||||
[CompletionResult]::new('--help', 'help', [CompletionResultType]::ParameterName, 'Print help')
|
||||
break
|
||||
}
|
||||
'bin-name;help' {
|
||||
[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
|
||||
}
|
||||
'bin-name;help;test' {
|
||||
break
|
||||
}
|
||||
'bin-name;help;help' {
|
||||
break
|
||||
}
|
||||
})
|
||||
|
||||
$completions.Where{ $_.CompletionText -like "$wordToComplete*" } |
|
||||
Sort-Object -Property ListItemText
|
||||
}
|
104
clap_complete/tests/snapshots/custom_bin_name.zsh
Normal file
104
clap_complete/tests/snapshots/custom_bin_name.zsh
Normal file
|
@ -0,0 +1,104 @@
|
|||
#compdef bin-name
|
||||
|
||||
autoload -U is-at-least
|
||||
|
||||
_bin-name() {
|
||||
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[@]}" \
|
||||
'-c[]' \
|
||||
'(-c)-v[]' \
|
||||
'-h[Print help]' \
|
||||
'--help[Print help]' \
|
||||
":: :_bin-name_commands" \
|
||||
"*::: :->my-app" \
|
||||
&& ret=0
|
||||
case $state in
|
||||
(my-app)
|
||||
words=($line[1] "${words[@]}")
|
||||
(( CURRENT += 1 ))
|
||||
curcontext="${curcontext%:*:*}:bin-name-command-$line[1]:"
|
||||
case $line[1] in
|
||||
(test)
|
||||
_arguments "${_arguments_options[@]}" \
|
||||
'*-d[]' \
|
||||
'-c[]' \
|
||||
'-h[Print help]' \
|
||||
'--help[Print help]' \
|
||||
&& ret=0
|
||||
;;
|
||||
(help)
|
||||
_arguments "${_arguments_options[@]}" \
|
||||
":: :_bin-name__help_commands" \
|
||||
"*::: :->help" \
|
||||
&& ret=0
|
||||
|
||||
case $state in
|
||||
(help)
|
||||
words=($line[1] "${words[@]}")
|
||||
(( CURRENT += 1 ))
|
||||
curcontext="${curcontext%:*:*}:bin-name-help-command-$line[1]:"
|
||||
case $line[1] in
|
||||
(test)
|
||||
_arguments "${_arguments_options[@]}" \
|
||||
&& ret=0
|
||||
;;
|
||||
(help)
|
||||
_arguments "${_arguments_options[@]}" \
|
||||
&& ret=0
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
(( $+functions[_bin-name_commands] )) ||
|
||||
_bin-name_commands() {
|
||||
local commands; commands=(
|
||||
'test:Subcommand' \
|
||||
'help:Print this message or the help of the given subcommand(s)' \
|
||||
)
|
||||
_describe -t commands 'bin-name commands' commands "$@"
|
||||
}
|
||||
(( $+functions[_bin-name__help_commands] )) ||
|
||||
_bin-name__help_commands() {
|
||||
local commands; commands=(
|
||||
'test:Subcommand' \
|
||||
'help:Print this message or the help of the given subcommand(s)' \
|
||||
)
|
||||
_describe -t commands 'bin-name help commands' commands "$@"
|
||||
}
|
||||
(( $+functions[_bin-name__help__help_commands] )) ||
|
||||
_bin-name__help__help_commands() {
|
||||
local commands; commands=()
|
||||
_describe -t commands 'bin-name help help commands' commands "$@"
|
||||
}
|
||||
(( $+functions[_bin-name__help__test_commands] )) ||
|
||||
_bin-name__help__test_commands() {
|
||||
local commands; commands=()
|
||||
_describe -t commands 'bin-name help test commands' commands "$@"
|
||||
}
|
||||
(( $+functions[_bin-name__test_commands] )) ||
|
||||
_bin-name__test_commands() {
|
||||
local commands; commands=()
|
||||
_describe -t commands 'bin-name test commands' commands "$@"
|
||||
}
|
||||
|
||||
if [ "$funcstack[1]" = "_bin-name" ]; then
|
||||
_bin-name "$@"
|
||||
else
|
||||
compdef _bin-name bin-name
|
||||
fi
|
|
@ -72,6 +72,19 @@ fn sub_subcommands() {
|
|||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn custom_bin_name() {
|
||||
let name = "my-app";
|
||||
let bin_name = "bin-name";
|
||||
let cmd = common::basic_command(name);
|
||||
common::assert_matches_path(
|
||||
"tests/snapshots/custom_bin_name.bash",
|
||||
clap_complete::shells::Bash,
|
||||
cmd,
|
||||
bin_name,
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn value_hint() {
|
||||
let name = "my-app";
|
||||
|
|
|
@ -72,6 +72,19 @@ fn sub_subcommands() {
|
|||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn custom_bin_name() {
|
||||
let name = "my-app";
|
||||
let bin_name = "bin-name";
|
||||
let cmd = common::basic_command(name);
|
||||
common::assert_matches_path(
|
||||
"tests/snapshots/custom_bin_name.elvish",
|
||||
clap_complete::shells::Elvish,
|
||||
cmd,
|
||||
bin_name,
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn value_hint() {
|
||||
let name = "my-app";
|
||||
|
|
|
@ -72,6 +72,19 @@ fn sub_subcommands() {
|
|||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn custom_bin_name() {
|
||||
let name = "my-app";
|
||||
let bin_name = "bin-name";
|
||||
let cmd = common::basic_command(name);
|
||||
common::assert_matches_path(
|
||||
"tests/snapshots/custom_bin_name.fish",
|
||||
clap_complete::shells::Fish,
|
||||
cmd,
|
||||
bin_name,
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn value_hint() {
|
||||
let name = "my-app";
|
||||
|
|
|
@ -72,6 +72,19 @@ fn sub_subcommands() {
|
|||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn custom_bin_name() {
|
||||
let name = "my-app";
|
||||
let bin_name = "bin-name";
|
||||
let cmd = common::basic_command(name);
|
||||
common::assert_matches_path(
|
||||
"tests/snapshots/custom_bin_name.ps1",
|
||||
clap_complete::shells::PowerShell,
|
||||
cmd,
|
||||
bin_name,
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn value_hint() {
|
||||
let name = "my-app";
|
||||
|
|
|
@ -72,6 +72,19 @@ fn sub_subcommands() {
|
|||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn custom_bin_name() {
|
||||
let name = "my-app";
|
||||
let bin_name = "bin-name";
|
||||
let cmd = common::basic_command(name);
|
||||
common::assert_matches_path(
|
||||
"tests/snapshots/custom_bin_name.zsh",
|
||||
clap_complete::shells::Zsh,
|
||||
cmd,
|
||||
bin_name,
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn value_hint() {
|
||||
let name = "my-app";
|
||||
|
|
Loading…
Reference in a new issue