π

My Emacs Key Binding Strategy

Show Sidebar

Emacs is a really wonderful piece of software. When it comes to customization, no other tool is as flexible as this platform. Please notice, that I intentionally avoid the word "editor" here.

Customization is the process of adapting the tool to your requirements instead of adapting your workflow to the given tool. For any decent person, this also includes keyboard shortcuts. In the Emacs ecosystem, keyboard shortcuts are referred to as "key bindings".

This is how I designed my strategy to define key bindings in my Emacs.

Key Binding Basics

Emacs key bindings follow a specific key notation which is easy to remember. For an Emacs beginner, the key bindings might seem like chaos. However, there is an elaborate binding convention associated which really makes sense when you think of it. You have to learn about it, before starting to map your own bindings. This way, you know that there are domains which are reserved for Emacs (e.g., C-c followed by a control character or a digit or {}<>:;; C-h; C-g) and domains which are up to the user (e.g., the function keys).

Please do read this chapter of the "Mastering Emacs" book and blog posts like this to learn about keyboard bindings.

The Advantage of Maintaining A Separate Namespace

In order not to get a binding conflict with my current or future minor and major modes, I decided to stick with a personal prefix for almost all of my own key bindings. This prefix should be easy to reach and fast to type.

My prefix of choice is C-c C-, and it is called my-map within my Emacs configuration which I maintain within an Org mode file for better legibility and maintainability.

The prefix my-map is configured here and it is used many times throughout my configuration.

Handling Related Bindings

Many functions do have a related twin brother. For example C-c C-, a (also referred to as my-map a) starts my Org mode agenda. With C-c C-, A (same binding but upper-case A) I am able to toggle the list of agenda files. my-map u calls my-url-linkify() whereas my-map U calls my-insert-orgmode-url-from-clipboard(). You get the idea.

In future, I am probably going to switch over using the commonly used universal prefix argument pattern using M-u instead of lower- and upper-case letters. I just learned how to do this in Elisp.

Tools and Tricks to Not Forget Bindings

When you do map many keys according to your requirements, you might forget the mapping for non-daily commands. A package that helped me to compensate this effect is called guide-key. When I type in my prefix and wait for a second, it shows me a pop-up window with all possible keys and their mapping as long as they are final ones and not further menus. Please take a look at the screenshots on the projects page.

For remembering key bindings on the function keys F1 to F12, I put a sticker to my keyboard. It shows me notions of the corresponding functions because in recent time, I tend to constantly refactor the mapping to get to an optimum.

Currently, my F-key mapping looks like this:

F1 my-toggle-beginner-setup
shift F1 my-toggle-dark-bright-theme
F2 goto-last-change
F3 goto-last-change-reverse
F4 char-menu
F5 hydra-spelling/body
shift F5 my-toggle-ispell-language
F8 minimap-mode
F9 a mode-specific hydra
F12 my-toggle-naked-emacs

For details on the functions, please refer to my latest configuration.

You might have noticed the F9 binding. It shows a hydra which depends on the current major mode. Therefore, in Org mode I get a different hydra than in a Python buffer.

Hydras is another really cool combination of "helping to remember bindings" and "visualization". I tend to have not only key bindings within a hydra but also a cheat sheet of the current mode with things I want to lookup from time to time.

In a Python buffer, the hydra that shows with F9 looks like that:

Emacs buffer in Python mode showing my hydra-dired commands (left) and a small cheatsheet (right).

Notice the different colors: red commands stay within the hydra when invoked, blue ones quit the hydra when invoked.

When I am in a dired buffer, the F9 hydra shows a different screen:

Emacs buffer in dired mode showing my hydra-python commands (left) and a larger cheatsheet (right).

Those hydra-based cheat sheets replaced the old-fashioned paper-based cheat sheets as well as the occasional Org mode notes look-ups.

If you are interested in how I defined the hydras, take a look at my configuration. All hydras being with hydra- which helps you when searching in my configuration.

If you are using John Wiegley's awesome use-package to set-up libraries and define key bindings, you might find M-x describe-personal-keybindings a helpful function. Since I do not define all bindings via use-package (yet?), this does not cover all my bindings.

Some people are using guru-mode for learning bindings on the fly. I did not like it much.

Lessons Learned

When I first began using Emacs, everything I did was experiencing and creating chaos. The backronym "Escape Meta Alt Ctrl Shift" for Emacs was not unfamiliar to me. I was not aware of binding conventions, it was not obvious to me why something has a key bindings that looks like C-? or M-? or C-c ? and others are like M-u C-c C-?. My own bindings occasionally were overwriting minor and major mode bindings or the modes were overwriting my own bindings which caused much irritation on my side. What a mess I was in.

With a little background knowledge I got from my second - and more systematic - encounter with Emacs, I learned a lot. This time, my approach was smarter. And that is why I wrote this article here. Feel free to learn from my mistakes and steal one or two tricks I learned on the way.

Comment via email or via Disqus comments below: