KMonad and the power of infinite leader keys
First of all that was a title clickbait. Title click-baits are still legal in Mexico (I think).
Jokes aside, I will show you how every key in your keyboard can be a leader key.
Since most of the Emacs community are keyboard driven freaks, I hope you will see the potential in your workflow.
What is KMonad?
It is a program that lets you remap the keys of your keyboard.
Install KMonad
Download the executable from https://github.com/kmonad/kmonad/releases.
Put it somewhere your PATH environment variable.
In my case I like to put executables in $HOME/bin
. So I add this line
export PATH="$HOME/bin:$PATH"
in the ~.profile
file.
Then run the following commands.
# Add self to the input and uinput groups
sudo usermod -aG input $USER
sudo groupadd uinput
sudo usermod -aG uinput $USER
echo 'KERNEL=="uinput", MODE="0660", GROUP="uinput", OPTIONS+="static_node=uinput"' | sudo tee /etc/udev/rules.d/90-uinput.rules
# This seems to be needed because uinput isn't compiled as a loadable module these days.
# See https://github.com/chrippa/ds4drv/issues/93#issuecomment-265300511
echo uinput | sudo tee /etc/modules-load.d/uinput.conf
For more info check https://github.com/kmonad/kmonad/issues/160#issuecomment-766121884.
Create a KMonad configuration file
mkdir -p ~/.config/kmonad
touch ~/.config/kmonad/config.kbd
Add system information
On the top of config.kbd
add the next.
(defcfg
input (device-file "<path to your keyboard input>")
output (uinput-sink "KMonad kbd"))
Go to /dev/input/by-path/
or /dev/input/by-id/
and look for any file
ending in kbd
.
I think if your keyboard is plugable, it should appear in
/dev/input/by-id/
and your build-in laptop keyboard should appear in
/dev/input/by-path/
.
In my case I am using my build-in laptop keyboard. This is what I added in the configuration file. Yours should be different, modify it with your information.
(defcfg
input (device-file "/dev/input/by-path/platform-i8042-serio-0-event-kbd")
output (uinput-sink "KMonad kbd"))
uinput-sink
will be the name given to the virtual keyboard that KMonad
creates. You can write anything in there.
Keyboard blueprint
Now we need to create the blueprint of our keyboard. The layouts that will create later will be based of this blueprint.
This is the blueprint of my keyboard. Modify it as you need.
(defsrc
esc f1 f2 f3 f4 f5 f6 f7 f8 f9 f10 f11 f12 pause prnt ins del
` 1 2 3 4 5 6 7 8 9 0 - = bspc home
tab q w e r t y u i o p [ ] ret pgup
caps a s d f g h j k l ; ' \ pgdn
lsft z x c v b n m , . / rsft up end
lctl lmet lalt spc ralt cmps rctl left down rght
)
Base layout (default)
KMonad takes the first layout as the default layout. Let's create our
first layout and named it base
. And let's also swap capslock
and
escape
.
(deflayer base
caps f1 f2 f3 f4 f5 f6 f7 f8 f9 f10 f11 f12 pause prnt ins del
` 1 2 3 4 5 6 7 8 9 0 - = bspc home
tab q w e r t y u i o p [ ] ret pgup
esc a s d f g h j k l ; ' \ pgdn
lsft z x c v b n m , . / rsft up end
lctl lmet lalt spc ralt cmps rctl left down rght
)
Now if we run:
kmonad ~/.config/kmonad/config.kbd
You will notice that capslock
and escape
have been swaped.
Create a second layout
Let's call the second layout syms
, short for symbols. First lets
modify our base layout
so when we hold a
, it calls the syms
layout
.
(deflayer base
caps f1 f2 f3 f4 f5 f6 f7 f8 f9 f10 f11 f12 pause prnt ins del
` 1 2 3 4 5 6 7 8 9 0 - = bspc home
tab q w e r t y u i o p [ ] ret pgup
esc (layer-toggle syms) s d f g h j k l ; ' \ pgdn
lsft z x c v b n m , . / rsft up end
lctl lmet lalt spc ralt cmps rctl left down rght
)
But that is too messy. Let's create an alias for that command.
(defalias
sym (layer-toggle syms))
And now we can modify out base layout
like this:
(deflayer base
caps f1 f2 f3 f4 f5 f6 f7 f8 f9 f10 f11 f12 pause prnt ins del
` 1 2 3 4 5 6 7 8 9 0 - = bspc home
tab q w e r t y u i o p [ ] ret pgup
esc @sym s d f g h j k l ; ' \ pgdn
lsft z x c v b n m , . / rsft up end
lctl lmet lalt spc ralt cmps rctl left down rght
)
Let's create our syms layout
. We will start simple and just add two
symbols to make everything more clear.
(deflayer syms
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _
_ _ _ _ _ _ _ [ ] _ _ _ _ _
_ _ _ _ _ _ _ _ _ _ _ _ _ _
_ _ _ _ _ _ _ _ _ _
)
Now if we if we run our configuration.
kmonad ~/.config/kmonad/config.kbd
When we hold a
and press j
, we get [
. And when we hold a
and
press k
, we get ]
.
The bad news is that we lost the ability to type the letter a
.
Let's use the a
key as leader key
From our last example let's modify the alias we made for calling the
syms layout
.
(defalias
sym (tap-next a (layer-toggle syms)))
With this modification, if we just tap a
, we get a
. But if we hold
a
and press j
, we get [
. And also if we hold a
and press k
, we
get ]
.
Let's create another leader key
(defcfg
input (device-file "<path to your keyboard input>")
output (uinput-sink "KMonad kbd"))
(defalias
sym (tap-next bspc (layer-toggle syms)))
(defsrc
esc f1 f2 f3 f4 f5 f6 f7 f8 f9 f10 f11 f12 pause prnt ins del
` 1 2 3 4 5 6 7 8 9 0 - = bspc home
tab q w e r t y u i o p [ ] ret pgup
caps a s d f g h j k l ; ' \ pgdn
lsft z x c v b n m , . / rsft up end
lctl lmet lalt spc ralt cmps rctl left down rght
)
(deflayer base
esc f1 f2 f3 f4 f5 f6 f7 f8 f9 f10 f11 f12 pause prnt ins del
` 1 2 3 4 5 6 7 8 9 0 - = bspc home
tab q w e r t y u i o p [ ] ret pgup
@sym a s d f g h j k l ; ' \ pgdn
lsft z x c v b n m , . / rsft up end
lctl lmet lalt spc ralt cmps rctl left down rght
)
(deflayer syms
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _
_ _ _ _ _ _ _ [ ] _ _ _ _ _
_ _ _ _ _ _ _ _ _ _ _ _ _ _
_ _ _ _ _ _ _ _ _ _
)
That is a full configuration. In this configuration when we tap
caplocks
, get a backspace
. If we hold caplocks
and press j
, we
get [
. If we hold caplocks
and press k
, we get ]
. And the good
news is that we got rid of caplocks
previous life functionality.
Conclusion
There is much more you can do with KMonad. I suggest you to read the official tutorial to learn more about KMonad.
Now you know how covert every key in a leader key.
One last thing. Since I use Linux Mint and Stumpwm. I added this line
kmonad $HOME/.config/kmonad/config.kbd &
to my .profile
file, so
kmonad starts when I log in.
Extra
(defcfg
input (device-file "<path to your keyboard input>")
output (uinput-sink "KMonad kbd"))
(defalias
d (tap-hold-next 150 d [)
f (tap-hold-next 150 f ]))
(defsrc
esc f1 f2 f3 f4 f5 f6 f7 f8 f9 f10 f11 f12 pause prnt ins del
` 1 2 3 4 5 6 7 8 9 0 - = bspc home
tab q w e r t y u i o p [ ] ret pgup
caps a s d f g h j k l ; ' \ pgdn
lsft z x c v b n m , . / rsft up end
lctl lmet lalt spc ralt cmps rctl left down rght
)
(deflayer base
esc f1 f2 f3 f4 f5 f6 f7 f8 f9 f10 f11 f12 pause prnt ins del
` 1 2 3 4 5 6 7 8 9 0 - = bspc home
tab q w e r t y u i o p [ ] ret pgup
caps a s @d @f g h j k l ; ' \ pgdn
lsft z x c v b n m , . / rsft up end
lctl lmet lalt spc ralt cmps rctl left down rght
)
If you hold d
more than 150 milliseconds, you will get [
. If you
quickly tap d
, you will get d
. If you hold f
more than 150
milliseconds, you will get ]
. If you quickly tap f
, you will get
f
.