Skip to content

Commit

Permalink
feat(Help): allows wrapping at specified term width (Even on Windows!)
Browse files Browse the repository at this point in the history
Now using `App::set_term_width` will set a wrapping width regardless of terminal size. This can
also be used when no terminal size can be determined (Such as on Windows). All help is now wrapped
at 120 if no terminal size has been specified, or can be determined.

Closes #451
  • Loading branch information
kbknapp committed Jun 14, 2016
1 parent 9088ade commit 1761dc0
Show file tree
Hide file tree
Showing 4 changed files with 49 additions and 13 deletions.
16 changes: 9 additions & 7 deletions src/app/help.rs
Original file line number Diff line number Diff line change
Expand Up @@ -80,21 +80,24 @@ pub struct Help<'a> {
writer: &'a mut Write,
next_line_help: bool,
hide_pv: bool,
term_w: Option<usize>,
term_w: usize,
color: bool,
cizer: Colorizer,
}

// Public Functions
impl<'a> Help<'a> {
/// Create a new `Help` instance.
pub fn new(w: &'a mut Write, next_line_help: bool, hide_pv: bool, color: bool, cizer: Colorizer) -> Self {
pub fn new(w: &'a mut Write, next_line_help: bool, hide_pv: bool, color: bool, cizer: Colorizer, term_w: Option<usize>) -> Self {
debugln!("fn=Help::new;");
Help {
writer: w,
next_line_help: next_line_help,
hide_pv: hide_pv,
term_w: term::dimensions().map(|(w, _)| w),
term_w: match term_w {
Some(width) => width,
None => term::dimensions().map(|(w, _)| w).unwrap_or(120),
},
color: color,
cizer: cizer,
}
Expand Down Expand Up @@ -132,7 +135,7 @@ impl<'a> Help<'a> {
use_stderr: stderr,
when: parser.color(),
};
Self::new(w, nlh, hide_v, color, cizer).write_help(parser)
Self::new(w, nlh, hide_v, color, cizer, parser.meta.term_w).write_help(parser)
}

/// Writes the parser help to the wrapped stream.
Expand Down Expand Up @@ -336,10 +339,9 @@ impl<'a> Help<'a> {
longest + 12
};
// determine if our help fits or needs to wrap
let width = self.term_w.unwrap_or(0);
let width = self.term_w;
debugln!("Term width...{}", width);
let too_long = self.term_w.is_some() &&
(spcs + str_width(h) + str_width(&*spec_vals) >= width);
let too_long = spcs + str_width(h) + str_width(&*spec_vals) >= width;
debugln!("Too long...{:?}", too_long);

// Is help on next line, if so newline + 2x tab
Expand Down
3 changes: 3 additions & 0 deletions src/app/meta.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ pub struct AppMeta<'b> {
pub usage: Option<String>,
pub help_str: Option<&'b str>,
pub disp_ord: usize,
pub term_w: Option<usize>,
pub template: Option<&'b str>,
}

Expand All @@ -32,6 +33,7 @@ impl<'b> Default for AppMeta<'b> {
disp_ord: 999,
template: None,
aliases: None,
term_w: None,
}
}
}
Expand Down Expand Up @@ -61,6 +63,7 @@ impl<'b> Clone for AppMeta<'b> {
disp_ord: self.disp_ord,
template: self.template,
aliases: self.aliases.clone(),
term_w: self.term_w,
}
}
}
33 changes: 31 additions & 2 deletions src/app/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -482,6 +482,35 @@ impl<'a, 'b> App<'a, 'b> {
self
}

/// Sets the terminal width at which to wrap help messages. Defaults to `120`.
///
/// `clap` automatically tries to determine the terminal width on Unix, Linux, and OSX if the
/// `wrap_help` cargo "feature" has been used while compiling. If the terminal width cannot be
/// determined, `clap` defaults to `120`.
///
/// **NOTE:** This setting applies globally and *not* on a per-command basis.
///
/// **NOTE:** This setting must be set **before** any subcommands are added!
///
/// # Platform Specific
///
/// Only Unix, Linux, and OSX support automatic determination of terminal width. Even on those
/// platforms, this setting is useful if for any reason the terminal width cannot be
/// determined.
///
/// # Examples
///
/// ```no_run
/// # use clap::App;
/// App::new("myprog")
/// .set_term_width(80)
/// # ;
/// ```
pub fn set_term_width(mut self, width: usize) -> Self {
self.p.meta.term_w = Some(width);
self
}

/// Adds an [argument] to the list of valid possibilties.
///
/// # Examples
Expand Down Expand Up @@ -640,7 +669,7 @@ impl<'a, 'b> App<'a, 'b> {
self
}

/// Allows adding a [`SubCommand`] alias that functions exactly like those defined with
/// Allows adding a [`SubCommand`] alias that functions exactly like those defined with
/// [`App::alias`], except that they are visible inside the help message.
///
/// # Examples
Expand All @@ -664,7 +693,7 @@ impl<'a, 'b> App<'a, 'b> {
self
}

/// Allows adding multiple [`SubCommand`] aliases that functions exactly like those defined
/// Allows adding multiple [`SubCommand`] aliases that functions exactly like those defined
/// with [`App::aliases`], except that they are visible inside the help message.
///
/// # Examples
Expand Down
10 changes: 6 additions & 4 deletions src/app/parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -195,6 +195,8 @@ impl<'a, 'b> Parser<'a, 'b>

pub fn add_subcommand(&mut self, mut subcmd: App<'a, 'b>) {
debugln!("fn=Parser::add_subcommand;");
debugln!("Term widnth...{:?}", self.p.meta.term_w);
subcmd.p.meta.term_w = self.meta.term_w;
debug!("Is help...");
if subcmd.p.meta.name == "help" {
sdebugln!("Yes");
Expand Down Expand Up @@ -532,14 +534,14 @@ impl<'a, 'b> Parser<'a, 'b>
}
} else if let Some(c) = sc.subcommands
.iter()
.filter(|s|
.filter(|s|
if let Some(ref als) = s.p
.meta
.aliases {
.aliases {
als.iter()
.any(|&(a, _)| &a == &&*cmd.to_string_lossy())
} else {
false
} else {
false
}
)
.next()
Expand Down

0 comments on commit 1761dc0

Please sign in to comment.