mirror of
https://github.com/clap-rs/clap
synced 2024-12-14 06:42:33 +00:00
Merge pull request #5740 from epage/complete-id
fix(complete): De-duplicate built-in candidates
This commit is contained in:
commit
3af629a141
7 changed files with 68 additions and 100 deletions
|
@ -8,6 +8,7 @@ use clap::builder::StyledStr;
|
|||
pub struct CompletionCandidate {
|
||||
value: OsString,
|
||||
help: Option<StyledStr>,
|
||||
id: Option<String>,
|
||||
hidden: bool,
|
||||
}
|
||||
|
||||
|
@ -27,6 +28,14 @@ impl CompletionCandidate {
|
|||
self
|
||||
}
|
||||
|
||||
/// Only first for a given Id is shown
|
||||
///
|
||||
/// To reduce the risk of conflicts, this should likely contain a namespace.
|
||||
pub fn id(mut self, id: Option<String>) -> Self {
|
||||
self.id = id;
|
||||
self
|
||||
}
|
||||
|
||||
/// Set the visibility of the completion candidate
|
||||
///
|
||||
/// Only shown when there is no visible candidate for completing the current argument.
|
||||
|
@ -60,6 +69,11 @@ impl CompletionCandidate {
|
|||
self.help.as_ref()
|
||||
}
|
||||
|
||||
/// Get the id used for de-duplicating
|
||||
pub fn get_id(&self) -> Option<&String> {
|
||||
self.id.as_ref()
|
||||
}
|
||||
|
||||
/// Get the visibility of the completion candidate
|
||||
pub fn is_hide_set(&self) -> bool {
|
||||
self.hidden
|
||||
|
|
|
@ -257,6 +257,14 @@ fn complete_arg(
|
|||
if completions.iter().any(|a| !a.is_hide_set()) {
|
||||
completions.retain(|a| !a.is_hide_set());
|
||||
}
|
||||
let mut seen_ids = std::collections::HashSet::new();
|
||||
completions.retain(move |a| {
|
||||
if let Some(id) = a.get_id().cloned() {
|
||||
seen_ids.insert(id)
|
||||
} else {
|
||||
true
|
||||
}
|
||||
});
|
||||
|
||||
Ok(completions)
|
||||
}
|
||||
|
@ -388,6 +396,7 @@ fn longs_and_visible_aliases(p: &clap::Command) -> Vec<CompletionCandidate> {
|
|||
longs.into_iter().map(|s| {
|
||||
CompletionCandidate::new(format!("--{}", s))
|
||||
.help(a.get_help().cloned())
|
||||
.id(Some(format!("arg::{}", a.get_id())))
|
||||
.hide(a.is_hide_set())
|
||||
})
|
||||
})
|
||||
|
@ -406,6 +415,7 @@ fn hidden_longs_aliases(p: &clap::Command) -> Vec<CompletionCandidate> {
|
|||
longs.into_iter().map(|s| {
|
||||
CompletionCandidate::new(format!("--{}", s))
|
||||
.help(a.get_help().cloned())
|
||||
.id(Some(format!("arg::{}", a.get_id())))
|
||||
.hide(true)
|
||||
})
|
||||
})
|
||||
|
@ -425,6 +435,7 @@ fn shorts_and_visible_aliases(p: &clap::Command) -> Vec<CompletionCandidate> {
|
|||
shorts.into_iter().map(|s| {
|
||||
CompletionCandidate::new(s.to_string())
|
||||
.help(a.get_help().cloned())
|
||||
.id(Some(format!("arg::{}", a.get_id())))
|
||||
.hide(a.is_hide_set())
|
||||
})
|
||||
})
|
||||
|
@ -458,11 +469,13 @@ fn subcommands(p: &clap::Command) -> Vec<CompletionCandidate> {
|
|||
.map(|s| {
|
||||
CompletionCandidate::new(s.to_string())
|
||||
.help(sc.get_about().cloned())
|
||||
.id(Some(format!("command::{}", sc.get_name())))
|
||||
.hide(sc.is_hide_set())
|
||||
})
|
||||
.chain(sc.get_aliases().map(|s| {
|
||||
CompletionCandidate::new(s.to_string())
|
||||
.help(sc.get_about().cloned())
|
||||
.id(Some(format!("command::{}", sc.get_name())))
|
||||
.hide(true)
|
||||
}))
|
||||
})
|
||||
|
|
|
@ -255,8 +255,8 @@ fn complete_dynamic_env_toplevel() {
|
|||
let input = "exhaustive \t\t";
|
||||
let expected = snapbox::str![[r#"
|
||||
%
|
||||
action help last quote --global --help -h
|
||||
alias hint pacman value --generate --version -V
|
||||
action help last quote --global --help
|
||||
alias hint pacman value --generate --version
|
||||
"#]];
|
||||
let actual = runtime.complete(input, &term).unwrap();
|
||||
assert_data_eq!(actual, expected);
|
||||
|
@ -275,10 +275,9 @@ fn complete_dynamic_env_quoted_help() {
|
|||
let input = "exhaustive quote \t\t";
|
||||
let expected = snapbox::str![[r#"
|
||||
%
|
||||
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
|
||||
cmd-backslash cmd-double-quotes escape-help --double-quotes --brackets --global
|
||||
cmd-backticks cmd-expansions help --backticks --expansions --help
|
||||
cmd-brackets cmd-single-quotes --single-quotes --backslash --choice --version
|
||||
"#]];
|
||||
let actual = runtime.complete(input, &term).unwrap();
|
||||
assert_data_eq!(actual, expected);
|
||||
|
|
|
@ -198,8 +198,8 @@ fn complete_dynamic_env_toplevel() {
|
|||
let expected = snapbox::str![[r#"
|
||||
% exhaustive --generate
|
||||
COMPLETING argument
|
||||
--generate --help -V action help last quote
|
||||
--global --version -h alias hint pacman value
|
||||
--generate --help action help last quote
|
||||
--global --version alias hint pacman value
|
||||
"#]];
|
||||
let actual = runtime.complete(input, &term).unwrap();
|
||||
assert_data_eq!(actual, expected);
|
||||
|
@ -219,10 +219,9 @@ fn complete_dynamic_env_quoted_help() {
|
|||
let expected = snapbox::str![[r#"
|
||||
% exhaustive quote --backslash
|
||||
COMPLETING argument
|
||||
--backslash --double-quotes --single-quotes cmd-backslash cmd-expansions
|
||||
--backticks --expansions --version cmd-backticks cmd-single-quotes
|
||||
--brackets --global -V cmd-brackets escape-help
|
||||
--choice --help -h cmd-double-quotes help
|
||||
--backslash --choice --global --version cmd-brackets cmd-single-quotes
|
||||
--backticks --double-quotes --help cmd-backslash cmd-double-quotes escape-help
|
||||
--brackets --expansions --single-quotes cmd-backticks cmd-expansions help
|
||||
"#]];
|
||||
let actual = runtime.complete(input, &term).unwrap();
|
||||
assert_data_eq!(actual, expected);
|
||||
|
|
|
@ -75,19 +75,12 @@ fn suggest_hidden_subcommand_and_aliases() {
|
|||
|
||||
assert_data_eq!(
|
||||
complete!(cmd, "test"),
|
||||
snapbox::str![[r#"
|
||||
test_visible
|
||||
test_visible-alias_visible
|
||||
"#]]
|
||||
snapbox::str!["test_visible"]
|
||||
);
|
||||
|
||||
assert_data_eq!(
|
||||
complete!(cmd, "test_h"),
|
||||
snapbox::str![[r#"
|
||||
test_hidden
|
||||
test_hidden-alias_hidden
|
||||
test_hidden-alias_visible
|
||||
"#]]
|
||||
snapbox::str!["test_hidden"]
|
||||
);
|
||||
|
||||
assert_data_eq!(
|
||||
|
@ -119,9 +112,7 @@ fn suggest_subcommand_aliases() {
|
|||
complete!(cmd, "hello"),
|
||||
snapbox::str![[r#"
|
||||
hello-moon
|
||||
hello-moon-foo
|
||||
hello-world
|
||||
hello-world-foo
|
||||
"#]],
|
||||
);
|
||||
}
|
||||
|
@ -167,19 +158,12 @@ fn suggest_hidden_long_flag_aliases() {
|
|||
|
||||
assert_data_eq!(
|
||||
complete!(cmd, "--test"),
|
||||
snapbox::str![[r#"
|
||||
--test_visible
|
||||
--test_visible-alias_visible
|
||||
"#]]
|
||||
snapbox::str!["--test_visible"]
|
||||
);
|
||||
|
||||
assert_data_eq!(
|
||||
complete!(cmd, "--test_h"),
|
||||
snapbox::str![[r#"
|
||||
--test_hidden
|
||||
--test_hidden-alias_visible
|
||||
--test_hidden-alias_hidden
|
||||
"#]]
|
||||
snapbox::str!["--test_hidden"]
|
||||
);
|
||||
|
||||
assert_data_eq!(
|
||||
|
@ -287,7 +271,6 @@ 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')
|
||||
"#]],
|
||||
);
|
||||
}
|
||||
|
@ -361,10 +344,6 @@ pos_c
|
|||
--stream
|
||||
--count
|
||||
--help Print help
|
||||
-F
|
||||
-S
|
||||
-c
|
||||
-h Print help
|
||||
"#]]
|
||||
);
|
||||
|
||||
|
@ -433,9 +412,6 @@ val3
|
|||
--certain-num
|
||||
--uncertain-num
|
||||
--help Print help
|
||||
-Y
|
||||
-N
|
||||
-h Print help
|
||||
"#]]
|
||||
);
|
||||
|
||||
|
@ -457,9 +433,6 @@ val3
|
|||
--certain-num
|
||||
--uncertain-num
|
||||
--help Print help
|
||||
-Y
|
||||
-N
|
||||
-h Print help
|
||||
"#]]
|
||||
);
|
||||
|
||||
|
@ -469,9 +442,6 @@ val3
|
|||
--certain-num
|
||||
--uncertain-num
|
||||
--help Print help
|
||||
-Y
|
||||
-N
|
||||
-h Print help
|
||||
"#]]
|
||||
);
|
||||
|
||||
|
@ -499,9 +469,6 @@ val3
|
|||
--certain-num
|
||||
--uncertain-num
|
||||
--help Print help
|
||||
-Y
|
||||
-N
|
||||
-h Print help
|
||||
"#]]
|
||||
);
|
||||
|
||||
|
@ -523,9 +490,6 @@ val3
|
|||
--certain-num
|
||||
--uncertain-num
|
||||
--help Print help
|
||||
-Y
|
||||
-N
|
||||
-h Print help
|
||||
"#]]
|
||||
);
|
||||
|
||||
|
@ -535,9 +499,6 @@ val3
|
|||
--certain-num
|
||||
--uncertain-num
|
||||
--help Print help
|
||||
-Y
|
||||
-N
|
||||
-h Print help
|
||||
"#]]
|
||||
);
|
||||
}
|
||||
|
@ -775,8 +736,6 @@ pos_b
|
|||
pos_c
|
||||
--format
|
||||
--help Print help
|
||||
-F
|
||||
-h Print help
|
||||
"#]]
|
||||
);
|
||||
|
||||
|
@ -794,8 +753,6 @@ pos_c
|
|||
snapbox::str![[r#"
|
||||
--format
|
||||
--help Print help
|
||||
-F
|
||||
-h Print help
|
||||
"#]]
|
||||
);
|
||||
|
||||
|
@ -935,8 +892,6 @@ b_pos
|
|||
c_pos
|
||||
--delimiter
|
||||
--help Print help
|
||||
-D
|
||||
-h Print help
|
||||
"#]]);
|
||||
|
||||
assert_data_eq!(complete!(cmd, " -- a_pos,[TAB]"), snapbox::str![[r#"
|
||||
|
@ -1028,16 +983,12 @@ fn suggest_positional_long_allow_hyphen() {
|
|||
pos_b
|
||||
--format
|
||||
--help Print help
|
||||
-F
|
||||
-h Print help
|
||||
"#]]
|
||||
);
|
||||
assert_data_eq!(complete!(cmd, "-F --json --pos_a [TAB]"), snapbox::str![[r#"
|
||||
pos_b
|
||||
--format
|
||||
--help Print help
|
||||
-F
|
||||
-h Print help
|
||||
"#]]);
|
||||
|
||||
assert_data_eq!(
|
||||
|
@ -1076,15 +1027,11 @@ fn suggest_positional_short_allow_hyphen() {
|
|||
pos_b
|
||||
--format
|
||||
--help Print help
|
||||
-F
|
||||
-h Print help
|
||||
"#]]);
|
||||
assert_data_eq!(complete!(cmd, "-F --json -a [TAB]"), snapbox::str![[r#"
|
||||
pos_b
|
||||
--format
|
||||
--help Print help
|
||||
-F
|
||||
-h Print help
|
||||
"#]]);
|
||||
|
||||
assert_data_eq!(
|
||||
|
@ -1125,30 +1072,20 @@ pos-a
|
|||
pos-b
|
||||
pos-c
|
||||
--required-flag
|
||||
--required-flag2
|
||||
--optional-flag
|
||||
--2optional-flag
|
||||
--long-flag
|
||||
--help Print help
|
||||
-r
|
||||
-o
|
||||
-s
|
||||
-h Print help
|
||||
"#]]
|
||||
);
|
||||
assert_data_eq!(
|
||||
complete!(cmd, "-[TAB]"),
|
||||
snapbox::str![[r#"
|
||||
--required-flag
|
||||
--required-flag2
|
||||
--optional-flag
|
||||
--2optional-flag
|
||||
--long-flag
|
||||
--help Print help
|
||||
-r
|
||||
-o
|
||||
-s
|
||||
-h Print help
|
||||
"#]]
|
||||
);
|
||||
}
|
||||
|
|
|
@ -192,11 +192,10 @@ fn complete_dynamic_env_toplevel() {
|
|||
let input = "exhaustive \t\t";
|
||||
let expected = snapbox::str![[r#"
|
||||
% 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)
|
||||
action last --global (everywhere)
|
||||
alias pacman --generate (generate)
|
||||
help (Print this message or the help of the given subcommand(s)) quote --help (Print help)
|
||||
hint value --version (Print version)
|
||||
"#]];
|
||||
let actual = runtime.complete(input, &term).unwrap();
|
||||
assert_data_eq!(actual, expected);
|
||||
|
@ -215,16 +214,24 @@ fn complete_dynamic_env_quoted_help() {
|
|||
let input = "exhaustive quote \t\t";
|
||||
let expected = snapbox::str![[r#"
|
||||
% exhaustive quote
|
||||
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)
|
||||
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))
|
||||
--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)
|
||||
"#]];
|
||||
let actual = runtime.complete(input, &term).unwrap();
|
||||
assert_data_eq!(actual, expected);
|
||||
|
|
|
@ -185,8 +185,8 @@ fn complete_dynamic_env_toplevel() {
|
|||
let input = "exhaustive \t\t";
|
||||
let expected = snapbox::str![[r#"
|
||||
% exhaustive
|
||||
--generate --help -V action help last quote
|
||||
--global --version -h alias hint pacman value
|
||||
--generate --help action help last quote
|
||||
--global --version alias hint pacman value
|
||||
"#]];
|
||||
let actual = runtime.complete(input, &term).unwrap();
|
||||
assert_data_eq!(actual, expected);
|
||||
|
@ -205,10 +205,9 @@ fn complete_dynamic_env_quoted_help() {
|
|||
let input = "exhaustive quote \t\t";
|
||||
let expected = snapbox::str![[r#"
|
||||
% exhaustive quote
|
||||
--backslash --double-quotes --single-quotes cmd-backslash cmd-expansions
|
||||
--backticks --expansions --version cmd-backticks cmd-single-quotes
|
||||
--brackets --global -V cmd-brackets escape-help
|
||||
--choice --help -h cmd-double-quotes help
|
||||
--backslash --choice --global --version cmd-brackets cmd-single-quotes
|
||||
--backticks --double-quotes --help cmd-backslash cmd-double-quotes escape-help
|
||||
--brackets --expansions --single-quotes cmd-backticks cmd-expansions help
|
||||
"#]];
|
||||
let actual = runtime.complete(input, &term).unwrap();
|
||||
assert_data_eq!(actual, expected);
|
||||
|
|
Loading…
Reference in a new issue