Published 2025-11-11
tag(s): #emacs
So, last weekend I finally moved away from use-package, like I predicted it would
happen in an earlier post. In
that post I also hinted that I was going to write about my keybinding changes...and here it
is.
This post is as
much self-documentation,
as it is way to hopefully get some feedback and comments from others.
I had started typing a section with the history of how I got to this system, but I deleted it.
The truth is that the setup I have now has some influence from what came before, but
it is a complete redesign based on the the idea that commands correspond to different
needs/categories.
Also, remember that I have F6 as a key right next to the spacebar, courtesy of the Dygma Raise
"8-key spacebar". And F5 in the Enter key.[1]
And if you think code speaks louder than words, you can see
the bindings
here.
Now that I moved all of them to single file, that runs after all packages are loaded, it
is very easy to detect inconsistencies or forgotten keys. The code is separated in
neat pages:
6 pages in buffer bindings.el (delimiter: "^")
28: ;; Custom prefix keymaps: editing and shortcuts (45 lines)
73: ;; Other custom keymaps (82 lines)
155: ;; Mode-specific bindings (28 lines)
183: ;; Remaps (16 lines)
199: ;; ctl-x-map (23 lines)
222: ;; Repeat keymaps (47 lines)
According to me, of course. According to me today, who knows what I came up with in
the future.
And like with most categorizations, some commands will blur the lines between the labels.
Example of these are copy-from-above-command, kill-whole-line,
and hoagie-split-by-sep.
These are commands that manipulate text at the lowest level, and don't have default bindings
(or are commands I wrote). I put them in their
own prefix
keymap, hoagie-editing-keymap. It is assigned to F6.
This makes them all accessible under my thumb[2]. Also, none of them are long sequences, just a quick key press, since they are used while typing.
These are things that I use often enough that I consider it worth it to have them under a key
sequence. But they aren't part of the "typing flow".
It also includes keymaps that have "menu options", like the one I described
for find-*
commands here.
These are assigned to F5. Tapping in succession, F5 f {another
letter} and I can invoke find-name-dired
or find-grep-dired[3].
Other examples of commands in this group are ediff-buffers,
and rgrep.
Also, as per the Emacs manual, it is suggested that users assign things in the key
sequence C-C LETTER. I use these for some long-but-mnemonic sequences. For
example, C-c l for Eglot:
(defvar-keymap hoagie-eglot-keymap
:doc "Keymap for Eglot commands."
:name "Eglot"
"r" '("rename" . eglot-rename)
"h" '("help" . eldoc)
"c" '("code actions" . eglot-code-actions))
;; "l" for LSP
(keymap-set hoagie-shortcut-keymap "l" hoagie-eglot-keymap)
There are things are useful, but seldom used. For example align-regexp,
or flush-lines. It is good to know about these commands, but I
use them once a month (if that). I don't need to assign a key to them.
I learned from experience that if I put them under a key sequence, I will have to use the
command name to find out what was the key binding anyway. So it is OK to just M-x
them.
For the longest time, I
used expand-region to...well, expand
the region. But after reading Mastering Emacs (specifically, the section
about mark-* commands, I gave the built ins a try. And turns out that most times
it is easier to use those instead.
And there's one scenario that expand-region doesn't cover: What happens if you are
moving or killing or transposing two sexps or lines in a row, right next to each
other? There's no "outer semantic unit" for that, and it is a pretty common scenario.
For those cases, I lean on repeat-mode:
(defvar-keymap hoagie-mark-repeat-map
:doc "Keymap to extend selections after a mark command"
:repeat t
"SPC" #'mark-sexp
"@" #'mark-word
"h" #'mark-paragraph)
Another example of how I use repeat maps: some quick navigation without holding modifiers down.
(defvar-keymap hoagie-sexp-movement-repeat-map
:doc "Keymap to repeat a few \"C-M-something\" movement commands."
:repeat t
"u" #'backward-up-list
"d" #'down-list
"f" #'forward-sexp
"b" #'backward-sexp
"a" #'beginning-of-defun
"e" #'end-of-defun)
I think the biggest lesson related to this I've learned over my few years as an Emacser, is
that if I didn't use a bound command, I should try to keep it in mind in the coming days.
But by the second time I notice I bound something and I never call it, then I can free that
key.
It makes no sense to have a gazillion bindings that you don't remember, and you can M-x
command-name if you need it. They don't go anywhere!
dired-do-find-regexp-and-replace
and dired-do-replace-regexp-as-diff.