mirror of
https://github.com/clap-rs/clap
synced 2024-12-12 13:52:34 +00:00
Merge pull request #4258 from epage/features
fix(help)!: Wrapping is behind wrap_help
This commit is contained in:
commit
18ed37ee67
9 changed files with 65 additions and 13 deletions
14
CHANGELOG.md
14
CHANGELOG.md
|
@ -125,9 +125,12 @@ 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. Resolve compiler errors
|
||||
6. Resolve behavior changes (see "subtle changes" under BREAKING CHANGES)
|
||||
7. *At your leisure:* resolve new deprecation notices
|
||||
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
|
||||
|
||||
Example test (derive):
|
||||
```rust
|
||||
|
@ -155,7 +158,7 @@ fn verify_cli() {
|
|||
}
|
||||
```
|
||||
|
||||
Note: the idomatic / recommended way of specifying different types of args in the Builder API has changed:
|
||||
Note: the idiomatic / recommended way of specifying different types of args in the Builder API has changed:
|
||||
|
||||
Before
|
||||
```rust
|
||||
|
@ -184,10 +187,11 @@ Subtle changes (i.e. compiler won't catch):
|
|||
- `mut_arg` can no longer be used to customize help and version arguments, instead disable them (`Command::disable_help_flag`, `Command::disable_version_flag`) and provide your own (#4056)
|
||||
- Removed lifetimes from `Command`, `Arg`, `ArgGroup`, and `PossibleValue`, assuming `'static`. `string` feature flag will enable support for `String`s (#1041, #2150, #4223)
|
||||
- `arg!(--flag <value>)` is now optional, instead of required. Add `.required(true)` at the end to restore the original behavior (#4206)
|
||||
- Added default feature flags, `help`, `usage` and `error-context` (#4236)
|
||||
- Added default feature flags, `help`, `usage` and `error-context`, requiring adding them back in if `default-features = false` (#4236)
|
||||
- *(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)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -19,7 +19,7 @@
|
|||
//! * **env**: Turns on the usage of environment variables during parsing.
|
||||
//! * **unicode**: Turns on support for unicode characters (including emoji) in arguments and help messages.
|
||||
//! * **wrap_help**: Turns on the help text wrapping feature, based on the terminal size.
|
||||
//! * **string**: Allow runtime generated strings
|
||||
//! * **string**: Allow runtime generated strings (e.g. with [`Str`][crate::builder::Str]).
|
||||
//!
|
||||
//! #### Experimental features
|
||||
//!
|
||||
|
|
|
@ -1,6 +1,9 @@
|
|||
use crate::builder::Str;
|
||||
|
||||
/// A UTF-8-encoded fixed string
|
||||
///
|
||||
/// **NOTE:** To support dynamic values (i.e. `OsString`), enable the [`string`
|
||||
/// feature][crate::_features]
|
||||
#[derive(Default, Clone, Eq, PartialEq, PartialOrd, Ord, Hash)]
|
||||
pub struct OsStr {
|
||||
name: Inner,
|
||||
|
|
|
@ -1,4 +1,7 @@
|
|||
/// A UTF-8-encoded fixed string
|
||||
///
|
||||
/// **NOTE:** To support dynamic values (i.e. `String`), enable the [`string`
|
||||
/// feature][crate::_features]
|
||||
#[derive(Default, Clone, Eq, PartialEq, PartialOrd, Ord, Hash)]
|
||||
pub struct Str {
|
||||
name: Inner,
|
||||
|
|
|
@ -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() {
|
||||
|
|
|
@ -1020,10 +1020,11 @@ 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");
|
||||
}
|
||||
|
@ -1031,6 +1032,8 @@ mod test {
|
|||
#[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);
|
||||
|
@ -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);
|
||||
|
|
|
@ -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();
|
||||
|
@ -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> {
|
||||
|
|
|
@ -531,6 +531,7 @@ Options:
|
|||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(feature = "wrap_help")]
|
||||
fn issue_626_unicode_cutoff() {
|
||||
static ISSUE_626_CUTOFF: &str = "\
|
||||
Usage: ctest [OPTIONS]
|
||||
|
@ -679,6 +680,7 @@ Options:
|
|||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(feature = "wrap_help")]
|
||||
fn issue_626_panic() {
|
||||
static ISSUE_626_PANIC: &str = "\
|
||||
Usage: ctest [OPTIONS]
|
||||
|
@ -713,6 +715,7 @@ Options:
|
|||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(feature = "wrap_help")]
|
||||
fn issue_626_variable_panic() {
|
||||
for i in 10..320 {
|
||||
let _ = Command::new("ctest")
|
||||
|
@ -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
|
||||
|
@ -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:
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
|
@ -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]
|
||||
|
@ -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
|
||||
|
@ -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]
|
||||
|
|
Loading…
Reference in a new issue