---
title: "Kanata: advanced keyboard configuration"
date: "2023-01-20 18:11:00"
tags:
  - linux
  - logitech
  - keyboard
  - layout
  - rust
---

[Kanata](https://github.com/jtroo/kanata/) is a software keyboard remapper that aims to improve keyboard comfort and usability with advanced customization.
Keyboard remappers are a good alternative to running a custom keyboard with QMK/ZMK, and have two main advantages: they work on any keyboard, and you can configure them to launch any command or program you want, not just key presses.
On the other hand, you need to configure them on every PC/OS you're using your keyboard with, and all the processing is done on software on top of the OS, so there may be glitches and performance issues.

The project was inspired by the more popular [KMonad](https://github.com/kmonad/kmonad), and the author cites some of the [differences](https://github.com/jtroo/kanata/blob/main/docs/kmonad_comparison.md).
Both projects use a very similar configuration format based on lisp.
The configuration consists of a set of general options, a base key configuration, a series of layers, and macros that can be used within those layers.
[Here's a very complete config that serves as documentation](https://github.com/jtroo/kanata/blob/main/cfg_samples/kanata.kbd).


One big disadvantage of the lispy configuration is that you need to specify your hardware layout/all your keys, and repeat that every time you define a new layer.
The result visually maps to your keyboard, but can be very verbose/big if you need really few changes.

[Keyd](https://github.com/rvaiya/keyd/) is another alternative with a more declarative configuration format, which might lend itself to smaller.


For now I'm just trying it out, and getting a feel for using fewer keys before I build my own ZMK keyboard.
I particularly like the option of using mod-keys on the home row (e.g., having A work as a CTRL when held).
Mod-tap, tap-dancing and the like are very common techniques in sub-40% layouts, where there simply aren't enough keys for all the letters and symbols.
In a regular-sized keyboard, these techniques can also help you stay on the home row and type more comfortably.
At least, that's the idea.
We'll see if I like it enough to stick with it.

For now, here's my very simple config:


```lisp
(defcfg
  ;; Your keyboard device will likely differ from this.
  linux-dev  /dev/input/by-id/usb-Logitech_USB_Receiver-if02-event-mouse

  ;; Windows doesn't need any input/output configuration entries; however, there
  ;; must still be a defcfg entry. You can keep the linux-dev entry or delete
  ;; it and leave it empty.
)

(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 rctl
)


(deflayer qwerty
  grv  _    _    _    _    _    _    _    _    _    _    _    _    _
  _  _    @warrows    _    _    _    _    _    _    _    _    _    _    
  lctrl     @alctrl    @slsft    @dlalt    @flmet    _    _    @jrmet    @kralt    @lrsft    @;rctrl    _ _
  _ _ _    _    _    _    _    _    _    _    _    _    _
  _ _ _           @smartspace            _ _ _
)

(deflayer arrows
  _  _    _    _    _    _    _    _    _    _    _    _    _    _
  _  _    _    _    _    _    _    _    _    _    _    _    _    
  _     _    _    _    @flmet    _    left down up rght _ _ _
  _ _ _    _    _    _    _    _    _    _    _    _    _
  _ _ _           @smartspace            _ _ _
)

(deflayer colemak
  grv XX    XX    XX    XX    XX    XX    XX    XX    XX    XX    XX    XX    _
  tab         q       w       f       p       b       j       l       u       y       ;       [       ]    
  lctrl   @alctrl @rlsft      @slalt      @tlmet      g       m       @nrmet      @eralt      @irsft      @orctrl      '       ret
  lsft    XX z       x       c       d       v     k       h       ,       .       /       rsft
  XX XX XX           @smartspace            XX XX XX
)

(deflayer magic
  _  @clmk    @qwerty    _    _    _    _    _    _    _    _    _    _    _
  _  _    _    _    _    _    _    _    _    _    _    _    _    
  _     tab    A-tab    _    _    _    _    bspc  esc   _ ret    _  _
  _ _ _    _    _    _    _    _    _    _    _    _    _
  _ _ _           _            _ _ _
)

(defalias
  warrows (tap-hold 200 200 w (layer-toggle arrows))

  alctrl (tap-hold 200 200 a lctrl)
  slsft (tap-hold 200 200 s lsft)
  dlalt (tap-hold 200 200 d lalt)
  flmet (tap-hold 200 200 f lmet)

  jrmet (tap-hold 200 200 j rmet)
  kralt (tap-hold 200 200 k ralt)
  lrsft (tap-hold 200 200 l rsft)
  ;rctrl (tap-hold 200 200 ; rctrl)

  rlsft (tap-hold 200 200 r lsft)
  slalt (tap-hold 200 200 s lalt)
  tlmet (tap-hold 200 200 t lmet)
  nrmet (tap-hold 200 200 n rmet)
  eralt (tap-hold 200 200 e ralt)
  irsft (tap-hold 200 200 i rsft)
  orctrl (tap-hold 200 200 o rctrl)
  clmk (layer-switch colemak)
  qwerty (layer-switch qwerty)

  smartspace (tap-dance 200 (
      (tap-hold 300 300 spc (layer-toggle magic))
      (tap-hold 300 300 (one-shot 300 lalt) spc)
      a
      ))

  )
```
