Merge pull request #5585 from shannmu/hidden_possible_values

feat(clap_complete): Support hiding possible values
This commit is contained in:
Ed Page 2024-07-19 11:37:42 -05:00 committed by GitHub
commit e142795de6
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 44 additions and 16 deletions

View file

@ -110,15 +110,14 @@ fn complete_arg(
completions.extend( completions.extend(
complete_arg_value(value.to_str().ok_or(value), arg, current_dir) complete_arg_value(value.to_str().ok_or(value), arg, current_dir)
.into_iter() .into_iter()
.map(|(os, help)| { .map(|comp| {
// HACK: Need better `OsStr` manipulation
CompletionCandidate::new(format!( CompletionCandidate::new(format!(
"--{}={}", "--{}={}",
flag, flag,
os.to_string_lossy() comp.get_content().to_string_lossy()
)) ))
.help(help) .help(comp.get_help().cloned())
.visible(true) .visible(comp.is_visible())
}), }),
); );
} }
@ -169,11 +168,7 @@ fn complete_arg(
.get_positionals() .get_positionals()
.find(|p| p.get_index() == Some(pos_index)) .find(|p| p.get_index() == Some(pos_index))
{ {
completions.extend( completions.extend(complete_arg_value(arg.to_value(), positional, current_dir).into_iter());
complete_arg_value(arg.to_value(), positional, current_dir)
.into_iter()
.map(|(os, help)| CompletionCandidate::new(os).help(help).visible(true)),
);
} }
if let Ok(value) = arg.to_value() { if let Ok(value) = arg.to_value() {
@ -191,7 +186,7 @@ fn complete_arg_value(
value: Result<&str, &OsStr>, value: Result<&str, &OsStr>,
arg: &clap::Arg, arg: &clap::Arg,
current_dir: Option<&std::path::Path>, current_dir: Option<&std::path::Path>,
) -> Vec<(OsString, Option<StyledStr>)> { ) -> Vec<CompletionCandidate> {
let mut values = Vec::new(); let mut values = Vec::new();
debug!("complete_arg_value: arg={arg:?}, value={value:?}"); debug!("complete_arg_value: arg={arg:?}, value={value:?}");
@ -199,8 +194,11 @@ fn complete_arg_value(
if let Ok(value) = value { if let Ok(value) = value {
values.extend(possible_values.into_iter().filter_map(|p| { values.extend(possible_values.into_iter().filter_map(|p| {
let name = p.get_name(); let name = p.get_name();
name.starts_with(value) name.starts_with(value).then(|| {
.then(|| (OsString::from(name), p.get_help().cloned())) CompletionCandidate::new(OsString::from(name))
.help(p.get_help().cloned())
.visible(!p.is_hide_set())
})
})); }));
} }
} else { } else {
@ -249,7 +247,7 @@ fn complete_path(
value_os: &OsStr, value_os: &OsStr,
current_dir: Option<&std::path::Path>, current_dir: Option<&std::path::Path>,
is_wanted: impl Fn(&std::path::Path) -> bool, is_wanted: impl Fn(&std::path::Path) -> bool,
) -> Vec<(OsString, Option<StyledStr>)> { ) -> Vec<CompletionCandidate> {
let mut completions = Vec::new(); let mut completions = Vec::new();
let current_dir = match current_dir { let current_dir = match current_dir {
@ -281,12 +279,20 @@ fn complete_path(
let path = entry.path(); let path = entry.path();
let mut suggestion = pathdiff::diff_paths(&path, current_dir).unwrap_or(path); let mut suggestion = pathdiff::diff_paths(&path, current_dir).unwrap_or(path);
suggestion.push(""); // Ensure trailing `/` suggestion.push(""); // Ensure trailing `/`
completions.push((suggestion.as_os_str().to_owned(), None)); completions.push(
CompletionCandidate::new(suggestion.as_os_str().to_owned())
.help(None)
.visible(true),
);
} else { } else {
let path = entry.path(); let path = entry.path();
if is_wanted(&path) { if is_wanted(&path) {
let suggestion = pathdiff::diff_paths(&path, current_dir).unwrap_or(path); let suggestion = pathdiff::diff_paths(&path, current_dir).unwrap_or(path);
completions.push((suggestion.as_os_str().to_owned(), None)); completions.push(
CompletionCandidate::new(suggestion.as_os_str().to_owned())
.help(None)
.visible(true),
);
} }
} }
} }

View file

@ -122,6 +122,28 @@ hello-world-foo"
); );
} }
#[test]
fn suggest_hidden_possible_value() {
let mut cmd = Command::new("exhaustive").arg(
clap::Arg::new("possible_value").long("test").value_parser([
PossibleValue::new("test-visible").help("Say hello to the world"),
PossibleValue::new("test-hidden")
.help("Say hello to the moon")
.hide(true),
]),
);
assert_data_eq!(
complete!(cmd, "--test=test"),
snapbox::str!["--test=test-visible\tSay hello to the world"]
);
assert_data_eq!(
complete!(cmd, "--test=test-h"),
snapbox::str!["--test=test-hidden\tSay hello to the moon"]
)
}
#[test] #[test]
fn suggest_hidden_long_flag_aliases() { fn suggest_hidden_long_flag_aliases() {
let mut cmd = Command::new("exhaustive") let mut cmd = Command::new("exhaustive")