feat(Help): allows wrapping at specified term width (Even on Windows!)

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
This commit is contained in:
Kevin K 2016-06-13 21:45:24 -04:00
parent 9088ade4f3
commit 1761dc0d27
4 changed files with 49 additions and 13 deletions

View file

@ -80,7 +80,7 @@ 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,
}
@ -88,13 +88,16 @@ pub struct Help<'a> {
// 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,
}
@ -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.
@ -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

View file

@ -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>,
}
@ -32,6 +33,7 @@ impl<'b> Default for AppMeta<'b> {
disp_ord: 999,
template: None,
aliases: None,
term_w: None,
}
}
}
@ -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,
}
}
}

View file

@ -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
@ -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
@ -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

View file

@ -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");
@ -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()