From c8ab24bafa81e64fed518c7deb95645290e304cb Mon Sep 17 00:00:00 2001 From: Kevin K Date: Sat, 4 Mar 2017 17:37:08 -0500 Subject: [PATCH] imp: when AppSettings::SubcommandsNegateReqs and ArgsNegateSubcommands are used, a new more accurate double line usage string is shown Closes #871 --- src/app/parser.rs | 31 ++++++++++++++++++++----------- tests/positionals.rs | 2 +- 2 files changed, 21 insertions(+), 12 deletions(-) diff --git a/src/app/parser.rs b/src/app/parser.rs index f43620a3bf5..d13a7f59c6c 100644 --- a/src/app/parser.rs +++ b/src/app/parser.rs @@ -578,7 +578,7 @@ impl<'a, 'b> Parser<'a, 'b> #[inline] pub fn has_visible_subcommands(&self) -> bool { if self.subcommands.is_empty() { return false; } - self.subcommands.iter().any(|s| !s.is_set(AppSettings::Hidden)) + self.subcommands.iter().any(|s| !s.p.is_set(AS::Hidden)) } #[inline] @@ -2120,7 +2120,7 @@ impl<'a, 'b> Parser<'a, 'b> if let Some(u) = self.meta.usage_str { usage.push_str(&*u); } else if used.is_empty() { - usage.push_str(&*self.meta + let name = self.meta .usage .as_ref() .unwrap_or_else(|| { @@ -2128,7 +2128,8 @@ impl<'a, 'b> Parser<'a, 'b> .bin_name .as_ref() .unwrap_or(&self.meta.name) - })); + }); + usage.push_str(&*name); let mut reqs: Vec<&str> = self.required().map(|r| &**r).collect(); reqs.dedup(); let req_string = self.get_required_from(&reqs, None, None) @@ -2141,9 +2142,9 @@ impl<'a, 'b> Parser<'a, 'b> } else if flags { usage.push_str(" [OPTIONS]"); } - if !self.is_set(AS::UnifiedHelpMessage) && self.has_opts() && + if !self.is_set(AS::UnifiedHelpMessage) && self.opts.iter().any(|o| !o.is_set(ArgSettings::Required) && - !o.is_set!(AS::Hidden)) { + !o.is_set(ArgSettings::Hidden)) { usage.push_str(" [OPTIONS]"); } @@ -2154,7 +2155,7 @@ impl<'a, 'b> Parser<'a, 'b> if self.has_positionals() && self.opts.iter().any(|o| o.is_set(ArgSettings::Multiple)) && self.positionals.values().any(|p| !p.is_set(ArgSettings::Required)) && - !self.has_subcommands() { + !self.has_visible_subcommands() { usage.push_str(" [--]") } if self.has_positionals() && @@ -2168,11 +2169,19 @@ impl<'a, 'b> Parser<'a, 'b> } - if self.has_subcommands() && !self.is_set(AS::SubcommandRequired) { - usage.push_str(" [SUBCOMMAND]"); - } else if (self.is_set(AS::SubcommandRequired) || - self.is_set(AS::SubcommandRequiredElseHelp)) && self.has_subcommands() { - usage.push_str(" "); + if self.is_set(AS::SubcommandsNegateReqs) || self.is_set(AS::ArgsNegateSubcommands) { + if self.has_visible_subcommands() { + usage.push_str("\n "); + usage.push_str(&*name); + usage.push_str(" "); + } + } else { + if self.has_visible_subcommands() && !self.is_set(AS::SubcommandRequired) { + usage.push_str(" [SUBCOMMAND]"); + } else if (self.is_set(AS::SubcommandRequired) || + self.is_set(AS::SubcommandRequiredElseHelp)) && self.has_subcommands() { + usage.push_str(" "); + } } } else { self.smart_usage(&mut usage, used); diff --git a/tests/positionals.rs b/tests/positionals.rs index e8a0cd7b8b3..b356d2994c3 100644 --- a/tests/positionals.rs +++ b/tests/positionals.rs @@ -180,7 +180,7 @@ fn multiple_positional_one_required_usage_string() { .arg_from_usage(" 'some file'") .arg_from_usage("[FILES]... 'some file'") .get_matches_from(vec!["test", "file"]); - assert_eq!(m.usage(), "USAGE:\n test [ARGS]"); + assert_eq!(m.usage(), "USAGE:\n test [FILES]..."); } #[test]