Zsh Mailing List Archive
Messages sorted by: Reverse Date, Date, Thread, Author

Re: disable substring match on command name

On Mar 3,  1:08am, Amm wrote:
} zstyle ':completion:*' matcher-list '' 'r:|[._-]=** r:|=**' 'l:|=* r:|=*'
} This can cause accidental running of some different command if there is 
} spelling mistake.
} What I would like is substring match to work only on file and
} directory names. (i.e. arguments to command)

Hmm.  The matcher-list style is looked up very early by _main_complete
so details of the context (like whether you are in command position or
in the argument list) are not available.

However, you could use "zstyle -e" to examine a bit more state and set
the matcher-list accordingly.  For (incomplete) example:

  zstyle -e ':completion:*' matcher-list '(( CURRENT > 1 )) && ...'

The difficulty with this is that the quoting to assign to the $reply
array (in the part I elided with "...") gets really complicated.

Fortunately, I thought of a way to make that a little easier, by the
somewhat non-obvious trick of chaining zstyles together.

The format of the zstyle context is freeform (compsys meerly imposes a
standard set of colon-separated components) so we can put some extra
stuff at the front to create a new "style namespace".  In this case I
suggest prefixing with "word-N" where N is the value of $CURRENT.  So
first we modify your matcher-list context like so:

  zstyle 'word-*:completion:*' matcher-list \
    '' 'r:|[._-]=** r:|=**' 'l:|=* r:|=*'

Then we introduce a new matcher for word-1, which will be preferred to
the generic word-* context when looked up:

  zstyle 'word-1:completion:*' matcher-list ''

This just says not to use any matcher for the first word.  If you want
to do *some* kinds of matching on the command name (case-insensitivity,
for example) just add those to this style.

Finally we tweak the style that compsys is actually going to look up,
to have it prefix the context with the word position and then look up
the new style:

  zstyle -e ':completion:*' matcher-list \
    'zstyle -a "word-${CURRENT}:completion:$curcontext" matcher-list reply'

By stuffing the result of the chained zstyle -a into the $reply parameter,
we satisfy the requirement of "zstyle -e" to pass this back to whatever
actual lookup was done.

And presto, we have different matcher-list styles for the first word
and the rest of the words.

A few remarks for zsh-workers (please follow up there if interested):

It would be useful for "zstyle -e" if the lookup context and style name
were available in parameters.  E.g. the above trick could be made more
generic if one could do

  zstyle -e ':completion:*' matcher-list \
    'zstyle -a "word-${CURRENT}$LOOKUP" "$STYLE" reply'

The example names LOOKUP and STYLE are probably not the best choices.

Additionally, the line number for xtrace is messed up while evaluating
the "zstyle -e" command.  I *think* it ends up being the line number in
the init file (or interpreter line) where the zstyle was declared, but
it is labeled with the name of the calling function.  E.g. output from

+_main_complete:160> zstyle -a :completion::complete::: matcher-list _matchers
+_main_complete:5> zstyle -a word-2:completion::complete:: matcher-list reply

Not sure whether anything can be done about that.

Messages sorted by: Reverse Date, Date, Thread, Author