Dual Function Keys is a plugin for Interception Tools. It is great for modifying keys. It allows you to configure a key for both holding and tapping actions. For example, you can configure the Caps Lock key to act as Escape when tapped and Control when held. I am using this plugin to modify my Shift keys. When tapped, they act as ( and ) respectively. When held, they act as Shift key. This config is great for programming (and training your pinkies?). I am using this config for a long time and I am very happy with it.

In my Modern Space Cadet for Linux post, I explained how to configure this plugin on Linux distributions for humans. In this post, I will explain how to configure this plugin on NixOS. I am not going into the details of NixOS on this post. I am planning to write a post about it in the future.

Enough talking. Let’s start. It is pretty easy to configure this plugin on NixOS. NixOS already has a pre-configured service for interception-tools. So, we just need to add our config file to the service:

services.interception-tools = {
    enable = true;
    plugins = [ pkgs.interception-tools-plugins.dual-function-keys ];
    udevmonConfig = ''
    - JOB: "${pkgs.interception-tools}/bin/intercept -g $DEVNODE | ${pkgs.interception-tools-plugins.dual-function-keys}/bin/dual-function-keys -c /etc/dual-function-keys.yaml | ${pkgs.interception-tools}/bin/uinput -d $DEVNODE"
        DEVICE:
        EVENTS:
            EV_KEY: [KEY_CAPSLOCK, KEY_RIGHTSHIFT, KEY_LEFTSHIFT]
    '';
};

Note that this is for up and running the udevmon service. We still need to create the config file for the plugin. You can keep your config in a dual-function-keys.yaml file next to your configuration.nix file. Here is mine:

# https://github.com/torvalds/linux/blob/master/include/uapi/linux/input-event-codes.h
TIMING:
  TAP_MILLISEC: 200
  DOUBLE_TAP_MILLISEC: 0

MAPPINGS:
  - KEY: KEY_LEFTSHIFT
    TAP: [KEY_LEFTSHIFT, KEY_9]
    HOLD: KEY_LEFTSHIFT
  - KEY: KEY_RIGHTSHIFT
    TAP: [KEY_RIGHTSHIFT, KEY_0]
    HOLD: KEY_RIGHTSHIFT
  - KEY: KEY_CAPSLOCK
    TAP: KEY_ESC
    HOLD: KEY_LEFTCTRL

Since the above configuration expects to have a dual-function-keys.yaml file under the /etc directory, we need to save the file there. We can do this by adding the following line to our configuration.nix file:

environment.etc."dual-function-keys.yaml".text = builtins.readFile ./dual-function-keys.yaml;

That’s it. Just rebuild your NixOS:

sudo nixos-rebuild switch

Now you should be able to use your Shift keys as ( and ) when tapped and as Shift when held. If you have any questions, feel free to ask them in the comments. Thanks for reading.