Add DisableColoredHelp setting to improve flexibility (clap-rs/clap#2956)

Until we have a modular help generator that can be configured and/or
authored by the users themselves as part of #2914, we will provide the
flexibility of turning off colored help messages but still wanting
colored error messages.

This flexibility was available before #2845 and @dbrgn immediately
noticed it and requested it back to which I agree. This was also
suggested by Josh in
[here](https://github.com/clap-rs/clap/issues/2806#issuecomment-933877438)
This commit is contained in:
Pavan Kumar Sunkara 2021-10-27 22:01:04 +01:00 committed by Ed Page
parent f6635b0baa
commit cc2dddba8e
3 changed files with 35 additions and 5 deletions

View file

@ -25,6 +25,7 @@ bitflags! {
const NO_POS_VALUES = 1 << 17; const NO_POS_VALUES = 1 << 17;
const NEXT_LINE_HELP = 1 << 18; const NEXT_LINE_HELP = 1 << 18;
const DERIVE_DISP_ORDER = 1 << 19; const DERIVE_DISP_ORDER = 1 << 19;
const DISABLE_COLORED_HELP = 1 << 20;
const COLOR_ALWAYS = 1 << 21; const COLOR_ALWAYS = 1 << 21;
const COLOR_AUTO = 1 << 22; const COLOR_AUTO = 1 << 22;
const COLOR_NEVER = 1 << 23; const COLOR_NEVER = 1 << 23;
@ -99,6 +100,8 @@ impl_settings! { AppSettings, AppFlags,
=> Flags::DONT_COLLAPSE_ARGS, => Flags::DONT_COLLAPSE_ARGS,
DeriveDisplayOrder("derivedisplayorder") DeriveDisplayOrder("derivedisplayorder")
=> Flags::DERIVE_DISP_ORDER, => Flags::DERIVE_DISP_ORDER,
DisableColoredHelp("disablecoloredhelp")
=> Flags::DISABLE_COLORED_HELP,
DisableHelpSubcommand("disablehelpsubcommand") DisableHelpSubcommand("disablehelpsubcommand")
=> Flags::DISABLE_HELP_SC, => Flags::DISABLE_HELP_SC,
DisableHelpFlag("disablehelpflag") DisableHelpFlag("disablehelpflag")
@ -571,6 +574,18 @@ pub enum AppSettings {
/// [`Arg::use_delimiter(false)`]: crate::Arg::use_delimiter() /// [`Arg::use_delimiter(false)`]: crate::Arg::use_delimiter()
DontDelimitTrailingValues, DontDelimitTrailingValues,
/// Disables colorized help messages.
///
/// # Examples
///
/// ```no_run
/// # use clap::{App, AppSettings};
/// App::new("myprog")
/// .setting(AppSettings::DisableColoredHelp)
/// .get_matches();
/// ```
DisableColoredHelp,
/// Disables `-h` and `--help` flag. /// Disables `-h` and `--help` flag.
/// ///
/// # Examples /// # Examples
@ -1194,6 +1209,10 @@ mod test {
"derivedisplayorder".parse::<AppSettings>().unwrap(), "derivedisplayorder".parse::<AppSettings>().unwrap(),
AppSettings::DeriveDisplayOrder AppSettings::DeriveDisplayOrder
); );
assert_eq!(
"disablecoloredhelp".parse::<AppSettings>().unwrap(),
AppSettings::DisableColoredHelp
);
assert_eq!( assert_eq!(
"propagateversion".parse::<AppSettings>().unwrap(), "propagateversion".parse::<AppSettings>().unwrap(),
AppSettings::PropagateVersion AppSettings::PropagateVersion

View file

@ -24,13 +24,14 @@
#[cfg(not(feature = "std"))] #[cfg(not(feature = "std"))]
compile_error!("`std` feature is currently required to build `clap`"); compile_error!("`std` feature is currently required to build `clap`");
#[cfg(feature = "color")]
pub use crate::util::color::ColorChoice;
pub use crate::{ pub use crate::{
build::{ build::{
App, AppFlags, AppSettings, Arg, ArgFlags, ArgGroup, ArgSettings, PossibleValue, ValueHint, App, AppFlags, AppSettings, Arg, ArgFlags, ArgGroup, ArgSettings, PossibleValue, ValueHint,
}, },
parse::errors::{Error, ErrorKind, Result}, parse::errors::{Error, ErrorKind, Result},
parse::{ArgMatches, Indices, OsValues, Values}, parse::{ArgMatches, Indices, OsValues, Values},
util::color::ColorChoice,
}; };
pub use crate::derive::{ArgEnum, Args, FromArgMatches, IntoApp, Parser, Subcommand}; pub use crate::derive::{ArgEnum, Args, FromArgMatches, IntoApp, Parser, Subcommand};

View file

@ -19,7 +19,7 @@ use crate::{
parse::features::suggestions, parse::features::suggestions,
parse::{ArgMatcher, SubCommand}, parse::{ArgMatcher, SubCommand},
parse::{Validator, ValueType}, parse::{Validator, ValueType},
util::{ChildGraph, Id}, util::{color::ColorChoice, ChildGraph, Id},
INTERNAL_ERROR_MSG, INVALID_UTF8, INTERNAL_ERROR_MSG, INVALID_UTF8,
}; };
@ -332,6 +332,16 @@ impl<'help, 'app> Parser<'help, 'app> {
} }
} }
} }
// Should we color the help?
pub(crate) fn color_help(&self) -> ColorChoice {
#[cfg(feature = "color")]
if self.is_set(AS::DisableColoredHelp) {
return ColorChoice::Never;
}
self.app.get_color()
}
} }
// Parsing Methods // Parsing Methods
@ -1869,7 +1879,7 @@ impl<'help, 'app> Parser<'help, 'app> {
} }
pub(crate) fn write_help_err(&self) -> ClapResult<Colorizer> { pub(crate) fn write_help_err(&self) -> ClapResult<Colorizer> {
let mut c = Colorizer::new(true, self.app.get_color()); let mut c = Colorizer::new(true, self.color_help());
Help::new(HelpWriter::Buffer(&mut c), self, false).write_help()?; Help::new(HelpWriter::Buffer(&mut c), self, false).write_help()?;
Ok(c) Ok(c)
} }
@ -1881,7 +1891,7 @@ impl<'help, 'app> Parser<'help, 'app> {
); );
use_long = use_long && self.use_long_help(); use_long = use_long && self.use_long_help();
let mut c = Colorizer::new(false, self.app.get_color()); let mut c = Colorizer::new(false, self.color_help());
match Help::new(HelpWriter::Buffer(&mut c), self, use_long).write_help() { match Help::new(HelpWriter::Buffer(&mut c), self, use_long).write_help() {
Err(e) => e.into(), Err(e) => e.into(),
@ -1897,7 +1907,7 @@ impl<'help, 'app> Parser<'help, 'app> {
debug!("Parser::version_err"); debug!("Parser::version_err");
let msg = self.app._render_version(use_long); let msg = self.app._render_version(use_long);
let mut c = Colorizer::new(false, self.app.get_color()); let mut c = Colorizer::new(false, self.color_help());
c.none(msg); c.none(msg);
ClapError::new( ClapError::new(
c, c,