:title: Emacs Completions :date: 2026-04-22 :tags: emacs :identifier: 20260422T183610 :signature: 5=13 Emacs Completions ================= No Emacs configuration is complete without a lengthy discussion on how completions are handled. .. _emacs-completions-native: ``*Completions*`` ----------------- .. seealso:: `The *Completions* Buffer Gets a Big Upgrade in Emacs 29 `__ I actually quite like the default ``*Completions*`` buffer and used it extensively from Emacs 29.1 to around 30.1. (Also seeing how there is a `bunch of stuff `__ coming in Emacs 31 I'm sure I will switch back again to it before long! 😅) My config wasn't anything particuarly exciting, as I only: - Tweaked some options that control how it is rendered .. code-block:: elisp :project: emacs :filename: init.el (setq completions-detailed t completions-format 'one-column completions-group t completions-header-format (propertize "%s candidates\n" 'face 'shadow) completions-max-height 15 completion-show-help nil) - Tweaked some options that control its behaviour .. code-block:: elisp :project: emacs :filename: init.el (setq completion-auto-help 'visible completion-auto-select 'second-tab completion-cycle-threshold 3) That is to say, the ``*Completions*`` buffer only opens on the *second* attempt at completing something. However, once it is open keep it updated and only focus it on the second completion attempt with no progress made. If there are only 3 or fewer options, don't bother with the ``*Completions*`` buffer at all. - Finally, use :kbd:`C-n` and :kbd:`C-p` to cycle through completion candidates. .. code-block:: elisp (dolist (kmap (list minibuffer-local-map completion-in-region-mode-map)) (keymap-set kmap "C-p" #'minibuffer-previous-completion) (keymap-set kmap "C-n" #'minibuffer-next-completion)) However there are occasions where you want just a little bit... :ref:`more `. Consult ------- `Consult `__, the grab-bag of utility functions built on top of ``completing-read``. I admit, I probably don't use this as much as I should. .. code-block:: elisp :project: emacs :filename: init.el (use-package consult :ensure t :custom (consult-preview-key "M-.") :bind (("C-x b" . consult-buffer))) I don't often want the live preview feature, but it's nice to be able to opt into it by hitting :kbd:`M-.` Embark ------ .. seealso:: `Fifteen ways to use Embark `__ `Embark `__, another excellent package, that I should try and use more deeply! .. code-block:: elisp :project: emacs :filename: init.el (use-package embark :ensure t :bind (("C-." . embark-act) ("M-." . embark-dwim))) Since I have consult installed, use the recommended `emabrk-consult `__ package (though I admit I'm not sure what it does!) .. code-block:: elisp :project: emacs :filename: init.el (use-package embark-consult :after (embark consult) :ensure t) Orderless --------- Continuing with the established theme I use the `orderless `__ completion style as even a basic config is useful, but it would be great to experiment with some `style dispatchers `__! .. code-block:: elisp :project: emacs :filename: init.el (use-package orderless :ensure t :custom (completion-styles '(orderless basic)) (completion-category-defaults nil) (completion-category-overrides '((file (styles basic partial-completion))))) .. _emacs-completions-vertico: Vertico ------- .. seealso:: `VOMPECCC: A Modular Completion Framework for Emacs `__ The article that pushed me over the edge to actually setting vertico up. As mentioned in the :ref:`emacs-completions-native` section above, I was really happy with the built-in completions experience. I find the ~95% of the time, I already know what I'm trying to select and I'm only really looking for a bit of tab-completion to save on the typing. Therefore vertico's `unobtrusive `__ mode is perfect. To cover that remaining 5%, I can use the `multiform extension `__ to switch to a different mode for some pre-determined cases, or on an ad-hoc basis thanks to the ``vertico-mutliform-map`` keymap. So I have arrived at the following config. .. code-block:: elisp :project: emacs :filename: init.el (use-package vertico :ensure t :init (vertico-mode) :config (setq vertico-multiform-commands '((consult-line buffer))) (setq vertico-multiform-categories '((t unobtrusive))) (vertico-multiform-mode t)) The trick was realising I could use ``(t unobtrusive)`` as a fallback to active the unobtrusive mode by default! As for ``completion-in-region``, I still don't feel the need for something like `corfu `__ but I was definitely excited to see the following snippet in vertico's README. .. code-block:: elisp :project: emacs :filename: init.el (setq completion-in-region-function #'consult-completion-in-region) So I get to keep my consistent completion experience regardless of what I am completing!