diff --git a/CHANGELOG.md b/CHANGELOG.md index 1862cc0733c..5317af34c60 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,8 @@ and this project adheres to [Semantic Versioning](http://semver.org/). ### Breaking Changes - Made `ArgPredicate` `non_exhaustive` +- *(help)* Change default `Command::term_width` to "source format" +- *(help)* Change default `Command::max_term_width` to 100 - *(derive)* `Vec>` types are now assuming to capture occurrences ### Features @@ -18,6 +20,24 @@ and this project adheres to [Semantic Versioning](http://semver.org/). ## [Unreleased] - ReleaseDate +## [4.3.14] - 2023-07-17 + +### Features + +- `ArgAction::HelpShort` and `ArgAction::HelpLong` for explicitly specifying which style of help to display + +### Fixes + +- Skip `[OPTIONS]` in usage if a help or version `ArgAction` is used + +## [4.3.13] - 2023-07-17 + +## [4.3.12] - 2023-07-14 + +### Fixes + +- *(derive)* Don't error on enum variant field attributes + ## [4.3.11] - 2023-07-05 ### Features @@ -4329,7 +4349,10 @@ Minimum version of Rust is now v1.13.0 (Stable) * **arg** allow lifetimes other than 'static in arguments ([9e8c1fb9](https://github.com/clap-rs/clap/commit/9e8c1fb9406f8448873ca58bab07fe905f1551e5)) -[Unreleased]: https://github.com/clap-rs/clap/compare/v4.3.11...HEAD +[Unreleased]: https://github.com/clap-rs/clap/compare/v4.3.14...HEAD +[4.3.14]: https://github.com/clap-rs/clap/compare/v4.3.13...v4.3.14 +[4.3.13]: https://github.com/clap-rs/clap/compare/v4.3.12...v4.3.13 +[4.3.12]: https://github.com/clap-rs/clap/compare/v4.3.11...v4.3.12 [4.3.11]: https://github.com/clap-rs/clap/compare/v4.3.10...v4.3.11 [4.3.10]: https://github.com/clap-rs/clap/compare/v4.3.9...v4.3.10 [4.3.9]: https://github.com/clap-rs/clap/compare/v4.3.8...v4.3.9 diff --git a/CITATION.cff b/CITATION.cff index 58a6ac00630..8607431a2fd 100644 --- a/CITATION.cff +++ b/CITATION.cff @@ -3,8 +3,8 @@ cff-version: 1.2.0 message: Please cite this crate using these information. # Version information. -date-released: 2023-07-05 -version: 4.3.11 +date-released: 2023-07-17 +version: 4.3.14 # Project information. abstract: A full featured, fast Command Line Argument Parser for Rust diff --git a/Cargo.lock b/Cargo.lock index c5613e2f7d7..26d0f7d44da 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -481,9 +481,9 @@ dependencies = [ [[package]] name = "clap" -version = "4.3.11" +version = "4.3.14" dependencies = [ - "clap_builder 4.3.11", + "clap_builder 4.3.14", "clap_derive", "humantime", "once_cell", @@ -500,7 +500,7 @@ dependencies = [ name = "clap_bench" version = "0.0.0" dependencies = [ - "clap 4.3.11", + "clap 4.3.14", "criterion", "lazy_static", ] @@ -518,7 +518,7 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.3.11" +version = "4.3.14" dependencies = [ "anstream", "anstyle", @@ -542,9 +542,9 @@ dependencies = [ [[package]] name = "clap_complete" -version = "4.3.1" +version = "4.3.2" dependencies = [ - "clap 4.3.11", + "clap 4.3.14", "clap_lex 0.5.0", "is_executable", "pathdiff", @@ -558,7 +558,7 @@ dependencies = [ name = "clap_complete_fig" version = "4.3.1" dependencies = [ - "clap 4.3.11", + "clap 4.3.14", "clap_complete", "snapbox", ] @@ -567,7 +567,7 @@ dependencies = [ name = "clap_complete_nushell" version = "4.3.1" dependencies = [ - "clap 4.3.11", + "clap 4.3.14", "clap_complete", "nu-cli", "nu-command", @@ -580,7 +580,7 @@ dependencies = [ [[package]] name = "clap_derive" -version = "4.3.2" +version = "4.3.12" dependencies = [ "heck", "proc-macro2", @@ -602,7 +602,7 @@ checksum = "2da6da31387c7e4ef160ffab6d5e7f00c42626fe39aea70a7b0f1773f7dd6c1b" name = "clap_mangen" version = "0.2.12" dependencies = [ - "clap 4.3.11", + "clap 4.3.14", "roff", "snapbox", ] diff --git a/Cargo.toml b/Cargo.toml index e6fbfa05974..696fb6357ac 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -27,7 +27,7 @@ include = [ [package] name = "clap" -version = "4.3.11" +version = "4.3.14" description = "A simple to use, efficient, and full-featured Command Line Argument Parser" repository = "https://github.com/clap-rs/clap" categories = ["command-line-interface"] @@ -45,7 +45,7 @@ include.workspace = true [package.metadata.docs.rs] features = ["unstable-doc"] -rustdoc-args = ["--cfg", "docsrs"] +rustdoc-args = ["--cfg", "docsrs", "--generate-link-to-definition"] cargo-args = ["-Zunstable-options", "-Zrustdoc-scrape-examples"] [package.metadata.playground] @@ -101,8 +101,8 @@ unstable-styles = ["clap_builder/unstable-styles"] bench = false [dependencies] -clap_builder = { path = "./clap_builder", version = "=4.3.11", default-features = false } -clap_derive = { path = "./clap_derive", version = "=4.3.2", optional = true } +clap_builder = { path = "./clap_builder", version = "=4.3.14", default-features = false } +clap_derive = { path = "./clap_derive", version = "=4.3.12", optional = true } once_cell = { version = "1.12.0", optional = true } [dev-dependencies] diff --git a/clap_builder/Cargo.toml b/clap_builder/Cargo.toml index 1f4d5ac7925..6a64ace2690 100644 --- a/clap_builder/Cargo.toml +++ b/clap_builder/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "clap_builder" -version = "4.3.11" +version = "4.3.14" description = "A simple to use, efficient, and full-featured Command Line Argument Parser" repository = "https://github.com/clap-rs/clap" categories = ["command-line-interface"] diff --git a/clap_builder/src/builder/action.rs b/clap_builder/src/builder/action.rs index 79ee9238e47..2def801f401 100644 --- a/clap_builder/src/builder/action.rs +++ b/clap_builder/src/builder/action.rs @@ -257,6 +257,58 @@ pub enum ArgAction { /// # } /// ``` Help, + /// When encountered, display [`Command::print_help`][super::Command::print_help] + /// + /// # Examples + /// + /// ```rust + /// # #[cfg(feature = "help")] { + /// # use clap_builder as clap; + /// # use clap::Command; + /// # use clap::Arg; + /// let cmd = Command::new("mycmd") + /// .arg( + /// Arg::new("special-help") + /// .short('?') + /// .action(clap::ArgAction::HelpShort) + /// ); + /// + /// // Existing help still exists + /// let err = cmd.clone().try_get_matches_from(["mycmd", "-h"]).unwrap_err(); + /// assert_eq!(err.kind(), clap::error::ErrorKind::DisplayHelp); + /// + /// // New help available + /// let err = cmd.try_get_matches_from(["mycmd", "-?"]).unwrap_err(); + /// assert_eq!(err.kind(), clap::error::ErrorKind::DisplayHelp); + /// # } + /// ``` + HelpShort, + /// When encountered, display [`Command::print_long_help`][super::Command::print_long_help] + /// + /// # Examples + /// + /// ```rust + /// # #[cfg(feature = "help")] { + /// # use clap_builder as clap; + /// # use clap::Command; + /// # use clap::Arg; + /// let cmd = Command::new("mycmd") + /// .arg( + /// Arg::new("special-help") + /// .short('?') + /// .action(clap::ArgAction::HelpLong) + /// ); + /// + /// // Existing help still exists + /// let err = cmd.clone().try_get_matches_from(["mycmd", "-h"]).unwrap_err(); + /// assert_eq!(err.kind(), clap::error::ErrorKind::DisplayHelp); + /// + /// // New help available + /// let err = cmd.try_get_matches_from(["mycmd", "-?"]).unwrap_err(); + /// assert_eq!(err.kind(), clap::error::ErrorKind::DisplayHelp); + /// # } + /// ``` + HelpLong, /// When encountered, display [`Command::version`][super::Command::version] /// /// Depending on the flag, [`Command::long_version`][super::Command::long_version] may be shown @@ -299,6 +351,8 @@ impl ArgAction { Self::SetFalse => false, Self::Count => false, Self::Help => false, + Self::HelpShort => false, + Self::HelpLong => false, Self::Version => false, } } @@ -311,6 +365,8 @@ impl ArgAction { Self::SetFalse => Some(std::ffi::OsStr::new("true")), Self::Count => Some(std::ffi::OsStr::new("0")), Self::Help => None, + Self::HelpShort => None, + Self::HelpLong => None, Self::Version => None, } } @@ -323,6 +379,8 @@ impl ArgAction { Self::SetFalse => Some(std::ffi::OsStr::new("false")), Self::Count => None, Self::Help => None, + Self::HelpShort => None, + Self::HelpLong => None, Self::Version => None, } } @@ -335,6 +393,8 @@ impl ArgAction { Self::SetFalse => Some(super::ValueParser::bool()), Self::Count => Some(crate::value_parser!(u8).into()), Self::Help => None, + Self::HelpShort => None, + Self::HelpLong => None, Self::Version => None, } } @@ -348,6 +408,8 @@ impl ArgAction { Self::SetFalse => None, Self::Count => Some(AnyValueId::of::()), Self::Help => None, + Self::HelpShort => None, + Self::HelpLong => None, Self::Version => None, } } diff --git a/clap_builder/src/builder/arg.rs b/clap_builder/src/builder/arg.rs index 5bfea9ad469..d067dec1dcd 100644 --- a/clap_builder/src/builder/arg.rs +++ b/clap_builder/src/builder/arg.rs @@ -1650,6 +1650,8 @@ impl Arg { /// at runtime, nor were the conditions met for `Arg::default_value_if`, the `Arg::default_value` /// will be applied. /// + /// Like with command-line values, this will be split by [`Arg::value_delimiter`]. + /// /// # Examples /// /// First we use the default value without providing any value at runtime. @@ -1747,6 +1749,8 @@ impl Arg { /// [`.require_equals(true)`][Arg::require_equals] configuration option. These are required in /// order to unambiguously determine what, if any, value was supplied for the argument. /// + /// Like with command-line values, this will be split by [`Arg::value_delimiter`]. + /// /// # Examples /// /// For POSIX style `--color`: @@ -1893,6 +1897,8 @@ impl Arg { /// [`ArgMatches::get_one`][crate::ArgMatches::get_one] will /// return the default specified. /// + /// Like with command-line values, this will be split by [`Arg::value_delimiter`]. + /// /// # Examples /// /// In this example, we show the variable coming from the environment: @@ -2734,6 +2740,8 @@ impl Arg { /// and `Arg::default_value_if`, and the user **did not** provide this arg at runtime, nor were /// the conditions met for `Arg::default_value_if`, the `Arg::default_value` will be applied. /// + /// Like with command-line values, this will be split by [`Arg::value_delimiter`]. + /// /// # Examples /// /// First we use the default value only if another arg is present at runtime. @@ -2873,6 +2881,8 @@ impl Arg { /// **NOTE**: The conditions are stored in order and evaluated in the same order. I.e. the first /// if multiple conditions are true, the first one found will be applied and the ultimate value. /// + /// Like with command-line values, this will be split by [`Arg::value_delimiter`]. + /// /// # Examples /// /// First we use the default value only if another arg is present at runtime. diff --git a/clap_builder/src/builder/command.rs b/clap_builder/src/builder/command.rs index 2c5eb198944..c5a3dd6b8c1 100644 --- a/clap_builder/src/builder/command.rs +++ b/clap_builder/src/builder/command.rs @@ -1132,6 +1132,9 @@ impl Command { /// Defaults to current terminal width when `wrap_help` feature flag is enabled. If current /// width cannot be determined, the default is 100. /// + /// **`unstable-v5` feature**: Defaults to unbound, being subject to + /// [`Command::max_term_width`]. + /// /// **NOTE:** This setting applies globally and *not* on a per-command basis. /// /// **NOTE:** This requires the `wrap_help` feature @@ -1158,7 +1161,9 @@ impl Command { /// This only applies when [`term_width`][Command::term_width] is unset so that the current /// terminal's width will be used. See [`Command::term_width`] for more details. /// - /// Using `0` will ignore terminal widths and use source formatting (default). + /// Using `0` will ignore this, always respecting [`Command::term_width`] (default). + /// + /// **`unstable-v5` feature**: Defaults to 100. /// /// **NOTE:** This setting applies globally and *not* on a per-command basis. /// diff --git a/clap_builder/src/output/help_template.rs b/clap_builder/src/output/help_template.rs index 68ff58077e5..1ed16da7b9e 100644 --- a/clap_builder/src/output/help_template.rs +++ b/clap_builder/src/output/help_template.rs @@ -101,7 +101,23 @@ impl<'cmd, 'writer> HelpTemplate<'cmd, 'writer> { cmd.get_name(), use_long ); - let term_w = match cmd.get_term_width() { + let term_w = Self::term_w(cmd); + let next_line_help = cmd.is_next_line_help_set(); + + HelpTemplate { + writer, + cmd, + styles: cmd.get_styles(), + usage, + next_line_help, + term_w, + use_long, + } + } + + #[cfg(not(feature = "unstable-v5"))] + fn term_w(cmd: &'cmd Command) -> usize { + match cmd.get_term_width() { Some(0) => usize::MAX, Some(w) => w, None => { @@ -113,18 +129,27 @@ impl<'cmd, 'writer> HelpTemplate<'cmd, 'writer> { }; cmp::min(current_width, max_width) } + } + } + + #[cfg(feature = "unstable-v5")] + fn term_w(cmd: &'cmd Command) -> usize { + let term_w = match cmd.get_term_width() { + Some(0) => usize::MAX, + Some(w) => w, + None => { + let (current_width, _h) = dimensions(); + current_width.unwrap_or(usize::MAX) + } }; - let next_line_help = cmd.is_next_line_help_set(); - HelpTemplate { - writer, - cmd, - styles: cmd.get_styles(), - usage, - next_line_help, - term_w, - use_long, - } + let max_term_w = match cmd.get_max_term_width() { + Some(0) => usize::MAX, + Some(mw) => mw, + None => 100, + }; + + cmp::min(term_w, max_term_w) } /// Write help to stream for the parser in the format defined by the template. diff --git a/clap_builder/src/output/usage.rs b/clap_builder/src/output/usage.rs index 3f387a0d71e..884a64df960 100644 --- a/clap_builder/src/output/usage.rs +++ b/clap_builder/src/output/usage.rs @@ -4,6 +4,7 @@ #![cfg_attr(not(feature = "usage"), allow(dead_code))] // Internal +use crate::builder::ArgAction; use crate::builder::StyledStr; use crate::builder::Styles; use crate::builder::{ArgPredicate, Command}; @@ -210,6 +211,20 @@ impl<'cmd> Usage<'cmd> { debug!("Usage::needs_options_tag:iter Option is built-in"); continue; } + match f.get_action() { + ArgAction::Set + | ArgAction::Append + | ArgAction::SetTrue + | ArgAction::SetFalse + | ArgAction::Count => {} + ArgAction::Help + | ArgAction::HelpShort + | ArgAction::HelpLong + | ArgAction::Version => { + debug!("Usage::needs_options_tag:iter Option is built-in"); + continue; + } + } if f.is_hide_set() { debug!("Usage::needs_options_tag:iter Option is hidden"); diff --git a/clap_builder/src/parser/parser.rs b/clap_builder/src/parser/parser.rs index d2e198b2885..3e02d4c0bf7 100644 --- a/clap_builder/src/parser/parser.rs +++ b/clap_builder/src/parser/parser.rs @@ -1237,6 +1237,16 @@ impl<'cmd> Parser<'cmd> { debug!("Help: use_long={use_long}"); Err(self.help_err(use_long)) } + ArgAction::HelpShort => { + let use_long = false; + debug!("Help: use_long={use_long}"); + Err(self.help_err(use_long)) + } + ArgAction::HelpLong => { + let use_long = true; + debug!("Help: use_long={use_long}"); + Err(self.help_err(use_long)) + } ArgAction::Version => { let use_long = match ident { Some(Identifier::Long) => true, diff --git a/clap_complete/CHANGELOG.md b/clap_complete/CHANGELOG.md index 08a219f8dc7..6da60ee1396 100644 --- a/clap_complete/CHANGELOG.md +++ b/clap_complete/CHANGELOG.md @@ -7,6 +7,12 @@ and this project adheres to [Semantic Versioning](http://semver.org/). ## [Unreleased] - ReleaseDate +## [4.3.2] - 2023-07-05 + +### Fixes + +- *(powershell)* Attempt to allow completing `-s` separately from `-S` + ## [4.3.1] - 2023-06-02 ## [4.3.0] - 2023-05-19 @@ -147,7 +153,8 @@ MSRV changed to 1.64.0 ## [3.0.1] - 2022-01-03 -[Unreleased]: https://github.com/clap-rs/clap/compare/clap_complete-v4.3.1...HEAD +[Unreleased]: https://github.com/clap-rs/clap/compare/clap_complete-v4.3.2...HEAD +[4.3.2]: https://github.com/clap-rs/clap/compare/clap_complete-v4.3.1...clap_complete-v4.3.2 [4.3.1]: https://github.com/clap-rs/clap/compare/clap_complete-v4.3.0...clap_complete-v4.3.1 [4.3.0]: https://github.com/clap-rs/clap/compare/clap_complete-v4.2.3...clap_complete-v4.3.0 [4.2.3]: https://github.com/clap-rs/clap/compare/clap_complete-v4.2.2...clap_complete-v4.2.3 diff --git a/clap_complete/Cargo.toml b/clap_complete/Cargo.toml index f8e87de35a7..6bb5f1aa1a6 100644 --- a/clap_complete/Cargo.toml +++ b/clap_complete/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "clap_complete" -version = "4.3.1" +version = "4.3.2" description = "Generate shell completion scripts for your clap::Command" repository = "https://github.com/clap-rs/clap/tree/master/clap_complete" categories = ["command-line-interface"] diff --git a/clap_complete/README.md b/clap_complete/README.md index 4713a388743..e6f7afa7bf3 100644 --- a/clap_complete/README.md +++ b/clap_complete/README.md @@ -5,16 +5,16 @@ [![Crates.io](https://img.shields.io/crates/v/clap_complete?style=flat-square)](https://crates.io/crates/clap_complete) [![Crates.io](https://img.shields.io/crates/d/clap_complete?style=flat-square)](https://crates.io/crates/clap_complete) -[![License](https://img.shields.io/badge/license-Apache%202.0-blue?style=flat-square)](https://github.com/clap-rs/clap/blob/clap_complete-v4.3.1/LICENSE-APACHE) -[![License](https://img.shields.io/badge/license-MIT-blue?style=flat-square)](https://github.com/clap-rs/clap/blob/clap_complete-v4.3.1/LICENSE-MIT) +[![License](https://img.shields.io/badge/license-Apache%202.0-blue?style=flat-square)](https://github.com/clap-rs/clap/blob/clap_complete-v4.3.2/LICENSE-APACHE) +[![License](https://img.shields.io/badge/license-MIT-blue?style=flat-square)](https://github.com/clap-rs/clap/blob/clap_complete-v4.3.2/LICENSE-MIT) Dual-licensed under [Apache 2.0](LICENSE-APACHE) or [MIT](LICENSE-MIT). 1. [About](#about) 2. [API Reference](https://docs.rs/clap_complete) 3. [Questions & Discussions](https://github.com/clap-rs/clap/discussions) -4. [CONTRIBUTING](https://github.com/clap-rs/clap/blob/clap_complete-v4.3.1/clap_complete/CONTRIBUTING.md) -5. [Sponsors](https://github.com/clap-rs/clap/blob/clap_complete-v4.3.1/README.md#sponsors) +4. [CONTRIBUTING](https://github.com/clap-rs/clap/blob/clap_complete-v4.3.2/clap_complete/CONTRIBUTING.md) +5. [Sponsors](https://github.com/clap-rs/clap/blob/clap_complete-v4.3.2/README.md#sponsors) ## About diff --git a/clap_complete/src/shells/powershell.rs b/clap_complete/src/shells/powershell.rs index 417facf70c2..6b09b2e3ad8 100644 --- a/clap_complete/src/shells/powershell.rs +++ b/clap_complete/src/shells/powershell.rs @@ -124,7 +124,9 @@ fn generate_aliases(completions: &mut String, preamble: &String, arg: &Arg) { for alias in aliases { let _ = write!( completions, - "{preamble}'-{alias}', '{alias}', [CompletionResultType]::ParameterName, '{tooltip}')" + "{preamble}'-{alias}', '{alias}{}', [CompletionResultType]::ParameterName, '{tooltip}')", + // make PowerShell realize there is a difference between `-s` and `-S` + if alias.is_uppercase() { " " } else { "" }, ); } } diff --git a/clap_complete/tests/snapshots/aliases.ps1 b/clap_complete/tests/snapshots/aliases.ps1 index 7bc67b6a40f..5095c966091 100644 --- a/clap_complete/tests/snapshots/aliases.ps1 +++ b/clap_complete/tests/snapshots/aliases.ps1 @@ -22,16 +22,16 @@ Register-ArgumentCompleter -Native -CommandName 'my-app' -ScriptBlock { $completions = @(switch ($command) { 'my-app' { [CompletionResult]::new('-o', 'o', [CompletionResultType]::ParameterName, 'cmd option') - [CompletionResult]::new('-O', 'O', [CompletionResultType]::ParameterName, 'cmd option') + [CompletionResult]::new('-O', 'O ', [CompletionResultType]::ParameterName, 'cmd option') [CompletionResult]::new('--option', 'option', [CompletionResultType]::ParameterName, 'cmd option') [CompletionResult]::new('--opt', 'opt', [CompletionResultType]::ParameterName, 'cmd option') [CompletionResult]::new('-f', 'f', [CompletionResultType]::ParameterName, 'cmd flag') - [CompletionResult]::new('-F', 'F', [CompletionResultType]::ParameterName, 'cmd flag') + [CompletionResult]::new('-F', 'F ', [CompletionResultType]::ParameterName, 'cmd flag') [CompletionResult]::new('--flag', 'flag', [CompletionResultType]::ParameterName, 'cmd flag') [CompletionResult]::new('--flg', 'flg', [CompletionResultType]::ParameterName, 'cmd flag') [CompletionResult]::new('-h', 'h', [CompletionResultType]::ParameterName, 'Print help') [CompletionResult]::new('--help', 'help', [CompletionResultType]::ParameterName, 'Print help') - [CompletionResult]::new('-V', 'V', [CompletionResultType]::ParameterName, 'Print version') + [CompletionResult]::new('-V', 'V ', [CompletionResultType]::ParameterName, 'Print version') [CompletionResult]::new('--version', 'version', [CompletionResultType]::ParameterName, 'Print version') break } diff --git a/clap_complete/tests/snapshots/feature_sample.ps1 b/clap_complete/tests/snapshots/feature_sample.ps1 index 6f6dc5b9ec4..4d6853ee5c0 100644 --- a/clap_complete/tests/snapshots/feature_sample.ps1 +++ b/clap_complete/tests/snapshots/feature_sample.ps1 @@ -22,12 +22,12 @@ Register-ArgumentCompleter -Native -CommandName 'my-app' -ScriptBlock { $completions = @(switch ($command) { 'my-app' { [CompletionResult]::new('-c', 'c', [CompletionResultType]::ParameterName, 'some config file') - [CompletionResult]::new('-C', 'C', [CompletionResultType]::ParameterName, 'some config file') + [CompletionResult]::new('-C', 'C ', [CompletionResultType]::ParameterName, 'some config file') [CompletionResult]::new('--config', 'config', [CompletionResultType]::ParameterName, 'some config file') [CompletionResult]::new('--conf', 'conf', [CompletionResultType]::ParameterName, 'some config file') [CompletionResult]::new('-h', 'h', [CompletionResultType]::ParameterName, 'Print help') [CompletionResult]::new('--help', 'help', [CompletionResultType]::ParameterName, 'Print help') - [CompletionResult]::new('-V', 'V', [CompletionResultType]::ParameterName, 'Print version') + [CompletionResult]::new('-V', 'V ', [CompletionResultType]::ParameterName, 'Print version') [CompletionResult]::new('--version', 'version', [CompletionResultType]::ParameterName, 'Print version') [CompletionResult]::new('test', 'test', [CompletionResultType]::ParameterValue, 'tests things') [CompletionResult]::new('help', 'help', [CompletionResultType]::ParameterValue, 'Print this message or the help of the given subcommand(s)') @@ -37,7 +37,7 @@ Register-ArgumentCompleter -Native -CommandName 'my-app' -ScriptBlock { [CompletionResult]::new('--case', 'case', [CompletionResultType]::ParameterName, 'the case to test') [CompletionResult]::new('-h', 'h', [CompletionResultType]::ParameterName, 'Print help') [CompletionResult]::new('--help', 'help', [CompletionResultType]::ParameterName, 'Print help') - [CompletionResult]::new('-V', 'V', [CompletionResultType]::ParameterName, 'Print version') + [CompletionResult]::new('-V', 'V ', [CompletionResultType]::ParameterName, 'Print version') [CompletionResult]::new('--version', 'version', [CompletionResultType]::ParameterName, 'Print version') break } diff --git a/clap_complete/tests/snapshots/quoting.ps1 b/clap_complete/tests/snapshots/quoting.ps1 index 57b6691a426..cccbc79c552 100644 --- a/clap_complete/tests/snapshots/quoting.ps1 +++ b/clap_complete/tests/snapshots/quoting.ps1 @@ -29,7 +29,7 @@ Register-ArgumentCompleter -Native -CommandName 'my-app' -ScriptBlock { [CompletionResult]::new('--expansions', 'expansions', [CompletionResultType]::ParameterName, 'Execute the shell command with $SHELL') [CompletionResult]::new('-h', 'h', [CompletionResultType]::ParameterName, 'Print help') [CompletionResult]::new('--help', 'help', [CompletionResultType]::ParameterName, 'Print help') - [CompletionResult]::new('-V', 'V', [CompletionResultType]::ParameterName, 'Print version') + [CompletionResult]::new('-V', 'V ', [CompletionResultType]::ParameterName, 'Print version') [CompletionResult]::new('--version', 'version', [CompletionResultType]::ParameterName, 'Print version') [CompletionResult]::new('cmd-single-quotes', 'cmd-single-quotes', [CompletionResultType]::ParameterValue, 'Can be ''always'', ''auto'', or ''never''') [CompletionResult]::new('cmd-double-quotes', 'cmd-double-quotes', [CompletionResultType]::ParameterValue, 'Can be "always", "auto", or "never"') diff --git a/clap_complete/tests/snapshots/special_commands.ps1 b/clap_complete/tests/snapshots/special_commands.ps1 index f9e6a9da029..6a16ed3a67a 100644 --- a/clap_complete/tests/snapshots/special_commands.ps1 +++ b/clap_complete/tests/snapshots/special_commands.ps1 @@ -22,12 +22,12 @@ Register-ArgumentCompleter -Native -CommandName 'my-app' -ScriptBlock { $completions = @(switch ($command) { 'my-app' { [CompletionResult]::new('-c', 'c', [CompletionResultType]::ParameterName, 'some config file') - [CompletionResult]::new('-C', 'C', [CompletionResultType]::ParameterName, 'some config file') + [CompletionResult]::new('-C', 'C ', [CompletionResultType]::ParameterName, 'some config file') [CompletionResult]::new('--config', 'config', [CompletionResultType]::ParameterName, 'some config file') [CompletionResult]::new('--conf', 'conf', [CompletionResultType]::ParameterName, 'some config file') [CompletionResult]::new('-h', 'h', [CompletionResultType]::ParameterName, 'Print help') [CompletionResult]::new('--help', 'help', [CompletionResultType]::ParameterName, 'Print help') - [CompletionResult]::new('-V', 'V', [CompletionResultType]::ParameterName, 'Print version') + [CompletionResult]::new('-V', 'V ', [CompletionResultType]::ParameterName, 'Print version') [CompletionResult]::new('--version', 'version', [CompletionResultType]::ParameterName, 'Print version') [CompletionResult]::new('test', 'test', [CompletionResultType]::ParameterValue, 'tests things') [CompletionResult]::new('some_cmd', 'some_cmd', [CompletionResultType]::ParameterValue, 'tests other things') @@ -40,7 +40,7 @@ Register-ArgumentCompleter -Native -CommandName 'my-app' -ScriptBlock { [CompletionResult]::new('--case', 'case', [CompletionResultType]::ParameterName, 'the case to test') [CompletionResult]::new('-h', 'h', [CompletionResultType]::ParameterName, 'Print help') [CompletionResult]::new('--help', 'help', [CompletionResultType]::ParameterName, 'Print help') - [CompletionResult]::new('-V', 'V', [CompletionResultType]::ParameterName, 'Print version') + [CompletionResult]::new('-V', 'V ', [CompletionResultType]::ParameterName, 'Print version') [CompletionResult]::new('--version', 'version', [CompletionResultType]::ParameterName, 'Print version') break } @@ -48,21 +48,21 @@ Register-ArgumentCompleter -Native -CommandName 'my-app' -ScriptBlock { [CompletionResult]::new('--config', 'config', [CompletionResultType]::ParameterName, 'the other case to test') [CompletionResult]::new('-h', 'h', [CompletionResultType]::ParameterName, 'Print help') [CompletionResult]::new('--help', 'help', [CompletionResultType]::ParameterName, 'Print help') - [CompletionResult]::new('-V', 'V', [CompletionResultType]::ParameterName, 'Print version') + [CompletionResult]::new('-V', 'V ', [CompletionResultType]::ParameterName, 'Print version') [CompletionResult]::new('--version', 'version', [CompletionResultType]::ParameterName, 'Print version') break } 'my-app;some-cmd-with-hyphens' { [CompletionResult]::new('-h', 'h', [CompletionResultType]::ParameterName, 'Print help') [CompletionResult]::new('--help', 'help', [CompletionResultType]::ParameterName, 'Print help') - [CompletionResult]::new('-V', 'V', [CompletionResultType]::ParameterName, 'Print version') + [CompletionResult]::new('-V', 'V ', [CompletionResultType]::ParameterName, 'Print version') [CompletionResult]::new('--version', 'version', [CompletionResultType]::ParameterName, 'Print version') break } 'my-app;some-hidden-cmd' { [CompletionResult]::new('-h', 'h', [CompletionResultType]::ParameterName, 'Print help') [CompletionResult]::new('--help', 'help', [CompletionResultType]::ParameterName, 'Print help') - [CompletionResult]::new('-V', 'V', [CompletionResultType]::ParameterName, 'Print version') + [CompletionResult]::new('-V', 'V ', [CompletionResultType]::ParameterName, 'Print version') [CompletionResult]::new('--version', 'version', [CompletionResultType]::ParameterName, 'Print version') break } diff --git a/clap_complete/tests/snapshots/sub_subcommands.ps1 b/clap_complete/tests/snapshots/sub_subcommands.ps1 index 7256794316e..3880c2442ae 100644 --- a/clap_complete/tests/snapshots/sub_subcommands.ps1 +++ b/clap_complete/tests/snapshots/sub_subcommands.ps1 @@ -22,12 +22,12 @@ Register-ArgumentCompleter -Native -CommandName 'my-app' -ScriptBlock { $completions = @(switch ($command) { 'my-app' { [CompletionResult]::new('-c', 'c', [CompletionResultType]::ParameterName, 'some config file') - [CompletionResult]::new('-C', 'C', [CompletionResultType]::ParameterName, 'some config file') + [CompletionResult]::new('-C', 'C ', [CompletionResultType]::ParameterName, 'some config file') [CompletionResult]::new('--config', 'config', [CompletionResultType]::ParameterName, 'some config file') [CompletionResult]::new('--conf', 'conf', [CompletionResultType]::ParameterName, 'some config file') [CompletionResult]::new('-h', 'h', [CompletionResultType]::ParameterName, 'Print help') [CompletionResult]::new('--help', 'help', [CompletionResultType]::ParameterName, 'Print help') - [CompletionResult]::new('-V', 'V', [CompletionResultType]::ParameterName, 'Print version') + [CompletionResult]::new('-V', 'V ', [CompletionResultType]::ParameterName, 'Print version') [CompletionResult]::new('--version', 'version', [CompletionResultType]::ParameterName, 'Print version') [CompletionResult]::new('test', 'test', [CompletionResultType]::ParameterValue, 'tests things') [CompletionResult]::new('some_cmd', 'some_cmd', [CompletionResultType]::ParameterValue, 'top level subcommand') @@ -38,14 +38,14 @@ Register-ArgumentCompleter -Native -CommandName 'my-app' -ScriptBlock { [CompletionResult]::new('--case', 'case', [CompletionResultType]::ParameterName, 'the case to test') [CompletionResult]::new('-h', 'h', [CompletionResultType]::ParameterName, 'Print help') [CompletionResult]::new('--help', 'help', [CompletionResultType]::ParameterName, 'Print help') - [CompletionResult]::new('-V', 'V', [CompletionResultType]::ParameterName, 'Print version') + [CompletionResult]::new('-V', 'V ', [CompletionResultType]::ParameterName, 'Print version') [CompletionResult]::new('--version', 'version', [CompletionResultType]::ParameterName, 'Print version') break } 'my-app;some_cmd' { [CompletionResult]::new('-h', 'h', [CompletionResultType]::ParameterName, 'Print help') [CompletionResult]::new('--help', 'help', [CompletionResultType]::ParameterName, 'Print help') - [CompletionResult]::new('-V', 'V', [CompletionResultType]::ParameterName, 'Print version') + [CompletionResult]::new('-V', 'V ', [CompletionResultType]::ParameterName, 'Print version') [CompletionResult]::new('--version', 'version', [CompletionResultType]::ParameterName, 'Print version') [CompletionResult]::new('sub_cmd', 'sub_cmd', [CompletionResultType]::ParameterValue, 'sub-subcommand') [CompletionResult]::new('help', 'help', [CompletionResultType]::ParameterValue, 'Print this message or the help of the given subcommand(s)') @@ -55,7 +55,7 @@ Register-ArgumentCompleter -Native -CommandName 'my-app' -ScriptBlock { [CompletionResult]::new('--config', 'config', [CompletionResultType]::ParameterName, 'the other case to test') [CompletionResult]::new('-h', 'h', [CompletionResultType]::ParameterName, 'Print help (see more with ''--help'')') [CompletionResult]::new('--help', 'help', [CompletionResultType]::ParameterName, 'Print help (see more with ''--help'')') - [CompletionResult]::new('-V', 'V', [CompletionResultType]::ParameterName, 'Print version') + [CompletionResult]::new('-V', 'V ', [CompletionResultType]::ParameterName, 'Print version') [CompletionResult]::new('--version', 'version', [CompletionResultType]::ParameterName, 'Print version') break } diff --git a/clap_complete/tests/snapshots/value_hint.ps1 b/clap_complete/tests/snapshots/value_hint.ps1 index fc2bd878c7f..b228caf3c16 100644 --- a/clap_complete/tests/snapshots/value_hint.ps1 +++ b/clap_complete/tests/snapshots/value_hint.ps1 @@ -37,7 +37,7 @@ Register-ArgumentCompleter -Native -CommandName 'my-app' -ScriptBlock { [CompletionResult]::new('--cmd', 'cmd', [CompletionResultType]::ParameterName, 'cmd') [CompletionResult]::new('-u', 'u', [CompletionResultType]::ParameterName, 'u') [CompletionResult]::new('--user', 'user', [CompletionResultType]::ParameterName, 'user') - [CompletionResult]::new('-H', 'H', [CompletionResultType]::ParameterName, 'H') + [CompletionResult]::new('-H', 'H ', [CompletionResultType]::ParameterName, 'H') [CompletionResult]::new('--host', 'host', [CompletionResultType]::ParameterName, 'host') [CompletionResult]::new('--url', 'url', [CompletionResultType]::ParameterName, 'url') [CompletionResult]::new('--email', 'email', [CompletionResultType]::ParameterName, 'email') diff --git a/clap_derive/Cargo.toml b/clap_derive/Cargo.toml index e3f5bae2d95..39c7bfee418 100644 --- a/clap_derive/Cargo.toml +++ b/clap_derive/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "clap_derive" -version = "4.3.2" +version = "4.3.12" description = "Parse command line argument by defining a struct, derive crate." repository = "https://github.com/clap-rs/clap/tree/master/clap_derive" categories = ["command-line-interface", "development-tools::procedural-macro-helpers"] diff --git a/clap_derive/src/derives/subcommand.rs b/clap_derive/src/derives/subcommand.rs index 3ae74d01ad0..125a40f6105 100644 --- a/clap_derive/src/derives/subcommand.rs +++ b/clap_derive/src/derives/subcommand.rs @@ -182,7 +182,7 @@ fn gen_augment( Kind::Flatten(_) => match variant.fields { Unnamed(FieldsUnnamed { ref unnamed, .. }) if unnamed.len() == 1 => { - let ty = &unnamed[0]; + let ty = &unnamed[0].ty; let deprecations = if !override_required { item.deprecations() } else { @@ -223,7 +223,7 @@ fn gen_augment( } Unit => quote!( #subcommand_var ), Unnamed(FieldsUnnamed { ref unnamed, .. }) if unnamed.len() == 1 => { - let ty = &unnamed[0]; + let ty = &unnamed[0].ty; if override_required { quote_spanned! { ty.span()=> { @@ -293,7 +293,7 @@ fn gen_augment( } } Unnamed(FieldsUnnamed { ref unnamed, .. }) if unnamed.len() == 1 => { - let ty = &unnamed[0]; + let ty = &unnamed[0].ty; let arg_block = if override_required { quote_spanned! { ty.span()=> { @@ -390,7 +390,7 @@ fn gen_has_subcommand(variants: &[(&Variant, Item)]) -> Result { - let ty = &fields.unnamed[0]; + let ty = &fields.unnamed[0].ty; Ok(quote! { if <#ty as clap::Subcommand>::has_subcommand(__clap_name) { return true; @@ -496,7 +496,7 @@ fn gen_from_arg_matches(variants: &[(&Variant, Item)]) -> Result quote!(), Unnamed(ref fields) if fields.unnamed.len() == 1 => { - let ty = &fields.unnamed[0]; + let ty = &fields.unnamed[0].ty; quote!( ( <#ty as clap::FromArgMatches>::from_arg_matches_mut(__clap_arg_matches)? ) ) } Unnamed(..) => abort_call_site!("{}: tuple enums are not supported", variant.ident), @@ -512,7 +512,7 @@ fn gen_from_arg_matches(variants: &[(&Variant, Item)]) -> Result { - let ty = &fields.unnamed[0]; + let ty = &fields.unnamed[0].ty; Ok(quote! { if __clap_arg_matches .subcommand_name() @@ -632,7 +632,7 @@ fn gen_update_from_arg_matches(variants: &[(&Variant, Item)]) -> Result { - let ty = &fields.unnamed[0]; + let ty = &fields.unnamed[0].ty; Ok(quote! { if <#ty as clap::Subcommand>::has_subcommand(__clap_name) { if let Self :: #variant_name (child) = s { diff --git a/tests/builder/help.rs b/tests/builder/help.rs index 526bc0c6e4d..fda7a9aeb13 100644 --- a/tests/builder/help.rs +++ b/tests/builder/help.rs @@ -916,6 +916,7 @@ fn old_newline_variables() { #[test] #[cfg(feature = "wrap_help")] fn issue_688_hide_pos_vals() { + #[cfg(not(feature = "unstable-v5"))] static ISSUE_688: &str = "\ Usage: ctest [OPTIONS] @@ -927,6 +928,18 @@ Options: -V, --version Print version "; + #[cfg(feature = "unstable-v5")] + static ISSUE_688: &str = "\ +Usage: ctest [OPTIONS] + +Options: + --filter Sets the filter, or sampling method, to use for interpolation when resizing + the particle images. The default is Linear (Bilinear). [possible values: + Nearest, Linear, Cubic, Gaussian, Lanczos3] + -h, --help Print help + -V, --version Print version +"; + let filter_values = ["Nearest", "Linear", "Cubic", "Gaussian", "Lanczos3"]; let app1 = Command::new("ctest") @@ -1050,6 +1063,65 @@ Options: utils::assert_output(cmd, "myapp --help", LONG_ABOUT, false); } +#[test] +fn explicit_short_long_help() { + static SHORT_ABOUT: &str = "\ +bar + +Usage: myapp [arg1] + +Arguments: + [arg1] some option + +Options: + -? + -h, --help + -V, --version Print version +"; + + static LONG_ABOUT: &str = "\ +something really really long, with +multiple lines of text +that should be displayed + +Usage: myapp [arg1] + +Arguments: + [arg1] + some option + +Options: + -? + + + -h, --help + + + -V, --version + Print version +"; + + let cmd = Command::new("myapp") + .disable_help_flag(true) + .version("1.0") + .author("foo") + .about("bar") + .long_about( + "something really really long, with\nmultiple lines of text\nthat should be displayed", + ) + .arg(Arg::new("arg1").help("some option")) + .arg(Arg::new("short").short('?').action(ArgAction::HelpShort)) + .arg( + Arg::new("long") + .short('h') + .long("help") + .action(ArgAction::HelpLong), + ); + utils::assert_output(cmd.clone(), "myapp -?", SHORT_ABOUT, false); + utils::assert_output(cmd.clone(), "myapp -h", LONG_ABOUT, false); + utils::assert_output(cmd, "myapp --help", LONG_ABOUT, false); +} + #[test] fn ripgrep_usage() { static RIPGREP_USAGE: &str = "\ @@ -1279,7 +1351,7 @@ fn override_help_short() { } static OVERRIDE_HELP_LONG: &str = "\ -Usage: test [OPTIONS] +Usage: test Options: -h, --hell Print help @@ -1511,6 +1583,7 @@ fn hide_default_val() { #[test] #[cfg(feature = "wrap_help")] fn escaped_whitespace_values() { + #[cfg(not(feature = "unstable-v5"))] static ESCAPED_DEFAULT_VAL: &str = "\ Usage: default [OPTIONS] @@ -1521,6 +1594,17 @@ Options: -V, --version Print version "; + #[cfg(feature = "unstable-v5")] + static ESCAPED_DEFAULT_VAL: &str = "\ +Usage: default [OPTIONS] + +Options: + --arg Pass an argument to the program. [default: \"\\n\"] [possible values: normal, \" + \", \"\\n\", \"\\t\", other] + -h, --help Print help + -V, --version Print version +"; + let app1 = Command::new("default").version("0.1").term_width(120).arg( Arg::new("argument") .help("Pass an argument to the program.")