Currently I have this in my ~/.zshrc
:
zstyle ':completion:*' matcher-list 'm:{a-z}={A-Za-z}' 'r:|[._-]=* r:|=*' 'l:|=* r:|=*'
AFAIU 'm:{a-z}={A-Za-z}'
means that I will get case-insensitive tab completion, e.g. foo
will tab-complete to Foobar
(if that exists). And 'r:|[._-]=* r:|=*' 'l:|=* r:|=*'
means that I will get matches for later parts of a word, e.g. bar
will tab-complete to foobar
(if that exists). But those partial matches are not case-insensitive. So for example bar
will not tab-complete to FooBar
(again, in case that exists).
Is there a way to get that working?
The matchers in your matcher-list
are always tried one at a time, until one of them returns at least one match. By default, each matcher completely replaces the previous one. To instead make the next matcher include the previous one, you need to prefix it with +
:
zstyle ':completion:*' matcher-list \
'm:{[:lower:]}={[:upper:]}' \
'+r:|[._-]=* r:|=*' \
'+l:|=*'
See the matcher-list
completion style doc.
And
'r:|[._-]=* r:|=*' 'l:|=* r:|=*'
means that I will get matches for later parts of a word, e.g.bar
will tab-complete tofoobar
(if that exists).
Not exactly:
<word>
is the string on the command line that’s being completed, then, by default, Zsh will return completions matching the glob pattern <word>*
— except when COMPLETE_IN_WORD
is set, which case it will create a completion pattern by inserting the *
at the cursor position instead.r:|[._-]=*
means “For each occurrence in <word>
of the empty string followed to the right (r
) by .
, _
or -
, insert *
between them (|
) in the completion pattern.”r:|=*
means “If <word>
ends on the right with an empty string (which is always true), suffix the completion pattern with *
.”l:|=*
means “If <word>
starts on the left with an empty string (always true), prefix the completion pattern with *
.”See the completion matching control docs for a more in-depth explanation.