sxhkd-ish
another place the shell lives forever
For years now, I’ve used bspwm as my daily driver window manager. It does not ship with a builtin way to set keybindings – instead, the recommended path is to use another program by it’s author, sxhkd, to bind key presses to process calls. Such calls are launched with SHELL -c COMMAND
, where SHELL
is set by $SXHKD_SHELL
or $SHELL
. Here’s a pair of bindings from my sxhkdrc:
super + Escape
notify-send "reloading sxhkd!"; pkill -USR1 -x sxhkd
super + {_,shift,alt,ctrl} + {h,n,e,l}
{focus,move,resize,presel}.sh {west,south,north,east}
One of sxhkd’s most attractive features for me is the slick templating you can have. That second example assigns my preferred directional keys (colemak-dhk) to call scripts assigned to do different actions. The full expansion is as follows:
super + h focus.sh west super + n focus.sh south super + e focus.sh north super + l focus.sh east super + shift + h move.sh west super + shift + n move.sh south super + shift + e move.sh north super + shift + l move.sh east super + alt + h resize.sh west super + alt + n resize.sh south super + alt + e resize.sh north super + alt + l resize.sh east super + ctrl + h presel.sh west super + ctrl + n presel.sh south super + ctrl + e presel.sh north super + ctrl + l presel.sh east
WEW that’s a lot. Thanks Baskerbae.
Many of the newer wayland window managers have you assign keys individually via a client, mostly in a shape that sort of hails from the i3 config format. I’ll cherrypick sway’s, but you can see comparable formats in example configs for cardboard, river, and wayfire as well:
bindsym $mod+$left focus left bindsym $mod+$down focus down bindsym $mod+$up focus up bindsym $mod+$right focus right
This snippet comes from the example config, but if you prepend the lines with swaymsg
you get something you can run in a script. In the week or so I gave sway a drive, most of my configuring was done this way – with a swayrc
file containing swaymsg
client calls – the prospect of porting my comparably compact sxhkdrc file was annoying though. So, like the lazy programmer I am, I squinted at it a little bit and realized the sxhkd templating format looked a little… familiar. It’s supremely similar to shell templating!:
$ echo foo{bar,baz} foobar foobaz $ echo {,fae}{bar,baz} bar baz faebar faebaz $ echo super+{_,shift,alt,ctrl}+{h,n,e,l} super+_+h super+_+n super+_+e super+_+l super+shift+h super+shift+n super+shift+e super+shift+l super+alt+h super+alt+n super+alt+e super+alt+l super+ctrl+h super+ctrl+n super+ctrl+e super+ctrl+l
Armed with this knowledge, I glued together something terrible for my swayrc
file:
bind() { args=("$@") for i in $(seq 0 "$(( (${#args[@]} / 2) - 1 ))"); do key=$(echo "${args[$i]}" | sed 's/super/Mod4/' ) val_index=$(( i + (${#args[@]} / 2) )) val=${args[$val_index]} echo swaymsg bindsym "$key" "$bindprefix$val" swaymsg bindsym "$key" "$bindprefix$val" done } # bind exec binde() { bindprefix='exec ' bind "$@" }
And then, as long as I escaped the spaces to connect the terms, I could get away with this as my config:
binde super+{,shift+,alt+,ctrl+}{h,n,e,l} \ {focus,move,resize,presel}.sh\ {west,south,north,east}
Hooray!