On Fri, Nov 12, 2021 at 10:32:56PM +0300, Arseny Maslennikov wrote: > Hi! > > The doc page for _alternative (citing `info zsh`, menu item `Completion > Functions') states: > _alternative [ -O NAME ] [ -C NAME ] SPEC ... > <...> > The tags to use and the action to perform if a tag is requested are > described using the SPECs which are of the form: > 'TAG:DESCR:ACTION'. The TAGs are offered using _tags and if the > tag is requested, the ACTION is executed with the given description > DESCR. The ACTIONs are those accepted by the _arguments function > (described below), excluding the '->STATE' and '=...' forms. > <...> > > Later on, the text for _arguments advises to escape the separating > colons between the match candidate and its description in a (( )) > action spec, due to more complex spec parsing and further optional > fields. A thorough reader of the docs might think the same is > required by _alternative as well. > > I've been looking at the implementation of _alternative lately; the > function splits its specs into exactly 3 fields, delimited by `:'. The > following seems to be true: > > * the first field is delimited by the first colon; > * the second field spans from after the first field's delimiter to the > nearest colon; > * the rest of the spec is interpreted as the action field, unlike > the specs for _arguments. > On a related note: this looks so obvious with hindsight but I've found that the following way to avoid escaping the `:' works for _arguments too: function _ooo { local __ndescs=( '0:0' '1:1' '2:2' '3:3' '4:4' '5:5' '6:6' '7:7' '8:8' '9:9' 'A:10' 'B:11' 'C:12' 'D:13' 'E:14' 'F:15' ) _arguments '1:letter:(a b c y z)' '2:digit:(( "${(@)__ndescs}" ))' } The expansion of `__ndescs' happens during the action eval, and the expression does not contain any colons. This approach is surprisingly quite unpopular, especially in third-party completions — instead, the authors prefer to use a function as the action, which then calls _describe by itself (here goes another while tags; do while _next_label; do done; done loop) and does not introduce new tags.