Aug 8, 2024 ⋅ Justin Tanner
After successfully configuring Hammerspoon to bring Emacs keybindings to every application on macOS, I decided to port my script to Karabiner-Elements.
Porting my Hammerspoon script to Karabiner wasn’t a simple copy-paste job. I had to port the code from Lua to JavaScript. Before I started, I looked for existing karabiner configurations with Emacs keybindings. There were a few, but Emacs keybindings (rev13) by tekezo was the closest to what I needed.
The main configuration Karabiner config file starts like this:
function main() {
console.log(
JSON.stringify(
{
title: 'Universal Emacs Keybindings',
maintainers: ['justintanner'],
rules: [
{
description: 'Emacs Emulation in all apps without emacs keybindings (v1.2)',
manipulators: manipulators(),
},
],
},
null,
' '
)
)
}
function manipulators() {
return [].concat(
// --- Comment to prevent line combination by Prettier ---
cx(),
controlKeys(),
optionKeys()
)
}
This entry point controls the three major types of shortcuts: Ctrl, Option and the chord Ctrl+x.
These are fundamental Emacs shortcuts for navigation and other basic actions. Most of these shortcuts are already supported in macOS by default and did not need to be remapped.
Most Option (or Alt) shortcuts are supported by macOS by default. I wanted to provide basic Emacs compatibility for most apps, but I personally do not rely on Option shortcuts as they are harder to reach on the keyboard.
Ctrl+X chords are my favorite. They do not conflict with existing OS shortcuts and there are many un-used chords which can be assigned to new tasks.
Chrome, Brave and Firefox don’t have native shortcuts for the following tab operations:
To map these shortcuts correctly, you’ll need some browser plugins/extensions.
After installing those extensions we’ll need to configure the shortcuts manually with the following values:
If you want to try it yourself: