mirror of
https://github.com/clap-rs/clap
synced 2024-11-10 06:44:16 +00:00
fix(lex)!: Don't do prefix matching by default
Finding this a pain in `clap_complete`; not offering the benefits I expected.
This commit is contained in:
parent
3d64ebacac
commit
f083ef92c5
4 changed files with 35 additions and 61 deletions
|
@ -293,14 +293,14 @@ impl<'s> ParsedArg<'s> {
|
|||
}
|
||||
|
||||
/// Treat as a long-flag
|
||||
///
|
||||
/// **NOTE:** May return an empty flag. Check [`ParsedArg::is_escape`] to separately detect `--`.
|
||||
///
|
||||
/// **NOTE:** Will not match [`ParsedArg::is_stdio`], completion engines will need to check
|
||||
/// that case.
|
||||
pub fn to_long(&self) -> Option<(Result<&str, &RawOsStr>, Option<&RawOsStr>)> {
|
||||
if let Some(raw) = self.utf8 {
|
||||
let remainder = raw.strip_prefix("--")?;
|
||||
if remainder.is_empty() {
|
||||
debug_assert!(self.is_escape());
|
||||
return None;
|
||||
}
|
||||
|
||||
let (flag, value) = if let Some((p0, p1)) = remainder.split_once('=') {
|
||||
(p0, Some(p1))
|
||||
} else {
|
||||
|
@ -312,6 +312,11 @@ impl<'s> ParsedArg<'s> {
|
|||
} else {
|
||||
let raw = self.inner.as_ref();
|
||||
let remainder = raw.strip_prefix("--")?;
|
||||
if remainder.is_empty() {
|
||||
debug_assert!(self.is_escape());
|
||||
return None;
|
||||
}
|
||||
|
||||
let (flag, value) = if let Some((p0, p1)) = remainder.split_once('=') {
|
||||
(p0, Some(p1))
|
||||
} else {
|
||||
|
@ -323,20 +328,18 @@ impl<'s> ParsedArg<'s> {
|
|||
}
|
||||
|
||||
/// Can treat as a long-flag
|
||||
///
|
||||
/// **NOTE:** May return an empty flag. Check [`ParsedArg::is_escape`] to separately detect `--`.
|
||||
pub fn is_long(&self) -> bool {
|
||||
self.inner.as_ref().starts_with("--")
|
||||
self.inner.as_ref().starts_with("--") && !self.is_escape()
|
||||
}
|
||||
|
||||
/// Treat as a short-flag
|
||||
///
|
||||
/// **NOTE:** Maybe return an empty flag. Check [`ParsedArg::is_stdio`] to separately detect
|
||||
/// `-`.
|
||||
pub fn to_short(&self) -> Option<ShortFlags<'_>> {
|
||||
if let Some(remainder_os) = self.inner.as_ref().strip_prefix('-') {
|
||||
if remainder_os.starts_with('-') {
|
||||
None
|
||||
} else if remainder_os.is_empty() {
|
||||
debug_assert!(self.is_stdio());
|
||||
None
|
||||
} else {
|
||||
let remainder = self.utf8.map(|s| &s[1..]);
|
||||
Some(ShortFlags::new(remainder_os, remainder))
|
||||
|
@ -347,11 +350,10 @@ impl<'s> ParsedArg<'s> {
|
|||
}
|
||||
|
||||
/// Can treat as a short-flag
|
||||
///
|
||||
/// **NOTE:** Maybe return an empty flag. Check [`ParsedArg::is_stdio`] to separately detect
|
||||
/// `-`.
|
||||
pub fn is_short(&self) -> bool {
|
||||
self.inner.as_ref().starts_with('-') && !self.is_long()
|
||||
self.inner.as_ref().starts_with('-')
|
||||
&& !self.is_stdio()
|
||||
&& !self.inner.as_ref().starts_with("--")
|
||||
}
|
||||
|
||||
/// Treat as a value
|
||||
|
|
|
@ -13,17 +13,15 @@ fn to_long_stdio() {
|
|||
}
|
||||
|
||||
#[test]
|
||||
fn to_long_escape() {
|
||||
fn to_long_no_escape() {
|
||||
let raw = clap_lex::RawArgs::new(["bin", "--"]);
|
||||
let mut cursor = raw.cursor();
|
||||
assert_eq!(raw.next_os(&mut cursor), Some(std::ffi::OsStr::new("bin")));
|
||||
let next = raw.next(&mut cursor).unwrap();
|
||||
|
||||
assert!(next.is_long());
|
||||
assert!(!next.is_long());
|
||||
|
||||
let (key, value) = next.to_long().unwrap();
|
||||
assert_eq!(key, Ok(""));
|
||||
assert_eq!(value, None);
|
||||
assert_eq!(next.to_long(), None);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -75,10 +73,9 @@ fn to_short_stdio() {
|
|||
assert_eq!(raw.next_os(&mut cursor), Some(std::ffi::OsStr::new("bin")));
|
||||
let next = raw.next(&mut cursor).unwrap();
|
||||
|
||||
assert!(next.is_short());
|
||||
assert!(!next.is_short());
|
||||
|
||||
let mut shorts = next.to_short().unwrap();
|
||||
assert_eq!(shorts.next_value_os(), None);
|
||||
assert!(next.to_short().is_none());
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
|
|
@ -87,20 +87,6 @@ fn advance_by_nothing() {
|
|||
assert_eq!(actual, "short");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn advance_by_nothing_with_nothing() {
|
||||
let raw = clap_lex::RawArgs::new(["bin", "-"]);
|
||||
let mut cursor = raw.cursor();
|
||||
assert_eq!(raw.next_os(&mut cursor), Some(std::ffi::OsStr::new("bin")));
|
||||
let next = raw.next(&mut cursor).unwrap();
|
||||
let mut shorts = next.to_short().unwrap();
|
||||
|
||||
assert_eq!(shorts.advance_by(0), Ok(()));
|
||||
|
||||
let actual: String = shorts.map(|s| s.unwrap()).collect();
|
||||
assert_eq!(actual, "");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn advance_by_something() {
|
||||
let raw = clap_lex::RawArgs::new(["bin", "-short"]);
|
||||
|
@ -129,17 +115,6 @@ fn advance_by_out_of_bounds() {
|
|||
assert_eq!(actual, "");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn is_empty() {
|
||||
let raw = clap_lex::RawArgs::new(["bin", "-"]);
|
||||
let mut cursor = raw.cursor();
|
||||
assert_eq!(raw.next_os(&mut cursor), Some(std::ffi::OsStr::new("bin")));
|
||||
let next = raw.next(&mut cursor).unwrap();
|
||||
let shorts = next.to_short().unwrap();
|
||||
|
||||
assert!(shorts.is_empty());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn is_not_empty() {
|
||||
let raw = clap_lex::RawArgs::new(["bin", "-hello"]);
|
||||
|
@ -165,7 +140,7 @@ fn is_partial_not_empty() {
|
|||
|
||||
#[test]
|
||||
fn is_exhausted_empty() {
|
||||
let raw = clap_lex::RawArgs::new(["bin", "-"]);
|
||||
let raw = clap_lex::RawArgs::new(["bin", "-hello"]);
|
||||
let mut cursor = raw.cursor();
|
||||
assert_eq!(raw.next_os(&mut cursor), Some(std::ffi::OsStr::new("bin")));
|
||||
let next = raw.next(&mut cursor).unwrap();
|
||||
|
|
|
@ -190,7 +190,17 @@ impl<'help, 'cmd> Parser<'help, 'cmd> {
|
|||
}
|
||||
}
|
||||
|
||||
if let Some((long_arg, long_value)) = arg_os.to_long() {
|
||||
if arg_os.is_escape() {
|
||||
if matches!(&parse_state, ParseState::Opt(opt) | ParseState::Pos(opt) if
|
||||
self.cmd[opt].is_allow_hyphen_values_set())
|
||||
{
|
||||
// ParseResult::MaybeHyphenValue, do nothing
|
||||
} else {
|
||||
debug!("Parser::get_matches_with: setting TrailingVals=true");
|
||||
trailing_values = true;
|
||||
continue;
|
||||
}
|
||||
} else if let Some((long_arg, long_value)) = arg_os.to_long() {
|
||||
let parse_result = self.parse_long_arg(
|
||||
matcher,
|
||||
long_arg,
|
||||
|
@ -205,9 +215,7 @@ impl<'help, 'cmd> Parser<'help, 'cmd> {
|
|||
);
|
||||
match parse_result {
|
||||
ParseResult::NoArg => {
|
||||
debug!("Parser::get_matches_with: setting TrailingVals=true");
|
||||
trailing_values = true;
|
||||
continue;
|
||||
unreachable!("`to_long` always has the flag specified")
|
||||
}
|
||||
ParseResult::ValuesDone => {
|
||||
parse_state = ParseState::ValuesDone;
|
||||
|
@ -661,14 +669,6 @@ impl<'help, 'cmd> Parser<'help, 'cmd> {
|
|||
// If allow hyphen, this isn't a new arg.
|
||||
debug!("Parser::is_new_arg: Allow hyphen");
|
||||
false
|
||||
} else if next.is_escape() {
|
||||
// Ensure we don't assuming escapes are long args
|
||||
debug!("Parser::is_new_arg: -- found");
|
||||
false
|
||||
} else if next.is_stdio() {
|
||||
// Ensure we don't assume stdio is a short arg
|
||||
debug!("Parser::is_new_arg: - found");
|
||||
false
|
||||
} else if next.is_long() {
|
||||
// If this is a long flag, this is a new arg.
|
||||
debug!("Parser::is_new_arg: --<something> found");
|
||||
|
|
Loading…
Reference in a new issue