I'm writing a zsh completion for some program, and parts of it involves completing resource routes (/they/look/like/this
).
I have a command mycmd
that I can use to generate some completion candidates of resource routes, and provide completions for my program, using:
_multi_parts '/' "($(mycmd /some/resource/id))"
Now, I would like to implement a specific behavior to match resources that contain the last identifier in my query, not only those that start with it.
For example, $(mycmd "/resource/identifier/bc")
gives completions like :
/resource/identifier/abc456/
/resource/identifier/123abcXYZ/
We get resource names whose identifier contains bc
, which is the intended behavior.
Now here is the problem: zsh completion prevents these completions from showing up, because none of them matches "/resource/identifier/bc*"
, the default pattern for zsh.
I read the documentation for ZSH _multi_parts
, compadd
. It appears that using -M <pattern>
described in compadd
doc and available for _multi_parts
could do the trick, by specifying a custom pattern for completion as described in ZSH Matching Control documentation. However this doc is lacking useful examples and is overall very obscure to me.
I spent hours of trials and errors to find the right pattern argument for _multi_parts -M <pattern>
to achieve what I want with no success. Any hint on this would be much appreciated.
EDIT: actually, simply ignoring the last resource identifier bc
would also work. I did not manage to do this either using -M
.
Finally found out how to do this. The correct specification is:
_multi_parts -M 'l:|=*' '/' $completions
The pattern l:|=*
allows to recognize matches which contain extra character after the string on the command line.
Looking at zsh completion log below (C-x ?
), we find that it also uses patterns r:|/=* r:|=*
.
In my understanding, using both r:|=*
and l:|=*
allows recognizing any completion candidate -- which is fine in my case, since filtering relevant suggestions is done with $mycmd
.
Extract from ZSH completion log:
+_multi_parts:94> compadd -O tmp1 -M 'r:|/=* r:|=* l:|=*' - ENSG00000170615_SLC26A5_NT
+_multi_parts:96> [[ 1 -eq 0 ]]
+_multi_parts:99> [[ 1 -eq 1 ]]
+_multi_parts:106> [[ SLC = */* ]]
+_multi_parts:109> matches=( ENSG00000170615_SLC26A5_NT/ )
+_multi_parts:111> PREFIX=/run/echolocation_example/SLC
+_multi_parts:112> SUFFIX=''
+_multi_parts:114> [[ 0 -ne 0 ]]
+_multi_parts:115> zstyle -t :completion::complete:pelican:argument-2: expand suffix
+_multi_parts:119> (( 1 ))
+_multi_parts:120> compadd -p /run/echolocation_example/ -r / -S / -M 'r:|/=* r:|=* l:|=*' - ENSG00000170615_SLC26A5_NT