Table of Contents
Welcome to the KMonad quick reference guide. This document aims to provide a simple definition and a usable example for all possible configuration options in the KMonad program to act as a quick reference that you look into when forgetting a function or/and wanting to know something quickly. Note that this document does not try to be a full guide or a detailed documentation, this is the aim of tutorial.kbd.
The defcfg
block is where you can define all of your configuration
rules like setting up in- and output devices or certain global
configuration options.
A block can take the following arguments:
-
input
: define the input keyboard which the program will capture. -
output
: define the output keyboard which KMonad will create, with additional options to execute upon starting KMonad.
Here is how you would define the basic input and output settings on all supported systems:
-
GNU/Linux:
input (device-file "/dev/input/by-id/usb-04d9_daskeyboard-event-kbd") output (uinput-sink "My KMonad output")
-
Windows:
input (low-level-hook) output (send-event-sink)
-
MacOS:
input (iokit-name "my-keyboard-product-string") output (kext)
The following are all global config options that one can set in the
defcfg
block.
-
fallthrough
(boolean, defaults tofalse
): re-emit keys that are not defined in the correspondingdefsrc
block.This allows one to only specify certain parts of a layout, with all other keys having their "default" meaning.
-
allow-cmd
(boolean, defaults tofalse
): allow arbitrary shell commands to be run as keys.NOTE: This can be dangerous since someone with access to your keyboard file could bind
rm -rf ~/
to a key. Think about whether you really want this behaviour. -
cmp-seq
(key, defaults toRightAlt
): compose key for Unicode input (X11 specific). -
cmp-seq-delay
(natural number): delay between each pressed key in a compose-key sequence. -
implicit-around
(around variant, defaults toaround
): Specifies the variant ofaround
to use in implicit around constructs likeA
orS-a
. You can also specifydisabled
, which causes implicit arounds to result in errors.
Below is an example of a full defcfg
block for a GNU/Linux system.
(defcfg
input (device-file "/dev/input/by-id/usb-04d9_daskeyboard-event-kbd")
output (uinput-sink
"My KMonad output" ;; name of the created keyboard
"sleep 1 && setxkbmap -option compose:ralt") ;; additional, environment-specific, information
cmp-seq ralt
cmp-seq-delay 5
fallthrough true
allow-cmd true
)
Defining fancy buttons is why we're here, right? There are a variety of these things here, as well as some helpers to make entering them into layers (more below) much easier.
(press-only x)
: Send the press of x when this button is tapped(release-only x)
: Send the release of x when this button is tapped
It is possible to define buttons that only press or release a virtual output
button. They are useful in tap-macros, especially ones that are going to be
executed in a 'known context'. Assume you want to use your physical alt button
to both open a layer, but also to function as a basic alt
key. This can be
achieved by (around met (layer-toggle my-layer))
. However, if you have a macro
inside my-layer
that taps alt, then this would release alt until the layer is
reactivated (by physically releasing and repressing the alt
key). The macro,
however, can instead be affixed by (press-only met)
, making the last step of
the macro the reactivation of the alt
key, solving the problem.
To make key-entry easier, KMonad already provides some syntax for Emacs-like specification of key chords. They are defined like this:
C-
:(around-implicit lctl X)
A-
:(around-implicit lalt X)
M-
:(around-implicit lmet X)
S-
:(around-implicit lsft X)
Then RC-
, RA-
, RM-
, and RS-
behave exactly the same, except
using the right-modifier.
The definition of a key chord then looks like this:
(defalias Ca C-a) ;; this is equivalent to (defalias Ca (around-implicit Ctl a))
-
defalias
: define a name for a button. This can then be referenced in a layer using the@name
syntax (see layers below).(defalias num (layer-toggle numbers) ;; Bind num to a button that switches to a layer kil C-A-del ;; Bind kil to a button that Ctrl+Alt+deletes )
-
around
: combine two keys into one.(defalias ad (around alt del)) ;; this is like pressing Alt+Del
-
around-only
:around
but release the outer button as soon as others are pressed.(defalias A (around lsft a) A' (around-only lsft a) )
@A'
is simply an uppercase letter but with the following difference to the@A
:P@A Pb R@A Rb -> AB P@A' Pb R@A' Rb -> Ab
-
around-when-alone
: similar toaround-only
but when all other buttons have been released the outer button is repressed.(defalias A'' (around-when-alone lsft a) )
P@A'' Tb Tc R@A'' -> Plsft Pa Rlsft Tb Tlsft Tc Plsft Ra Rlsft
-
around-implicit
: the around variant used implicit(defalias =A (around-implicit lsft a) )
@=A
is the desugared form ofA
-
around-next
: perform the next button-press inside some context (likelayer-next
but more generalized)(defalias ns (around-next sft)) ;; Shift the next press
-
around-next-single
: perform only the next event (keypress or release) inside some context. -
before-after-next
: tap a button prior to key press and tap another after key release.(before-after-next tab S-tab a)
-
around-next-timeout
: likearound-next
except that if other button press is not detected within some timeout, some other button is tapped.(around-next-timeout 500 sft XX)
-
sticky-key
: act like the key is held temporarily after just one press for the given amount of time (in ms).(defalias slc (sticky-key 500 lctl))
-
stepped
: perform the next button in the circular sequence whenever it is pressed.(stepped (press-only lctl) (release-only lctl))
This button:
- presses control the first time it is tapped
- releases control the second time it is tapped
-
pause
: pause for the given number of ms.(defalias ta3 (tap-macro K P5 M P4 o P3 n P6 a (pause 5) d) ;; P5 = (pause 5) )
-
cmd-button
: take two arguments, the second one of which is optional. These represent the commands to be executed on pressing and releasing the button respectively(defalias dat (cmd-button "date >> /tmp/kmonad_example.txt") ;; Append date to tmpfile pth (cmd-button "echo $PATH > /tmp/kmonad_path.txt") ;; Write out PATH ;; `dat' on press and `pth' on release bth (cmd-button "date >> /tmp/kmonad_example.txt" "echo $PATH > /tmp/kmonad_path.txt") )
Tap buttons are an integral part of KMonad. Everyone has different preferences—that's why there are so many! Particularly when using home-row modifiers, you will find some of the more crazy seeming buttons to be the most comfortable.
-
tap-macro
: take a sequence of keys and tap them, but don’t release the last key until the button is released.(defalias ta1 (tap-macro K M o n a d))
A
tap-macro
can take an optional:delay
keyword (in ms)—this will wait for that amount of time after each keypress:(defalias ta1 (tap-macro K M o n a d :delay 5) ;; equivalent to: (tap-macro K P5 M P5 o P5 n P5 a P5 d) )
-
tap-macro-release
: liketap-macro
but don’t press the last key until the button is released.(defalias ta2 (tap-macro-release K M o n a d))
-
multi-tap
: combine a sequence of keys into one key with a timeout between each key, as well as a last (default) button without a delay.(defalias mt (multi-tap 300 a 300 b 300 c 300 d e))
-
tap-next
: combine 2 buttons, one for when the button is tapped and one for when it is held. The decision of what to execute is based upon whether the next button is the buttons own release or not.(defalias tan (tap-next a sft))
-
tap-hold
: liketap-next
but with a timeout for tapping. If the key is released before the timeout it taps, if not then it holds.(defalias tah (tap-hold 200 a sft))
-
tap-hold-next
: a combination oftap-next
andtap-hold
: liketap-next
, but also switch to hold after a period of time.(defalias thn (tap-hold-next 1000 a sft))
-
tap-next-release
: liketap-next
but decide whether to tap or hold based on the next release of a key (that was not already pressed when this button was pressed).(defalias tnr (tap-next-release a sft))
-
tap-next-press
: liketap-next
but decide whether to tap or hold based on whether another key is pressed before this one is released.(defalias tnp (tap-next-press a sft))
-
tap-hold-next-release
: liketap-next-release
but with an additional timeout. This is just liketap-next-release
, but withtap-next
swapped out fortap-next-release
.(defalias thr (tap-hold-next-release 1000 a sft))
-
tap-hold-next
andtap-hold-next-release
can take an optional:timeout-button
keyword to specify a button other than the hold button which should be held when the timeout expires.(defalias thn (tap-hold-next 200 a lsft :timeout-button x) thr (tap-hold-next-release 200 a lsft :timeout-button x) )
KMonad allows you to define and operate on several layers; these are just collections of keys.
-
defsrc
: define the input keys of your physical keyboard. This should reflect the keys on your keyboard as closely as possible. Although adefsrc
is very similar to a layer visually, it is not a one and will thus not be used as one! It only serves to define where the different keys are and what kind of layout kmonad is initially dealing with. It also supports giving a name via:name <my-source-name>
as the first argument.For example, an ANSI 60% keyboard may be represented as:
(defsrc grv 1 2 3 4 5 6 7 8 9 0 - = bspc tab q w e r t y u i o p [ ] \ caps a s d f g h j k l ; ' ret lsft z x c v b n m , . / rsft lctl lmet lalt spc ralt rmet cmp rctl )
See the keyboard templates for further inspiration.
-
deflayer
: defines a layer to be used later.For example, defining a qwerty layer, as well as one for special symbols and numbers:
To use a named source block add
:source <my-source-name>
after the layer name.you can also overwrite the
implicit-around
setting by adding:implicit-around <setting>
.(deflayer qwerty grv 1 2 3 4 5 6 7 8 9 0 - = bspc tab q w e r t y u i o p [ ] \ caps a s d f g h j k l ; ' ret lsft z x c v b n m , . / rsft lctl @num lalt spc ralt rmet @sym @kil ) (deflayer numbers _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ XX / 7 8 9 - _ _ _ _ _ _ _ _ XX * 4 5 6 + _ _ _ _ \( \) . XX 0 1 2 3 _ _ _ _ _ _ _ _ _ _ )
There are many buttons that can operate on layers.
-
layer-toggle
: toggles to a specific layer as long as the key is held.(defalias ket (layer-toggle toggled-layer))
-
layer-delay
: change to the layer temporarily for the given amount of time (in ms).(defalias ked (layer-delay 500 delayed-layer))
-
layer-next
: the next key press is handled by another layer (leader-key style).(defalias ken (layer-next next-layer))
-
layer-switch
: change the base layer; i.e., deregister the bottom-most layer and swap it out with another one.(defalias kes (layer-switch switch-layer))
-
layer-add
andlayer-rem
: overlay a layer on top of the current layer resp. remove the overlayed layer from the current layer.NOTE: The above two commands can be particularly dangerous if used alone and should really only be used together. Be careful that you don't make a configuration in which you can't switch back to your base layer!
(defalias add (layer-add multi-overlay) rem (layer-rem multi-overlay) )