Makes the validator functions more flexible by changing the return
type from Result<(), String> to Result<O, E> where O is anything
and E is anything convertible to a String.
This allows, for example, using the same function for validating
and parsing your argument.
Breaking change (albeit tiny) due to function signature change.
Args can now be added to custom help sections. This breaks up the builder pattern a little by adding help section declarations inline, but it's the most intuitive method and doesn't require strange nesting that feels awkward.
```rust
app::new("foo")
.arg(Arg::with_name("arg1")) // under normal headers
.help_heading("SPECIAL")
.arg(Arg::with_name("arg2")) // under SPECIAL: heading
```
Closes#805
Add logic to filter based on hidden long/short.
There is still an issue with the logic in parser.rs use_long_help. This
causes invalid evaluation of whether to show/hide based on long or short help
Complete check for use_long_help, add tests
Once can now mutate an Arg instance after it's already been added to an App struct.
This is helpful when you wish to add all the args in an non-verbose way, such as
via the usage strings, but wish for a handful to have settings which arne't posible
in the usage string definitions.
Adds the abiltiy to query the matches struct for the indices of values or flags. The index
is similar to that of an argv index, but not exactly a 1:1.
For flags (i.e. those arguments which don't have an associated value), indices refer
to occurrence of the switch, such as `-f`, or `--flag`. However, for options the indices
refer to the *values* `-o val` would therefore not represent two distinct indices, only the
index for `val` would be recorded. This is by design.
Besides the flag/option descrepancy, the primary difference between an argv index and clap
index, is that clap continues counting once all arguments have properly seperated, whereas
an argv index does not.
The examples should clear this up.
*NOTE:* If an argument is allowed multiple times, this method will only give the *first*
index.
The argv indices are listed in the comments below. See how they correspond to the clap
indices. Note that if it's not listed in a clap index, this is becuase it's not saved in
in an `ArgMatches` struct for querying.
```rust
let m = App::new("myapp")
.arg(Arg::with_name("flag")
.short("f"))
.arg(Arg::with_name("option")
.short("o")
.takes_value(true))
.get_matches_from(vec!["myapp", "-f", "-o", "val"]);
// ARGV idices: ^0 ^1 ^2 ^3
// clap idices: ^1 ^3
assert_eq!(m.index_of("flag"), Some(1));
assert_eq!(m.index_of("option"), Some(3));
```
Now notice, if we use one of the other styles of options:
```rust
let m = App::new("myapp")
.arg(Arg::with_name("flag")
.short("f"))
.arg(Arg::with_name("option")
.short("o")
.takes_value(true))
.get_matches_from(vec!["myapp", "-f", "-o=val"]);
// ARGV idices: ^0 ^1 ^2
// clap idices: ^1 ^3
assert_eq!(m.index_of("flag"), Some(1));
assert_eq!(m.index_of("option"), Some(3));
```
Things become much more complicated, or clear if we look at a more complex combination of
flags. Let's also throw in the final option style for good measure.
```rust
let m = App::new("myapp")
.arg(Arg::with_name("flag")
.short("f"))
.arg(Arg::with_name("flag2")
.short("F"))
.arg(Arg::with_name("flag3")
.short("z"))
.arg(Arg::with_name("option")
.short("o")
.takes_value(true))
.get_matches_from(vec!["myapp", "-fzF", "-oval"]);
// ARGV idices: ^0 ^1 ^2
// clap idices: ^1,2,3 ^5
//
// clap sees the above as 'myapp -f -z -F -o val'
// ^0 ^1 ^2 ^3 ^4 ^5
assert_eq!(m.index_of("flag"), Some(1));
assert_eq!(m.index_of("flag2"), Some(3));
assert_eq!(m.index_of("flag3"), Some(2));
assert_eq!(m.index_of("option"), Some(5));
```
One final combination of flags/options to see how they combine:
```rust
let m = App::new("myapp")
.arg(Arg::with_name("flag")
.short("f"))
.arg(Arg::with_name("flag2")
.short("F"))
.arg(Arg::with_name("flag3")
.short("z"))
.arg(Arg::with_name("option")
.short("o")
.takes_value(true)
.multiple(true))
.get_matches_from(vec!["myapp", "-fzFoval"]);
// ARGV idices: ^0 ^1
// clap idices: ^1,2,3^5
//
// clap sees the above as 'myapp -f -z -F -o val'
// ^0 ^1 ^2 ^3 ^4 ^5
assert_eq!(m.index_of("flag"), Some(1));
assert_eq!(m.index_of("flag2"), Some(3));
assert_eq!(m.index_of("flag3"), Some(2));
assert_eq!(m.index_of("option"), Some(5));
```
The last part to mention is when values are sent in multiple groups with a [delimiter].
```rust
let m = App::new("myapp")
.arg(Arg::with_name("option")
.short("o")
.takes_value(true)
.multiple(true))
.get_matches_from(vec!["myapp", "-o=val1,val2,val3"]);
// ARGV idices: ^0 ^1
// clap idices: ^2 ^3 ^4
//
// clap sees the above as 'myapp -o val1 val2 val3'
// ^0 ^1 ^2 ^3 ^4
assert_eq!(m.index_of("option"), Some(2));
```
For version 3, we want the args section to immediately follow
the usage section in the default help message.
One change that I am unhappy with is needing to make "write_arg"
in app/help.rs accept an extra param that makes it suppress the
extra line. This is to prevent an extra blank line from appearing
between args and options in the default help, and seems necessary,
but there might be a better way.
This adds a keys method to the internal implementation of vec_map and
adds conditional compilation in the parser to make the parser compile
with or without the vec_map dependency.
Before this commit, ansi_term was compiled anytime the `color` feature
was used. However, on Windows the `color` feature is ignored. Even so
ansi_term was compiled, and just not used. This commit fixes that by
only compiling ansi_term on non-Windows targets. Thanks to @retep998 for
the gudiance.
Closes#1155
This commit primarily changes to a lazy handling of POSIX overrides by
relying on github.com/bluss/ordermap instead of the old HashMap impl.
The ordermap allows us to keep track of which arguments arrived first,
and therefore determine which ones should be removed when an override
conflict is found.
This has the added benefit of we no longer have to do the bookkeeping to
keep track and override args as they come in, we can do it once at the
end.
Finally, ordermap allows fast Vec like iteration of the keys, which we
end up doing several times. Benching is still TBD once the v3 prep is
done, but this change should have a meaningful impact.
Contains a *MINOR* breaking change. App::write_help now requires `&mut self` instead of `&self`.
This fixes a major bug where the help message is entirely incorrect.
More can be found at https://github.com/kbknapp/clap-rs/issues/808
I've decided to make this change because it was preventing further progress.
Anyone's code who breaks the fix is trivial:
```rust
// OLD BROKEN
let app = App::new("broken");
let mut out = io::stdout();
app.write_help(&mut out).expect("failed to write to stdout");
// NEW FIX
let mut app = App::new("broken"); // <-- let mut
let mut out = io::stdout();
app.write_help(&mut out).expect("failed to write to stdout");
```
Closes#808
Optional positionals mixed with subcommands will still break this, since
I can't see how to tell which element of $line is the command than.
Mixing optional positionals with subcommands is a bit weird and awkward
though...
This changes the way we complete positionals to complete them using
_arguments, as should be done, instead of completing their uppercase name
as a string.
Currently I made it offer _files completion for all positional arguments.
This can be improved to complete actual possible values of the arguments
and only complete files if the argument truly takes them. But this will
require further changes in clap to actually have the required
functionality to get this information.
This commit removes heavy use of macros in certain functions which
drastically increased code size. Some of the macros could be turned
into functions, while others could be removed entirely.
Examples were removing arg_post_processing! which did things like
checked overrides, requirements, groups, etc. This would happen
after every argument was parsed. This macro also had several other
macros inside it, and would expand to several tens or hundreds of
lines of code.
Then add that due to borrowck and branch issues, this macro may be
included in multiple parts of a function. Unlike traditional functions
each of these uses expanded into TONS of code (just like agressive
inlining).
This commit primarily removes those arg_post_processing! calls and
breaks up the functionality into two types. The first must happen at
ever new argument (not new value, but new argument). This is pretty
cheap. The next type was moved to the end of parsing validation section
which is more expensive, but only happens once.
i.e. clap was validating each argument/value as it saw them, now it's
lazy and validates them all at once at the end. This MUCH more
efficient!
Long options take their argument either in the next word or after an
equals sign, but the Zsh completion specified that they take it either
in the same word with no separator or in the next word. See the
documentation of the Zsh _arguments function for more information.
Small correction to add a link to the source in the documentation, previously
it was a placeholder.
`rustdoc` does not appear to package assets with the docs, therefore
relative links looking for static files do not work. The links are
consistent enough on github that the static files can be directly linked
to on the master branch.
When used with `Arg::possible_values` it allows the argument value to pass validation even if
the case differs from that of the specified `possible_value`.
```rust
let m = App::new("pv")
.arg(Arg::with_name("option")
.long("--option")
.takes_value(true)
.possible_value("test123")
.case_insensitive(true))
.get_matches_from(vec![
"pv", "--option", "TeSt123",
]);
assert!(m.value_of("option").unwrap().eq_ignore_ascii_case("test123"));
```
This setting also works when multiple values can be defined:
```rust
let m = App::new("pv")
.arg(Arg::with_name("option")
.short("-o")
.long("--option")
.takes_value(true)
.possible_value("test123")
.possible_value("test321")
.multiple(true)
.case_insensitive(true))
.get_matches_from(vec![
"pv", "--option", "TeSt123", "teST123", "tESt321"
]);
let matched_vals = m.values_of("option").unwrap().collect::<Vec<_>>();
assert_eq!(&*matched_vals, &["TeSt123", "teST123", "tESt321"]);
```
Closes#1118
Currently to use these traits clap must be built with the `unstable` feature. This does not
require a nightly compiler. These traits and APIs may change without warning (hence the `unstable`
feature flag). Once they have been stablelized and the `clap-derive` crate is released the
`unstable` feature flag will no longer be required.
* bash-completions have code to use only `foo`, `foo.bash` and `_foo`
files for completion
* /usr is proper place for system-wide stuff rather than /etc
Signed-off-by: Igor Gnatenko <i.gnatenko.brain@gmail.com>
Since options have `empty_values(true)` by default, so long as another valid flag
or option came after the option in question, clap would parse it as an empty value
incorrectly. This commit forces the user to explicitly add an empty value.
`--option "" --flag` is allowed
`--option --flag` is no longer allowed unless the user has *also* set `min_values(0)`
This commit also fixes an issue where `-o=` would be parsed as a value of `Some("=")`
instead of `Some("")`.
Closes#1105
If one is using a nightly Rust compiler they should compile clap
with the `nightly` feature.
```toml
[dependencies]
clap = { version = "2.27", features = ["nightly"] }
```
This isn't required for compilation to succeed, only to take
advantage of any nightly features used by clap.
If one is compiling with `#[deny(warnings)]` this commit will cause
compilation to fail if one *does not* compile with the `nightly`
since `std::ascii::AsciiExt` is no longer required in in multiple
files as of the latest Rust nightly (Nov 6th, 2017).
Closes#1095
Prior to this commit, using `AppSettings::AllowHyphenValues` would allow
ANY argument to pass, even if there was no way it could be valid.
Imagine a CLI with only a single flag (i.e. *no value*) `--flag`, but this setting
is set. The following was valid:
```
$ prog hello
```
This commit fixes that by creating an UnknownArgument error unless the
unknown argument/value in question could legally be parsed as a value
to a valid argument.
Closes#1066
**This commit contains a breaking change in order to fix a bug.**
The only users affected are those relying on the "bug." The bug is only in code that uses
subcommands, and parent commands with arguments accepting multiple values (positionals or options)
unrestrained *and* where a value may coincide with a subcommand's name.
Imagine a CLI with a positional argument `files` that accepts multiple values but no other conditions
or parameters (just `Arg::multiple(true)`), and a subcommand `log`
Prior to this commit, the following was valid:
```
$ prog file1 file2 file3 log
```
which would be parsed as:
* files = file1, file2, file3
* subcommand = log
However, if there was a file named `log` the subcommand isn't callable.
The CLI should be designed in a way that either limits number of values so that clap knows
when `files` is done and can then look for subcommands, or other AppSettings which change
the behavior.
Possible fixes are `Arg::number_of_values`, `Arg::max_values`,
`AppSettings::ArgsNegateSubcommands`, `Arg::require_equals`,
`AppSettings::SubcommandsNegateArgs`, and more.
This *does not* affect CLIs which contain other arguments between the unrestrained multiple
value args, and the any subcommands. Such as if our example above also had a flag `-f`
The following would be parsed the same before and after this commit.
```
$ prog file1 file2 file3 -f log
```
This is because upon reaching the flag `-f`, clap stops parsing `files`.
No other breaking changes were made.
---
When using args with `multiple(true)` on options or positionals (i.e. those args that
accept values) and subcommands, one needs to consider the posibility of an argument value
being the same as a valid subcommand. By default `clap` will parse the argument in question
as a value *only if* a value is possible at that moment. Otherwise it will be parsed as a
subcommand. In effect, this means using `multiple(true)` with no additional parameters and
a possible value that coincides with a subcommand name, the subcommand cannot be called
unless another argument is passed first.
As an example, consider a CLI with an option `--ui-paths=<paths>...` and subcommand `signer`
The following would be parsed as values to `--ui-paths`.
```
$ program --ui-paths path1 path2 signer
```
This is because `--ui-paths` accepts multiple values. `clap` will continue parsing values
until another argument is reached and it knows `--ui-paths` is done.
By adding additional parameters to `--ui-paths` we can solve this issue. Consider adding
`Arg::number_of_values(1)` as discussed above. The following are all valid, and `signer`
is parsed as both a subcommand and a value in the second case.
```
$ program --ui-paths path1 signer
$ program --ui-paths path1 --ui-paths signer signer
```
Closes#1031