Today I learned

Configure Karabiner with Goku

Karabiner-Elements is a macOS utility for keyboard customization. I’ve been using it for years. It uses a verbose JSON configuration which can be painful to work with.

Goku lets you use the edn for configuration, which makes it a lot easier.

Here’s a quick sample for one of the most common Karabiner use cases:

{:des "caps_lock to esc when pressed alone, to ctrl as modifier"
 :rules [[:##caps_lock :left_control nil {:alone :escape}]]}

Compare directories with diff

diff (included in macOS and most Linux distributions) lets you easily compare two directories.

For example, diff --recursive --brief dir_one dir_two will give a brief list of differences between dir_one and dir_two.

Remap keys on Linux with keyd

Today I learned about the existence of keyd, which is a system-wide daemon program that lets you remap keys on a kernel level.

I previously used kmonad, but its configuration file can be overwhelming to setup for simple needs. Keyd feels simpler and has a minimalistic configuration syntax.

In author’s words:

Notably keyd was written entirely in C with performance and simplicitly in mind and will likely never be as configurable as kmonad (which is extensible in Haskell).

Here’s how my current configuration looks like:


shift = oneshot(shift)
control = oneshot(control)
leftalt = oneshot(meta)
leftmeta = oneshot(alt)
capslock = overload(C, esc)
f = overload(extend, f)
v = overload(number, v)

h = left
j = down
k = up
l = right
y = home
u = pagedown
i = pageup
o = end
m = enter
; = backspace

m = 1
, = 2
. = 3
j = 4
k = 5
l = 6
u = 7
i = 8
o = 9
; = 0

What it does:

  • turns all modifier keys into “one-shots”, meaning they stick until next keypress so you don’t have to hold them down;
  • swaps left alt and meta (cmd) keys;
  • capslock becomes esc on tap and ctrl on hold;
  • holding f activates the “extend” layer with navigation keys on the home row;
  • holding v activates the “number” layer with numbers arranged into a numpad on the home block.

Unfortunately, keyd is Linux-only. If you’re interested in a cross-platfom solution, check out kmonad.

Move window between spaces on macOS

I always use multiple spaces on macOS and the typical way to move windows between spaces always felt annoying:

  • open Mission Control;
  • grab the needed window on the current space and drag it to another space;
  • open the new space.

Given that I mostly use keyboard shortcuts for quick switching between spaces (which can be configured in System Preferences -> Keyboard -> Shortcuts -> Mission Control ), this whole multi-step operation involving several animations is way too slow.

There’s a better way:

  • without opening Mission Control, grab and hold the window on the current space;
  • use the keyboard shortcut (described above) to switch to a different space – the window will follow.

There are tools that let you do this without involving a mouse: like yabai or amethyst, but I stopped using them since macOS is hard to operate without a mouse in the first place, even when running the aforementioned tools.

Transforming a keyboard matrix in ZMK

I’ve had an issue with ZMK when I wanted to use my existing 34-key keymap for a new keyboard which has more keys.

After a brief look at the source code of keyboard definitions, I found that one can apply a transform in keymap file which maps listed keys to specific switches on the board.

// this is the keymap file for your keyboard (e.g. corne-ish-zen.keymap)

// include the keymap file with your layout
#include "34keys.keymap"
// include the matrix transform definitions from ZMK (used below)
#include <dt-bindings/zmk/matrix_transform.h>

/ {
    chosen {
        // apply the transfrom defined below
        zmk,matrix_transform = &thirty_four_key_transform;

    thirty_four_key_transform: keymap_transform_2 {
    compatible = "zmk,matrix-transform";
    columns = <10>;
    rows = <4>;
      // map keys listed in your keymap to specific switches on the board
      // | SW2  | SW3  | SW4  | SW5  | SW6  |   | SW6  | SW5  | SW4  | SW3  | SW2  |
      // | SW8  | SW9  | SW10 | SW11 | SW12 |   | SW12 | SW11 | SW10 | SW9  | SW8  |
      // | SW14 | SW15 | SW16 | SW17 | SW18 |   | SW18 | SW17 | SW16 | SW15 | SW14 |
      //                      | SW20 | SW21 |   | SW21 | SW20 |
            map = <
      RC(0,1) RC(0,2) RC(0,3) RC(0,4) RC(0,5)  RC(0,6) RC(0,7) RC(0,8) RC(0,9) RC(0,10)
      RC(1,1) RC(1,2) RC(1,3) RC(1,4) RC(1,5)  RC(1,6) RC(1,7) RC(1,8) RC(1,9) RC(1,10)
      RC(2,1) RC(2,2) RC(2,3) RC(2,4) RC(2,5)  RC(2,6) RC(2,7) RC(2,8) RC(2,9) RC(2,10)
                              RC(3,4) RC(3,5)  RC(3,6) RC(3,7)

Checkout files from another branch in git

Say you’re on branch foo and you need to grab some files from branch bar.

Turns out, git-checkout can help:

# on branch foo
git checkout bar path/to/file