* feat: adds App::with_defaults to automatically use crate_authors! and crate_version! macros
One can now use
```rust
let a = App::with_defaults("My Program");
// same as
let a2 = App::new("My Program")
.version(crate_version!())
.author(crate_authors!());
```
Closes#600
* imp(YAML Errors): vastly improves error messages when using YAML
When errors are made while developing, the panic error messages have
been improved instead of relying on the default panic message which is
extremely unhelpful.
Closes#574
* imp(Completions): uses standard conventions for bash completion files, namely '{bin}.bash-completion'
Closes#567
* imp(Help): automatically moves help text to the next line and wraps when term width is determined to be too small, or help text is too long
Now `clap` will check if it should automatically place long help
messages on the next line after the flag/option. This is determined by
checking to see if the space taken by flag/option plus spaces and values
doesn't leave enough room for the entirety of the help message, with the
single exception of of if the flag/option/spaces/values is less than 25%
of the width.
Closes#597
* tests: updates help tests to new forced new line rules
* fix(Groups): fixes some usage strings that contain both args in groups and ones that conflict with each other
Args that conflict *and* are in a group will now only display in the
group and not in the usage string itself.
Closes#616
* chore: updates dep graph
Closes#633
* chore: clippy run
* style: changes debug header to match other Rust projects
* chore: increase version
One can now use a list or single value for certain Arg YAML declarations
such as possible_values, etc.
Prior to this commit, if only a single value was desired one would have
to use the format:
```yaml
possible_values:
- value
```
But now once can use
```yaml
possible_values: value
```
Closes#614Closes#613
Using this setting requires a value delimiter be present in order to parse multiple values.
Otherwise it is assumed no values follow, and moves on to the next arg with a clean slate.
These examples demonstrate what happens when `require_delimiter(true)` is used. Notice
everything works in this first example, as we use a delimiter, as expected.
```rust
let delims = App::new("reqdelims")
.arg(Arg::with_name("opt")
.short("o")
.takes_value(true)
.multiple(true)
.require_delimiter(true))
// Simulate "$ reqdelims -o val1,val2,val3"
.get_matches_from(vec![
"reqdelims", "-o", "val1,val2,val3",
]);
assert!(delims.is_present("opt"));
assert_eq!(delims.values_of("opt").unwrap().collect::<Vec<_>>(), ["val1", "val2", "val3"]);
```
In this next example, we will *not* use a delimiter. Notice it's now an error.
```rust
let res = App::new("reqdelims")
.arg(Arg::with_name("opt")
.short("o")
.takes_value(true)
.multiple(true)
.require_delimiter(true))
// Simulate "$ reqdelims -o val1 val2 val3"
.get_matches_from_safe(vec![
"reqdelims", "-o", "val1", "val2", "val3",
]);
assert!(res.is_err());
let err = res.unwrap_err();
assert_eq!(err.kind, ErrorKind::UnknownArgument);
```
What's happening is `-o` is getting `val1`, and because delimiters are required yet none
were present, it stops parsing `-o`. At this point it reaches `val2` and because no
positional arguments have been defined, it's an error of an unexpected argument.
In this final example, we contrast the above with `clap`'s default behavior where the above
is *not* an error.
```rust
let delims = App::new("reqdelims")
.arg(Arg::with_name("opt")
.short("o")
.takes_value(true)
.multiple(true))
// Simulate "$ reqdelims -o val1 val2 val3"
.get_matches_from(vec![
"reqdelims", "-o", "val1", "val2", "val3",
]);
assert!(delims.is_present("opt"));
assert_eq!(delims.values_of("opt").unwrap().collect::<Vec<_>>(), ["val1", "val2", "val3"]);
```
imp(ArgGroup): Add multiple ArgGroups per Arg
Add the function `Arg.groups` that can take a `Vec<&'a str>` to add the `Arg` to multiple `ArgGroup`'s at once.
ex:
```rust
Arg::with_name("arg")
.groups(&["grp1", "grp2"])
```
Closes#426
Add the function `Arg.groups` that can take a `Vec<&'a str>` to add the `Arg` to multiple `ArgGroup`'s at once.
ex:
```rust
Arg::with_name("arg")
.groups(&["grp1", "grp2"])
```
Closes#426
Unlike the previous ArgGroups, which made all args in the group mutually exclusive, one can now use
`ArgGroup::multiple(true)` which allows using more than one arg in the group (i.e. they're not all
mutually exclusive). When combined with `ArgGroup::required(true)` this effectively says, "At least
one of the args must be used, and using morethan one is also OK."
Closes#533
Instead of blindly printing `[ARGS]` when only a single positional arg is present, it will now
print `[NAME]` (or `[NAME]...` for multiple values allowed)
Closes#518
Some types weren't viewable in the docs, such as `Values`, `OsValues`,
and `ArgSettings`. All these types should now be browsable in the
docs page.
Relates to #505
For example, if an arg is part of a required group, it will only appear
in the group usage string, and not in both the group as well as the arg
by itself.
Imagine a group containing two args, `arg1` and `--arg2`
OLD:
`myprog <arg1> <arg1|--arg2>`
NEW:
`myprog <arg1|--arg2>`
Closes#498
Adds three new methods of `Arg` which allow for specifying three new
types of rules.
* `Arg::required_unless`
Allows saying a particular arg is only required if a specific other arg
*isn't* present.
* `Arg::required_unless_all`
Allows saying a particular arg is only required so long as *all* the
following args aren't present
* `Arg::required_unless_one`
Allows saying a particular arg is required unless at least one of the
following args is present.
This commit introduces a new trait (`DispOrder`) with a single function
(`fn disp_order(&self) -> usize`). It is use to expose the display order
of an argument in a read-only manner.
Now if the terminal size is too small to properly wrap the help text
lines, it will default to just wrapping normalling as it should.
This is determined on a per help text basis, so because the terminal
size is too small for a single argument's help to wrap properly, all
other arguments will still wrap and align correctly. Only the one
affected argument will not align properly.
Closes#453
The `help` subcommand can now accept other subcommands as arguments to
display their help message. This is similar to how many other CLIs
already perform. For example:
```
$ myprog help mysubcmd
```
Would print the help message for `mysubcmd`. But even more, the `help`
subcommand accepts nested subcommands as well, i.e. a grandchild
subcommand such as
```
$ myprog help child grandchild
```
Would print the help message of `grandchild` where `grandchild` is a
subcommand of `child` and `child` is a subcommand of `myprog`.
Closes#416
By default `clap` now automatically wraps and aligns help strings to the
term width. i.e.
```
-o, --option <opt> some really long help
text that should be auto aligned but isn't righ
t now
```
Now looks like this:
```
-o, --option <opt> some really long help
text that should be
auto aligned but isn't
right now
```
The wrapping also respects words, and wraps at spaces so as to not cut
words in the middle.
This requires the `libc` dep which is enabled (by default) with the
`wrap_help` cargo feature flag.
Closes#428
Allows custom ordering of args within the help message. Args with a lower value will be
displayed first in the help message. This is helpful when one would like to emphasise
frequently used args, or prioritize those towards the top of the list. Duplicate values
**are** allowed. Args with duplicate display orders will be displayed in alphabetical
order.
**NOTE:** The default is 999 for all arguments.
**NOTE:** This setting is ignored for positional arguments which are always displayed in
index order.
```rust
use clap::{App, Arg};
let m = App::new("cust-ord")
.arg(Arg::with_name("a") // typically args are grouped by alphabetically by name
// Args without a display_order have a value of 999 and are
// displayed alphabetically with all other 999 args
.long("long-option")
.short("o")
.takes_value(true)
.help("Some help and text"))
.arg(Arg::with_name("b")
.long("other-option")
.short("O")
.takes_value(true)
.display_order(1) // Let's force this arg to appear *first*
// all we have to do is give it a value lower than 999
// any other args with a value of 1 would be displayed
// alphabetically with other 1 args. Then 2, then 3, etc.
.help("I should be first!"))
.get_matches_from(vec![
"cust-ord", "--help"
]);
```
The above example displays the following help message
```
cust-ord
USAGE:
cust-ord [FLAGS] [OPTIONS]
FLAGS:
-h, --help Prints help information
-V, --version Prints version information
OPTIONS:
-O, --other-option <b> I should be first!
-o, --long-option <a> Some help and text
```
Adds a setting for both `AppSettings` and an `Arg` method which allows
placing the help text for a particular argument (or all arguments via
the `AppSettings`) on the line after the argument itself and indented
once.
This is useful for when a single argument may have a very long
invocation flag, or many value names which throws off the alignment of
al other arguments. On a small terminal this can be terrible. Placing
the text on the line below the argument solves this issue. This is also
how many of the GNU utilities display their help strings for individual
arguments.
The final caes where this can be hepful is if the argument has a very
long or detailed and complex help string that will span multiple lines.
It can be visually more appealing and easier to read when those lines
don't wrap as frequently since there is more space on the next line.
Closes#427