fix(complete): Prioritize subcommands, positionals over flags

This commit is contained in:
Ed Page 2024-09-20 10:21:19 -05:00
parent d32b1fc52d
commit 2bd2c1262e
4 changed files with 59 additions and 69 deletions

View file

@ -146,6 +146,17 @@ fn complete_arg(
match state {
ParseState::ValueDone => {
if let Ok(value) = arg.to_value() {
completions.extend(complete_subcommand(value, cmd));
}
if let Some(positional) = cmd
.get_positionals()
.find(|p| p.get_index() == Some(pos_index))
{
completions.extend(complete_arg_value(arg.to_value(), positional, current_dir));
}
if let Some((flag, value)) = arg.to_long() {
if let Ok(flag) = flag {
if let Some(value) = value {
@ -219,17 +230,6 @@ fn complete_arg(
}
}
}
if let Some(positional) = cmd
.get_positionals()
.find(|p| p.get_index() == Some(pos_index))
{
completions.extend(complete_arg_value(arg.to_value(), positional, current_dir));
}
if let Ok(value) = arg.to_value() {
completions.extend(complete_subcommand(value, cmd));
}
}
ParseState::Pos(..) => {
if let Some(positional) = cmd

View file

@ -255,8 +255,8 @@ fn complete_dynamic_env_toplevel() {
let input = "exhaustive \t\t";
let expected = snapbox::str![[r#"
%
--global --help -h action help last quote
--generate --version -V alias hint pacman value
action help last quote --global --help -h
alias hint pacman value --generate --version -V
"#]];
let actual = runtime.complete(input, &term).unwrap();
assert_data_eq!(actual, expected);
@ -275,10 +275,10 @@ fn complete_dynamic_env_quoted_help() {
let input = "exhaustive quote \t\t";
let expected = snapbox::str![[r#"
%
--single-quotes --brackets --help cmd-backslash cmd-expansions
--double-quotes --expansions --version cmd-backticks cmd-single-quotes
--backticks --choice -h cmd-brackets escape-help
--backslash --global -V cmd-double-quotes help
cmd-backslash cmd-expansions --single-quotes --brackets --help
cmd-backticks cmd-single-quotes --double-quotes --expansions --version
cmd-brackets escape-help --backticks --choice -h
cmd-double-quotes help --backslash --global -V
"#]];
let actual = runtime.complete(input, &term).unwrap();
assert_data_eq!(actual, expected);

View file

@ -283,11 +283,11 @@ fn suggest_subcommand_positional() {
assert_data_eq!(
complete!(cmd, "hello-world [TAB]"),
snapbox::str![[r#"
--help Print help (see more with '--help')
-h Print help (see more with '--help')
hello-world Say hello to the world
hello-moon
goodbye-world
--help Print help (see more with '--help')
-h Print help (see more with '--help')
"#]],
);
}
@ -354,6 +354,9 @@ toml
assert_data_eq!(
complete!(cmd, "--format toml [TAB]"),
snapbox::str![[r#"
pos_a
pos_b
pos_c
--format
--stream
--count
@ -362,9 +365,6 @@ toml
-S
-c
-h Print help
pos_a
pos_b
pos_c
"#]]
);
@ -770,13 +770,13 @@ pos_c
assert_data_eq!(
complete!(cmd, "--format json pos_1 [TAB]"),
snapbox::str![[r#"
pos_a
pos_b
pos_c
--format
--help Print help
-F
-h Print help
pos_a
pos_b
pos_c
"#]]
);
@ -870,12 +870,12 @@ comma,tab
"#]]);
assert_data_eq!(complete!(cmd, "--delimiter=comma,[TAB]"), snapbox::str![[r#"
--delimiter=comma,comma
--delimiter=comma,space
--delimiter=comma,tab
--delimiter=comma,a_pos
--delimiter=comma,b_pos
--delimiter=comma,c_pos
--delimiter=comma,comma
--delimiter=comma,space
--delimiter=comma,tab
"#]]);
assert_data_eq!(
@ -911,12 +911,12 @@ comma,tab
"#]]);
assert_data_eq!(complete!(cmd, "-D=comma,[TAB]"), snapbox::str![[r#"
-D=comma,comma
-D=comma,space
-D=comma,tab
-D=comma,a_pos
-D=comma,b_pos
-D=comma,c_pos
-D=comma,comma
-D=comma,space
-D=comma,tab
"#]]);
assert_data_eq!(
@ -930,13 +930,13 @@ comma,tab
);
assert_data_eq!(complete!(cmd, "-- [TAB]"), snapbox::str![[r#"
a_pos
b_pos
c_pos
--delimiter
--help Print help
-D
-h Print help
a_pos
b_pos
c_pos
"#]]);
assert_data_eq!(complete!(cmd, " -- a_pos,[TAB]"), snapbox::str![[r#"
@ -1025,19 +1025,19 @@ fn suggest_positional_long_allow_hyphen() {
assert_data_eq!(
complete!(cmd, "--format --json --pos_a [TAB]"),
snapbox::str![[r#"
pos_b
--format
--help Print help
-F
-h Print help
pos_b
"#]]
);
assert_data_eq!(complete!(cmd, "-F --json --pos_a [TAB]"), snapbox::str![[r#"
pos_b
--format
--help Print help
-F
-h Print help
pos_b
"#]]);
assert_data_eq!(
@ -1073,18 +1073,18 @@ fn suggest_positional_short_allow_hyphen() {
);
assert_data_eq!(complete!(cmd, "--format --json -a [TAB]"), snapbox::str![[r#"
pos_b
--format
--help Print help
-F
-h Print help
pos_b
"#]]);
assert_data_eq!(complete!(cmd, "-F --json -a [TAB]"), snapbox::str![[r#"
pos_b
--format
--help Print help
-F
-h Print help
pos_b
"#]]);
assert_data_eq!(
@ -1119,6 +1119,11 @@ fn sort_and_filter() {
assert_data_eq!(
complete!(cmd, " [TAB]"),
snapbox::str![[r#"
help Print this message or the help of the given subcommand(s)
sub
pos-a
pos-b
pos-c
--required-flag
--required-flag2
--optional-flag
@ -1129,11 +1134,6 @@ fn sort_and_filter() {
-o
-s
-h Print help
pos-a
pos-b
pos-c
help Print this message or the help of the given subcommand(s)
sub
"#]]
);
assert_data_eq!(

View file

@ -191,12 +191,12 @@ fn complete_dynamic_env_toplevel() {
let input = "exhaustive \t\t";
let expected = snapbox::str![[r#"
% exhaustive --global
--global (everywhere) -V (Print version) last
--generate (generate) action pacman
--help (Print help) alias quote
--version (Print version) help (Print this message or the help of the given subcommand(s)) value
-h (Print help) hint
% exhaustive action
action pacman --help (Print help)
alias quote --version (Print version)
help (Print this message or the help of the given subcommand(s)) value -h (Print help)
hint --global (everywhere) -V (Print version)
last --generate (generate)
"#]];
let actual = runtime.complete(input, &term).unwrap();
assert_data_eq!(actual, expected);
@ -215,26 +215,16 @@ fn complete_dynamic_env_quoted_help() {
let input = "exhaustive quote \t\t";
let expected = snapbox::str![[r#"
% exhaustive quote
--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)
--choice
--global (everywhere)
--help (Print help (see more with '--help'))
--version (Print version)
-h (Print help (see more with '--help'))
-V (Print version)
cmd-backslash (Avoid '/n')
cmd-backticks (For more information see `echo test`)
cmd-brackets (List packages [filter])
cmd-double-quotes (Can be "always", "auto", or "never")
cmd-expansions (Execute the shell command with $SHELL)
cmd-single-quotes (Can be 'always', 'auto', or 'never')
escape-help (/tab "')
help (Print this message or the help of the given subcommand(s))
cmd-backslash (Avoid '/n') --backticks (For more information see `echo test`)
cmd-backticks (For more information see `echo test`) --backslash (Avoid '/n')
cmd-brackets (List packages [filter]) --brackets (List packages [filter])
cmd-double-quotes (Can be "always", "auto", or "never") --expansions (Execute the shell command with $SHELL)
cmd-expansions (Execute the shell command with $SHELL) --choice
cmd-single-quotes (Can be 'always', 'auto', or 'never') --global (everywhere)
escape-help (/tab "') --help (Print help (see more with '--help'))
help (Print this message or the help of the given subcommand(s)) --version (Print version)
--single-quotes (Can be 'always', 'auto', or 'never') -h (Print help (see more with '--help'))
--double-quotes (Can be "always", "auto", or "never") -V (Print version)
"#]];
let actual = runtime.complete(input, &term).unwrap();
assert_data_eq!(actual, expected);