Caps Lock as Escape and Control key
For the last few months I have been using Helix. As a modal editor, it depends a lot on the CTRL
(Control) and ESC
(Escape) keys. When I was using Emacs, I used to map Caps Lock
to CTRL
. But recently I knew it’s possible to map Caps Lock
to work as ESC
when tapped, and CTRL
when long pressed with another key.
I use three keyboards:
- At home, I use Keychron V10 Max.
- At work, I use Keychron K3 Pro.
- And when I’m away from desk, I use the laptop keyboard.
Mapping the Keychron Keyboards
Both V10 Max and K3 Pro keyboards can be programmed by the Keychron Launcher. Both keyboards are programmed by QMK open source firmware. QMK provides a key called Mod-Tap. Keys mapped to Mod-Tap
will work as modifier (e.g. Control, Shift, Alt) when held, and as regular keys when tapped.
In Keychron Launcher the Mod-Tap
key is mapped using the Any
key mapping (highlighted below):
The Caps Lock
can be mapped to CTRL
and ESC
by setting Any
to MT(MOD_LCTL, KC_ESC)
or CTL_T(KC_ESC)
(alias provided by QMK for convenience).
In QMK Docs there are other Mod-Tap
keys that can be mapped.
Mapping the Laptop Keyboard
For the laptop keyboard, evremap (from the developer of the awesome WezTerm terminal) was the easiest option (basically followed the README):
-
Installed evremap.
-
Created
/etc/evremap.toml
device_name = "AT Translated Set 2 keyboard" [[dual_role]] input = "KEY_CAPSLOCK" hold = ["KEY_LEFTCTRL"] tap = ["KEY_ESC"]
-
Created the systemd service
/usr/lib/systemd/system/evremap.service
to runevremap
as daemon:[Service] WorkingDirectory=/ ExecStart=bash -c "/usr/local/bin/evremap remap /etc/evremap.toml -d 0" Restart=always [Install] WantedBy=multi-user.target
-
Enabled the
evremap.service
systemd service:systemctl daemon-reload systemctl enable evremap.service systemctl start evremap.service
As of this writing, a evremap
process handles one keyboard device only. To map the Caps Lock
in more than one keyboard, every one must have separate evremap
process configured with separate evremap.toml
file. Only the device_name
parameter must be updated for every configuration file.