EmacsUnderstandingCompletion

Created on November 12, 2023 at 11:40 am

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.

Connecting to blog.lzomedia.com... Connected... Page load complete