I am attempting to write a completion plugin for YunoHost. I am struggling with the following case, where an argument, optional or not, can take multiple values:
ynh app addaccess apps [apps ...] [-u [USERS [USERS ...]]]
Typical usage:
ynh app addaccess foo-app1 bar-app2 -u barfoo1 foobar2
I've managed to get suggestions for those two parameters apps
and USERS
with the following code but I can't have a behavior coherent with what the command can handle.
(_ynh_app_list
and _ynh_users_list
are calls to compadd
)
_yunohost_app_addaccess() {
_arguments -s -C \
'1:apps:_ynh_app_list' \
'*'{-u,--users}'[users]:users:_ynh_users_list'
}
The code above kinda works, except:
-u
takes a single user (multiple -u
instances are valid though)I tried *:apps:_ynh_app_list
, but ynh app addaccess foo-app1 -u user1 <TAB>
calls _ynh_app_list
instead of _ynh_users_list
What I would like to get is:
ynh app addaccess <TAB>
shows the completions provided by __ynh_app_list
ynh app addaccess foo-app1 <TAB>
still shows the completions provided by __ynh_app_list
-u
is entered, and whatever the number of words after -u
, all completion suggestions should come from __ynh_users_list
: yunohost app addaccess foo-app1 bar-app2 -u barfoo1 foobar2 <TAB>
still completes with a username form __ynh_users_list
Is it possible to achieve this, at least the last item ([-u USER [USER...]]
)? Thanks a lot! :)
To use a list of exclusion option/argument functionality could rescue:
_yunohost_app_addaccess() {
_arguments -s -C \
{1,'*'}:apps:_ynh_app_list \
'(*)'{-u,--users}'[users]:*:users:_ynh_users_list'
}
The ynh addaccess app [APPS ...]
portion could be done by the normal argument SPECs; 1:MESSAGE:ACTION
and *:MESSAGE:ACTION
.
Shorthanded by a brace expansion: {1,'*'}:apps:_ynh_app_list
The [-u USER [USER...]]
portion could be done by the OPTSPECs with a preceded list of exclusions and :*PATTERN:MESSAGE:ACTION
with empty PATTERN
; '(*)-OPTNAME[EXPLANATION]:*:MESSAGE:ACTION'
.
Here is the zsh manual for the list of exclusions for a reference:
_arguments
...
...
Each of the forms above may be preceded by a list in parentheses of option names and argument numbers. If the given option is on the command line, the options and arguments indicated in parentheses will not be offered. For example,(-two -three 1)-one:...
completes the option-one
; if this appears on the command line, the options-two
and-three
and the first ordinary argument will not be completed after it.(-foo):...
specifies an ordinary argument completion;-foo
will not be completed if that argument is already present.Other items may appear in the list of excluded options to indicate various other items that should not be applied when the current specification is matched: a single star (
*
) for the rest arguments (i.e. a specification of the form*:...
); a colon (:
) for all normal (non-option-) arguments; and a hyphen (-
) for all options. For example, if(*)
appears before an option and the option appears on the command line, the list of remaining arguments (those shown in the above table beginning with*:
) will not be completed.--- zshcompsys(1),
_arguments
, zshcompsys - zsh completion system