autocompletezshtab-completioncardinality

ZSH completion - Multiple items per argument


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:

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:

Is it possible to achieve this, at least the last item ([-u USER [USER...]])? Thanks a lot! :)


Solution

  • 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