Skip to content

Commit

Permalink
fix(help)!: Wrapping is behind wrap_help
Browse files Browse the repository at this point in the history
If users don't want `wrap_help` feature, they can put newlines in where
needed.  Seems odd to support wrapping when the wrap size is fixed.  For
those hard coding the lines, this will save them a decent amount of
size.
  • Loading branch information
epage committed Sep 26, 2022
1 parent bac3eb3 commit 3c9bca5
Show file tree
Hide file tree
Showing 6 changed files with 53 additions and 8 deletions.
5 changes: 4 additions & 1 deletion CHANGELOG.md
Expand Up @@ -125,7 +125,9 @@ Steps:
2. *If using Builder API*: Explicitly set the `arg.action(ArgAction::...)` on each argument (`StoreValue` for options and `IncOccurrences` for flags)
3. Run `cargo check --features clap/deprecated` and resolve all deprecation warnings
4. Upgrade to v4
5. *If `default-features = false`*, run `cargo add clap -F help,usage,error-context`
5. Update feature flags
- *If `default-features = false`*, run `cargo add clap -F help,usage,error-context`
- Run `cargo add clap -F wrap_help` unless you want to hard code line wraps
6. Resolve compiler errors
7. Resolve behavior changes (see "subtle changes" under BREAKING CHANGES)
8. *At your leisure:* resolve new deprecation notices
Expand Down Expand Up @@ -189,6 +191,7 @@ Subtle changes (i.e. compiler won't catch):
- *(parser)* Always fill in `""` argument for external subcommands to make it easier to distinguish them from built-in commands (#3263)
- *(parser)* Short flags now have higher precedence than hyphen values with `Arg::allow_hyphen_values`, to be consistent with `Command::allow_hyphen_values` (#4187)
- *(parser)* `Arg::value_terminator` must be its own argument on the CLI rather than being in a delimited list (#4025)
- *(help)* Line wrapping of help is now behind the existing `wrap_help` feature flag, either enable it or hard code your wraps (#4258)
- *(help)* Make `DeriveDisplayOrder` the default and removed the setting. To sort help, set `next_display_order(None)` (#2808)
- *(help)* Subcommand display order respects `Command::next_display_order` instead of `DeriveDisplayOrder` and using its own initial display order value (#2808)
- *(help)* Subcommands are now listed before arguments. To get the old behavior, see `Command::help_template` (#4132)
Expand Down
2 changes: 1 addition & 1 deletion Cargo.toml
Expand Up @@ -77,7 +77,7 @@ suggestions = ["dep:strsim", "error-context"]
deprecated = ["clap_derive?/deprecated"] # Guided experience to prepare for next breaking release (at different stages of development, this may become default)
derive = ["clap_derive", "dep:once_cell"]
cargo = ["dep:once_cell"] # Disable if you're not using Cargo, enables Cargo-env-var-dependent macros
wrap_help = ["dep:terminal_size"]
wrap_help = ["help", "dep:terminal_size"]
env = [] # Use environment variables during arg parsing
unicode = ["dep:unicode-width", "dep:unicase"] # Support for unicode characters in arguments and help messages
string = [] # Allow runtime generated strings
Expand Down
5 changes: 4 additions & 1 deletion src/builder/styled_str.rs
Expand Up @@ -101,7 +101,10 @@ impl StyledStr {
}
}

#[cfg(feature = "help")]
#[cfg(all(not(feature = "wrap_help"), feature = "help"))]
pub(crate) fn wrap(&mut self, _hard_width: usize) {}

#[cfg(feature = "wrap_help")]
pub(crate) fn wrap(&mut self, hard_width: usize) {
let mut wrapper = crate::output::textwrap::wrap_algorithms::LineWrapper::new(hard_width);
for (_, content) in self.iter_mut() {
Expand Down
9 changes: 7 additions & 2 deletions src/output/help_template.rs
Expand Up @@ -1020,17 +1020,20 @@ fn longest_filter(arg: &Arg) -> bool {

#[cfg(test)]
mod test {
use super::*;

#[test]
#[cfg(feature = "wrap_help")]
fn wrap_help_last_word() {
use super::*;

let help = String::from("foo bar baz");
assert_eq!(wrap(&help, 5), "foo\nbar\nbaz");
}

#[test]
#[cfg(feature = "unicode")]
fn display_width_handles_non_ascii() {
use super::*;

// Popular Danish tongue-twister, the name of a fruit dessert.
let text = "rødgrød med fløde";
assert_eq!(display_width(text), 17);
Expand All @@ -1042,6 +1045,8 @@ mod test {
#[test]
#[cfg(feature = "unicode")]
fn display_width_handles_emojis() {
use super::*;

let text = "😂";
// There is a single `char`...
assert_eq!(text.chars().count(), 1);
Expand Down
9 changes: 9 additions & 0 deletions src/output/textwrap/mod.rs
Expand Up @@ -5,9 +5,12 @@
//! - `LineWrapper` is able to incrementally wrap which will help with `StyledStr

pub(crate) mod core;
#[cfg(feature = "wrap_help")]
pub(crate) mod word_separators;
#[cfg(feature = "wrap_help")]
pub(crate) mod wrap_algorithms;

#[cfg(feature = "wrap_help")]
pub(crate) fn wrap(content: &str, hard_width: usize) -> String {
let mut wrapper = wrap_algorithms::LineWrapper::new(hard_width);
let mut total = Vec::new();
Expand All @@ -19,7 +22,13 @@ pub(crate) fn wrap(content: &str, hard_width: usize) -> String {
total.join("")
}

#[cfg(not(feature = "wrap_help"))]
pub(crate) fn wrap(content: &str, _hard_width: usize) -> String {
content.to_owned()
}

#[cfg(test)]
#[cfg(feature = "wrap_help")]
mod test {
/// Compatibility shim to keep textwrap's tests
fn wrap(content: &str, hard_width: usize) -> Vec<String> {
Expand Down
31 changes: 28 additions & 3 deletions tests/builder/help.rs
Expand Up @@ -531,6 +531,7 @@ Options:
}

#[test]
#[cfg(feature = "wrap_help")]
fn issue_626_unicode_cutoff() {
static ISSUE_626_CUTOFF: &str = "\
Usage: ctest [OPTIONS]
Expand Down Expand Up @@ -679,6 +680,7 @@ Options:
}

#[test]
#[cfg(feature = "wrap_help")]
fn issue_626_panic() {
static ISSUE_626_PANIC: &str = "\
Usage: ctest [OPTIONS]
Expand Down Expand Up @@ -713,6 +715,7 @@ Options:
}

#[test]
#[cfg(feature = "wrap_help")]
fn issue_626_variable_panic() {
for i in 10..320 {
let _ = Command::new("ctest")
Expand All @@ -731,6 +734,7 @@ fn issue_626_variable_panic() {
}

#[test]
#[cfg(feature = "wrap_help")]
fn final_word_wrapping() {
static FINAL_WORD_WRAPPING: &str = "\
Usage: ctest
Expand All @@ -748,7 +752,10 @@ Options:
utils::assert_output(cmd, "ctest --help", FINAL_WORD_WRAPPING, false);
}

static WRAPPING_NEWLINE_CHARS: &str = "\
#[test]
#[cfg(feature = "wrap_help")]
fn wrapping_newline_chars() {
static WRAPPING_NEWLINE_CHARS: &str = "\
Usage: ctest [mode]
Arguments:
Expand All @@ -763,8 +770,6 @@ Options:
-V, --version Print version information
";

#[test]
fn wrapping_newline_chars() {
let cmd = Command::new("ctest")
.version("0.1")
.term_width(60)
Expand All @@ -777,7 +782,23 @@ fn wrapping_newline_chars() {
}

#[test]
#[cfg(feature = "wrap_help")]
fn wrapping_newline_variables() {
static WRAPPING_NEWLINE_CHARS: &str = "\
Usage: ctest [mode]
Arguments:
[mode] x, max, maximum 20 characters, contains symbols.
l, long Copy-friendly, 14 characters,
contains symbols.
m, med, medium Copy-friendly, 8 characters,
contains symbols.
Options:
-h, --help Print help information
-V, --version Print version information
";

let cmd = Command::new("ctest")
.version("0.1")
.term_width(60)
Expand All @@ -790,6 +811,7 @@ fn wrapping_newline_variables() {
}

#[test]
#[cfg(feature = "wrap_help")]
fn dont_wrap_urls() {
let cmd = Command::new("Example")
.term_width(30)
Expand Down Expand Up @@ -849,6 +871,7 @@ fn old_newline_variables() {
}

#[test]
#[cfg(feature = "wrap_help")]
fn issue_688_hide_pos_vals() {
static ISSUE_688: &str = "\
Usage: ctest [OPTIONS]
Expand Down Expand Up @@ -1147,6 +1170,7 @@ Options:
}

#[test]
#[cfg(feature = "wrap_help")]
fn issue_777_wrap_all_things() {
static ISSUE_777: &str = "A cmd with a crazy very long long
long name hahaha 1.0
Expand Down Expand Up @@ -1423,6 +1447,7 @@ fn hide_default_val() {
}

#[test]
#[cfg(feature = "wrap_help")]
fn escaped_whitespace_values() {
static ESCAPED_DEFAULT_VAL: &str = "\
Usage: default [OPTIONS]
Expand Down

0 comments on commit 3c9bca5

Please sign in to comment.