Skip to content

Commit 59bf26d

Browse files
shannmuepage
authored andcommitted
feat(clap_complete): Support delimiter values in native completions
1 parent ccecab3 commit 59bf26d

File tree

2 files changed

+82
-10
lines changed

2 files changed

+82
-10
lines changed

clap_complete/src/dynamic/complete.rs

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -262,6 +262,9 @@ fn complete_arg_value(
262262
let mut values = Vec::new();
263263
debug!("complete_arg_value: arg={arg:?}, value={value:?}");
264264

265+
let (prefix, value) =
266+
rsplit_delimiter(value, arg.get_value_delimiter()).unwrap_or((None, value));
267+
265268
let value_os = match value {
266269
Ok(value) => OsStr::new(value),
267270
Err(value_os) => value_os,
@@ -316,9 +319,28 @@ fn complete_arg_value(
316319
values.sort();
317320
}
318321

322+
if let Some(prefix) = prefix {
323+
values = values
324+
.into_iter()
325+
.map(|comp| comp.add_prefix(prefix))
326+
.collect();
327+
}
319328
values
320329
}
321330

331+
fn rsplit_delimiter<'s, 'o>(
332+
value: Result<&'s str, &'o OsStr>,
333+
delimiter: Option<char>,
334+
) -> Option<(Option<&'s str>, Result<&'s str, &'o OsStr>)> {
335+
let delimiter = delimiter?;
336+
let value = value.ok()?;
337+
let pos = value.rfind(delimiter)?;
338+
let (prefix, value) = value
339+
.split_at_checked(pos + delimiter.len_utf8())
340+
.expect("since delimiter was found, it is within bounds");
341+
Some((Some(prefix), Ok(value)))
342+
}
343+
322344
fn complete_path(
323345
value_os: &OsStr,
324346
current_dir: Option<&std::path::Path>,

clap_complete/tests/testsuite/dynamic.rs

Lines changed: 60 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -661,18 +661,35 @@ tab"
661661
snapbox::str!["--delimiter=comma"]
662662
);
663663

664-
assert_data_eq!(complete!(cmd, "--delimiter comma,[TAB]"), snapbox::str![""]);
664+
assert_data_eq!(
665+
complete!(cmd, "--delimiter comma,[TAB]"),
666+
snapbox::str![
667+
"comma,comma
668+
comma,space
669+
comma,tab"
670+
]
671+
);
665672

666-
assert_data_eq!(complete!(cmd, "--delimiter=comma,[TAB]"), snapbox::str![""]);
673+
assert_data_eq!(
674+
complete!(cmd, "--delimiter=comma,[TAB]"),
675+
snapbox::str![
676+
"--delimiter=comma,comma
677+
--delimiter=comma,space
678+
--delimiter=comma,tab
679+
--delimiter=comma,a_pos
680+
--delimiter=comma,b_pos
681+
--delimiter=comma,c_pos"
682+
]
683+
);
667684

668685
assert_data_eq!(
669686
complete!(cmd, "--delimiter comma,s[TAB]"),
670-
snapbox::str![""]
687+
snapbox::str!["comma,space"]
671688
);
672689

673690
assert_data_eq!(
674691
complete!(cmd, "--delimiter=comma,s[TAB]"),
675-
snapbox::str![""]
692+
snapbox::str!["--delimiter=comma,space"]
676693
);
677694

678695
assert_data_eq!(
@@ -697,13 +714,36 @@ tab"
697714

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

700-
assert_data_eq!(complete!(cmd, "-D comma,[TAB]"), snapbox::str![""]);
717+
assert_data_eq!(
718+
complete!(cmd, "-D comma,[TAB]"),
719+
snapbox::str![
720+
"comma,comma
721+
comma,space
722+
comma,tab"
723+
]
724+
);
701725

702-
assert_data_eq!(complete!(cmd, "-D=comma,[TAB]"), snapbox::str![""]);
726+
assert_data_eq!(
727+
complete!(cmd, "-D=comma,[TAB]"),
728+
snapbox::str![
729+
"-D=comma,comma
730+
-D=comma,space
731+
-D=comma,tab
732+
-D=comma,a_pos
733+
-D=comma,b_pos
734+
-D=comma,c_pos"
735+
]
736+
);
703737

704-
assert_data_eq!(complete!(cmd, "-D comma,s[TAB]"), snapbox::str![""]);
738+
assert_data_eq!(
739+
complete!(cmd, "-D comma,s[TAB]"),
740+
snapbox::str!["comma,space"]
741+
);
705742

706-
assert_data_eq!(complete!(cmd, "-D=comma,s[TAB]"), snapbox::str![""]);
743+
assert_data_eq!(
744+
complete!(cmd, "-D=comma,s[TAB]"),
745+
snapbox::str!["-D=comma,space"]
746+
);
707747

708748
assert_data_eq!(
709749
complete!(cmd, "-- [TAB]"),
@@ -718,9 +758,19 @@ c_pos"
718758
]
719759
);
720760

721-
assert_data_eq!(complete!(cmd, " -- a_pos,[TAB]"), snapbox::str![""]);
761+
assert_data_eq!(
762+
complete!(cmd, " -- a_pos,[TAB]"),
763+
snapbox::str![
764+
"a_pos,a_pos
765+
a_pos,b_pos
766+
a_pos,c_pos"
767+
]
768+
);
722769

723-
assert_data_eq!(complete!(cmd, "-- a_pos,b[TAB]"), snapbox::str![""]);
770+
assert_data_eq!(
771+
complete!(cmd, "-- a_pos,b[TAB]"),
772+
snapbox::str!["a_pos,b_pos"]
773+
);
724774
}
725775

726776
fn complete(cmd: &mut Command, args: impl AsRef<str>, current_dir: Option<&Path>) -> String {

0 commit comments

Comments
 (0)