To install this package, run in Emacs:
M-x package-install RET vertico RET
Vertico provides a performant and minimalistic vertical completion UI based on
the default completion system. The main focus of Vertico is to provide a UI
which behaves correctly under all circumstances. By reusing the built-in
facilities system, Vertico achieves full compatibility with built-in Emacs
completion commands and completion tables. Vertico only provides the
completion UI but aims to be highly flexible, extensible and modular.
Additional enhancements are available as extensions or complementary packages.
The code base is small and maintainable. The main
vertico.el package is only
about 600 lines of code without white space and comments.
TABand selected with
C-returnor by moving the point to the prompt.
Vertico defines its own local keymap in the minibuffer which is derived from
minibuffer-local-map. The keymap keeps most of the
keybindings intact and remaps and binds only a handful of commands. Note in
particular the binding of
vertico-insert and the bindings of
Vertico is available from GNU ELPA. You can install it directly via
package-install. After installation, you can activate the global minor mode
M-x vertico-mode. In order to configure Vertico and other packages in
your init.el, you may want to take advantage of
use-package. I recommend to
give Orderless completion a try, which is different from the prefix TAB
completion used by the basic default completion system or in shells. Here is
an example configuration:
;; Enable vertico (use-package vertico :init (vertico-mode) ;; Different scroll margin ;; (setq vertico-scroll-margin 0) ;; Show more candidates ;; (setq vertico-count 20) ;; Grow and shrink the Vertico minibuffer ;; (setq vertico-resize t) ;; Optionally enable cycling for `vertico-next' and `vertico-previous'. ;; (setq vertico-cycle t) ) ;; Optionally use the `orderless' completion style. See ;; `+orderless-dispatch' in the Consult wiki for an advanced Orderless style ;; dispatcher. Additionally enable `partial-completion' for file path ;; expansion. `partial-completion' is important for wildcard support. ;; Multiple files can be opened at once with `find-file' if you enter a ;; wildcard. You may also give the `initials' completion style a try. (use-package orderless :init ;; Configure a custom style dispatcher (see the Consult wiki) ;; (setq orderless-style-dispatchers '(+orderless-dispatch) ;; orderless-component-separator #'orderless-escapable-split-on-space) (setq completion-styles '(orderless) completion-category-defaults nil completion-category-overrides '((file (styles partial-completion))))) ;; Persist history over Emacs restarts. Vertico sorts by history position. (use-package savehist :init (savehist-mode)) ;; A few more useful configurations... (use-package emacs :init ;; Add prompt indicator to `completing-read-multiple'. ;; Alternatively try `consult-completing-read-multiple'. (defun crm-indicator (args) (cons (concat "[CRM] " (car args)) (cdr args))) (advice-add #'completing-read-multiple :filter-args #'crm-indicator) ;; Do not allow the cursor in the minibuffer prompt (setq minibuffer-prompt-properties '(read-only t cursor-intangible t face minibuffer-prompt)) (add-hook 'minibuffer-setup-hook #'cursor-intangible-mode) ;; Emacs 28: Hide commands in M-x which do not work in the current mode. ;; Vertico commands are hidden in normal buffers. ;; (setq read-extended-command-predicate ;; #'command-completion-default-include-p) ;; Enable recursive minibuffers (setq enable-recursive-minibuffers t))
See also the Vertico Wiki for additional configuration tips. For more general documentation read the chapter about completion in the Emacs manual. If you want to create your own completion commands, you can find documentation about completion in the Elisp manual.
The bindings of the
minibuffer-local-completion-map are not available in
Vertico by default. This means that TAB works differently from what you may
expect from the default Emacs completion system.
If you prefer to have the default completion commands a key press away you can
add new bindings or even replace the Vertico bindings. Then the default
completion commands behave as usual. For example you can use
M-TAB to cycle
between candidates if you have set
(define-key vertico-map "?" #'minibuffer-completion-help) (define-key vertico-map (kbd "M-RET") #'minibuffer-force-complete-and-exit) (define-key vertico-map (kbd "M-TAB") #'minibuffer-complete)
orderless completion style does not support completion of a common prefix
substring, as you may be familiar with from shells or the basic default
completion system. The reason is that the Orderless input string is usually
not a prefix. In order to support completing prefixes you may want to combine
substring in your
(setq completion-styles '(substring orderless))
Alternatively you can experiment with the built-in completion-styles, e.g.,
partial-completion style is important
to add if you want to open multiple files at once with
wildcards. In order to open multiple files at once, you have to move to the
prompt and then press
(setq completion-styles '(basic substring partial-completion flex))
Because Vertico is fully compatible with Emacs default completion
system, further customization of completion behavior can be achieved
by setting the designated Emacs variables. For example, one may wish
to disable case-sensitivity for file and buffer matching when built-in
completion styles are used instead of
(setq read-file-name-completion-ignore-case t read-buffer-completion-ignore-case t completion-ignore-case t)
completion-at-point command is usually bound to
TAB. In case you
want to use Vertico for completion-at-point/completion-in-region, you can use
consult-completion-in-region provided by the Consult package.
;; Use `consult-completion-in-region' if Vertico is enabled. ;; Otherwise use the default `completion--in-region' function. (setq completion-in-region-function (lambda (&rest args) (apply (if vertico-mode #'consult-completion-in-region #'completion--in-region) args)))
completion-in-region-function setting also affects TAB completion in the
eval-expression) is used.
You may also want to look into my Corfu package, which provides a minimal
completion system for
completion-in-region in a child frame popup. Corfu is
also a narrowly focused package and developed in the same spirit as Vertico.
Consult offers an enhanced
completing-read-multiple implementation which you
can use with Vertico.
(advice-add #'completing-read-multiple :override #'consult-completing-read-multiple)
We maintain small extension packages to Vertico in this repository in the
subdirectory extensions/. The extensions are installed together with Vertico
if you pull the package from ELPA. The extensions are inactive by default and
can be enabled manually if desired. Furthermore it is possible to install all
of the files separately, both
vertico.el and the
Currently the following extensions come with the Vertico ELPA package:
vertico-buffer-modeto display Vertico in a separate buffer.
vertico-flat-modeto enable a flat, horizontal display.
vertico-grid-modeto enable a grid display.
vertico-indexed-modeto select indexed candidates with prefix arguments.
vertico-mouse-modeto support for scrolling and candidate selection.
vertico-repeatrepeats the last completion session.
vertico-reverse-modeto reverse the display.
vertico-unobtrusive-modedisplays only the topmost candidate.
With these extensions it is possible to adapt Vertico such that it matches
your preference or behaves similar to other familiar UIs. For example, the
vertico-directory resembles Ido in look and
feel. For an interface similar to Helm, the extension
you to configure freely where the completion buffer opens, instead of growing
the minibuffer. Furthermore
vertico-buffer will adjust the number of displayed
candidates according to the buffer height.
Configuration example for
;; Configure directory extension. (use-package vertico-directory :after vertico :ensure nil ;; More convenient directory navigation commands :bind (:map vertico-map ("RET" . vertico-directory-enter) ("DEL" . vertico-directory-delete-char) ("M-DEL" . vertico-directory-delete-word)) ;; Tidy shadowed file names :hook (rfn-eshadow-update-overlay . vertico-directory-tidy))
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-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
;; 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)))
You can use your own functions or even lambdas to configure the completion behavior per command or per completion category. The function must have the calling convention of a mode, i.e., it takes a single argument, which is either 1 to turn on the mode and -1 to turn off the mode.
;; 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.
;; Change the default sorting function (setq vertico-multiform-commands '((describe-symbol (vertico-sort-function . vertico-sort-alpha)))) (setq vertico-multiform-categories '((symbol (vertico-sort-function . vertico-sort-alpha)) (file (vertico-sort-function . sort-directories-first)))) ;; Sort directories before files (defun sort-directories-first (files) (setq files (vertico-sort-history-length-alpha files)) (nconc (seq-filter (lambda (x) (string-suffix-p "/" x)) files) (seq-remove (lambda (x) (string-suffix-p "/" x)) files)))
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 the
current window for commands of the
consult-grep category (
consult-ripgrep). Note that this configuration is
incompatible with Consult preview, since the previewed buffer is usually shown
in exactly this window. Nevertheless this snippet demonstrates the flexibility
of the configuration system.
;; Configure the buffer display and the buffer display action (setq vertico-multiform-categories '((consult-grep buffer (vertico-buffer-display-action . (display-buffer-same-window))))) ;; 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
(ido-mode 'buffer), i.e., Ido when it is enabled only for completion of
vertico-cycle set to
t is necessary here to prevent completion
candidates from disappearing when they scroll off-screen to the left.
(setq vertico-multiform-categories '((buffer flat (vertico-cycle . t))))
Vertico integrates well with complementary packages, which enrich the completion UI. These packages are fully supported:
In order to get accustomed with the package ecosystem, I recommed the following quick start approach:
embark-act. I am using the mnemonic keybindings
C-.since these commands allow you to act on the object at point or in the minibuffer.
consult-bufferwith preview or the line-based search
occur-modebuffers and from
The ecosystem is modular. You don't have to use all of these components. Use
only the ones you like and the ones which fit well into your setup. The
steps 1. to 4. introduce no new commands over plain Emacs. Step 5. introduces
the new commands
embark-dwim. In step 6. you get the Consult
commands, some offer new functionality not present in Emacs already (e.g.,
consult-line) and some are substitutes (e.g.,
An often requested feature is the ability to display the completions in a child
frame popup. Personally I am critical of using child frames for minibuffer
completion. From my experience it introduces more problems than it solves. Most
importantly child frames hide the content of the underlying buffer. Furthermore
child frames do not play well together with changing windows and entering
recursive minibuffer sessions. On top, child frames can feel slow and sometimes
flicker. A better alternative is the
vertico-buffer display which can even be
configured individually per command using
vertico-multiform. On the plus side of
child frames, the completion display appears at the center of the screen, where
your eyes are focused. Please give the following packages a try and judge for
There are many alternative completion UIs, each UI with its own advantages and disadvantages.
Vertico aims to be 100% compliant with all Emacs commands and achieves that
with a minimal code base, relying purely on
completing-read while avoiding to
invent its own APIs. Inventing a custom API as Helm or Ivy is explicitly
avoided in order to increase flexibility and package reuse. Due to its small
code base and reuse of the Emacs built-in facilities, bugs and compatibility
issues are less likely to occur in comparison to completion UIs or full
completion systems, which reimplement a lot of functionality.
Since Vertico only provides the UI, you may want to combine it with some of the complementary packages, to give a full-featured completion experience similar to Helm or Ivy. Overall the packages in the spirit of Vertico have a different style than Helm or Ivy. The idea is to have smaller independent components, which one can add and understand step by step. Each component focuses on its niche and tries to be as non-intrusive as possible. Vertico targets users interested in crafting their Emacs precisely to their liking - completion plays an integral part in how the users interacts with Emacs.
There are other interactive completion UIs, which follow a similar philosophy:
*Completions*buffer and enhances it with automatic updates and additional keybindings, to select a candidate and move between minibuffer and completions buffer. Mct is great if you prefer an unobtrusive UI since it can be configured to open only when requested. Furthermore since Mct uses a fully functional buffer you can reuse all your familar buffer commands inside the completions buffer. The main distinction to Vertico's approach is that
*Completions*buffer displays all matching candidates. On the one hand this is good since it allows you to interact with all the candidates and jump around with Isearch or Avy. On the other hand it necessarily causes a slowdown in comparison to Vertico, which only displays a subset of candidates. Mct supports completion in region via its
If you want to learn more about Vertico, check out the following resources:
Since this package is part of GNU ELPA contributions require a copyright assignment to the FSF.
Vertico is robust in most scenarios. However some completion commands make certain assumptions about the completion styles and the completion UI. Some of these assumptions may not hold in Vertico or other UIs and require minor workarounds.
org-olpath-completing-read to complete the outline path
in steps, when
org-refile-use-outline-path is non-nil.
Unfortunately the implementation of this Org completion table assumes that
basic completion style is used. The table is incompatible with completion
orderless. In order to fix the issue at the
root, the completion table should make use of completion boundaries similar
to the built-in file completion table. In your user configuration you can
;; Alternative 1: Use the basic completion style (setq org-refile-use-outline-path 'file org-outline-path-complete-in-steps t) (advice-add #'org-olpath-completing-read :around (lambda (&rest args) (minibuffer-with-setup-hook (lambda () (setq-local completion-styles '(basic))) (apply args))))
Alternatively you may want to disable the outline path completion in steps. The completion on the full path can be quicker since the input string matches directly against substrings of the full path, which is useful with Orderless. However the list of possible completions becomes much more cluttered.
;; Alternative 2: Complete full paths (setq org-refile-use-outline-path 'file org-outline-path-complete-in-steps nil)
The text menu bar works well with Vertico but always shows a
buffer, which is unwanted if you use the Vertico UI. This completion buffer
can be disabled with an advice. If you disabled the standard GUI menu bar and
prefer the Vertico interface you may also overwrite the default F10
(global-set-key [f10] #'tmm-menubar) (advice-add #'tmm-add-prompt :after #'minibuffer-hide-completions)
ffap-menu shows the
=*Completions* buffer by default like
tmm-menubar, which is unnecessary with Vertico. This completion buffer can be
disabled as follows.
(advice-add #'ffap-menu-ask :around (lambda (&rest args) (cl-letf (((symbol-function #'minibuffer-completion-help) #'ignore)) (apply args))))
In combination with Orderless, hostnames are not made available for
completion after entering
/ssh:. In order to avoid this problem, the
completion style should be specified for the file completion category.
(setq completion-styles '(orderless) completion-category-overrides '((file (styles basic partial-completion))))
For users who are familiar with the
completion-style machinery: You may also
define a custom completion style which sets in only for remote files!
(defun basic-remote-try-completion (string table pred point) (and (vertico--remote-p string) (completion-basic-try-completion string table pred point))) (defun basic-remote-all-completions (string table pred point) (and (vertico--remote-p string) (completion-basic-all-completions string table pred point))) (add-to-list 'completion-styles-alist '(basic-remote basic-remote-try-completion basic-remote-all-completions nil)) (setq completion-styles '(orderless) completion-category-overrides '((file (styles basic-remote partial-completion))))