One essential part of my workflow is remapping the Caps Lock key to act as Ctrl when held and Esc when tapped. It’s always one of the very first things I set up whenever I get a new computer.

I’m so used to it that whenever I help someone with tech issues and have to use their computer, I start stumbling over basic tasks—and I can almost tell they begin to doubt if I’m actually good with computers.

On Windows, I use AutoHotKey with this script1.

On macOS, I use Karabiner-Elements with this complex modification2.

On Linux, my setup has changed a few times. For my current NixOS configuration, I use Interception Tools with the caps2esc plugin.

To set it up like I did, add this to your /etc/nixos/configuration.nix:

 1{ config, pkgs, ... }:
 2let
 3  udevmonConfigFile = pkgs.writeText "udevmon.yaml" ''
 4SHELL: [${pkgs.runtimeShell}, -c]
 5---
 6- JOB: "${pkgs.interception-tools}/bin/intercept -g $DEVNODE | ${pkgs.interception-tools-plugins.caps2esc}/bin/caps2esc -m 1 | ${pkgs.interception-tools}/bin/uinput -d $DEVNODE"
 7  DEVICE:
 8    EVENTS:
 9      EV_KEY: [KEY_CAPSLOCK, KEY_ESC, KEY_LEFTCTRL]
10  '';
11in
12{
13  # ...
14  systemd.services.udevmon = {
15    description = "Interception Tools - udevmon";
16    wantedBy = [ "multi-user.target" ];
17    serviceConfig.ExecStart = "${pkgs.interception-tools}/bin/udevmon -c ${udevmonConfigFile}";
18  };
19}

This configuration applies the change system-wide. I chose to configure it in configuration.nix rather than home-manager because udevmon needs to run as root to work correctly.


  1. A copy of the script can be found here ↩︎

  2. A copy of the JSON configuration can be found here ↩︎