Don't make Emacs keymaps -- define them.

June 2023

You know how I've encouraged contributing code upstream? Let it not be said I don't take my own advice.

This all started when I was looking at some Emacs keymaps. I realized that making keymaps is verbose, with a lot of boilerplate. The code looks something like:

(let ((map (make-sparse-keymap)))
  (define-key map (kbd "a") #'function-a-here)
  (define-key map (kbd "M-a") #'function-a-here)
  (define-key map (kbd "b") #'my-function-b)
  (define-key map (kbd "C-c C") #'function-c-here)
  (define-key map (kbd "d") #'function-d-here)
  map)

I thought I could make something better – where you could not have this boilerplate. A function that created and returned a keymap that's filled with your values and doesn't need to be locally bound. A keymap-creation function that knows what you want, where you don't have to wrap all the keys in kbd calls.

So I programmed and tested, and the new code was ready. While writing a proposal to the emacs mailing list, I looked up examples of make-keymap already in Emacs.

Then I found define-keymap.

It does everything I wanted. Everything I made, this function does. Even better, it's a single function instead of two. I had made one function for sparse keymaps and a second function for normal keymaps.

Why didn't I find this earlier? Well, define-keymap is not documented in the creating keymaps documentation. For that matter, it's nowhere in the documentation.

It's not even in Emacs!

Well, it is. It's just not in a released Emacs. It will come out as part of Emacs 29, but earlier Emacs versions can get define-keymap from the compat package. Right now, the best place to look at its documentation is in the git repository.

It's a very nice function. The sparse keymap above can instead be:

(define-keymap
  "a" #'function-a-here
  "M-a" #'function-a-here
  "b" #'my-function-b
  "C-c C" #'function-c-here
  "d" #'function-d-here)

This is far simpler and more readable. There are many options it can take, which I won't go over here.

So I don't think there's a reason to use make-keymap anymore. define-keymap is better.

If you want to hear when I publish more, sign up for my mailing list!