I have taken a moment to switch away from Doom Emacs to regular Emacs. One of the things I liked about Doom Emacs, however, was the nice mnemonic key chords. C-c f r, where ‘f’ and ‘r’ stand for ‘file’ and ‘recent’ respectively, running the command recentf.

When using which-key-mode, it will also show human-friendly names for each step. It shows +file and Recent files respectively at each step.

To achieve this, Doom Emacs uses general.el, a huge dependency that does heaps of things. I wanted to achieve the same without this dependency. I have found a super naïve way of doing this, but it actually works rather well.

The code:

(defun defkey (key cmd &optional name keymap)
  "Bind KEY to CMD, or if CMD is nil, just set which-key NAME."
  (when cmd
    (keymap-set (or keymap global-map) key cmd))
  (when name
    (which-key-add-keymap-based-replacements (or keymap global-map) key name)))

This simple function is all I need. It is a little more repetitive than the nested map! call in Doom Emacs, but I don’t need to define that many key chords anyway.

This is how I use it:

;; Define the prefix. It has no command.
(defkey "C-c f" nil "file")
;; Define the command.
(defkey "C-c f r" 'recentf "Recent files")

;; Define a 'local' prefix which is dependent on the major mode.
(defkey "C-c l" nil "local")
;; Define a deeper prefix which is only visible in python-mode.
(defkey "C-c l t" nil "test" python-mode-map)
;; Define a command which is only accessible in python-mode.
(defkey "C-c l t a" 'python-pytest "Test all" python-mode-map)

It could be a lot better, but I do not need anything more than this in my init.el.