diff --git a/src/build/app/mod.rs b/src/build/app/mod.rs index 9f6c30eb11e..0d6c9d1a39d 100644 --- a/src/build/app/mod.rs +++ b/src/build/app/mod.rs @@ -658,6 +658,8 @@ impl<'help> App<'help> { /// Prints the short help message (`-h`) to [`io::stdout()`]. /// + /// If [`AppSettings::PrintToStderr`] is set, this will print to [`io::stderr()`] instead of stdout. + /// /// See also [`App::print_long_help`]. /// /// # Examples @@ -668,18 +670,22 @@ impl<'help> App<'help> { /// app.print_help(); /// ``` /// [`io::stdout()`]: std::io::stdout() + /// [`io::stderr()`]: std::io::stderr() pub fn print_help(&mut self) -> io::Result<()> { self._build(); + let use_stderr = self.settings.is_set(AppSettings::PrintToStderr); let color = self.get_color(); let p = Parser::new(self); - let mut c = Colorizer::new(false, color); + let mut c = Colorizer::new(use_stderr, color); Help::new(HelpWriter::Buffer(&mut c), &p, false).write_help()?; c.print() } /// Prints the long help message (`--help`) to [`io::stdout()`]. /// + /// If [`AppSettings::PrintToStderr`] is set, this will print to [`io::stderr()`] instead of stdout. + /// /// See also [`App::print_help`]. /// /// # Examples @@ -690,15 +696,17 @@ impl<'help> App<'help> { /// app.print_long_help(); /// ``` /// [`io::stdout()`]: std::io::stdout() + /// [`io::stderr()`]: std::io::stderr() /// [`BufWriter`]: std::io::BufWriter /// [`-h` (short)]: Arg::help() /// [`--help` (long)]: Arg::long_help() pub fn print_long_help(&mut self) -> io::Result<()> { self._build(); + let use_stderr = self.settings.is_set(AppSettings::PrintToStderr); let color = self.get_color(); let p = Parser::new(self); - let mut c = Colorizer::new(false, color); + let mut c = Colorizer::new(use_stderr, color); Help::new(HelpWriter::Buffer(&mut c), &p, true).write_help()?; c.print() } diff --git a/src/build/app/settings.rs b/src/build/app/settings.rs index f166795ea08..4c02c9414dd 100644 --- a/src/build/app/settings.rs +++ b/src/build/app/settings.rs @@ -950,6 +950,18 @@ pub enum AppSettings { /// ``` NoAutoVersion, + /// Prints the autogenerated help and version messages to stderr instead of stdout. + /// + /// # Examples + /// + /// ```no_run + /// # use clap::{App, AppSettings}; + /// App::new("myprog") + /// .global_setting(AppSettings::PrintToStderr) + /// .get_matches(); + /// ``` + PrintToStderr, + /// Deprecated, replaced with [`AppSettings::AllowHyphenValues`] #[deprecated( since = "3.0.0", @@ -1067,8 +1079,9 @@ bitflags! { const USE_LONG_FORMAT_FOR_HELP_SC = 1 << 42; const INFER_LONG_ARGS = 1 << 43; const IGNORE_ERRORS = 1 << 44; + const PRINT_TO_STDERR = 1 << 45; #[cfg(feature = "unstable-multicall")] - const MULTICALL = 1 << 45; + const MULTICALL = 1 << 46; const NO_OP = 0; } } @@ -1169,7 +1182,9 @@ impl_settings! { AppSettings, AppFlags, AllArgsOverrideSelf => Flags::ARGS_OVERRIDE_SELF, InferLongArgs - => Flags::INFER_LONG_ARGS + => Flags::INFER_LONG_ARGS, + PrintToStderr + => Flags::PRINT_TO_STDERR } /// Deprecated in [Issue #3087](https://github.com/clap-rs/clap/issues/3087), maybe [`clap::Parser`][crate::Parser] would fit your use case? @@ -1229,6 +1244,7 @@ impl FromStr for AppSettings { "infersubcommands" => Ok(AppSettings::InferSubcommands), "allargsoverrideself" => Ok(AppSettings::AllArgsOverrideSelf), "inferlongargs" => Ok(AppSettings::InferLongArgs), + "printtostderr" => Ok(AppSettings::PrintToStderr), _ => Err(format!("unknown AppSetting: `{}`", s)), } } diff --git a/src/parse/parser.rs b/src/parse/parser.rs index b33002392ce..30fcdf8f0dd 100644 --- a/src/parse/parser.rs +++ b/src/parse/parser.rs @@ -1600,7 +1600,10 @@ impl<'help, 'app> Parser<'help, 'app> { ); use_long = use_long && self.use_long_help(); - let mut c = Colorizer::new(false, self.color_help()); + let mut c = Colorizer::new( + self.app.settings.is_set(AS::PrintToStderr), + self.color_help(), + ); match Help::new(HelpWriter::Buffer(&mut c), self, use_long).write_help() { Err(e) => e.into(), @@ -1616,7 +1619,10 @@ impl<'help, 'app> Parser<'help, 'app> { debug!("Parser::version_err"); let msg = self.app._render_version(use_long); - let mut c = Colorizer::new(false, self.color_help()); + let mut c = Colorizer::new( + self.app.settings.is_set(AS::PrintToStderr), + self.color_help(), + ); c.none(msg); ClapError::new( c,