Files
command-center/scripts/gen-keybinds.sh
T
Frank f63d11de85 feat(blankpad): desk.sh profile switcher, hotplug autoswitch daemon, keybinds doc generator + bats suite
- desk.sh: list/current/switch/cycle/match/capture over cfg/desk-*.kdl
  profiles; apply = relink display.kdl, niri validate (rollback on fail),
  load-config-file, noctalia notification; match scores // requires: lines
  (EDID long names) against live niri msg outputs
- desk-autoswitch.sh: watch niri msg --json event-stream for
  OutputsChanged, debounced desk.sh match --apply, reconnect loop
- blankpad-desk-autoswitch.service: ConditionHost=blankpad user unit
- gen-keybinds.sh: keybinds.kdl -> markdown cheat sheet (sections from
  // --- headers, hotkey-overlay-title preferred over action)
- tests/: 27 bats cases, all green (desk 16, gen-keybinds 6,
  niri-config 5 incl. real niri validate on the assembled tree with
  each desk profile active)
2026-10-09 14:40:26 -07:00

82 lines
2.2 KiB
Bash
Executable File

#!/usr/bin/env bash
# scripts/gen-keybinds.sh — generate the niri keybinding cheat sheet (markdown)
# from a keybinds.kdl file.
#
# Usage:
# gen-keybinds.sh [keybinds.kdl] # markdown to stdout
# gen-keybinds.sh [keybinds.kdl] --write OUT # markdown to OUT
#
# Default input: ~/.config/niri/cfg/keybinds.kdl
# Recognized: section comments `// ─── Name ───`, bind lines with optional
# hotkey-overlay-title="..."; the action inside { } is used when there is no title.
set -euo pipefail
usage() { sed -n '2,11p' "$0" | sed 's/^# \{0,1\}//'; }
KBD=""
OUT=""
while [ $# -gt 0 ]; do
case "$1" in
-h|--help) usage; exit 0 ;;
--write) OUT="${2:?--write needs an output path}"; shift 2 ;;
*) KBD="$1"; shift ;;
esac
done
KBD="${KBD:-$HOME/.config/niri/cfg/keybinds.kdl}"
[ -f "$KBD" ] || { echo "error: no such file: $KBD" >&2; exit 1; }
gen() {
echo "# Niri Keybindings"
echo
echo "> GENERATED by \`scripts/gen-keybinds.sh\` from \`$(basename "$KBD")\` — do not edit by hand."
echo
awk '
# section header: // ─── Name ───
/^[[:space:]]*\/\/[[:space:]]*─+ (.+) ─+[[:space:]]*$/ {
s = $0
sub(/^[[:space:]]*\/\/[[:space:]]*─+ /, "", s)
sub(/ ─+[[:space:]]*$/, "", s)
if (in_table) print ""
print "## " s
print ""
print "| Key | Action |"
print "|-----|--------|"
in_table = 1
next
}
# bind line: KEY [flags] [hotkey-overlay-title="..."] { action; }
/^[[:space:]]*[A-Z][A-Za-z0-9+]*( |$)/ && /\{/ {
key = $1
title = ""
if (match($0, /hotkey-overlay-title="[^"]*"/)) {
title = substr($0, RSTART + 22, RLENGTH - 23)
}
act = ""
if (match($0, /\{[^}]*\}/)) {
act = substr($0, RSTART + 1, RLENGTH - 2)
sub(/;[[:space:]]*$/, "", act)
gsub(/[[:space:]]+/, " ", act)
sub(/^ /, "", act); sub(/ $/, "", act)
}
out = (title != "") ? title : act
gsub(/\|/, "\\|", out)
print "| `" key "` | " out " |"
n++
next
}
END {
if (in_table) print ""
printf("<!-- %d bindings -->\n", n) > "/dev/stderr"
}
' "$KBD"
}
if [ -n "$OUT" ]; then
mkdir -p "$(dirname "$OUT")"
gen > "$OUT"
echo "wrote $OUT" >&2
else
gen
fi