Zsh completion arguments: Difference between revisions
Line 154: | Line 154: | ||
# parsers for each subparser | # parsers for each subparser | ||
subparser="$words[1]" | |||
curcontext="${curcontext%:*}-$ | curcontext="${curcontext%:*}-$subparser:" # <-- unecessary (?) | ||
case $ | case $subparser in | ||
(archive) | (archive) | ||
_arguments -A "-*" \ | _arguments -A "-*" \ | ||
Line 172: | Line 172: | ||
;; | ;; | ||
(*) | (*) | ||
_message "unknown sub-command: $ | _message "unknown sub-command: $subparser" | ||
;; | ;; | ||
esac | esac |
Revision as of 22:30, 24 July 2021
The _arguments
function is one method available for producing completions.
Syntax
Basics
arguments \ '( ${excludes} )${param}:[:]${message}:${action}'# ${excludes} is an array of param ${state_descr}s # arguments \ # '::one:_normal' \ # '::two:_normal' \ # '(one)::three:(foo bar baz)' # # don't complete 'three' if 'one' has been used# ${param} has different formats depending the param # (or the next param, depending on param type) # ex: '-h[show help]' # flag # ex: '1' # positional # ex: '*' # rest argument(s) # ex: '' # optional# ':' vs '::' # here ${param}:${message}:${action} is a required param # here ${param}::${message}:${action} is an optional param# ${message} is the name of the param # this is the name of the param, when referred to in other completer functions. # it gets bound to ${state_descr}.# ${action} is instructions on how to complete the next param # '1:one:' # ? valid ? # '1:one:(one two three)' # argument must be one, two, or three # '1:one:_user' # argument uses '_user' (function) to provide completionsFlag Arguments
_arguments \ {-h,--help}'[show help]' \ # param: -h/--help # desc: show help # action: (none) '-o[output file]:::_files' \ # param: -o # desc: output file # action: (complete any file)Positional Arguments
# ex: ${position}:${state_descr}:${action} _arguments \ '1:user:_users' \ # 1st positional arg (required) '2:priority:(low med high)' \ # 2nd positional arg (required) (complete to low/med/high) '3::group:_groups' \ # 3nd positional arg (optional)The argument-name is bound to
$state_descr
.Value for last defined Param
:${message}:${action} # reqd completion for prev command ::${message}:${action} # optional completion for prev command_arguments \ {-h,--help}'[show help]' \ '*::extra:(foo bar baz)' \ # any extra parameters, (complete to (foo bar baz)) ':value:(foo bar baz)' # after prev param (extra), always complete one of these wordsRest Arguments
Any arguments not consumed earlier use this completer.
*:${message}:${action} # *::${message}:${action} # *:::${message}:${action} #State Setting/Parsing
The
-C
argument enables state-setting.
This lets you determine the parser that gets used based on the state you set.local state # scope state locally _arguments -C \ '*:extra:->my-state' # sets `$state='my-state'` case $state in (my-state) _arguments '1:foo:(one two three four)' ;; esac
Strategies
TODO:
This section is unclear, requires experimentation and clarity
Subparsers
Sometimes, the use of a particular flag opens up a chain of possible sub-commands. (ex: git add, git commit, ...). This can be handled in ZSH as follows:
#compdef wtest _wtest() { # limit scope of variables used by zsh completer local context state line expl implementation # list of subparsers local -a subparsers subparsers=(archive display data) # Determine completer for subcommand # (based on 1st positional argument) _arguments -C \ {-h,--help}'[show help information]' \ '1:subcommand:compadd -a subparsers' \ '*:: :->subcmd' && return # parsers for each subparser subparser="$words[1]" curcontext="${curcontext%:*}-$subparser:" # <-- unecessary (?) case $subparser in (archive) _arguments -A "-*" \ '-a[append files to archive]' \ '-e[extract files to archive]' ;; (display) _arguments -A "-*" \ '-n[next file in archive]' \ '-p[previous file in archive]' ;; (data) _arguments -A "-*" \ '-s[shuffle order of wallpapers]' ;; (*) _message "unknown sub-command: $subparser" ;; esac } _wtest "$@"Dynamic Arguments
Generate autocomplete options based on the options that were entered previously. This can do just about anything you need it to, it's really cool. This isn't my example, and I haven't yet needed this level of flexibility yet. This example is just so clear, I had to add it.
Some Background Info:
$words[]
is an array of all arguments used so far$state
is set in_arguments
. In the below example. If completion is used for '1', the value of $state will be 'country'#compdef hello _hello() { local curcontext="$curcontext" state line ## These two lines are required, typeset -A opt_args ## they initialize some internal variables ## for your function _arguments \ ## Initial Arguments '1: :->country'\ '*: :->city' case $state in ## Expand Arguments based on their category country) _arguments '1:Countries:(France Germany Italy)' ;; *) case $words[2] in France) compadd "$@" Paris Lyon Marseille ;; Germany) compadd "$@" Berlin Munich Dresden ;; Italy) compadd "$@" Rome Napoli Palermo ;; *) _files esac esac } _hello "$@" ## Passes _hello() function all arguments that was passed to the script.