-
-
Notifications
You must be signed in to change notification settings - Fork 1.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Aliases the other way around (POSIX style) #970
Comments
This accomplishes 95% of what you're looking for: .arg(flag("foo"))
.arg(flag("no-foo").overrides_with("foo"))
.arg(flag("bar")
.takes_value(true)
.possible_values(&["0", "1"])
.default_value("0")
.default_value_if("baz", None, "1"))
.arg(flag("baz"))
.arg(flag("no-baz").overrides_with_all(&["baz", "foo"])) The The the above solution meet what you're looking for, or are there additional details I'm missing? |
The Also, if I just provide the option And if I just give the Maybe other scenarios would fail too... Not sure if my description of the problem was clear enough. The idea is that:
I sure didn't provide all possible scenarios in the examples I gave before. Let me try a complete list now:
(empty means option is not present) |
As for the separate issue, I opened #976. |
I greatly appreciate the additional details! 👍 The parts that jump out at me are going to be things like struct Args {
foo: bool,
bar: i32 // for simplicity
}
let matches = /* skpped */.get_matches();
let a = Args {
foo: matches.is_present("foo") || matches.is_present("baz"),
bar: matches.value_of("bar").unwrap() // all the encoding in clap made this unwrap safe
}; That isn't to say I can't make a feature to imply another arg, as requiring already works. Right now, if one requires a flag it arbitrarily The way requirements work, if a required arg is missing it throws an error. But it'd be super easy to add a check if the required arg is actually a flag, and just include it as if it was used. |
In a usual POSIX implementation I would be able to do so with something like (replaced foo, no-foo, bar, baz, no-baz by a, b, c, d, e respectively): int c, errflg = 0;
bool foo = FALSE; // no-foo is the default
char* bar = NULL;
while ((c = getopt(argc, argv, ":abc:de")) != -1) {
switch(c) {
case 'a': // foo
foo = TRUE;
break;
case 'b': // no-foo
foo = FALSE;
break;
case 'c': // bar
bar = optarg;
break;
case 'd': // baz
foo = TRUE;
bar = "1";
break;
case 'e': // no-baz
foo = FALSE;
bar = "0";
break;
case ':': // -c without operand
fprintf(stderr, "Option -%c requires an operand\n", optopt);
errflg++;
break;
case '?':
fprintf(stderr, "Unrecognized option: '-%c'\n", optopt);
errflg++;
}
} The loop iterating the options in order guarantees that later options will override previous ones, and I'll get the result from the table above, in the previous comment, for each case. I could not figure out a way to achieve the same in clap. Declaring |
to better organize options. These are the changes: - color will have default value of "never" if --vimgrep is given, and only if no --color option is given - last overrides previous: --line-number and --no-line-number, --heading and --no-heading, --with-filename and --no-filename, and --vimgrep and --count - no heading will be show if --vimgrep is defined. This worked inside vim actually because heading is also only shown if tty is stdout (which is not the case when rg is called from vim). Unfortunately, clap does not behave like a usual GNU/POSIX in some cases, as reported in clap-rs/clap#970 and clap-rs/clap#976 (having all the bells and whistles, on the other hand). So we still have issues like rg failing when same argument is given more than once (unless for the few ones marked with `multiple(true)`), or having unintuitive precedence rules (and probably non-intentional, just there because of clap's limitations) like: - --no-filename over --vimgrep - --no-line-number over --column, --pretty or --vimgrep - --no-heading over --pretty regardless of the order in which options where given, where the desired behavior would be that the last option would override the previous ones given.
This was the piece of information I was missing. In my mind, a flag being either present or not doesn't really matter when it appeared in the argv, just that it either did or didn't. What you're saying that it matters where it appears, as to whether or not it should be counted as present (i.e. if another flag overrides it, etc.) This change is doable by me relaxing the requirements for flags. Let me play with some implementations and I'll get this knocked out. |
This should be good now with 2.30.0. Feel free to re-open if there is something we're missing. |
Clap 2.24.1 and rust 1.12 are currently being used.
Suppose I have defined these:
And I want to have two other options that work as aliases for the previous ones:
--baz
=--foo --bar=1
--no-baz
=--no-foo --bar=0
and they would also override the individual options in POSIX style. So for example:
--baz --bar=0
yields only foo, and bar with value 0--no-baz --foo
also yields only foo, and bar with value 0--no-foo --baz
yields only foo, and bar with value 1--bar=1 --no-baz
yields only no-foo, and bar with value 0Any way to accomplish this with current clap implementation just by using the args builder?
(Note for maybe another issue: Not sure if
flag("bar").overrides_with("bar")
is valid. The idea is that only the last provided value should be used. E.g.--bar=0 --bar=1
should yield bar with value 1. Curiously, it works when at least 2 of the same option are given. But it fails withThe argument '--bar' was provided more than once, but cannot be used multiple times
when 3 or more are given...)The text was updated successfully, but these errors were encountered: