4

I have a zsh auto completion function for a command called gd which does a fuzzy search based on the $words[CURRENT] value and return suggestions. The search is working fine but zsh does not show any candidates because the entered text is not a prefix of the suggestion.

e.g.

% gd hw

Might generate the completion oh hello there, world

But zsh won't show that because hw is not found at the start of the suggestion.

Can I make zsh offer the suggestion as something that would replace the current word when chosen?

Here's a simplified version of my completion script in a file called _gd which is in my fpath:

#compdef gd

_gd() {
  local -a list

  clue="$words[CURRENT]"

      pattern=""
      for i in $(seq $#clue)
      do
        pattern="$pattern.*${clue[i]}"
      done
      while read dir
      do
        list=( $list $dir )
      done <<<$(grep "$pattern" ~/.recent-dirs)

  _describe gd list
}

2 Answers 2

2

Get rid of that _gd function and just add the following to your .zshrc file:

autoload -Uz compinit
compinit
zstyle ':completion:*' matcher-list 'r:|?=**'

This tells the completion code to allow any number of additional between and around what you’ve types. With this, Zsh can now fuzzy complete anything.

  • r:X|Y=Z looks for all non-overlapping substrings that match pattern XY and makes it so the part matched by X also matches anything matched by pattern Z when checking for matching completions.
  • ? matches any one character.
  • If X or Y equals *, it matches any number of consecutive characters.
  • If Z equals *, it matches any number of consecutive characters except anything matched by Y.
  • If Z equals **, it matches any number of consecutive characters.
  • In r:|?=**, X equals the empty string.
  • By default, Zsh already adds a wildcard to the end of your input, thus completing the circle for full fuzzy matching.

You can find the documentation over here: http://zsh.sourceforge.net/Doc/Release/Completion-Widgets.html#Completion-Matching-Control

4
0

This is hack while I wait on more wise answers...

What I've done is made my suggestion generator produce suggestions like:

hw»oh hello there, world

Because the command (actually a function) is in my control, I simply strip off the rubbish at the start:

input="${input#*»}"

But it would be nice to know how to do it properly.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .