diff --git a/src/app/help.rs b/src/app/help.rs index 78b3d44f4fe..34f97ac322e 100644 --- a/src/app/help.rs +++ b/src/app/help.rs @@ -7,27 +7,31 @@ use std::io::{self, Cursor, Read, Write}; use std::usize; // Internal -use app::{App, AppSettings}; use app::parser::Parser; +use app::usage; +use app::{App, AppSettings}; use args::{AnyArg, ArgSettings, DispOrder}; use errors::{Error, Result as ClapResult}; use fmt::{Colorizer, ColorizerOption, Format}; -use app::usage; use map::VecMap; use INTERNAL_ERROR_MSG; // Third Party -use unicode_width::UnicodeWidthStr; #[cfg(feature = "wrap_help")] use term_size; use textwrap; +use unicode_width::UnicodeWidthStr; #[cfg(not(feature = "wrap_help"))] mod term_size { - pub fn dimensions() -> Option<(usize, usize)> { None } + pub fn dimensions() -> Option<(usize, usize)> { + None + } } -fn str_width(s: &str) -> usize { UnicodeWidthStr::width(s) } +fn str_width(s: &str) -> usize { + UnicodeWidthStr::width(s) +} const TAB: &'static str = " "; @@ -46,13 +50,19 @@ impl<'b, 'c, T> ArgWithOrder<'b, 'c> for T where T: ArgWithDisplay<'b, 'c> + DispOrder, { - fn as_base(&self) -> &ArgWithDisplay<'b, 'c> { self } + fn as_base(&self) -> &ArgWithDisplay<'b, 'c> { + self + } } -fn as_arg_trait<'a, 'b, T: ArgWithOrder<'a, 'b>>(x: &T) -> &ArgWithOrder<'a, 'b> { x } +fn as_arg_trait<'a, 'b, T: ArgWithOrder<'a, 'b>>(x: &T) -> &ArgWithOrder<'a, 'b> { + x +} impl<'b, 'c> DispOrder for App<'b, 'c> { - fn disp_ord(&self) -> usize { 999 } + fn disp_ord(&self) -> usize { + 999 + } } macro_rules! color { @@ -203,9 +213,7 @@ impl<'a> Help<'a> { self.longest = 2; let mut arg_v = Vec::with_capacity(10); let use_long = self.use_long; - for arg in args.filter(|arg| { - should_show_arg(use_long, *arg) - }) { + for arg in args.filter(|arg| should_show_arg(use_long, *arg)) { if arg.longest_filter() { self.longest = cmp::max(self.longest, str_width(arg.to_string().as_str())); } @@ -444,13 +452,13 @@ impl<'a> Help<'a> { /// Writes argument's help to the wrapped stream. fn help<'b, 'c>(&mut self, arg: &ArgWithDisplay<'b, 'c>, spec_vals: &str) -> io::Result<()> { debugln!("Help::help;"); - let h = if self.use_long { + let h = if self.use_long && arg.name() != "" { arg.long_help().unwrap_or_else(|| arg.help().unwrap_or("")) } else { arg.help().unwrap_or_else(|| arg.long_help().unwrap_or("")) }; let mut help = String::from(h) + spec_vals; - let nlh = self.next_line_help || arg.is_set(ArgSettings::NextLineHelp) || self.use_long; + let nlh = self.next_line_help || arg.is_set(ArgSettings::NextLineHelp) || (self.use_long && arg.name() != ""); debugln!("Help::help: Next Line...{:?}", nlh); let spcs = if nlh || self.force_next_line { @@ -508,15 +516,14 @@ impl<'a> Help<'a> { env.1 ); let env_val = if !a.is_set(ArgSettings::HideEnvValues) { - format!("={}", env.1.map_or(Cow::Borrowed(""), |val| val.to_string_lossy())) + format!( + "={}", + env.1.map_or(Cow::Borrowed(""), |val| val.to_string_lossy()) + ) } else { String::new() }; - let env_info = format!( - " [env: {}{}]", - env.0.to_string_lossy(), - env_val - ); + let env_info = format!(" [env: {}{}]", env.0.to_string_lossy(), env_val); spec_vals.push(env_info); } if !a.is_set(ArgSettings::HideDefaultValue) { @@ -572,9 +579,9 @@ fn should_show_arg(use_long: bool, arg: &ArgWithOrder) -> bool { return false; } - (!arg.is_set(ArgSettings::HiddenLongHelp) && use_long) || - (!arg.is_set(ArgSettings::HiddenShortHelp) && !use_long) || - arg.is_set(ArgSettings::NextLineHelp) + (!arg.is_set(ArgSettings::HiddenLongHelp) && use_long) + || (!arg.is_set(ArgSettings::HiddenShortHelp) && !use_long) + || arg.is_set(ArgSettings::NextLineHelp) } // Methods to write Parser help. @@ -714,8 +721,7 @@ impl<'a> Help<'a> { ($thing:expr) => {{ let mut owned_thing = $thing.to_owned(); owned_thing = owned_thing.replace("{n}", "\n"); - write!(self.writer, "{}\n", - wrap_help(&owned_thing, self.term_w))? + write!(self.writer, "{}\n", wrap_help(&owned_thing, self.term_w))? }}; } // Print the version @@ -726,20 +732,21 @@ impl<'a> Help<'a> { if let Some(author) = parser.meta.author { write_thing!(author) } - if self.use_long { - if let Some(about) = parser.meta.long_about { - debugln!("Help::write_default_help: writing long about"); - write_thing!(about) - } else if let Some(about) = parser.meta.about { - debugln!("Help::write_default_help: writing about"); - write_thing!(about) - } + // if self.use_long { + // if let Some(about) = parser.meta.long_about { + // debugln!("Help::write_default_help: writing long about"); + // write_thing!(about) + // } else if let Some(about) = parser.meta.about { + // debugln!("Help::write_default_help: writing about"); + // write_thing!(about) + // } + // } else + if let Some(about) = parser.meta.long_about { + debugln!("Help::write_default_help: writing long about"); + write_thing!(about) } else if let Some(about) = parser.meta.about { debugln!("Help::write_default_help: writing about"); write_thing!(about) - } else if let Some(about) = parser.meta.long_about { - debugln!("Help::write_default_help: writing long about"); - write_thing!(about) } color!(self, "\nUSAGE:", warning)?; @@ -867,7 +874,6 @@ fn copy_and_capture( } } - // Methods to write Parser help using templates. impl<'a> Help<'a> { /// Write help to stream for the parser in the format defined by the template. diff --git a/src/app/mod.rs b/src/app/mod.rs index 5facbfb7fbc..f2d9d52bcf2 100644 --- a/src/app/mod.rs +++ b/src/app/mod.rs @@ -1671,6 +1671,7 @@ impl<'a> From<&'a Yaml> for App<'a, 'a> { yaml_str!(a, yaml, author); yaml_str!(a, yaml, bin_name); yaml_str!(a, yaml, about); + yaml_str!(a, yaml, long_about); yaml_str!(a, yaml, before_help); yaml_str!(a, yaml, after_help); yaml_str!(a, yaml, template); @@ -1788,7 +1789,7 @@ impl<'a, 'b> Clone for App<'a, 'b> { impl<'n, 'e> AnyArg<'n, 'e> for App<'n, 'e> { fn name(&self) -> &'n str { - unreachable!("App struct does not support AnyArg::name, this is a bug!") + "" } fn overrides(&self) -> Option<&[&'e str]> { None } fn requires(&self) -> Option<&[(Option<&'e str>, &'n str)]> { None } diff --git a/tests/help.rs b/tests/help.rs index 97f26ac04f3..4b15281f4b9 100644 --- a/tests/help.rs +++ b/tests/help.rs @@ -1158,3 +1158,48 @@ fn show_env_vals() { .takes_value(true)); assert!(test::compare_output(app, "ctest --help", SHOW_ENV_VALS, false)); } + +static ISSUE_897: &'static str = "ctest-foo 0.1 +Long about foo + +USAGE: + ctest foo + +FLAGS: + -h, --help + Prints help information + + -V, --version + Prints version information"; + +#[test] +fn show_long_about_issue_897() { + let app = App::new("ctest") + .version("0.1") + .subcommand(SubCommand::with_name("foo") + .version("0.1") + .about("About foo") + .long_about("Long about foo")); + assert!(test::compare_output(app, "ctest foo --help", ISSUE_897, false)); +} + +static ISSUE_897_SHORT: &'static str = "ctest-foo 0.1 +Long about foo + +USAGE: + ctest foo + +FLAGS: + -h, --help Prints help information + -V, --version Prints version information"; + +#[test] +fn show_short_about_issue_897() { + let app = App::new("ctest") + .version("0.1") + .subcommand(SubCommand::with_name("foo") + .version("0.1") + .about("About foo") + .long_about("Long about foo")); + assert!(test::compare_output(app, "ctest foo -h", ISSUE_897_SHORT, false)); +}