jMilton13 · 2022-10-15 16:36
I have `corfu` start suggesting completion candidates after I type 3 characters, and one feature I want is for candidates to include symbols or words that *contain* (rather than just *start with*) the 3 characters I typed. This is because it’s often hard to know whether the word or symbol I’m searching for is a substring of the word or symbol (especially in a coding environment).
I’m especially wanting this functionality for completions for `dabbrev` and lisp symbols. I’m new to `completion-at-point-functions`, so I was hoping to get some help from the community. Thank you!
[deleted] · 2022-10-15 17:20
[deleted]
CorysInTheHouse69 · 2022-10-15 19:12
By default completion uses prefix matching only. Try out orderless. Really cool package that does what you want.
https://github.com/oantolin/orderless
```
(use-package orderless
:ensure t
:custom
(completion-styles '(orderless flex))
(completion-category-overrides '((file (styles basic partial-completion)))))
```
Read the github for more info
JDRiverRun · 2022-10-15 19:43
You probably want to investigate [completion styles](https://www.gnu.org/software/emacs/manual/html_node/emacs/Completion-Styles.html). There are many builtin styles, from *basic*, which just does prefix completion, on up. But there are also 3rd party styles. One of the most powerful is called [orderless](https://github.com/oantolin/orderless). Considering all these styles, there really is a *ton* of flexibility in how you can get to a completion candidate like `some-named-something` (`some`, `s-n-s`, `sns`, `soso`, `[a-z]\{4\}-na`, `e\b \bs`, ...). You can even configure more than one style at a time (and usually do).
But here is a super important point to understand: completion styles can only alter how a list of completion candidates gets *filtered* and *sorted*. They cannot control the *production* of those candidates! The way fancy completion styles like *initials* attempt to do so is to ask the completion backend (a "completion-at-point-function") for a list of *everything* you could possibly complete at this position, independent of what's in the buffer, then do their fancy filtering on that **big** list using the buffer context.
Sometimes this works great. For example, Emacs is happy to tell you about \_all\_ the internal lisp symbols it knows (150k here), so completion styles for elisp functions and variables works just like you'd expect.
But here is something the manual doesn't tell you: some completion-providing backends just aren't so accommodating. Dabbrev is one of them: it *insists* on prefix completion. No amount of configuring completion styles will overcome that fact. When asked for "every possible completion" after "foo", it will *never* provide "barfood". It simply does not provide any non-prefix completions.
Another very important category of completion backends with their own opinions: lsp servers. LSP servers care nothing about how Emacs has its completion styles configured. They produce the completion candidates *they* think are relevant at the current position. And this varies greatly among servers. Some are quite generous and give you all kinds of flexible matches. Some provide prefix-matches only (like dabbrev). Some limit their list to a fixed number of candidates. Etc. See the [corfu wiki](https://github.com/minad/corfu/wiki) for more on this.
A good rule of thumb: if Emacs knows all the completion symbols already, it probably will supports all completion styles well. If Emacs has to go ask another process (LSP server, shell process, network host, etc.) for relevant completions, it will likely have less to work with, and fancy completion styles won't work as well.
So is all hope lost? There is one silver lining: once corfu *has* a list of candidates, it can continue to whittle it down using whatever completion styles you have configured. I use the orderless style with corfu, and so can `M-Space` whenever to activate full orderless narrowing. E.g. for dabbrev, I might type just a single character that I know something starts with, `M-Tab` to pop up a long list with corfu, `M-Space` to introduce a space without quitting corfu, and then quickly trim the list way down using orderless filtering (with regexes, negation, and any order). This feels very similar to `M-x` followed by vertico + orderless filtering, if you use that.
meedstrom · 2022-10-20 19:37
Thank you *so much* -- that `M-Space` was what I've been missing. I never used company or corfu, but now I start seeing it as usable.
By the way, you write wonderfully. I'd read your blog.