diff --git a/clap_builder/src/parser/parser.rs b/clap_builder/src/parser/parser.rs index a4e15fef49d..d6d8e8da436 100644 --- a/clap_builder/src/parser/parser.rs +++ b/clap_builder/src/parser/parser.rs @@ -302,6 +302,13 @@ impl<'cmd> Parser<'cmd> { .map(|p_name| !p_name.is_last_set()) .unwrap_or_default(); + let is_terminated = self + .cmd + .get_keymap() + .get(&pos_counter) + .map(|a| a.get_value_terminator().is_some()) + .unwrap_or_default(); + let missing_pos = self.cmd.is_allow_missing_positional_set() && is_second_to_last && !trailing_values; @@ -309,7 +316,7 @@ impl<'cmd> Parser<'cmd> { debug!("Parser::get_matches_with: Positional counter...{pos_counter}"); debug!("Parser::get_matches_with: Low index multiples...{low_index_mults:?}"); - if low_index_mults || missing_pos { + if (low_index_mults || missing_pos) && !is_terminated { let skip_current = if let Some(n) = raw_args.peek(&args_cursor) { if let Some(arg) = self .cmd diff --git a/tests/builder/multiple_values.rs b/tests/builder/multiple_values.rs index 421d61924ee..57691f177f1 100644 --- a/tests/builder/multiple_values.rs +++ b/tests/builder/multiple_values.rs @@ -1375,6 +1375,32 @@ fn multiple_value_terminator_option_other_arg() { assert!(*m.get_one::("flag").expect("defaulted by clap")); } +#[test] +fn all_multiple_value_terminator() { + let m = Command::new("lip") + .arg( + Arg::new("files") + .value_terminator(";") + .action(ArgAction::Set) + .num_args(0..), + ) + .arg(Arg::new("other").num_args(0..)) + .try_get_matches_from(vec!["test", "value", ";"]); + + assert!(m.is_ok(), "{:?}", m.unwrap_err().kind()); + let m = m.unwrap(); + + assert!(m.contains_id("files")); + assert!(!m.contains_id("other")); + assert_eq!( + m.get_many::("files") + .unwrap() + .map(|v| v.as_str()) + .collect::>(), + ["value".to_owned()], + ); +} + #[test] fn multiple_vals_with_hyphen() { let res = Command::new("do")