Skip to content

Configure Vertico per command or completion category

https://github.com/minad/vertico/blob/screenshots/vertico-ripgrep.png?raw=true

Vertico offers the ‘vertico-multiform-mode’ which allows you to configure Vertico per command or per completion category. The ‘vertico-buffer-mode’ enables a Helm-like buffer display, which takes more space but also displays more candidates. This verbose display mode is useful for commands like consult-imenu or consult-outline since the buffer display allows you to get a better overview over the entire current buffer. But for other commands you want to keep using the default Vertico display. vertico-multiform-mode solves this configuration problem.

emacs-lisp
;; Enable vertico-multiform
(vertico-multiform-mode)

;; Configure the display per command.
;; Use a buffer with indices for imenu
;; and a flat (Ido-like) menu for M-x.
(setq vertico-multiform-commands
      '((consult-imenu buffer indexed)
        (execute-extended-command unobtrusive)))

;; Configure the display per completion category.
;; Use the grid display for files and a buffer
;; for the consult-grep commands.
(setq vertico-multiform-categories
      '((file grid)
        (consult-grep buffer)))

The different display modes can be toggled temporarily. The ‘vertico-multiform-map’ binds the following toggle commands to keys. Depending on preference, these bindings can be changed in the ‘vertico-multiform-map’.

BindingVertico command
M-Bvertico-multiform-buffer
M-Fvertico-multiform-flat
M-Gvertico-multiform-grid
M-Rvertico-multiform-reverse
M-Uvertico-multiform-unobtrusive
M-Vvertico-multiform-vertical

For special configuration you can use your own functions or even lambdas to configure the completion behavior per command or per completion category. Functions must have the calling convention of a mode, i.e., take a single argument, which is either 1 to turn on the mode and -1 to turn off the mode.

emacs-lisp
;; Configure `consult-outline' as a scaled down TOC in a separate buffer
(setq vertico-multiform-commands
      `((consult-outline buffer ,(lambda (_) (text-scale-set -1)))))

Furthermore you can tune buffer-local settings per command or category.

emacs-lisp
;; Change the default sorting function.
;; See `vertico-sort-function' and `vertico-sort-override-function'.
(setq vertico-multiform-commands
      '((describe-symbol (vertico-sort-function . vertico-sort-alpha))
        (execute-extended-command (:keymap "X" execute-extended-command-cycle))))

(setq vertico-multiform-categories
      '((symbol (vertico-sort-function . vertico-sort-alpha))
        (file (vertico-sort-function . vertico-sort-directories-first)
              (:keymap . vertico-directory-map))))

Key maps or key bindings can be set per command or category.

emacs-lisp
;; Bind "X" to `execute-extended-command-cycle' in M-x.
(setq vertico-multiform-commands
      '((execute-extended-command (:keymap "X" execute-extended-command-cycle))))

;; Bind directory commands for all commands in file category.
(setq vertico-multiform-categories
      '((file (vertico-sort-function . vertico-sort-directories-first)
              (:keymap . vertico-directory-map))))

Combining these features allows us to fine-tune the completion display even more by adjusting the vertico-buffer-display-action. We can for example reuse a window above the current window for commands of the consult-grep category (consult-grep, consult-git-grep and consult-ripgrep). This snippet demonstrates the flexibility of the configuration system.

emacs-lisp
;; Configure the buffer display and the buffer display action
(setq vertico-multiform-categories
      '((consult-grep
         buffer
         (vertico-buffer-display-action display-buffer-in-direction
                                        (direction . above)
                                        (window-height . 20)))))

;; Disable preview for consult-grep commands
(consult-customize consult-ripgrep consult-git-grep consult-grep :preview-key nil)

As another example, the following code uses vertico-flat and vertico-cycle to emulate (ido-mode 'buffer), i.e., Ido when it is enabled only for completion of buffer names. vertico-cycle set to t is necessary here to prevent completion candidates from disappearing when they scroll off-screen to the left.

emacs-lisp
(setq vertico-multiform-categories
      '((buffer flat (vertico-cycle . t))))