diff --git a/src/output/help.rs b/src/output/help.rs index 152955d25a8..eb53bfa5451 100644 --- a/src/output/help.rs +++ b/src/output/help.rs @@ -174,7 +174,12 @@ impl<'help, 'cmd, 'writer> Help<'help, 'cmd, 'writer> { .filter(|arg| should_show_arg(self.use_long, *arg)) { if arg.longest_filter() { - longest = longest.max(display_width(arg.to_string().as_str())); + longest = longest.max(display_width(&arg.to_string())); + debug!( + "Help::write_args_unsorted: arg={:?} longest={}", + arg.get_id(), + longest + ); } arg_v.push(arg) } @@ -189,8 +194,8 @@ impl<'help, 'cmd, 'writer> Help<'help, 'cmd, 'writer> { } /// Sorts arguments by length and display order and write their help to the wrapped stream. - fn write_args(&mut self, args: &[&Arg<'help>]) -> io::Result<()> { - debug!("Help::write_args"); + fn write_args(&mut self, args: &[&Arg<'help>], _category: &str) -> io::Result<()> { + debug!("Help::write_args {}", _category); // The shortest an arg can legally be is 2 (i.e. '-x') let mut longest = 2; let mut ord_v = Vec::new(); @@ -203,9 +208,12 @@ impl<'help, 'cmd, 'writer> Help<'help, 'cmd, 'writer> { should_show_arg(self.use_long, *arg) }) { if arg.longest_filter() { - debug!("Help::write_args: Current Longest...{}", longest); - longest = longest.max(display_width(arg.to_string().as_str())); - debug!("Help::write_args: New Longest...{}", longest); + longest = longest.max(display_width(&arg.to_string())); + debug!( + "Help::write_args: arg={:?} longest={}", + arg.get_id(), + longest + ); } // Formatting key like this to ensure that: @@ -250,7 +258,18 @@ impl<'help, 'cmd, 'writer> Help<'help, 'cmd, 'writer> { ) -> io::Result<()> { let spec_vals = &self.spec_vals(arg); - self.write_arg_inner(arg, spec_vals, next_line_help, longest)?; + self.short(arg)?; + self.long(arg)?; + self.val(arg)?; + self.align_to_about(arg, next_line_help, longest)?; + + let about = if self.use_long { + arg.long_help.or(arg.help).unwrap_or("") + } else { + arg.help.or(arg.long_help).unwrap_or("") + }; + + self.help(Some(arg), about, spec_vals, next_line_help, longest)?; if !last_arg { self.none("\n")?; @@ -330,35 +349,41 @@ impl<'help, 'cmd, 'writer> Help<'help, 'cmd, 'writer> { next_line_help: bool, longest: usize, ) -> io::Result<()> { - debug!("Help::align_to_about: arg={}", arg.name); - debug!("Help::align_to_about: Has switch..."); - if self.use_long { + debug!( + "Help::align_to_about: arg={}, next_line_help={}, longest={}", + arg.name, next_line_help, longest + ); + if self.use_long || next_line_help { // long help prints messages on the next line so it doesn't need to align text debug!("Help::align_to_about: printing long help so skip alignment"); } else if !arg.is_positional() { - debug!("Yes"); - debug!("Help::align_to_about: nlh...{:?}", next_line_help); - if !next_line_help { - let self_len = display_width(arg.to_string().as_str()); - // subtract ourself - let mut spcs = longest - self_len; - // Since we're writing spaces from the tab point we first need to know if we - // had a long and short, or just short - if arg.long.is_some() { - // Only account 4 after the val - spcs += 4; - } else { - // Only account for ', --' + 4 after the val - spcs += 8; - } + let self_len = display_width(&arg.to_string()); + // Since we're writing spaces from the tab point we first need to know if we + // had a long and short, or just short + let padding = if arg.long.is_some() { + // Only account 4 after the val + 4 + } else { + // Only account for ', --' + 4 after the val + 8 + }; + let spcs = longest + padding - self_len; + debug!( + "Help::align_to_about: positional=false arg_len={}, spaces={}", + self_len, spcs + ); - self.spaces(spcs)?; - } - } else if !next_line_help { - debug!("No, and not next_line"); - self.spaces(longest + 4 - display_width(&arg.to_string()))?; + self.spaces(spcs)?; } else { - debug!("No"); + let self_len = display_width(&arg.to_string()); + let padding = 4; + let spcs = longest + padding - self_len; + debug!( + "Help::align_to_about: positional=true arg_len={}, spaces={}", + self_len, spcs + ); + + self.spaces(spcs)?; } Ok(()) } @@ -529,29 +554,6 @@ impl<'help, 'cmd, 'writer> Help<'help, 'cmd, 'writer> { Ok(()) } - /// Writes help for an argument to the wrapped stream. - fn write_arg_inner( - &mut self, - arg: &Arg<'help>, - spec_vals: &str, - next_line_help: bool, - longest: usize, - ) -> io::Result<()> { - self.short(arg)?; - self.long(arg)?; - self.val(arg)?; - self.align_to_about(arg, next_line_help, longest)?; - - let about = if self.use_long { - arg.long_help.or(arg.help).unwrap_or("") - } else { - arg.help.or(arg.long_help).unwrap_or("") - }; - - self.help(Some(arg), about, spec_vals, next_line_help, longest)?; - Ok(()) - } - /// Will use next line help on writing args. fn will_args_wrap(&self, args: &[&Arg<'help>], longest: usize) -> bool { args.iter() @@ -854,7 +856,7 @@ impl<'help, 'cmd, 'writer> Help<'help, 'cmd, 'writer> { self.none("\n\n")?; } self.warning("OPTIONS:\n")?; - self.write_args(&non_pos)?; + self.write_args(&non_pos, "OPTIONS")?; first = false; } if !custom_headings.is_empty() { @@ -876,7 +878,7 @@ impl<'help, 'cmd, 'writer> Help<'help, 'cmd, 'writer> { self.none("\n\n")?; } self.warning(format!("{}:\n", heading))?; - self.write_args(&args)?; + self.write_args(&args, heading)?; first = false } } @@ -1079,10 +1081,10 @@ impl<'help, 'cmd, 'writer> Help<'help, 'cmd, 'writer> { "options" => { // Include even those with a heading as we don't have a good way of // handling help_heading in the template. - self.write_args(&self.cmd.get_non_positionals().collect::>())?; + self.write_args(&self.cmd.get_non_positionals().collect::>(), "options")?; } "positionals" => { - self.write_args(&self.cmd.get_positionals().collect::>())?; + self.write_args(&self.cmd.get_positionals().collect::>(), "positionals")?; } "subcommands" => { self.write_subcommands(self.cmd)?;