Cool Emacs

Input Completiton

Emacs consists of a massive set of tools with a long history. Therefore, whatever the problem is, someone likely has already created a package for it. In many cases, this package is already baked in Emacs. This is great for veterans but very confusing to newcomers - like me.

The three modes

Emacs comes with three modes for input completion: Icomplete, IDO, and FIDO. Input completion works with whatever you select in the Minibuffer section. For text competition, you must use a different solution, like Company mode1.

The oldest one of those is icomplete2 mode. It allows you to select from a list of choices incrementally3, so you need to type the beginning, and icomplete will narrow the list of propositions. For example, when searching for “magit”, the user needs to type “m” first as omitting it and starting with “i” will instead narrow to options beginning with “i”. Similarly, “mgt” will not limit to “magit” as we’re missing"a". Newer Emacs versions allowallow us to use “flex” matching with icomplete, but more on this later. Incomplete work for all lists using a mini buffer, like filenames or imenu.

Then IDO4 mode (Interactively Do) came in. It uses the aforementioned “flex” matching, where you can search for any part of the word. “Magit” would be found with “agit”, “mgt” or just “git”. IDO, however, works only with files and buffers, so `M-x` would still fall back to icomplete.

Starting with Emacs 27, we’ve got fido mode (Fake Ido). It combines the best things about icomplete (works anywhere) with flex matching. In fact, all Fido does under the hood is to enable Icomplete with flex matching.

There are also other solutions for competition, not baked into emacs, with the most popular being Helm5 and Ivy6. Personally, I always try the default option, and only if their limits become annoying do I look at the alternatives. So, I am now a happy FIDO mode user.

Using FIDO

To start FIDO mode run

fido-mode

or, if you find a vertical list to be more readable, use

fido-veritcal-mode

You can also customize variables to have it auto-load in your `init.el`:

(fido-mode t)
;; or
(fido-vertical-mode t)

As I’ve stated above, FIDO is nothing more than flex-enabled Icomplete, so all keybindings work the same. For vertical mode:

  • Typing a string will narrow the selection
  • `C-n` and `C-p` will select the next/prev element on the list
  • `Tab` will display a buffer with a list of narrowed elements
  • `enter` or `C-j` will select the option

One cool thing you can do with FIDO is file deletion (when selecting files) or closing buffers (when selecting buffers) using `C-k`.

Customizing the Minibuffer

We can, of course, customize how Icomplete looks works7.

  • icompleteatches-format (default “%s/%s”) - how the number of filtered and total options is presented
  • complete-first-match (default (t :weight bold)) - how the first filtered option is presented
  • icomplete-selected-match (default (t :inherit highlight)) - the same as above, but for vertical mode
  • icomplete-section (default (t :inherit shadow :slant italic)) - how the section title for vertical mode is presented
  • icomplete-compute-delay (default .15) - how fast the filtering will start after a keypress when a larger number of options is presented
  • icomplete-delay-completions-threshold (default 400) - defines the “large number” for icomplete-compute-delay
  • icomplete-max-delay-chars (default 2) - maximum number of initial characters before applying icomplete-compute-delay. I have no idea what it means, nor have I the knowledge of Elisp to dig into it.
  • icomplete-in-buffer (default nil) - enables usage of Icomplete outside of the Minibuffer. I have not tested it.

We can also use icomplete-minibuffer-setup-hook hook if needed.

Using Completions from Elisp

The great thing about FIDO is that it, like Icomplete, uses Minibuffer API8, so you can simply:

(completing-read
 "prompt: "
 '(("option1" 1) ("option" 2))
 nil t "default query")

  1. Company-mode website ↩︎

  2. Icomplete documentation ↩︎

  3. According to a Reddit comment this behavior is relatively new. Until recently, Icompelete only showed the narrowed selection in a dedicated buffer, similar to using `Tab-Tab` now. The actual input was still up to the user to type in. Thanks for the tidbit ↩︎

  4. IDO documentation ↩︎

  5. Helm website ↩︎

  6. Ivy website ↩︎

  7. list based on Icomplete source code ↩︎

  8. Guide on Minibuffer completition ↩︎


Previous: Multiprocess Emacs environment, Next: Introduction to Literate programming, Up: Cool Emacs