mirror of
https://github.com/clap-rs/clap
synced 2025-03-04 07:17:26 +00:00
fix(help): Do not propagate global args to help
This prevents global args from showing in help completions, since help completions should only suggest subcommands. Adds tests to ensure the args still show in the generated help messages of subcommands.
This commit is contained in:
parent
1f3df00388
commit
eec047a6f6
8 changed files with 118 additions and 30 deletions
|
@ -39,7 +39,7 @@ _my-app() {
|
|||
return 0
|
||||
;;
|
||||
my__app__help)
|
||||
opts="-c test help"
|
||||
opts="test help"
|
||||
if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then
|
||||
COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
|
||||
return 0
|
||||
|
@ -53,7 +53,7 @@ _my-app() {
|
|||
return 0
|
||||
;;
|
||||
my__app__help__help)
|
||||
opts="-c"
|
||||
opts=""
|
||||
if [[ ${cur} == -* || ${COMP_CWORD} -eq 3 ]] ; then
|
||||
COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
|
||||
return 0
|
||||
|
@ -67,7 +67,7 @@ _my-app() {
|
|||
return 0
|
||||
;;
|
||||
my__app__help__test)
|
||||
opts="-c"
|
||||
opts=""
|
||||
if [[ ${cur} == -* || ${COMP_CWORD} -eq 3 ]] ; then
|
||||
COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
|
||||
return 0
|
||||
|
|
|
@ -32,15 +32,12 @@ set edit:completion:arg-completer[my-app] = {|@words|
|
|||
cand --help 'Print help information'
|
||||
}
|
||||
&'my-app;help'= {
|
||||
cand -c 'c'
|
||||
cand test 'Subcommand'
|
||||
cand help 'Print this message or the help of the given subcommand(s)'
|
||||
}
|
||||
&'my-app;help;test'= {
|
||||
cand -c 'c'
|
||||
}
|
||||
&'my-app;help;help'= {
|
||||
cand -c 'c'
|
||||
}
|
||||
]
|
||||
$completions[$command]
|
||||
|
|
|
@ -6,8 +6,5 @@ complete -c my-app -n "__fish_use_subcommand" -f -a "help" -d 'Print this messag
|
|||
complete -c my-app -n "__fish_seen_subcommand_from test" -s d
|
||||
complete -c my-app -n "__fish_seen_subcommand_from test" -s c
|
||||
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 help; and not __fish_seen_subcommand_from test; and not __fish_seen_subcommand_from help" -s c
|
||||
complete -c my-app -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 my-app -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)'
|
||||
complete -c my-app -n "__fish_seen_subcommand_from help; and __fish_seen_subcommand_from test" -s c
|
||||
complete -c my-app -n "__fish_seen_subcommand_from help; and __fish_seen_subcommand_from help" -s c
|
||||
|
|
|
@ -37,17 +37,14 @@ Register-ArgumentCompleter -Native -CommandName 'my-app' -ScriptBlock {
|
|||
break
|
||||
}
|
||||
'my-app;help' {
|
||||
[CompletionResult]::new('-c', 'c', [CompletionResultType]::ParameterName, 'c')
|
||||
[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;help;test' {
|
||||
[CompletionResult]::new('-c', 'c', [CompletionResultType]::ParameterName, 'c')
|
||||
break
|
||||
}
|
||||
'my-app;help;help' {
|
||||
[CompletionResult]::new('-c', 'c', [CompletionResultType]::ParameterName, 'c')
|
||||
break
|
||||
}
|
||||
})
|
||||
|
|
|
@ -38,7 +38,6 @@ _arguments "${_arguments_options[@]}" /
|
|||
;;
|
||||
(help)
|
||||
_arguments "${_arguments_options[@]}" /
|
||||
'*-c[]' /
|
||||
":: :_my-app__help_commands" /
|
||||
"*::: :->help" /
|
||||
&& ret=0
|
||||
|
@ -51,12 +50,10 @@ _arguments "${_arguments_options[@]}" /
|
|||
case $line[1] in
|
||||
(test)
|
||||
_arguments "${_arguments_options[@]}" /
|
||||
'*-c[]' /
|
||||
&& ret=0
|
||||
;;
|
||||
(help)
|
||||
_arguments "${_arguments_options[@]}" /
|
||||
'*-c[]' /
|
||||
&& ret=0
|
||||
;;
|
||||
esac
|
||||
|
|
|
@ -26,25 +26,10 @@ const completion: Fig.Spec = {
|
|||
{
|
||||
name: "test",
|
||||
description: "Subcommand",
|
||||
options: [
|
||||
{
|
||||
name: "-c",
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "help",
|
||||
description: "Print this message or the help of the given subcommand(s)",
|
||||
options: [
|
||||
{
|
||||
name: "-c",
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
options: [
|
||||
{
|
||||
name: "-c",
|
||||
},
|
||||
],
|
||||
},
|
||||
|
|
|
@ -4070,7 +4070,17 @@ impl Command {
|
|||
pub(crate) fn _propagate_global_args(&mut self) {
|
||||
debug!("Command::_propagate_global_args:{}", self.name);
|
||||
|
||||
let autogenerated_help_subcommand = !self.is_disable_help_subcommand_set();
|
||||
|
||||
for sc in &mut self.subcommands {
|
||||
if sc.get_name() == "help" && autogenerated_help_subcommand {
|
||||
// Avoid propagating args to the autogenerated help subtrees used in completion.
|
||||
// This prevents args from showing up during help completions like
|
||||
// `myapp help subcmd <TAB>`, which should only suggest subcommands and not args,
|
||||
// while still allowing args to show up properly on the generated help message.
|
||||
continue;
|
||||
}
|
||||
|
||||
for a in self.args.args().filter(|a| a.is_global_set()) {
|
||||
if sc.find(&a.id).is_some() {
|
||||
debug!(
|
||||
|
|
|
@ -2097,6 +2097,111 @@ Arguments:
|
|||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn global_args_should_show_on_toplevel_help_message() {
|
||||
static HELP: &str = "myapp\x20
|
||||
|
||||
Usage:
|
||||
myapp [OPTIONS] [SUBCOMMAND]
|
||||
|
||||
Subcommands:
|
||||
subcmd\x20\x20\x20\x20
|
||||
help Print this message or the help of the given subcommand(s)
|
||||
|
||||
Options:
|
||||
-g, --some-global <someglobal>\x20\x20\x20\x20
|
||||
-h, --help Print help information
|
||||
";
|
||||
|
||||
let cmd = Command::new("myapp")
|
||||
.arg(
|
||||
Arg::new("someglobal")
|
||||
.short('g')
|
||||
.long("some-global")
|
||||
.global(true),
|
||||
)
|
||||
.subcommand(Command::new("subcmd").subcommand(Command::new("multi").version("1.0")));
|
||||
|
||||
utils::assert_output(cmd, "myapp help", HELP, false);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn global_args_should_not_show_on_help_message_for_help_help() {
|
||||
static HELP_HELP: &str = "myapp-help\x20
|
||||
Print this message or the help of the given subcommand(s)
|
||||
|
||||
Usage:
|
||||
myapp help [SUBCOMMAND]...
|
||||
|
||||
Arguments:
|
||||
[SUBCOMMAND]... The subcommand whose help message to display
|
||||
";
|
||||
|
||||
let cmd = Command::new("myapp")
|
||||
.arg(
|
||||
Arg::new("someglobal")
|
||||
.short('g')
|
||||
.long("some-global")
|
||||
.global(true),
|
||||
)
|
||||
.subcommand(Command::new("subcmd").subcommand(Command::new("multi").version("1.0")));
|
||||
|
||||
utils::assert_output(cmd, "myapp help help", HELP_HELP, false);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn global_args_should_show_on_help_message_for_subcommand() {
|
||||
static HELP_SUBCMD: &str = "myapp-subcmd\x20
|
||||
|
||||
Usage:
|
||||
myapp subcmd [OPTIONS] [SUBCOMMAND]
|
||||
|
||||
Subcommands:
|
||||
multi\x20\x20\x20\x20
|
||||
help Print this message or the help of the given subcommand(s)
|
||||
|
||||
Options:
|
||||
-g, --some-global <someglobal>\x20\x20\x20\x20
|
||||
-h, --help Print help information
|
||||
";
|
||||
|
||||
let cmd = Command::new("myapp")
|
||||
.arg(
|
||||
Arg::new("someglobal")
|
||||
.short('g')
|
||||
.long("some-global")
|
||||
.global(true),
|
||||
)
|
||||
.subcommand(Command::new("subcmd").subcommand(Command::new("multi").version("1.0")));
|
||||
|
||||
utils::assert_output(cmd, "myapp help subcmd", HELP_SUBCMD, false);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn global_args_should_show_on_help_message_for_nested_subcommand() {
|
||||
static HELP_SUB_SUBCMD: &str = "myapp-subcmd-multi 1.0
|
||||
|
||||
Usage:
|
||||
myapp subcmd multi [OPTIONS]
|
||||
|
||||
Options:
|
||||
-g, --some-global <someglobal>\x20\x20\x20\x20
|
||||
-h, --help Print help information
|
||||
-V, --version Print version information
|
||||
";
|
||||
|
||||
let cmd = Command::new("myapp")
|
||||
.arg(
|
||||
Arg::new("someglobal")
|
||||
.short('g')
|
||||
.long("some-global")
|
||||
.global(true),
|
||||
)
|
||||
.subcommand(Command::new("subcmd").subcommand(Command::new("multi").version("1.0")));
|
||||
|
||||
utils::assert_output(cmd, "myapp help subcmd multi", HELP_SUB_SUBCMD, false);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn option_usage_order() {
|
||||
static OPTION_USAGE_ORDER: &str = "order
|
||||
|
|
Loading…
Add table
Reference in a new issue