Skip to content

Instantly share code, notes, and snippets.

@amiorin
Last active May 12, 2024 08:11
Show Gist options
  • Save amiorin/4c74f63fe599a1dcbd0933628df1aac9 to your computer and use it in GitHub Desktop.
Save amiorin/4c74f63fe599a1dcbd0933628df1aac9 to your computer and use it in GitHub Desktop.
How to configure Home Row Mods with KMonad on macOS

Intro

Karabiner and KMonad are great open source software. Don't forget to support the authors and contributors.

If you want to try home row mods on OSX, don't use Karabiner but KMonad. KMonad is harder at the beginning but then it is easier than Karabiner. Creating layers in KMonad is trivial and without drawbacks, while it is impossible in Karabiner without drawbacks.

You need to compile a PR of the project. Install https://github.com/pqrs-org/Karabiner-DriverKit-VirtualHIDDevice/releases/download/v2.1.0/Karabiner-DriverKit-VirtualHIDDevice-2.1.0.pkg

Install 
/Applications/.Karabiner-VirtualHIDDevice-Manager.app/Contents/MacOS/Karabiner-VirtualHIDDevice-Manager activate
git clone --recursive https://github.com/vosaica/kmonad.git
cd kmonad
git checkout Upgrade-DriverKit-VirtualHIDDevice
git submodule update --init
stack build --flag kmonad:dext --extra-include-dirs=c_src/mac/Karabiner-DriverKit-VirtualHIDDevice/include/pqrs/karabiner/driverkit:c_src/mac/Karabiner-DriverKit-VirtualHIDDevice/src/Client/vendor/include

You need to see the virtual keyboard. Try to restart OSX if it doesn't appear. Screenshot of osx

Debug

I use KeyCastr to have visual feedback

header image

Skip sudo password

# create a new file for writing - visudo uses the vim editor by default.
# go read about this if you have no idea what is going on.

sudo visudo -f /private/etc/sudoers.d/kmonad

# input the line below into the file you are editing.
#  replace <kmonad> with the path to the kmonad binary (output of: which kmonad).
#  replace <user> with your username (output of: whoami). 
#  replace <hash> with the sha256 hash of the kmonad binary (output of: shasum -a 256 $(which kmonad)).
#   this hash must be updated manually after running brew upgrade.

<user> ALL=(root) NOPASSWD: sha256:<hash> <kmonad>

If it works

If it works, this will be the output

❯ sudo kmonad .kmonad.kbd
connected
driver_loaded 0
driver_version_matched 0
driver_loaded 1
driver_version_matched 1

Bugs

  1. The european MBP keyboard is not recognized correctly and this symbol (§) makes kmonad quit with this error.
Encountered error in KeySource: [Cannot translate from mac keycode: (7,100)]
kmonad: [Cannot translate from mac keycode: (7,100)]
  1. Suspend breaks kmonad and it needs to be restarted. I keep Activity Monitor around to kill kmonad with the mouse.

References

(defcfg
input (iokit-name)
output (kext)
;; Comment this if you want unhandled events not to be emitted
fallthrough true
;; Set this to false to disable any command-execution in KMonad
allow-cmd true
)
;; lmet -> cmd
;; lalt -> option
;; fn -> fn
(defalias
sft_a (tap-hold-next-release 200 a lsft)
alt_s (tap-hold-next-release 200 s lalt)
ctl_d (tap-hold-next-release 200 d lctl)
met_f (tap-hold-next-release 200 f lmet)
met_j (tap-hold-next-release 200 j rmet)
ctl_k (tap-hold-next-release 200 k rctl)
alt_l (tap-hold-next-release 200 l lalt)
sft_; (tap-hold-next-release 200 ; rsft)
nav (layer-toggle nav)
m_q (around lmet q)
m_w (around lmet w)
m_e (around lmet e)
m_r (around lmet r)
m_t (around lmet t)
m_a (around lmet a)
m_s (around lmet s)
m_d (around lmet d)
m_f (around lmet f)
m_g (around lmet g)
m_z (around lmet z)
m_x (around lmet x)
m_c (around lmet c)
m_v (around lmet v)
m_sp (around lmet space)
sub (layer-toggle sublime)
sm_sp (around lmet P)
)
(defsrc
f10 f11 f12
tab q w e r t u i o p
caps a s d f g h j k l ;
lsft z x c v b n m , . /
fn lctl lalt lmet space
)
(deflayer qwerty
mute vold volu
tab q w e r t u i o p
lctrl @sft_a @alt_s @ctl_d @met_f g h @met_j @ctl_k @alt_l @sft_;
lsft z x c v b n m , . /
fn lctl lalt @nav space
)
(deflayer nav
_ _ _
tab @m_q @m_w @m_e @m_r @m_t { } \( \)
lctrl @m_a @m_s @m_d @m_f @m_g left down up right ;
@sub @m_z @m_x @m_c @m_v b n [ ] < >
fn lctl lalt @nav @m_sp
)
;; cmd-shift-p
(deflayer sublime
_ _ _
_ _ _ _ _ _ _ _ _ @sm_sp
_ _ _ _ _ _ _ _ _ _ _
_ _ _ _ _ _ _ _ _ _ _
_ _ _ _ _
)
@michaelbarrientos
Copy link

michaelbarrientos commented Jan 7, 2024

There is a fix for bug #2 above, although at the time of writing is still in a pull request. See: kmonad/kmonad#753
A workaround is to fully specify the name of the of the keyboard in defcfg:
(defcfg input (iokit-name "Apple Internal Keyboard / Trackpad") output (kext) )
Rather than use the potentially outdated (and mostly duplicated) information on this page, I suggest anyone interested in using kmonad instead refer to the official documentation for installation: https://github.com/kmonad/kmonad/blob/master/doc/installation.md

@devxalted
Copy link

Took a lot of inspiration from your layout man, well done. Works freakin great. Can't wait for this to turn into muscle memory. So much better this way. This should be more widely adopted.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment