Switching from Company to Corfu for Emacs Completion

Thinking Through the Principle of Discovery

Both Company and Corfu are completion packages for Emacs 📖. Corfu’s README outlines alternatives, one of which is Company.

Why Corfu?

There are three considerations:

Corfu’s package is one .el file at 1220 lines of code and comments. Whereas Company’s package is many .el files, the company.el file alone is 3916 lines of code and comments.

That’s not to say that that is intrinsically bad, but Corfu’s narrow focus and adherence to the Emacs API 📖 means that the long-term maintenance of Corfu is likely easier.

But that is somewhat ideological. I primarily write Ruby on Rails software; a gigantic code-base. So as with all things ideological, I look towards pragmatism.

The actual “killer” feature of Corfu, which I’m sure I could implement in Company, is the export the popup completion candidates to the mini-buffer.

Embark on a Tangent

I spend quite a lot of time in Emacs’s mini-buffer: searching a project, invoking M-x (e.g., execute-extended-command) to look for Emacs commands, searching for matching lines via consult-line, etc.

Based on my configuration of Emacs, I annotate the mini-buffer with Marginalia. This helps me better understand the context around the candidates.

Throughout the day, I often rely on Embark’s embark-export for exporting those mini-buffer candidates to another buffer, the Embark Export Occur buffer; a buffer I the further search, edit, and manipulate.

Stay on Target

With Corfu, I can send the “pop-up” completion to the mini-buffer. And once in the mini-buffer I can use embark-export.

Below is the code, from the Corfu wiki for transferring the in region popup to the mini-buffer.

(defun corfu-move-to-minibuffer ()
  (let (completion-cycle-threshold completion-cycling)
    (apply #'consult-completion-in-region completion-in-region--data)))
(define-key corfu-map "\M-m" #'corfu-move-to-minibuffer))

This means I can more thoroughly inspect the candidates recommended by the completion-at-point functions. See their marginalia, and if applicable export each one to an Embark Export Occur buffer for even further interaction.

Back to Principles

ago I wrote . As I’ve worked with Emacs, I’ve grown to appreciate it’s discoverability.

And Corfu’s ability to move a completion popup to the mini-buffer is a wonderful discoverability feature.

In moving from Company to Corfu I do lose out on the spiffy company-org-block package; which provides a nice convenience method.

In my mental rubric, I would rather have the ability to more thoroughly explore the completion candidates than a convenience function regarding source code in org files.