Skip to content

Commit 3a222de

Browse files
committed
fix(complete): Fix path completion in bash
Fix #5239
1 parent 62a5ace commit 3a222de

File tree

4 files changed

+48
-17
lines changed

4 files changed

+48
-17
lines changed

clap_complete/src/shells/bash.rs

Lines changed: 35 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -168,29 +168,48 @@ fn option_details_for_path(cmd: &Command, path: &str) -> String {
168168
let mut opts = vec![String::new()];
169169

170170
for o in p.get_opts() {
171+
let compopt = match o.get_value_hint() {
172+
ValueHint::FilePath => Some("compopt -o filenames"),
173+
_ => None,
174+
};
175+
171176
if let Some(longs) = o.get_long_and_visible_aliases() {
172177
opts.extend(longs.iter().map(|long| {
173-
format!(
174-
"--{})
175-
COMPREPLY=({})
176-
return 0
177-
;;",
178-
long,
179-
vals_for(o)
180-
)
178+
let mut v = vec![
179+
format!("--{})", long),
180+
format!("COMPREPLY=({})", vals_for(o)),
181+
];
182+
183+
if let Some(copt) = compopt {
184+
v.extend([
185+
r#"if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then"#.to_string(),
186+
format!(" {}", copt),
187+
"fi".to_string(),
188+
]);
189+
}
190+
191+
v.extend(["return 0", ";;"].iter().map(|s| s.to_string()));
192+
v.join("\n ")
181193
}));
182194
}
183195

184196
if let Some(shorts) = o.get_short_and_visible_aliases() {
185197
opts.extend(shorts.iter().map(|short| {
186-
format!(
187-
"-{})
188-
COMPREPLY=({})
189-
return 0
190-
;;",
191-
short,
192-
vals_for(o)
193-
)
198+
let mut v = vec![
199+
format!("-{})", short),
200+
format!("COMPREPLY=({})", vals_for(o)),
201+
];
202+
203+
if let Some(copt) = compopt {
204+
v.extend([
205+
r#"if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then"#.to_string(),
206+
format!(" {}", copt),
207+
"fi".to_string(),
208+
]);
209+
}
210+
211+
v.extend(["return 0", ";;"].iter().map(|s| s.to_string()));
212+
v.join("\n ")
194213
}));
195214
}
196215
}

clap_complete/tests/snapshots/home/static/exhaustive/bash/.bashrc

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -554,10 +554,16 @@ _exhaustive() {
554554
;;
555555
--file)
556556
COMPREPLY=($(compgen -f "${cur}"))
557+
if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then
558+
compopt -o filenames
559+
fi
557560
return 0
558561
;;
559562
-f)
560563
COMPREPLY=($(compgen -f "${cur}"))
564+
if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then
565+
compopt -o filenames
566+
fi
561567
return 0
562568
;;
563569
--dir)

clap_complete/tests/snapshots/value_hint.bash

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,10 +47,16 @@ _my-app() {
4747
;;
4848
--file)
4949
COMPREPLY=($(compgen -f "${cur}"))
50+
if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then
51+
compopt -o filenames
52+
fi
5053
return 0
5154
;;
5255
-f)
5356
COMPREPLY=($(compgen -f "${cur}"))
57+
if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then
58+
compopt -o filenames
59+
fi
5460
return 0
5561
;;
5662
--dir)

clap_complete/tests/testsuite/bash.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -164,7 +164,7 @@ fn complete() {
164164

165165
// Issue 5239 (https://github.com/clap-rs/clap/issues/5239)
166166
let input = "exhaustive hint --file test\t";
167-
let expected = "exhaustive hint --file test % exhaustive hint --file tests ";
167+
let expected = "exhaustive hint --file test % exhaustive hint --file tests/";
168168
let actual = runtime.complete(input, &term).unwrap();
169169
snapbox::assert_eq(expected, actual);
170170

0 commit comments

Comments
 (0)