Added argparse support for arguments with multiple optional values.

This commit fixes #8432 by adding put =* in an option spec to indicate that the
option takes an optional value, where subsequent uses of the option accumulate
the value (so the parsing behaviour is like =?, but the _flag_ variables are
appended to like =+). If the option didn't have a value, it appends an empty
string. As an example,. long=* -- --long=1 --long will execute
set -l _flag_long 1 '' (i.e. count $_flag_long is 2), whereas with =? instead,
you'd get set -l _flag_long (i.e. count $_flag_long is 0).

As a use case, I'm aware of git clone which has a
--recurse-submodules=[<pathspec>]: if you use it without a value, it operates on
all submodules, with a value, it operates on the given submodule.

The fish_opt function will generate an =* option spec when given both the
--optional-val and --multiple-vals options (previously, doing so was an error).
fish_opt now also accepts -m as an abbreviation for --multiple-vals, to go with
the pre-existing -o and -r abbreviations for --optional-val and --required-val.
This commit is contained in:
Isaac Oscar Gariano
2025-08-19 13:25:26 +10:00
parent 9d56cdbcbc
commit 4db61ee117
7 changed files with 58 additions and 19 deletions

View File

@@ -552,11 +552,6 @@ and echo unexpected status $status
#CHECKERR: fish_opt: o/optional-val r/required-val: options cannot be used together
# XXX FIXME the error should output -r and --optional-val: what the user used
# A repeated and optional arg makes no sense
fish_opt -s h -l help --multiple-vals --optional-val
and echo unexpected status $status
#CHECKERR: fish_opt: multiple-vals o/optional-val: options cannot be used together
# An unexpected arg not associated with a flag is an error
fish_opt -s h -l help hello
and echo unexpected status $status
@@ -598,19 +593,37 @@ fish_opt --short h -l help --multiple-vals
or echo unexpected status $status
#CHECK: h/help=+
# Repeated and optional val, short and long valid
fish_opt --short h -l help --optional-val -m
or echo unexpected status $status
#CHECK: h/help=*
# Repeated val, short and long but short not valid
fish_opt --short h -l help --multiple-vals --long-only
fish_opt --short h -ml help --long-only
or echo unexpected status $status
#CHECK: h-help=+
# Repeated and optional val, short and long but short not valid
fish_opt --short h -l help --long-only -mo
or echo unexpected status $status
#CHECK: h-help=*
# Repeated val, short only, and deleted
fish_opt -s h --multiple-vals
or echo unexpected status $status
#CHECK: h=+
fish_opt -s h --multiple-vals --long-only -d
fish_opt -s h -md --long-only
or echo unexpected status $status
#CHECK: h=+&
# Repeated and optional val, short only
fish_opt -s h -om
or echo unexpected status $status
fish_opt -s h --optional-val --multiple-vals --long-only
or echo unexpected status $status
#CHECK: h=*
#CHECK: h=*
function wrongargparse
argparse -foo -- banana
argparse a-b
@@ -735,5 +748,16 @@ begin
# CHECKERR: argparse: -valu: unknown option
end
# Check =* options
begin
set -l _flag_o previous value
argparse 'o/opt=*' -- -o non-value -oval --opt arg --opt=456
set -l
# CHECK: _flag_o '' 'val' '' '456'
# CHECK: _flag_opt '' 'val' '' '456'
# CHECK: argv 'non-value' 'arg'
# CHECK: argv_opts '-o' '-oval' '--opt' '--opt=456'
end
# Check that the argparse's are properly wrapped in begin blocks
set -l