From ad86e43334c4f70e86909689a088fb87e26ff95a Mon Sep 17 00:00:00 2001 From: Kevin K Date: Thu, 10 Mar 2016 16:31:59 -0500 Subject: [PATCH] feat(Settings): adds support for automatically deriving custom display order of args Args and subcommands can now have their display order automatically derived by using the setting `AppSettings::DeriveDisplayOrder` which will display the args and subcommands in the order that they were declared in, instead of alphabetical order which is the default. Closes #444 --- src/app/parser.rs | 21 ++++++++++++++-- src/app/settings.rs | 59 ++++++++++++++++++++++++++++----------------- 2 files changed, 56 insertions(+), 24 deletions(-) diff --git a/src/app/parser.rs b/src/app/parser.rs index 701293c5..040d79ea 100644 --- a/src/app/parser.rs +++ b/src/app/parser.rs @@ -154,10 +154,24 @@ impl<'a, 'b> Parser<'a, 'b> where 'a: 'b { let pb = PosBuilder::from_arg(&a, i as u64, &mut self.required); self.positionals.insert(i, pb); } else if a.is_set(ArgSettings::TakesValue) { - let ob = OptBuilder::from_arg(&a, &mut self.required); + let mut ob = OptBuilder::from_arg(&a, &mut self.required); + if self.settings.is_set(AppSettings::DeriveDisplayOrder) && a.disp_ord == 999 { + ob.disp_ord = if self.settings.is_set(AppSettings::UnifiedHelpMessage) { + self.flags.len() + self.opts.len() + } else { + self.opts.len() + }; + } self.opts.push(ob); } else { - let fb = FlagBuilder::from(a); + let mut fb = FlagBuilder::from(a); + if self.settings.is_set(AppSettings::DeriveDisplayOrder) && a.disp_ord == 999 { + fb.disp_ord = if self.settings.is_set(AppSettings::UnifiedHelpMessage) { + self.flags.len() + self.opts.len() + } else { + self.flags.len() + }; + } self.flags.push(fb); } if a.is_set(ArgSettings::Global) { @@ -210,6 +224,9 @@ impl<'a, 'b> Parser<'a, 'b> where 'a: 'b { subcmd = subcmd.setting(AppSettings::GlobalVersion) .version(self.meta.version.unwrap()); } else { sdebugln!("No"); } + if self.settings.is_set(AppSettings::DeriveDisplayOrder) { + subcmd.p.meta.disp_ord = self.subcommands.len(); + } self.subcommands.push(subcmd); } diff --git a/src/app/settings.rs b/src/app/settings.rs index 8bdc429d..73d54727 100644 --- a/src/app/settings.rs +++ b/src/app/settings.rs @@ -3,27 +3,28 @@ use std::ascii::AsciiExt; bitflags! { flags Flags: u32 { - const SC_NEGATE_REQS = 0b000000000000000000001, - const SC_REQUIRED = 0b000000000000000000010, - const A_REQUIRED_ELSE_HELP = 0b000000000000000000100, - const GLOBAL_VERSION = 0b000000000000000001000, - const VERSIONLESS_SC = 0b000000000000000010000, - const UNIFIED_HELP = 0b000000000000000100000, - const WAIT_ON_ERROR = 0b000000000000001000000, - const SC_REQUIRED_ELSE_HELP= 0b000000000000010000000, - const NEEDS_LONG_HELP = 0b000000000000100000000, - const NEEDS_LONG_VERSION = 0b000000000001000000000, - const NEEDS_SC_HELP = 0b000000000010000000000, - const DISABLE_VERSION = 0b000000000100000000000, - const HIDDEN = 0b000000001000000000000, - const TRAILING_VARARG = 0b000000010000000000000, - const NO_BIN_NAME = 0b000000100000000000000, - const ALLOW_UNK_SC = 0b000001000000000000000, - const UTF8_STRICT = 0b000010000000000000000, - const UTF8_NONE = 0b000100000000000000000, - const LEADING_HYPHEN = 0b001000000000000000000, - const NO_POS_VALUES = 0b010000000000000000000, - const NEXT_LINE_HELP = 0b100000000000000000000, + const SC_NEGATE_REQS = 0b0000000000000000000001, + const SC_REQUIRED = 0b0000000000000000000010, + const A_REQUIRED_ELSE_HELP = 0b0000000000000000000100, + const GLOBAL_VERSION = 0b0000000000000000001000, + const VERSIONLESS_SC = 0b0000000000000000010000, + const UNIFIED_HELP = 0b0000000000000000100000, + const WAIT_ON_ERROR = 0b0000000000000001000000, + const SC_REQUIRED_ELSE_HELP= 0b0000000000000010000000, + const NEEDS_LONG_HELP = 0b0000000000000100000000, + const NEEDS_LONG_VERSION = 0b0000000000001000000000, + const NEEDS_SC_HELP = 0b0000000000010000000000, + const DISABLE_VERSION = 0b0000000000100000000000, + const HIDDEN = 0b0000000001000000000000, + const TRAILING_VARARG = 0b0000000010000000000000, + const NO_BIN_NAME = 0b0000000100000000000000, + const ALLOW_UNK_SC = 0b0000001000000000000000, + const UTF8_STRICT = 0b0000010000000000000000, + const UTF8_NONE = 0b0000100000000000000000, + const LEADING_HYPHEN = 0b0001000000000000000000, + const NO_POS_VALUES = 0b0010000000000000000000, + const NEXT_LINE_HELP = 0b0100000000000000000000, + const DERIVE_DISP_ORDER = 0b1000000000000000000000, } } @@ -63,7 +64,8 @@ impl AppFlags { AllowInvalidUtf8 => UTF8_NONE, AllowLeadingHyphen => LEADING_HYPHEN, HidePossibleValuesInHelp => NO_POS_VALUES, - NextLineHelp => NEXT_LINE_HELP + NextLineHelp => NEXT_LINE_HELP, + DeriveDisplayOrder => DERIVE_DISP_ORDER } } @@ -426,6 +428,18 @@ pub enum AppSettings { /// .get_matches(); /// ``` NextLineHelp, + /// Displays the arguments and subcommands in the help message in the order that they were + /// declared in, vice alphabetically which is the default. + /// + /// # Examples + /// + /// ```no_run + /// # use clap::{App, Arg, SubCommand, AppSettings}; + /// App::new("myprog") + /// .setting(AppSettings::DeriveDisplayOrder) + /// .get_matches(); + /// ``` + DeriveDisplayOrder, #[doc(hidden)] NeedsLongVersion, #[doc(hidden)] @@ -457,6 +471,7 @@ impl FromStr for AppSettings { "allowleadinghyphen" => Ok(AppSettings::AllowLeadingHyphen), "hidepossiblevaluesinhelp" => Ok(AppSettings::HidePossibleValuesInHelp), "nextlinehelp" => Ok(AppSettings::NextLineHelp), + "derivedisplayorder" => Ok(AppSettings::DeriveDisplayOrder), _ => Err("unknown AppSetting, cannot convert from str".to_owned()), } }