Skip to content

Commit

Permalink
imp(Help): automatically moves help text to the next line and wraps w…
Browse files Browse the repository at this point in the history
…hen term width is determined to be too small, or help text is too long

Now `clap` will check if it should automatically place long help
messages on the next line after the flag/option. This is determined by
checking to see if the space taken by flag/option plus spaces and values
doesn't leave enough room for the entirety of the help message, with the
single exception of of if the flag/option/spaces/values is less than 25%
of the width.

Closes #597
  • Loading branch information
kbknapp committed Aug 28, 2016
1 parent 27f5bbf commit 150964c
Showing 1 changed file with 27 additions and 8 deletions.
35 changes: 27 additions & 8 deletions src/app/help.rs
Original file line number Diff line number Diff line change
Expand Up @@ -339,8 +339,16 @@ impl<'a> Help<'a> {
} else {
try!(color!(self, "{}", arg, good));
}

let spec_vals = self.spec_vals(arg);
let h = arg.help().unwrap_or("");
let nlh = self.next_line_help || arg.is_set(ArgSettings::NextLineHelp);
let width = self.term_w;
let taken = (longest + 12) + str_width(&*spec_vals);
let force_next_line = !nlh && width >= taken && str_width(h) > (width - taken) && (taken as f32 / width as f32) > 0.25;

if arg.has_switch() {
if !(self.next_line_help || arg.is_set(ArgSettings::NextLineHelp)) {
if !(nlh || force_next_line) {
let self_len = arg.to_string().len();
// subtract ourself
let mut spcs = longest - self_len;
Expand All @@ -356,7 +364,7 @@ impl<'a> Help<'a> {

write_nspaces!(self.writer, spcs);
}
} else if !(self.next_line_help || arg.is_set(ArgSettings::NextLineHelp)) {
} else if !(nlh || force_next_line) {
write_nspaces!(self.writer, longest + 4 - (arg.to_string().len()));
}
Ok(())
Expand Down Expand Up @@ -416,19 +424,30 @@ impl<'a> Help<'a> {
let spec_vals = self.spec_vals(arg);
let mut help = String::new();
let h = arg.help().unwrap_or("");
let spcs = if self.next_line_help || arg.is_set(ArgSettings::NextLineHelp) {
let nlh = self.next_line_help || arg.is_set(ArgSettings::NextLineHelp);
debugln!("Next Line...{:?}", nlh);

// determine if our help fits or needs to wrap
let width = self.term_w;
debugln!("Term width...{}", width);

// We calculate with longest+12 since if it's already NLH we don't care
let taken = (longest + 12) + str_width(&*spec_vals);
let force_next_line = !nlh && width >= taken && str_width(h) > (width - taken) && (taken as f32 / width as f32) > 0.25;
debugln!("Force Next Line...{:?}", force_next_line);
debugln!("Force Next Line math (help_len > (width - flags/opts/spcs))...{} > ({} - {})", str_width(h), width, taken);

let spcs = if nlh || force_next_line {
8 // "tab" + "tab"
} else {
longest + 12
};
// determine if our help fits or needs to wrap
let width = self.term_w;
debugln!("Term width...{}", width);

let too_long = spcs + str_width(h) + str_width(&*spec_vals) >= width;
debugln!("Spaces: {}", spcs);

// Is help on next line, if so newline + 2x tab
if self.next_line_help || arg.is_set(ArgSettings::NextLineHelp) {
if nlh || force_next_line {
try!(write!(self.writer, "\n{}{}", TAB, TAB));
}

Expand Down Expand Up @@ -470,7 +489,7 @@ impl<'a> Help<'a> {
}
for part in help.split("{n}").skip(1) {
try!(write!(self.writer, "\n"));
if self.next_line_help || arg.is_set(ArgSettings::NextLineHelp) {
if nlh || force_next_line {
try!(write!(self.writer, "{}{}", TAB, TAB));
} else if arg.has_switch() {
write_nspaces!(self.writer, longest + 12);
Expand Down

0 comments on commit 150964c

Please sign in to comment.