Codebase for my homepage.
git clone git://vcs.sapka.me/michal-sapka-me
Log | Files | Refs

commit 79dc7a95c44f22f3cdf0aebbd7a762e49f00d4b1
parent 0289c16b4f676264423a1b18206be8b85f215553
Author: MichaƂ M. Sapka <michal@sapka.me>
Date:   Fri, 26 May 2023 21:21:34 +0200

feat: article for 2023-05-27

Acontent/2023/input-completition-in-emacs.md | 90+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Mstatic/style.css | 1-
2 files changed, 90 insertions(+), 1 deletion(-)

diff --git a/content/2023/input-completition-in-emacs.md b/content/2023/input-completition-in-emacs.md @@ -0,0 +1,90 @@ +--- +title: "Input Completition in Emacs" +category: "emacs" +abstract: Icomplete, IDO and FIDO +date: 2023-05-26T21:10:08+02:00 +year: 2023 +draft: false +tags: +- IComplete +- IDO-mode +- FIDO-mode +- Emacs +--- +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 mode[^company]. +[^company]: [Company-mode website](https://company-mode.github.io/) + +The oldest one of those is *icomplete*[^icomplete] mode. It allows you to select from a list of choices incrementally, 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. +[^icomplete]: [Icomplete documentation](https://www.gnu.org/software/emacs/manual/html_node/emacs/Icomplete.html) + +Then *IDO*[^ido] 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. +[^ido]: [IDO documentation](https://www.gnu.org/software/emacs/manual/html_mono/ido.html) + +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 Helm[^helm] and Ivy[^ivy]. 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. +[^helm]: [Helm website](https://emacs-helm.github.io/helm/) +[^ivy]: [Ivy website](https://oremacs.com/swiper/) + +### Using FIDO + +To start FIDO mode run + +{{<highlight lisp>}} +fido-mode +{{</highlight>}} + +or, if you find a vertical list to be more readable, use + +{{<highlight lisp>}} +fido-veritcal-mode +{{</highlight>}} + +You can also customize variables to have it auto-load in your `init.el`: + +{{<highlight lisp>}} +(fido-mode t) +;; or +(fido-vertical-mode t) +{{</highlight>}} + +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 mini buffer + +We can, of course, customize how Icomplete looks works[^savanah]. + +- *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. +[^savanah]: list based on [Icomplete source code](https://git.savannah.gnu.org/cgit/emacs.git/tree/lisp/icomplete.el) + +### Using competition from Elisp + +The great thing about FIDO is that it, like Icomplete, uses Minibuffer API[^minubuffer], so you can simply: +[^minibuffer]: [Guide on Minibuffer completition](https://www.gnu.org/software/emacs/manual/html_node/elisp/Minibuffer-Completion.html) + +{{<highlight lisp>}} +(completing-read + "prompt: " + '(("option1" 1) ("option" 2)) + nil t "default query") +{{</highlight>}} diff --git a/static/style.css b/static/style.css @@ -147,7 +147,6 @@ blockquote { color: var(--blockquote-color); } pre { - width: 93%; padding-bottom: 5px; white-space: pre-wrap; padding: 11px;