Skip to content

Commit

Permalink
fix(clap_complete): Fix support for -abcd bar completion
Browse files Browse the repository at this point in the history
  • Loading branch information
shannmu committed Jun 30, 2024
1 parent 46dcc90 commit fb43187
Show file tree
Hide file tree
Showing 2 changed files with 84 additions and 30 deletions.
67 changes: 37 additions & 30 deletions clap_complete/src/dynamic/completer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -110,40 +110,47 @@ pub fn complete(
}
} else if let Some(short) = arg.to_short() {
let mut short = short.clone();
let opt = short.next_flag();

if let Some(Ok(opt)) = opt {
let opt = current_cmd.get_arguments().find(|a| {
let shorts = a.get_short_and_visible_aliases();
let is_find = shorts.map(|v| {
let mut iter = v.into_iter();
let c = iter.find(|c| *c == opt);
c.is_some()
loop {
if let Some(Ok(opt)) = short.next_flag() {
let opt = current_cmd.get_arguments().find(|a| {
let shorts = a.get_short_and_visible_aliases();
let is_find = shorts.map(|v| {
let mut iter = v.into_iter();
let c = iter.find(|c| *c == opt);
c.is_some()
});
is_find.unwrap_or(false)
});
is_find.unwrap_or(false)
});
state = opt
.map(|o| match o.get_action() {
clap::ArgAction::Set | clap::ArgAction::Append => {
if short.next_value_os().is_some() {
let mut flag = false;
state = opt
.map(|o| match o.get_action() {
clap::ArgAction::Set | clap::ArgAction::Append => {
flag = true;
if short.next_value_os().is_some() {
ParseState::ValueDone
} else {
ParseState::Opt(o.clone())
}
}
clap::ArgAction::SetTrue | clap::ArgAction::SetFalse => {
ParseState::ValueDone
} else {
ParseState::Opt(o.clone())
}
}
clap::ArgAction::SetTrue | clap::ArgAction::SetFalse => {
ParseState::ValueDone
}
clap::ArgAction::Count => ParseState::ValueDone,
clap::ArgAction::Version => ParseState::ValueDone,
clap::ArgAction::Help
| clap::ArgAction::HelpShort
| clap::ArgAction::HelpLong => ParseState::ValueDone,
_ => ParseState::ValueDone,
})
.unwrap_or(ParseState::ValueDone)
} else {
state = ParseState::ValueDone
clap::ArgAction::Count => ParseState::ValueDone,
clap::ArgAction::Version => ParseState::ValueDone,
clap::ArgAction::Help
| clap::ArgAction::HelpShort
| clap::ArgAction::HelpLong => ParseState::ValueDone,
_ => ParseState::ValueDone,
})
.unwrap_or(ParseState::ValueDone);
if flag {
break;
}
} else {
state = ParseState::ValueDone;
break;
}
}
} else {
pos_index += 1;
Expand Down
47 changes: 47 additions & 0 deletions clap_complete/tests/testsuite/dynamic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,12 @@ fn suggest_argument_value() {
.short('F')
.value_parser(["json", "yaml", "toml"]),
)
.arg(
clap::Arg::new("count")
.long("count")
.short('c')
.action(clap::ArgAction::Count),
)
.args_conflicts_with_subcommands(true);

let testdir = snapbox::dir::DirRoot::mutable_temp().unwrap();
Expand Down Expand Up @@ -213,6 +219,47 @@ toml"
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, "-chi [TAB]", current_dir = Some(testdir_path)),
snapbox::str![
"a_file
b_file
c_dir/
d_dir/"
]
);

assert_data_eq!(
complete!(cmd, "-chi a[TAB]", current_dir = Some(testdir_path)),
snapbox::str!["a_file"],
);

assert_data_eq!(
complete!(cmd, "-chF [TAB]"),
snapbox::str![
"json
yaml
toml"
]
);

assert_data_eq!(complete!(cmd, "-chF j[TAB]"), snapbox::str!["json"]);

// NOTE: Treat `F` as a value of `-i`, so pressing [TAB] will complete other arguments and subcommands.
assert_data_eq!(
complete!(cmd, "-ciF [TAB]"),
snapbox::str![
"--input
--format
--count
--help Print help
-i
-F
-c
-h Print help"
]
)
}

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

0 comments on commit fb43187

Please sign in to comment.