EmacsUnderstandingCompletion

By admin

One
CARDINAL

of the things that happens when you (I) only touch your Emacs configuration

every few years
DATE

is that you forget exactly how things work, especially if you didn’t fully understand them when you were copying directions from elsewhere when you set things up. Due to recent events I’ve been doing a lot of

GNU Emacs
PRODUCT

stuff, which has involved both recovering old understanding and learning new things about completions. Before I forget it all again, I’m writing it down for my future use.


GNU Emacs
PRODUCT

broadly has

two
CARDINAL

built-in forms of completion. The

one
CARDINAL

people use routinely is minibuffer completion. Because it’s so common, there are a variety of built-in and

third
ORDINAL

party things to change and improve it, such as fido-vertical-mode and

vertico
GPE

to always show some of the completion targets and marginalia to add more information about them.

Orderless
PERSON

technically affects more than minibuffer completion, but in practice it can be hard to use it outside of the minibuffer.

The

second
ORDINAL

form is on-demand completion in buffers. The dominant form of this is completion at point (‘point’ is the

Emacs
ORG

term for where the cursor is), normally invoked through

M-TAB
ORG

, but standard

Emacs
PRODUCT

also has, for example, dabbrev-expand (bound to

M-/
ORG

), which tries to complete things through another mechanism. The default completion at point behavior has some aspects that are like minibuffer completion, but it’s more minimal. The corfu package augments M-TAB completion at point to always show (some of) the completion targets.

(Because dabbrev-expand is not doing its completion as ‘completion at point’ completion,

corfu
GPE

‘s

UI
ORG

doesn’t appear for it. The whole thing is part of

Abbrevs
PERSON

, also, and also completions in general. Defined

abbrevs
PERSON

can be expanded as you type, instead of on demand.)

Emacs has an entire ecosystem for generating the completions for on-demand buffer completion at point. The data for this can come from all sorts of sources, depending on what’s in the buffer. In particular, if you’re editing something with a

LSP
ORG

server active (through eg lsp-mode or eglot (also), which is part of

Emacs 29.1
PRODUCT

), then information from the language server will be used to provide completion at point data, so you can use M-TAB to complete things on demand, possibly with

corfu
GPE

providing a popup list and so on.

As far as I know, nothing in stock

GNU Emacs
PRODUCT

provides general IDE like, ‘as you type’ autocompletion (and this is not normally provided by LSP modes). To get this, you need to use a package like

company(-mode
ORG

) (also). Company can draw from multiple completion sources, but in modern use it normally primarily draws from the same ‘completion at point’ information than

M-TAB
ORG

uses, which means that it draws completion information from a LSP mode if you have that active. You can use company autocompletion independently from a LSP mode; for example, you can enable it in

Emacs
PRODUCT

Lisp buffers (where there’s no LSP for elisp). Since company is doing its actual completion outside of the completion at point system, it has its own popup UI of completion targets and information about them, which is independent of standard completion at point enhancements like

corfu.
ORG

Company has a command to explicitly start a company completion, which is potentially useful to bind to eg

M-/
ORG

so that you can restart a completion that you exited without having to delete and retype some characters. Or you can type M-TAB to use

Emacs
ORG

‘ regular completion at point

UI
ORG

for this (including, eg,

corfu
GPE

‘s

UI
ORG

), unless you rebound M-TAB to company’s completion (which you might, to avoid confusion).

(You can use company without as you type autocompletion and instead bind company-complete to

M-TAB
ORG

and

M-/
ORG

, if you globally set ‘ company-begin-commands ‘ to ‘ nil ‘ (it also works as a buffer local variable). I believe that this will still use the company

UI
ORG

, not the standard completion at point or

corfu UI
ORG

. To use company completion, the buffer must be in company-mode, but you can disable as you type autocomplete with a buffer local value for ‘ company-begin-commands ‘.)

This gives us (me)

three
CARDINAL

different completion environments with

three
CARDINAL

different sets of completion customizations. There’s minibuffer completions (

vertico
GPE

, marginalia, and orderless),

Emacs
PRODUCT

native completion at point (corfu), and finally company as you type (auto)completion (well, that’s the normal setup for company). Depending on your usage, you may normally use

only one
CARDINAL

of the last

two
CARDINAL

; for example, until recently I made basically no use of M-TAB completion at point.

To summarize the common situation in LSP modes for me, company-mode is providing as you type autocompletion stacked on top of

Emacs
ORG

‘ general completion at point infrastructure, with the LSP mode (and

LSP
ORG

server) providing the primary completion data. In non LSP modes, like

Emacs Lisp or C
PRODUCT

, I could enable company-mode and it would most likely be drawing completion data from the language mode. Even if I don’t enable company-mode, I can still access the same completions through standard M-TAB completion at point (either with or without a LSP).

My personal experience has been that programming languages with large, flat namespaces of identifiers with short names don’t necessarily go very well with as you type autocompletion. There are generally so many options so you get prompted all of the time (which is at best distracting and at worst routinely obscures code that you want to see), and many of them aren’t very useful (or are actively wrong). Possibly this would be improved by increasing the number of characters before company starts offering autocomplete options, but so far it’s been simpler to only use company in modes where I already use LSP.

(For instance, with shell scripts and LSP-mode, company will sometimes offer you autocompletion that includes every program in your $PATH. This is technically correct but often not particularly useful. Unfortunately disabling company within specific language lsp-modes seems rather difficult and I haven’t been successful so far.)

PS: My understanding is that the

Emacs
ORG

situation used to be much less unified, especially for company, which in

old days
DATE

required its own specialized connections to programming language modes (eg company-go) and LSP modes (eg company-lsp).

Modern Emacs
PRODUCT

has unified all of this around the completion at point infrastructure (often using the acronym ‘

capf
PERSON

‘, which is short for ‘completion at point functions’, which are backend functions that provide completion information; see eg). I’m not sure what

Emacs
PRODUCT

version is ‘modern’ here, but probably you want to be using a recent

Emacs
PRODUCT

anyway.

PPS: This can make it perfectly sensible to have a whole collection of

third
ORDINAL

party packages (especially small, focused ones) that affect the different sorts of completion. If you count company, I’m currently up to

five
CARDINAL

:

vertico
GPE

, marginalia, orderless,

corfu
GPE

, and company itself. There are undoubtedly more that I could add; suggestions are welcome.