mirror of
https://github.com/clap-rs/clap
synced 2024-12-04 18:19:13 +00:00
feat(complete): Native support for hyphen values
This commit is contained in:
parent
1d97c293ba
commit
b7cfbdcf96
2 changed files with 59 additions and 21 deletions
|
@ -59,6 +59,13 @@ pub fn complete(
|
|||
} else if arg.is_escape() {
|
||||
is_escaped = true;
|
||||
} else if let Some((flag, value)) = arg.to_long() {
|
||||
if let ParseState::Opt((opt, count)) = current_state {
|
||||
if opt.is_allow_hyphen_values_set() {
|
||||
next_state = parse_opt(opt, count);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if let Ok(flag) = flag {
|
||||
let opt = current_cmd.get_arguments().find(|a| {
|
||||
let longs = a.get_long_and_visible_aliases();
|
||||
|
@ -69,18 +76,32 @@ pub fn complete(
|
|||
});
|
||||
is_find.unwrap_or(false)
|
||||
});
|
||||
if opt.map(|o| o.get_action().takes_values()).unwrap_or(false) {
|
||||
if value.is_none() {
|
||||
next_state = ParseState::Opt((opt.unwrap(), 1));
|
||||
|
||||
if let Some(opt) = opt {
|
||||
if opt.get_action().takes_values() && value.is_none() {
|
||||
next_state = ParseState::Opt((opt, 1));
|
||||
};
|
||||
} else if pos_allows_hyphen(current_cmd, pos_index) {
|
||||
(next_state, pos_index) =
|
||||
parse_positional(current_cmd, pos_index, is_escaped, current_state);
|
||||
}
|
||||
}
|
||||
} else if let Some(short) = arg.to_short() {
|
||||
if let ParseState::Opt((opt, count)) = current_state {
|
||||
if opt.is_allow_hyphen_values_set() {
|
||||
next_state = parse_opt(opt, count);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
let (_, takes_value_opt, mut short) = parse_shortflags(current_cmd, short);
|
||||
if let Some(opt) = takes_value_opt {
|
||||
if short.next_value_os().is_none() {
|
||||
next_state = ParseState::Opt((opt, 1));
|
||||
}
|
||||
} else if pos_allows_hyphen(current_cmd, pos_index) {
|
||||
(next_state, pos_index) =
|
||||
parse_positional(current_cmd, pos_index, is_escaped, current_state);
|
||||
}
|
||||
} else {
|
||||
match current_state {
|
||||
|
@ -88,14 +109,7 @@ pub fn complete(
|
|||
(next_state, pos_index) =
|
||||
parse_positional(current_cmd, pos_index, is_escaped, current_state);
|
||||
}
|
||||
|
||||
ParseState::Opt((opt, count)) => {
|
||||
let range = opt.get_num_args().expect("built");
|
||||
let max = range.max_values();
|
||||
if count < max {
|
||||
next_state = ParseState::Opt((opt, count + 1));
|
||||
}
|
||||
}
|
||||
ParseState::Opt((opt, count)) => next_state = parse_opt(opt, count),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -546,3 +560,21 @@ fn parse_positional<'a>(
|
|||
),
|
||||
}
|
||||
}
|
||||
|
||||
/// Parse optional flag argument. Return new state
|
||||
fn parse_opt(opt: &clap::Arg, count: usize) -> ParseState<'_> {
|
||||
let range = opt.get_num_args().expect("built");
|
||||
let max = range.max_values();
|
||||
if count < max {
|
||||
ParseState::Opt((opt, count + 1))
|
||||
} else {
|
||||
ParseState::ValueDone
|
||||
}
|
||||
}
|
||||
|
||||
fn pos_allows_hyphen(cmd: &clap::Command, pos_index: usize) -> bool {
|
||||
cmd.get_positionals()
|
||||
.find(|a| a.get_index() == Some(pos_index))
|
||||
.map(|p| p.is_allow_hyphen_values_set())
|
||||
.unwrap_or(false)
|
||||
}
|
||||
|
|
|
@ -1018,10 +1018,13 @@ fn suggest_allow_hyhpen() {
|
|||
|
||||
assert_data_eq!(
|
||||
complete!(cmd, "--format --json --j[TAB]"),
|
||||
snapbox::str![""]
|
||||
snapbox::str!["--json"]
|
||||
);
|
||||
|
||||
assert_data_eq!(complete!(cmd, "-F --json --j[TAB]"), snapbox::str![""]);
|
||||
assert_data_eq!(
|
||||
complete!(cmd, "-F --json --j[TAB]"),
|
||||
snapbox::str!["--json"]
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -1062,7 +1065,7 @@ fn suggest_positional_long_allow_hyhpen() {
|
|||
--help Print help
|
||||
-F
|
||||
-h Print help
|
||||
--pos_a"
|
||||
pos_b"
|
||||
]
|
||||
);
|
||||
assert_data_eq!(
|
||||
|
@ -1072,17 +1075,17 @@ fn suggest_positional_long_allow_hyhpen() {
|
|||
--help Print help
|
||||
-F
|
||||
-h Print help
|
||||
--pos_a"
|
||||
pos_b"
|
||||
]
|
||||
);
|
||||
|
||||
assert_data_eq!(
|
||||
complete!(cmd, "--format --json --pos_a p[TAB]"),
|
||||
snapbox::str![""]
|
||||
snapbox::str!["pos_b"]
|
||||
);
|
||||
assert_data_eq!(
|
||||
complete!(cmd, "-F --json --pos_a p[TAB]"),
|
||||
snapbox::str![""]
|
||||
snapbox::str!["pos_b"]
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -1115,7 +1118,7 @@ fn suggest_positional_short_allow_hyhpen() {
|
|||
--help Print help
|
||||
-F
|
||||
-h Print help
|
||||
-a"
|
||||
pos_b"
|
||||
]
|
||||
);
|
||||
assert_data_eq!(
|
||||
|
@ -1125,15 +1128,18 @@ fn suggest_positional_short_allow_hyhpen() {
|
|||
--help Print help
|
||||
-F
|
||||
-h Print help
|
||||
-a"
|
||||
pos_b"
|
||||
]
|
||||
);
|
||||
|
||||
assert_data_eq!(
|
||||
complete!(cmd, "--format --json -a p[TAB]"),
|
||||
snapbox::str![""]
|
||||
snapbox::str!["pos_b"]
|
||||
);
|
||||
assert_data_eq!(
|
||||
complete!(cmd, "-F --json -a p[TAB]"),
|
||||
snapbox::str!["pos_b"]
|
||||
);
|
||||
assert_data_eq!(complete!(cmd, "-F --json -a p[TAB]"), snapbox::str![""]);
|
||||
}
|
||||
|
||||
fn complete(cmd: &mut Command, args: impl AsRef<str>, current_dir: Option<&Path>) -> String {
|
||||
|
|
Loading…
Reference in a new issue