File: README.org

package info (click to toggle)
vertico 2.5-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 404 kB
  • sloc: lisp: 1,713; makefile: 7
file content (687 lines) | stat: -rw-r--r-- 33,839 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
#+title: vertico.el - VERTical Interactive COmpletion
#+author: Daniel Mendler
#+language: en
#+export_file_name: vertico.texi
#+texinfo_dir_category: Emacs misc features
#+texinfo_dir_title: Vertico: (vertico).
#+texinfo_dir_desc: VERTical Interactive COmpletion.

#+macro: version 2.1

Vertico provides a performant and minimalistic vertical completion UI based on
the default completion system. The 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, extendable and modular. Additional enhancements are
available as [[#extensions][extensions]] or [[#complementary-packages][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.

#+toc: headlines 8

* Features

- Vertical display with arrow key navigation. Many additional display modes are
  provided as [[#extensions][extensions]].
- Prompt shows the current candidate index and the total number of candidates.
- The current candidate is inserted with =TAB= and selected with =RET=.
- Non-existing candidates can be submitted with =M-RET= or by moving the point to the prompt.
- Efficient sorting by history position, frequency, length and alphabetically.
- Long candidates with newlines are formatted to take up less space.
- Lazy completion candidate highlighting for performance.
- Annotations are displayed next to the candidates (~annotation-~ and ~affixation-function~).
- Support for candidate grouping and group cycling commands (~group-function~).

* Installation

After installation, activate the global minor mode with =M-x vertico-mode RET=.

* Key bindings

Vertico defines its own local keymap in the minibuffer which is derived from
~minibuffer-local-map~. The keymap keeps most of the ~fundamental-mode~ keybindings
intact and remaps and binds only a handful of commands.

| Binding/Remapping                                   | Vertico command        |
|-----------------------------------------------------+------------------------|
| ~beginning-of-buffer~, ~minibuffer-beginning-of-buffer~ | ~vertico-first~          |
| ~end-of-buffer~                                       | ~vertico-last~           |
| ~scroll-down-command~                                 | ~vertico-scroll-down~    |
| ~scroll-up-command~                                   | ~vertico-scroll-up~      |
| ~next-line~, ~next-line-or-history-element~             | ~vertico-next~           |
| ~previous-line~, ~previous-line-or-history-element~     | ~vertico-previous~       |
| ~forward-paragraph~                                   | ~vertico-next-group~     |
| ~backward-paragraph~                                  | ~vertico-previous-group~ |
| ~exit-minibuffer~                                     | ~vertico-exit~           |
| ~kill-ring-save~                                      | ~vertico-save~           |
| =M-RET=                                               | ~vertico-exit-input~     |
| =TAB=                                                 | ~vertico-insert~         |

Note in particular the binding of =TAB= to ~vertico-insert~, which inserts the
currently selected candidate, and the binding of =RET= and =M-RET= to ~vertico-exit~
and ~vertico-exit-input~ respectively.

~vertico-exit~ exits with the currently selected candidate, while
~vertico-exit-input~ exits with the minibuffer input instead. Exiting with the
current input is needed when you want to create a new buffer or a new file with
~find-file~ or ~switch-to-buffer~. As an alternative to pressing =M-RET=, move the
selection up to the input prompt by pressing the =up= arrow key and then press
=RET=.

* Configuration

In order to configure Vertico and other packages in your init.el, you may want
to take advantage of ~use-package~ (~apt install elpa-use-package~). Here is an example configuration:

#+begin_src emacs-lisp
;; Enable Vertico.
(use-package vertico
  :custom
  ;; (vertico-scroll-margin 0) ;; Different scroll margin
  ;; (vertico-count 20) ;; Show more candidates
  ;; (vertico-resize t) ;; Grow and shrink the Vertico minibuffer
  ;; (vertico-cycle t) ;; Enable cycling for `vertico-next/previous'
  :init
  (vertico-mode))

;; Persist history over Emacs restarts. Vertico sorts by history position.
(use-package savehist
  :init
  (savehist-mode))

;; Emacs minibuffer configurations.
(use-package emacs
  :custom
  ;; Enable context menu. `vertico-multiform-mode' adds a menu in the minibuffer
  ;; to switch display modes.
  (context-menu-mode t)
  ;; Support opening new minibuffers from inside existing minibuffers.
  (enable-recursive-minibuffers t)
  ;; Hide commands in M-x which do not work in the current mode.  Vertico
  ;; commands are hidden in normal buffers. This setting is useful beyond
  ;; Vertico.
  (read-extended-command-predicate #'command-completion-default-include-p)
  ;; Do not allow the cursor in the minibuffer prompt
  (minibuffer-prompt-properties
   '(read-only t cursor-intangible t face minibuffer-prompt)))
#+end_src

I recommend to give Orderless completion a try, which is more flexible and
powerful than the default completion styles.

#+begin_src emacs-lisp
;; Optionally use the `orderless' completion style.
(use-package orderless
  :custom
  ;; Configure a custom style dispatcher (see the Consult wiki)
  ;; (orderless-style-dispatchers '(+orderless-consult-dispatch orderless-affix-dispatch))
  ;; (orderless-component-separator #'orderless-escapable-split-on-space)
  (completion-styles '(orderless basic))
  (completion-category-defaults nil)
  (completion-category-overrides '((file (styles partial-completion)))))
#+end_src

The =basic= completion style is specified as fallback in addition to =orderless= in
order to ensure that completion commands which rely on dynamic completion
tables, e.g., ~completion-table-dynamic~ or ~completion-table-in-turn~, work
correctly. See the [[https://github.com/minad/consult/wiki#minads-orderless-configuration][Consult wiki]] for my advanced Orderless configuration with
style dispatchers. Additionally enable =partial-completion= for file path
expansion. =partial-completion= is important for file wildcard support in
=find-file=. In order to open multiple files with a wildcard at once, you have to
submit the prompt with =M-RET=. Alternative first move to the prompt and then
press =RET=.

See also the [[https://github.com/minad/vertico/wiki][Vertico Wiki]] for additional configuration tips. For more general
documentation read the chapter about completion in the [[info:emacs#Completion][Emacs manual]]. If you want
to create your own completion commands, you can find documentation about
completion in the [[info:elisp#Completion][Elisp manual]].

** Completion styles and TAB completion

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
shells like Bash or the default Emacs completion system. In Vertico =TAB= inserts
the currently selected candidate.

If you prefer to have the default completion commands available you can add new
bindings or even replace the Vertico bindings. For example you can use =M-TAB= to
expand the prefix of candidates (TAB complete) or cycle between candidates if
~completion-cycle-threshold~ is non-nil, with the following configuration.

#+begin_src emacs-lisp
;; Option 1: Additional bindings
(keymap-set vertico-map "?" #'minibuffer-completion-help)
(keymap-set vertico-map "M-RET" #'minibuffer-force-complete-and-exit)
(keymap-set vertico-map "M-TAB" #'minibuffer-complete)

;; Option 2: Replace `vertico-insert' to enable TAB prefix expansion.
;; (keymap-set vertico-map "TAB" #'minibuffer-complete)
#+end_src

The command ~minibuffer-complete~ performs prefix expansion for the ~basic~
completion style, while the ~orderless~ and ~substring~ completion styles expand to
the longest candidate substring. Alternatively you can use completion-styles
like ~partial-completion~, ~flex~ or ~initials~, which perform different expansion and
filtering. The ~partial-completion~ style is important if you want to open
multiple files at once with ~find-file~ using wildcards. In order to open multiple
files with a wildcard at once, you have to submit the prompt with =M-RET=.
Alternative first move to the prompt and then press =RET=.

#+begin_src emacs-lisp
(setq completion-styles '(basic substring partial-completion flex))
#+end_src

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:

#+begin_src emacs-lisp
(setq read-file-name-completion-ignore-case t
      read-buffer-completion-ignore-case t
      completion-ignore-case t)
#+end_src

** Completion-at-point and completion-in-region

The tab completion command =completion-at-point= command is usually bound to =M-TAB=
or =TAB=. Tab completion is also used in the minibuffer by =M-:= (~eval-expression~).
In case you want to use Vertico to show the completion candidates of
=completion-at-point= and =completion-in-region=, you can use the function
~consult-completion-in-region~ provided by the Consult package.

#+begin_src emacs-lisp
(setq completion-in-region-function #'consult-completion-in-region)
#+end_src

You may also want to look into my [[https://github.com/minad/corfu][Corfu]] package, which provides a minimal
completion system for =completion-in-region= in a child frame popup. Corfu is a
narrowly focused package and developed in the same spirit as Vertico. You can
even use Corfu in the minibuffer.

** Completing-read-multiple

The function ~completing-read-multiple~ is similar to ~completing-read~ but returns
a list of completed strings. The strings are separated by ~crm-separator~ in the
minibuffer. On Emacs 30 and older, ~completing-read-multiple~ does not indicate to
the user that multiple strings can be completed. I have contributed a patch to
Emacs 31, which fixes this issue. See the variable ~crm-prompt~ and [[https://debbugs.gnu.org/cgi/bugreport.cgi?bug=76028][bug#76028]]. On
older Emacs versions you can use the following advice:

#+begin_src emacs-lisp
;; Prompt indicator for `completing-read-multiple'.
(when (< emacs-major-version 31)
  (advice-add #'completing-read-multiple :filter-args
              (lambda (args)
                (cons (format "[CRM%s] %s"
                              (string-replace "[ \t]*" "" crm-separator)
                              (car args))
                      (cdr args))))))
#+end_src

* Extensions
:properties:
:custom_id: extensions
:end:

We maintain small extension packages to Vertico in this repository in the
subdirectory extensions/. The extensions are installed together with Vertico.
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 ~vertico-*.el~ extensions. Currently the following
extensions come with the ~elpa-vertico~ package in the
~/usr/share/emacs/site-lisp/vertico-{{{version}}}~ directory:

- vertico-buffer: =vertico-buffer-mode= to display Vertico like a regular buffer.
- vertico-directory: Commands for Ido-like directory navigation.
- vertico-flat: =vertico-flat-mode= to enable a flat, horizontal display.
- vertico-grid: =vertico-grid-mode= to enable a grid display.
- vertico-indexed: =vertico-indexed-mode= to select indexed candidates with prefix arguments.
- vertico-mouse: =vertico-mouse-mode= to support for scrolling and candidate selection.
- vertico-multiform: Configure Vertico modes per command or completion category.
- vertico-quick: Commands to select using Avy-style quick keys.
- vertico-repeat: The command =vertico-repeat= repeats the last completion session.
- vertico-reverse: =vertico-reverse-mode= to reverse the display.
- vertico-sort: Provides optimized sort functions, by history, by length and lexical.
- vertico-suspend: The command =vertico-suspend= suspends and restores the current session.
- vertico-unobtrusive: =vertico-unobtrusive-mode= displays only the topmost candidate.

See the commentary of those files for configuration details. 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 combination
=vertico-flat= plus =vertico-directory= resembles Ido in look and feel. For an
interface similar to Helm, the extension =vertico-buffer= allows 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 =vertico-directory=:

#+begin_src emacs-lisp
;; 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))
#+end_src

** Configure Vertico per command or completion category

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.

#+begin_src 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)))
#+end_src

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=.

| =M-B= | ~vertico-multiform-buffer~      |
| =M-F= | ~vertico-multiform-flat~        |
| =M-G= | ~vertico-multiform-grid~        |
| =M-R= | ~vertico-multiform-reverse~     |
| =M-U= | ~vertico-multiform-unobtrusive~ |
| =M-V= | ~vertico-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.

#+begin_src 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)))))
#+end_src

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

#+begin_src 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))))
#+end_src

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

#+begin_src 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))))
#+end_src

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-grep~,
~consult-git-grep~ and ~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.

#+begin_src emacs-lisp
;; 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)
#+end_src

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.

#+begin_src emacs-lisp
(setq vertico-multiform-categories
      '((buffer flat (vertico-cycle . t))))
#+end_src

* Complementary packages
:properties:
:custom_id: complementary-packages
:end:

Vertico integrates well with complementary packages, which enrich the completion
UI. These packages are fully supported:

- Marginalia (~apt install elpa-marginalia~): Rich annotations in the minibuffer
- Consult (~apt install elpa-consult~): Useful search and navigation commands
- Embark (~apt install elpa-embark~): Minibuffer actions and context menu
- Orderless (~apt install elpa-orderless~): Advanced completion style

In order to get accustomed with the package ecosystem, I recommend the following
quick start approach:

1. Start with plain Emacs (~emacs -Q~).
2. Install and enable Vertico to get incremental minibuffer completion.
3. Install Orderless and/or configure the built-in completion styles
   for more flexible minibuffer filtering.
4. Install Marginalia if you like rich minibuffer annotations.
5. Install Embark and add two keybindings for ~embark-dwim~ and ~embark-act~.
   I am using the mnemonic keybindings =M-.= and =C-.= since these commands allow
   you to act on the object at point or in the minibuffer.
6. Install Consult if you want additional featureful completion commands,
   e.g., the buffer switcher ~consult-buffer~ with preview or the line-based
   search ~consult-line~.
7. Install Embark-Consult for export from =consult-line= to editable =occur-mode=
   buffers and from =consult-grep= to =grep-mode= buffers. On Emacs 31, use
   =grep-edit-mode= for editing or [[https://github.com/mhayashi1120/Emacs-wgrep][wgrep]] on older Emacs version.
8. Fine tune Vertico with [[#extensions][extensions]].

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-act~ and ~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., ~consult-buffer~ for ~switch-to-buffer~).

* Child frames and Popups

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
yourself.

- [[https://github.com/muffinmad/emacs-mini-frame][mini-frame]]: Display the entire minibuffer in a child frame.
- [[https://github.com/minad/mini-popup][mini-popup]]: Slightly simpler alternative to mini-frame.
- [[https://github.com/tumashu/vertico-posframe][vertico-posframe]]: Display only the Vertico minibuffer in a child frame using
  the posframe library.

* Alternatives

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 monolithic completion systems.

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. 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:

- [[https://git.sr.ht/~protesilaos/mct][Mct]]: Minibuffer and Completions in Tandem. Mct reuses the default
  ~*Completions*~ buffer and enhances it with automatic updates. Since Mct uses a
  regular buffer you can use the usual movement commands. The main distinction
  to Vertico's approach is that ~*Completions*~ buffer displays all matching
  candidates. This has the advantage that you can interact freely with the
  candidates and jump around with Isearch or Avy. On the other hand it
  necessarily causes a slowdown.
- Icomplete: Emacs comes with the builtin =icomplete-vertical-mode=, which is more
  bare-bone than Vertico. Vertico offers additional flexibility via its
  [[#extensions][extensions]].
- [[https://github.com/radian-software/selectrum][Selectrum]]: Selectrum is the predecessor of Vertico has been deprecated in
  favor of Vertico. Read the [[https://github.com/minad/vertico/wiki/Migrating-from-Selectrum-to-Vertico][migration guide]] when migrating from Selectrum.

* Resources

If you want to learn more about Vertico and minibuffer completion, check out the
following resources:

- Configurations which use Vertico and Corfu for completion:
  + [[https://github.com/doomemacs/doomemacs/tree/master/modules/completion/vertico][Doom Emacs Vertico Module]]
  + [[https://github.com/SystemCrafters/crafted-emacs/blob/master/modules/crafted-completion.el][Crafted Emacs Completion Module]]
  + [[https://git.sr.ht/~protesilaos/dotfiles/tree/master/item/emacs/.emacs.d/][Prot's Emacs configuration]]
- Videos:
  + [[https://www.youtube.com/watch?v=fnE0lXoe7Y0][Emacs Completion Explained]] (2022-07-19) by Andrew Tropin.
  + [[https://www.youtube.com/watch?v=w9hHMDyF9V4][Emacs Minibuffer Completions]] (2022-02-12) by Greg Yut.
  + [[https://www.youtube.com/watch?v=hPwDbx--Waw][Vertico Extensions for Emacs]] (2022-01-08) by Karthik Chikmagalur.
  + [[https://youtu.be/5ffb2at2d7w][Using Emacs Episode 80 - Vertico, Marginalia, Consult and Embark]] (2021-10-26) by Mike Zamansky.
  + [[https://www.youtube.com/watch?v=UtqE-lR2HCA][System Crafters Live! - Replacing Ivy and Counsel with Vertico and Consult]] (2021-05-21) by David Wilson.
  + [[https://www.youtube.com/watch?v=J0OaRy85MOo][Streamline Your Emacs Completions with Vertico]] (2021-05-17) by David Wilson.
  + [[https://www.youtube.com/watch?v=SOxlQ7ogplA&t=1952s][Modern Emacs: all those new tools that make Emacs better and faster]] (2024-03-06) by Marie-Hélène Burle.

* Contributions

Since this package is part of [[https://elpa.gnu.org/packages/vertico.html][GNU ELPA]] contributions require a copyright
assignment to the FSF.

* Debugging Vertico

Vertico will automatically print a stack trace to the =*Messages*= buffer when an
error is detected. The stack trace allows you to narrow down the exact code
location which caused the error.

* Problematic completion commands

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-refile~

~org-refile~ uses ~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 the
~basic~ completion style is used. The table is incompatible with completion styles
like ~substring~, ~flex~ or ~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 prioritize
~basic~ before ~orderless~.

#+begin_src emacs-lisp
;; 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 #'vertico-enforce-basic-completion)

(defun vertico-enforce-basic-completion (&rest args)
  (minibuffer-with-setup-hook
      (:append
       (lambda ()
         (let ((map (make-sparse-keymap)))
           (define-key map [tab] #'minibuffer-complete)
           (use-local-map (make-composed-keymap (list map) (current-local-map))))
         (setq-local completion-styles (cons 'basic completion-styles)
                     vertico-preselect 'prompt)))
    (apply args)))
#+end_src

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.

#+begin_src emacs-lisp
;; Alternative 2: Complete full paths
(setq org-refile-use-outline-path 'file
      org-outline-path-complete-in-steps nil)
#+end_src

** ~org-agenda-filter~ and ~org-tags-view~

Similar to ~org-refile~, the commands ~org-agenda-filter~ and ~org-tags-view~ do not
make use of completion boundaries. The internal completion tables are
~org-agenda-filter-completion-function~ and ~org-tags-completion-function~.
Unfortunately =TAB= completion (~minibuffer-complete~) does not work for this reason
with arbitrary completion styles like ~substring~, ~flex~ or ~orderless~. This affects
Vertico and also the Emacs default completion system. For example if you enter
~+tag<0 TAB~ the input is replaced with ~0:10~ which is not correct. With preserved
completion boundaries, the expected result would be ~+tag<0:10~. Completion
boundaries are used for example by file completion, where each part of the path
can be completed separately. Ideally this issue would be fixed in Org.

#+begin_src emacs-lisp
(advice-add #'org-make-tags-matcher :around #'vertico-enforce-basic-completion)
(advice-add #'org-agenda-filter :around #'vertico-enforce-basic-completion)
#+end_src

** ~tmm-menubar~

*NOTE*: I have implemented a fix for this problem upstream in Emacs, see
[[https://debbugs.gnu.org/cgi/bugreport.cgi?bug=74616][bug#74616]]. From Emacs 31 and newer the workaround is not needed anymore.

The text menu bar works well with Vertico but always shows a =*Completions*=
buffer, which is unwanted if Vertico is used. Right now the 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 keybinding.

#+begin_src emacs-lisp
(keymap-global-set "<f10>" #'tmm-menubar)
(advice-add #'tmm-add-prompt :after #'minibuffer-hide-completions)
#+end_src

** ~ffap-menu~

*NOTE*: I have implemented a fix for this problem upstream in Emacs, see
[[https://debbugs.gnu.org/cgi/bugreport.cgi?bug=74616][bug#74616]]. From Emacs 31 and newer the workaround is not needed anymore.

The command ~ffap-menu~ shows the =*Completions*= buffer by default like
~tmm-menubar~, which is unwanted if Vertico is used. The completions buffer can be
disabled as follows.

#+begin_src emacs-lisp
(advice-add #'ffap-menu-ask :around
            (lambda (&rest args)
              (cl-letf (((symbol-function #'minibuffer-completion-help)
                         #'ignore))
                (apply args))))
#+end_src

** ~completion-table-dynamic~

Dynamic completion tables (~completion-table-dynamic~, ~completion-table-in-turn~,
...) should work well with Vertico. The only requirement is that the =basic=
completion style is enabled. The =basic= style performs prefix filtering by
passing the input to the completion table (or the dynamic completion table
function). The =basic= completion style must not necessarily be configured with
highest priority, it can also come after other completion styles like =orderless=,
=substring= or =flex=, as is also recommended by the Orderless documentation because
of ~completion-table-dynamic~.

#+begin_src emacs-lisp
(setq completion-styles '(basic))
;; (setq completion-styles '(orderless basic))
(completing-read "Dynamic: "
                 (completion-table-dynamic
                  (lambda (str)
                    (list (concat str "1")
                          (concat str "2")
                          (concat str "3")))))
#+end_src

** Submitting the empty string

The commands ~multi-occur~, ~auto-insert~, ~bbdb-create~ read multiple arguments from
the minibuffer with ~completing-read~, one at a time, until you submit an empty
string. You should type =M-RET= (~vertico-exit-input~) to finish the loop. Directly
pressing =RET= (~vertico-exit~) does not work since the first candidate is
preselected.

The underlying issue is that ~completing-read~ always allows you to exit with the
empty string, which is called the /null completion/, even if the ~REQUIRE-MATCH~
argument is non-nil. Try the following two calls to ~completing-read~ with =C-x C-e=:

#+begin_src emacs-lisp
(completing-read "Select: " '("first" "second" "third") nil 'require-match)
(completing-read "Select: " '("first" "second" "third") nil 'require-match nil nil "")
#+end_src

In both cases the empty string can be submitted. In the first case no explicit
default value is specified and Vertico preselects the *first* candidate. In order
to exit with the empty string, press =M-RET=. In the second case the explicit
default value "" is specified and Vertico preselects the prompt, such that
exiting with the empty string is possible by pressing =RET= only.

** Tramp hostname and username completion

*NOTE:* On Emacs 29.2 and Tramp 2.7 the workarounds described in this section are
not necessary anymore, since the relevant completion tables have been improved.

In combination with Orderless or other non-prefix completion styles like
=substring= or =flex=, host names and user names are not made available for
completion after entering =/ssh:=. In order to avoid this problem, the =basic=
completion style should be specified for the file completion category, such that
=basic= is tried before =orderless=. This can be achieved by putting =basic= first in
the completion style overrides for the file completion category.

#+begin_src emacs-lisp
(setq completion-styles '(orderless basic)
      completion-category-defaults nil
      completion-category-overrides '((file (styles basic partial-completion))))
#+end_src

If you are familiar with the =completion-style= machinery, you may also define a
custom completion style which activates only for remote files. The custom
completion style ensures that you can always match substrings within non-remote
file names, since =orderless= will stay the preferred style for non-remote files.

#+begin_src emacs-lisp
(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 basic)
      completion-category-defaults nil
      completion-category-overrides '((file (styles basic-remote partial-completion))))
#+end_src