(or emacs irrelevant)

Better fuzzy matching support in Ivy

Recently, I wrote some code to add better highlighting for Ivy's fuzzy matcher. Here's a quick step-by-step to get an equivalent of flx-ido-mode working with Ivy.

Step 1: install the packages

M-x package-install - counsel and flx (MELPA should be configured).

Step 2: configure ivy-re-builders-alist

Here's the default setting:

(setq ivy-re-builders-alist
      '((t . ivy--regex-plus)))

The default matcher will use a .* regex wild card in place of each single space in the input. If you want to use the fuzzy matcher, which instead uses a .* regex wild card between each input letter, write this in your config:

(setq ivy-re-builders-alist
      '((t . ivy--regex-fuzzy)))

You can also mix the two regex builders, for example:

(setq ivy-re-builders-alist
      '((ivy-switch-buffer . ivy--regex-plus)
        (t . ivy--regex-fuzzy)))

The t key is used for all fall-through cases, otherwise the key is the command or collection name.

The fuzzy matcher often results in substantially more matching candidates than the regular one for similar input. That's why some kind of sorting is important to bring the more relevant matching candidates to the start of the list. Luckily, that's already been figured out in flx, so to have it working just make sure that the flx package is installed.

Step 3: optionally configure ivy-initial-inputs-alist

The ivy-initial-inputs-alist variable is pretty useful in conjunction with the default matcher. It's usually used to insert ^ into the input area for certain commands.

If you're going fuzzy all the way, you can do without the initial ^, and simply let flx (hopefully) sort the matches in a nice way:

(setq ivy-initial-inputs-alist nil)

The result

Here's how M-x counsel-M-x looks like now:

ivy-flx-highlight.png