I’ve been an Emacs user for a while now and, since the beginning, I’ve been pondering whether to override the keybindings that come with the editor by default.
I’ve seen good arguments for both cases and I’d love to say that I agreed with one side more than the other (that would make the decision much more easy).
On one hand, people advocate that keeping the default keybindings intact will make you “more portable”. This would be a good practice if you engaged in pair programming on regular basis. Knowing the defaults will help you move to other environment and have, potentially, the same fluidness as in your own (assuming that this new env has the same approach).
But on the other hand, Emacs comes with a very (VERY) extensive collection of default keybindings. And you also need to consider the new ones that every installed package brings to the table. This leaves little room for custom keys, which is a good argument for overriding them: your environment should be comfortable to you, because you’ll be the one spending the majority of the time there. This approach can make you extremely proficient, because you won’t need to assign weird and/or uncomfortable fatalities to the list. You’ll be able to perform your most common tasks in a single keystroke.
As I said, I’ve been in the middle of this choice from the beginning and I couldn’t decide which approach I liked the most. Until I discovered the
In this article I’ll explain why I use the
Hyper key on my configuration and how to set it up on GNU/Linux for you to use it too.
In simple terms, it’s a modifier key, the same way
Meta are. But it’s unused by default and in most systems not even present. It’s usually mapped to the
Menu key (the one that normally appears between the
A case for the
After a lot of thinking over the time, I remembered a concept from my
Vim uses the
comma as the “leader key”, which basically means that it’s a key that’s left for the user to, well, use. It’s sort of a modifier key, so you can have multiple bindings assigned to it.
Hyper key is a perfect candidate to use the way
Vim uses the
comma. There are no bindings assigned by default, so you can use the entire range of options.
For example, I have
Hyper plus the letter "c"), =H-h,
H-n mapped as my cursor keys (Up, Left, Down, Right), so I don’t have the need to reach for the arrow keys.
And, even though I still have a lot of custom mappings that use the
Meta keys, I’m slowly moving towards changing them to
By doing this, I have the best of both worlds
- I have the original keybindings available, which I try to use more or less on a regular basis in order to have them committed to memory
- And I have an enormous amount of flexibility when I need to add a new binding
The case that pushed me to embrace
Long time ago, in a pairing session far far away I was working with a friend. We both used
Emacs at the time and had, of course, very different configurations.
I was using Linux while he was a Mac user. We were working on my setup at the moment and he was driving the keyboard from his end. After a while, I noticed a pattern on his workflow… every few seconds the current line got duplicated. He was typing, made an error and suddenly the line appeared in the next line. The problem was that the default keybinding for
C-d, but I had this remapped to a custom command that was used to, you guessed it, duplicate the current line.
Having this happen every couple of seconds was very annoying and kept us context switching all the time.
After remapping my
duplicate-line command to
H-d we never had this problem again.
How to set it up in GNU/Linux
In order to make the
Hyper key available on your keyboard, we first need to decide to what modifier to assign it.
So we check the modifier’s table by running
$ xmodmap -pm xmodmap: up to 4 keys per modifier, (keycodes in parentheses): shift Shift_L (0x32), Shift_R (0x3e) lock Caps_Lock (0x42) control Control_L (0x25), Control_R (0x69) mod1 Alt_L (0x40), Meta_L (0xcd) mod2 Num_Lock (0x4d) mod3 mod4 Super_L (0x85), Super_R (0x86), Super_L (0xce), Hyper_L (0xcf) mod5 ISO_Level3_Shift (0x5c), Mode_switch (0xcb)
In my config,
mod3 is available so we can use this one. For you it might be different, but whatever slot is unused (either by the OS or by you), you can use.
Now that we know this, we can create a file for configuring
Xmodmap (the program we’ll use to remap keys at the OS level).
I called it
~/.Xmodmap. There, we start by making sure our slot is clear
Then we need to get the code that corresponds to the key we want to use (
Menu in my case). To do this, we run the
xev command from the terminal. This command has two parts|
- The GUI, where we can press and release keys and mouse buttons
- and the terminal, were the codes of the key and mouse events will show up.
Here’s the part of the output that corresponds to me pressing and releasing the
$ xev # ... KeyPress event, serial 32, synthetic NO, window 0x2000001, root 0x2a5, subw 0x0, time 547514766, (39,347), root:(1323,371), state 0x0, keycode 135 (keysym 0xffee, Hyper_R), same_screen YES, XLookupString gives 0 bytes: XmbLookupString gives 0 bytes: XFilterEvent returns: False KeyRelease event, serial 32, synthetic NO, window 0x2000001, root 0x2a5, subw 0x0, time 547514852, (39,347), root:(1323,371), state 0x20, keycode 135 (keysym 0xffee, Hyper_R), same_screen YES, XLookupString gives 0 bytes: XFilterEvent returns: False # ...
This is the line that interest us:
state 0x0, keycode 135 (keysym 0xffee, Hyper_R), same_screen YES,
It says that the code for the
Menu key is
135. The next step is to update the
Xmodmap config to assign the code to the
clear mod3 keycode 135 = Hyper_R
And finally assign the
Hyper key to
clear mod3 keycode 135 = Hyper_R add mod3 = Hyper_R
And our config is done. After invoking the new configuration file
$ xmodmap ~/.Xmodmap
we can see that the
Hyper key is ready to be used
$ xmodmap -pm xmodmap: up to 4 keys per modifier, (keycodes in parentheses): shift Shift_L (0x32), Shift_R (0x3e) lock Caps_Lock (0x42) control Control_L (0x25), Control_R (0x69) mod1 Alt_L (0x40), Meta_L (0xcd) mod2 Num_Lock (0x4d) mod3 Hyper_R (0x87) mod4 Super_L (0x85), Super_R (0x86), Super_L (0xce), Hyper_L (0xcf) mod5 ISO_Level3_Shift (0x5c), Mode_switch (0xcb)
Using it on Emacs
Having this key in our arsenal, we can now use it to create awesome keybindings by using
local-set-key at any point in our
Here are some of the ones I’m using myself
;; Moving cursor (global-set-key (kbd "H-h") 'backward-char) (global-set-key (kbd "H-n") 'forward-char) (global-set-key (kbd "H-c") 'previous-line) (global-set-key (kbd "H-t") 'next-line) ;; Text (global-set-key (kbd "H--") 'kill-whole-line) (global-set-key (kbd "H-d") 'fdx/duplicate-line) (global-set-key (kbd "<H-S-down>") 'fdx/move-line-down) (global-set-key (kbd "<H-S-up>") 'fdx/move-line-up) ;; Compilation (global-set-key (kbd "H-m") 'recompile) (global-set-key (kbd "H-b") 'compile) (global-set-key (kbd "H-e") 'er/expand-region)
I love this technique, it’s provided a lot of flexibility for me and my
Emacs workflow. Did you like it? Would you be willing to try it out? I’d love to know your take on this topic.
I hope this post triggers a
Hyper revolution! Thanks for reading and see you on the next one.