Completion (in Emacs hledger)
The Emacs Carnival for February is hosted by Sacha Chua and its topic is “Completion”.
What is a carnival?
From Christian Tietze:
A blog carnival is a fun way to tie together a community with shared writing prompts, and marvel at all the creative interpretations of the topic of the month.
You can get a sense of Emacs Carnivals by checking out the previous ones.
Confusion about completion
In Emacs there are always 1000 ways to do something. That is its power, that is its achilles heel. Over the last couple of years I have coached a lot of my students in the use of Emacs. Most of the time they come to me with questions such as “I am using this package and copied over some configuration, now X stopped working”. One of my favorite topics here is the completion frameworks; company vs corfu.
The Emacs distribution I mostly recommend to my students is Doom Emacs. It is easy to get going, well documented and it has an active community. One thing to really know about this setup, though, is the completion mechanism. This is the init section of Doom Emacs.
:completion
;;company ; the ultimate code completion backend
(corfu +orderless +icons) ; complete with cap(f), cape and a flying feather!
;;helm ; the *other* search engine for love and life
;;ido ; the other *other* search engine...
;;ivy ; a search engine for love and life
vertico ; the search engine of the future
Although I like the quirky comments in the config, it is not very helpful to new users. The default configuration gives a decent setup using corfu and vertico. This is what I use and I highly recommend new users to just stick with that.
But our Emacs community is fragmented on what completion framework everyone uses. This is great because you can use the thing you want to use, but it puts a lot of responsibility on you as a user to just know what you are using.
Let's take a look at hledger as an example (I love hledger, this is no dis, just an example). I use hledger to keep track of my finances, and it really needs a completion setup to be accessible to users (I don't always know what accounts I have setup, so completion helps me there).
The documentation says the following (and only this) on completion with hledger:
;;; Auto-completion for account names
;; For company-mode users,
(add-to-list 'company-backends 'hledger-company)
;; For auto-complete users,
(add-to-list 'ac-modes 'hledger-mode)
(add-hook 'hledger-mode-hook
(lambda ()
(setq-local ac-sources '(hledger-ac-source))))
So, what do you think new users are putting in their configuration? I had multiple students that just put both in their configuration, some then went to look for “company” in their configuration, and also enabled that, next to corfu. You might imagine the mess that makes.
hledger and completion
So, how do you actually configure completion for hledger when using corfu? Well, there is a package in the orphanage called ac-capf.el, which you will find with a google search, but it does the exact opposite of what we want to achieve.
I got it all to work by creating my own completion-at-point-functions entry, which is shown below, Kristoffer Balintona has a great resource on this topic.
(defun hledger-completion-accounts ()
(when-let ((bounds (and (boundp 'hledger-accounts-cache)
(bounds-of-thing-at-point 'symbol))))
(list (car bounds) (point) hledger-accounts-cache)))
(add-hook 'hledger-mode-hook
(lambda ()
(add-hook 'completion-at-point-functions 'hledger-completion-accounts)))
So, what now?
This is actually an area where I think, we as a community, can improve. Having a mechanism to detect and properly configure completion for new users will save a lot of headache and lower the bar of entry for new users.
Or at least spend a little bit more documentation on this topic for new users, we already expect so much from our new users, lets help them get going with a little friction as possible.