This is a short guide to setting up unified window movement bindings with Yabai + SKHD and Emacs, inspired by this tmux-vim movement guide. Short video demo here.
For example, if there’s if Emacs is in focus and there’s an Emacs window to the left, then that window will be focused with the binding. Otherwise, the next application to the left will be focused. In this guide I’m using alt - HJKL, but you can substitute those with whatever you’d like.
- Configure SKHD to passthrough the movement keys when Emacs is focused.
- Add custom yabai window movement commands to Emacs load-path or config.
- Add matching bindings to Emacs config.
- Profit!
Add the following snippet to your .skhdrc
file:
alt - h [ * : yabai -m window --focus west "Emacs" ~ ] alt - l [ * : yabai -m window --focus east "Emacs" ~ ] alt - k [ * : yabai -m window --focus north "Emacs" ~ ] alt - j [ * : yabai -m window --focus south "Emacs" ~ ]
SKHD will now allow the above keys to pass through to Emacs when focused.
Next add the following functions to your emacs config:
(defun yabai-move-on-error (direction move-fn)
(interactive)
(condition-case nil
(funcall move-fn)
(user-error (start-process "yabai" nil "yabai" "-m" "window" "--focus" direction))))
(defun yabai-window-left ()
(interactive)
(yabai-move-on-error "west" #'windmove-left))
(defun yabai-window-right ()
(interactive)
(yabai-move-on-error "east" #'windmove-right))
(defun yabai-window-up ()
(interactive)
(yabai-move-on-error "north" #'windmove-up))
(defun yabai-window-down ()
(interactive)
(yabai-move-on-error "south" #'windmove-down))
These functions will attempt to move in a given direction, but if a user-error is signaled (meaning there’s no emacs window in that direction) a yabai movement command will be issued instead.
Finally, you can add in matching key bindings with global-set-key
, or
define-key
, or map!
, etc…