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.

In more detail:

  • ?= matches any one character.
  • r:|? matches any substring that ends (r) in ? (any one character).
  • r:|?=* says, in your input, from left to right, find a substring that ends in ? (any one character), insert a * (wildcard, which matches any number of characters) into the position indicated by the | and try to find completion matches with that. If that fails, find the next such input substring, until you either find one or more completion matches or you run out of substrings.
  • r:|?=** says, in your input, find every substring that ends in ? (any one character), insert a wildcard (*) into every position indicated by the | and try to find completion matches with that.
  • Finally, 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 .