Skip to content

Commit

Permalink
Merge pull request #5741 from epage/complete-short
Browse files Browse the repository at this point in the history
fix(complete): When completing -[TAB], prioritize shorts
  • Loading branch information
epage committed Sep 20, 2024
2 parents 3af629a + cd6280f commit 2450ca7
Show file tree
Hide file tree
Showing 2 changed files with 128 additions and 69 deletions.
61 changes: 39 additions & 22 deletions clap_complete/src/engine/complete.rs
Original file line number Diff line number Diff line change
Expand Up @@ -157,7 +157,40 @@ fn complete_arg(
completions.extend(complete_arg_value(arg.to_value(), positional, current_dir));
}

if let Some((flag, value)) = arg.to_long() {
if arg.is_empty() {
completions.extend(longs_and_visible_aliases(cmd));
completions.extend(hidden_longs_aliases(cmd));

let dash_or_arg = if arg.is_empty() {
"-".into()
} else {
arg.to_value_os().to_string_lossy()
};
completions.extend(
shorts_and_visible_aliases(cmd)
.into_iter()
.map(|comp| comp.add_prefix(dash_or_arg.to_string())),
);
} else if arg.is_stdio() {
// HACK: Assuming knowledge of is_stdio
let dash_or_arg = if arg.is_empty() {
"-".into()
} else {
arg.to_value_os().to_string_lossy()
};
completions.extend(
shorts_and_visible_aliases(cmd)
.into_iter()
.map(|comp| comp.add_prefix(dash_or_arg.to_string())),
);

completions.extend(longs_and_visible_aliases(cmd));
completions.extend(hidden_longs_aliases(cmd));
} else if arg.is_escape() {
// HACK: Assuming knowledge of is_escape
completions.extend(longs_and_visible_aliases(cmd));
completions.extend(hidden_longs_aliases(cmd));
} else if let Some((flag, value)) = arg.to_long() {
if let Ok(flag) = flag {
if let Some(value) = value {
if let Some(arg) = cmd.get_arguments().find(|a| a.get_long() == Some(flag))
Expand All @@ -172,31 +205,11 @@ fn complete_arg(
completions.extend(longs_and_visible_aliases(cmd).into_iter().filter(
|comp| comp.get_value().starts_with(format!("--{}", flag).as_str()),
));

completions.extend(hidden_longs_aliases(cmd).into_iter().filter(|comp| {
comp.get_value().starts_with(format!("--{}", flag).as_str())
}));
}
}
} else if arg.is_escape() || arg.is_stdio() || arg.is_empty() {
// HACK: Assuming knowledge of is_escape / is_stdio
completions.extend(longs_and_visible_aliases(cmd));

completions.extend(hidden_longs_aliases(cmd));
}

if arg.is_empty() || arg.is_stdio() {
let dash_or_arg = if arg.is_empty() {
"-".into()
} else {
arg.to_value_os().to_string_lossy()
};
// HACK: Assuming knowledge of is_stdio
completions.extend(
shorts_and_visible_aliases(cmd)
.into_iter()
.map(|comp| comp.add_prefix(dash_or_arg.to_string())),
);
} else if let Some(short) = arg.to_short() {
if !short.is_negative_number() {
// Find the first takes_values option.
Expand Down Expand Up @@ -434,7 +447,11 @@ fn shorts_and_visible_aliases(p: &clap::Command) -> Vec<CompletionCandidate> {
a.get_short_and_visible_aliases().map(|shorts| {
shorts.into_iter().map(|s| {
CompletionCandidate::new(s.to_string())
.help(a.get_help().cloned())
.help(
a.get_help()
.cloned()
.or_else(|| a.get_long().map(|long| format!("--{long}").into())),
)
.id(Some(format!("arg::{}", a.get_id())))
.hide(a.is_hide_set())
})
Expand Down
136 changes: 89 additions & 47 deletions clap_complete/tests/testsuite/engine.rs
Original file line number Diff line number Diff line change
Expand Up @@ -73,15 +73,9 @@ fn suggest_hidden_subcommand_and_aliases() {
.hide(true),
);

assert_data_eq!(
complete!(cmd, "test"),
snapbox::str!["test_visible"]
);
assert_data_eq!(complete!(cmd, "test"), snapbox::str!["test_visible"]);

assert_data_eq!(
complete!(cmd, "test_h"),
snapbox::str!["test_hidden"]
);
assert_data_eq!(complete!(cmd, "test_h"), snapbox::str!["test_hidden"]);

assert_data_eq!(
complete!(cmd, "test_hidden-alias_h"),
Expand Down Expand Up @@ -156,15 +150,9 @@ fn suggest_hidden_long_flag_aliases() {
.hide(true),
);

assert_data_eq!(
complete!(cmd, "--test"),
snapbox::str!["--test_visible"]
);
assert_data_eq!(complete!(cmd, "--test"), snapbox::str!["--test_visible"]);

assert_data_eq!(
complete!(cmd, "--test_h"),
snapbox::str!["--test_hidden"]
);
assert_data_eq!(complete!(cmd, "--test_h"), snapbox::str!["--test_hidden"]);

assert_data_eq!(
complete!(cmd, "--test_visible-alias_h"),
Expand Down Expand Up @@ -801,17 +789,23 @@ fn suggest_delimiter_values() {
.value_delimiter(','),
);

assert_data_eq!(complete!(cmd, "--delimiter [TAB]"), snapbox::str![[r#"
assert_data_eq!(
complete!(cmd, "--delimiter [TAB]"),
snapbox::str![[r#"
comma
space
tab
"#]]);
"#]]
);

assert_data_eq!(complete!(cmd, "--delimiter=[TAB]"), snapbox::str![[r#"
assert_data_eq!(
complete!(cmd, "--delimiter=[TAB]"),
snapbox::str![[r#"
--delimiter=comma
--delimiter=space
--delimiter=tab
"#]]);
"#]]
);

assert_data_eq!(complete!(cmd, "--delimiter c[TAB]"), snapbox::str!["comma"]);

Expand All @@ -820,20 +814,26 @@ tab
snapbox::str!["--delimiter=comma"]
);

assert_data_eq!(complete!(cmd, "--delimiter comma,[TAB]"), snapbox::str![[r#"
assert_data_eq!(
complete!(cmd, "--delimiter comma,[TAB]"),
snapbox::str![[r#"
comma,comma
comma,space
comma,tab
"#]]);
"#]]
);

assert_data_eq!(complete!(cmd, "--delimiter=comma,[TAB]"), snapbox::str![[r#"
assert_data_eq!(
complete!(cmd, "--delimiter=comma,[TAB]"),
snapbox::str![[r#"
--delimiter=comma,a_pos
--delimiter=comma,b_pos
--delimiter=comma,c_pos
--delimiter=comma,comma
--delimiter=comma,space
--delimiter=comma,tab
"#]]);
"#]]
);

assert_data_eq!(
complete!(cmd, "--delimiter comma,s[TAB]"),
Expand All @@ -845,36 +845,48 @@ comma,tab
snapbox::str!["--delimiter=comma,space"]
);

assert_data_eq!(complete!(cmd, "-D [TAB]"), snapbox::str![[r#"
assert_data_eq!(
complete!(cmd, "-D [TAB]"),
snapbox::str![[r#"
comma
space
tab
"#]]);
"#]]
);

assert_data_eq!(complete!(cmd, "-D=[TAB]"), snapbox::str![[r#"
assert_data_eq!(
complete!(cmd, "-D=[TAB]"),
snapbox::str![[r#"
-D=comma
-D=space
-D=tab
"#]]);
"#]]
);

assert_data_eq!(complete!(cmd, "-D c[TAB]"), snapbox::str!["comma"]);

assert_data_eq!(complete!(cmd, "-D=c[TAB]"), snapbox::str!["-D=comma"]);

assert_data_eq!(complete!(cmd, "-D comma,[TAB]"), snapbox::str![[r#"
assert_data_eq!(
complete!(cmd, "-D comma,[TAB]"),
snapbox::str![[r#"
comma,comma
comma,space
comma,tab
"#]]);
"#]]
);

assert_data_eq!(complete!(cmd, "-D=comma,[TAB]"), snapbox::str![[r#"
assert_data_eq!(
complete!(cmd, "-D=comma,[TAB]"),
snapbox::str![[r#"
-D=comma,a_pos
-D=comma,b_pos
-D=comma,c_pos
-D=comma,comma
-D=comma,space
-D=comma,tab
"#]]);
"#]]
);

assert_data_eq!(
complete!(cmd, "-D comma,s[TAB]"),
Expand All @@ -886,19 +898,25 @@ comma,tab
snapbox::str!["-D=comma,space"]
);

assert_data_eq!(complete!(cmd, "-- [TAB]"), snapbox::str![[r#"
assert_data_eq!(
complete!(cmd, "-- [TAB]"),
snapbox::str![[r#"
a_pos
b_pos
c_pos
--delimiter
--help Print help
"#]]);
"#]]
);

assert_data_eq!(complete!(cmd, " -- a_pos,[TAB]"), snapbox::str![[r#"
assert_data_eq!(
complete!(cmd, " -- a_pos,[TAB]"),
snapbox::str![[r#"
a_pos,a_pos
a_pos,b_pos
a_pos,c_pos
"#]]);
"#]]
);

assert_data_eq!(
complete!(cmd, "-- a_pos,b[TAB]"),
Expand All @@ -923,17 +941,23 @@ fn suggest_allow_hyphen() {
assert_data_eq!(complete!(cmd, "--format --t[TAB]"), snapbox::str!["--toml"]);
assert_data_eq!(complete!(cmd, "-F --t[TAB]"), snapbox::str!["--toml"]);

assert_data_eq!(complete!(cmd, "--format --[TAB]"), snapbox::str![[r#"
assert_data_eq!(
complete!(cmd, "--format --[TAB]"),
snapbox::str![[r#"
--json
--toml
--yaml
"#]]);
"#]]
);

assert_data_eq!(complete!(cmd, "-F --[TAB]"), snapbox::str![[r#"
assert_data_eq!(
complete!(cmd, "-F --[TAB]"),
snapbox::str![[r#"
--json
--toml
--yaml
"#]]);
"#]]
);

assert_data_eq!(
complete!(cmd, "--format --json --j[TAB]"),
Expand Down Expand Up @@ -985,11 +1009,14 @@ pos_b
--help Print help
"#]]
);
assert_data_eq!(complete!(cmd, "-F --json --pos_a [TAB]"), snapbox::str![[r#"
assert_data_eq!(
complete!(cmd, "-F --json --pos_a [TAB]"),
snapbox::str![[r#"
pos_b
--format
--help Print help
"#]]);
"#]]
);

assert_data_eq!(
complete!(cmd, "--format --json --pos_a p[TAB]"),
Expand Down Expand Up @@ -1023,16 +1050,22 @@ fn suggest_positional_short_allow_hyphen() {
.value_parser(["pos_b"]),
);

assert_data_eq!(complete!(cmd, "--format --json -a [TAB]"), snapbox::str![[r#"
assert_data_eq!(
complete!(cmd, "--format --json -a [TAB]"),
snapbox::str![[r#"
pos_b
--format
--help Print help
"#]]);
assert_data_eq!(complete!(cmd, "-F --json -a [TAB]"), snapbox::str![[r#"
"#]]
);
assert_data_eq!(
complete!(cmd, "-F --json -a [TAB]"),
snapbox::str![[r#"
pos_b
--format
--help Print help
"#]]);
"#]]
);

assert_data_eq!(
complete!(cmd, "--format --json -a p[TAB]"),
Expand Down Expand Up @@ -1081,11 +1114,20 @@ pos-c
assert_data_eq!(
complete!(cmd, "-[TAB]"),
snapbox::str![[r#"
-r --required-flag
-o --optional-flag
-s
-h Print help
--long-flag
"#]]
);
assert_data_eq!(
complete!(cmd, "--[TAB]"),
snapbox::str![[r#"
--required-flag
--optional-flag
--long-flag
--help Print help
-s
"#]]
);
}
Expand Down

0 comments on commit 2450ca7

Please sign in to comment.