diff --git a/clap_complete/src/engine/complete.rs b/clap_complete/src/engine/complete.rs index fb0463e4708..9ed091b8b14 100644 --- a/clap_complete/src/engine/complete.rs +++ b/clap_complete/src/engine/complete.rs @@ -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)) @@ -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. @@ -434,7 +447,11 @@ fn shorts_and_visible_aliases(p: &clap::Command) -> Vec { 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()) }) diff --git a/clap_complete/tests/testsuite/engine.rs b/clap_complete/tests/testsuite/engine.rs index 8659cc38b31..59a5a64deaa 100644 --- a/clap_complete/tests/testsuite/engine.rs +++ b/clap_complete/tests/testsuite/engine.rs @@ -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"), @@ -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"), @@ -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"]); @@ -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]"), @@ -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]"), @@ -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]"), @@ -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]"), @@ -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]"), @@ -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]"), @@ -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 "#]] ); }