fix(complete): Fix path completion in bash

Fix #5239
This commit is contained in:
sudotac 2023-12-03 17:13:57 +09:00
parent 62a5ace9f1
commit 3a222def22
4 changed files with 48 additions and 17 deletions

View file

@ -168,29 +168,48 @@ fn option_details_for_path(cmd: &Command, path: &str) -> String {
let mut opts = vec![String::new()]; let mut opts = vec![String::new()];
for o in p.get_opts() { for o in p.get_opts() {
let compopt = match o.get_value_hint() {
ValueHint::FilePath => Some("compopt -o filenames"),
_ => None,
};
if let Some(longs) = o.get_long_and_visible_aliases() { if let Some(longs) = o.get_long_and_visible_aliases() {
opts.extend(longs.iter().map(|long| { opts.extend(longs.iter().map(|long| {
format!( let mut v = vec![
"--{}) format!("--{})", long),
COMPREPLY=({}) format!("COMPREPLY=({})", vals_for(o)),
return 0 ];
;;",
long, if let Some(copt) = compopt {
vals_for(o) v.extend([
) r#"if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then"#.to_string(),
format!(" {}", copt),
"fi".to_string(),
]);
}
v.extend(["return 0", ";;"].iter().map(|s| s.to_string()));
v.join("\n ")
})); }));
} }
if let Some(shorts) = o.get_short_and_visible_aliases() { if let Some(shorts) = o.get_short_and_visible_aliases() {
opts.extend(shorts.iter().map(|short| { opts.extend(shorts.iter().map(|short| {
format!( let mut v = vec![
"-{}) format!("-{})", short),
COMPREPLY=({}) format!("COMPREPLY=({})", vals_for(o)),
return 0 ];
;;",
short, if let Some(copt) = compopt {
vals_for(o) v.extend([
) r#"if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then"#.to_string(),
format!(" {}", copt),
"fi".to_string(),
]);
}
v.extend(["return 0", ";;"].iter().map(|s| s.to_string()));
v.join("\n ")
})); }));
} }
} }

View file

@ -554,10 +554,16 @@ _exhaustive() {
;; ;;
--file) --file)
COMPREPLY=($(compgen -f "${cur}")) COMPREPLY=($(compgen -f "${cur}"))
if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then
compopt -o filenames
fi
return 0 return 0
;; ;;
-f) -f)
COMPREPLY=($(compgen -f "${cur}")) COMPREPLY=($(compgen -f "${cur}"))
if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then
compopt -o filenames
fi
return 0 return 0
;; ;;
--dir) --dir)

View file

@ -47,10 +47,16 @@ _my-app() {
;; ;;
--file) --file)
COMPREPLY=($(compgen -f "${cur}")) COMPREPLY=($(compgen -f "${cur}"))
if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then
compopt -o filenames
fi
return 0 return 0
;; ;;
-f) -f)
COMPREPLY=($(compgen -f "${cur}")) COMPREPLY=($(compgen -f "${cur}"))
if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then
compopt -o filenames
fi
return 0 return 0
;; ;;
--dir) --dir)

View file

@ -164,7 +164,7 @@ fn complete() {
// Issue 5239 (https://github.com/clap-rs/clap/issues/5239) // Issue 5239 (https://github.com/clap-rs/clap/issues/5239)
let input = "exhaustive hint --file test\t"; let input = "exhaustive hint --file test\t";
let expected = "exhaustive hint --file test % exhaustive hint --file tests "; let expected = "exhaustive hint --file test % exhaustive hint --file tests/";
let actual = runtime.complete(input, &term).unwrap(); let actual = runtime.complete(input, &term).unwrap();
snapbox::assert_eq(expected, actual); snapbox::assert_eq(expected, actual);