The section rule was `/^[[:space:]]*\/\/[[:space:]]*─+ (.+) ─+…$/`, a quantifier on a multibyte character. Under LC_ALL=C — which is what cron, systemd user units and agent shells get, regardless of LANG — gawk matches byte-wise, so `─+` means "the last byte of U+2500, repeated" and never matches. Measured on the live keybinds.kdl: the old script emitted 0 section headers instead of 12, all 120 binding rows intact, exit status 0. A silent one-third-of-the-page loss, invisible to any caller that only checks the status. The dash is now matched and stripped as a literal (`gsub(/─/, "")`), which is byte-safe in every locale, and a comment must be dash-decorated on both sides to open a section, so plain comments are still ignored. A test pins the C-locale case explicitly, because the box's own terminal has always been UTF-8 and could never have caught this. The committed artifact omp-docs/tools/niri/keybindings.md is unaffected (12 headers, 120 rows — it was generated from a UTF-8 shell); output is now identical either way.
102 lines
3.1 KiB
Bash
Executable File
102 lines
3.1 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 "---"
|
|
echo "type: reference"
|
|
echo "title: Niri Keybindings"
|
|
echo "description: Live keybinding cheat sheet generated from $(basename "$KBD") — do not edit by hand."
|
|
echo "tags:"
|
|
echo " - niri"
|
|
echo " - keybindings"
|
|
echo "generated: { by: scripts/gen-keybinds.sh }"
|
|
echo "---"
|
|
echo
|
|
echo "# Niri Keybindings"
|
|
echo
|
|
echo "> GENERATED by \`scripts/gen-keybinds.sh\` from \`$(basename "$KBD")\` — do not edit by hand."
|
|
echo
|
|
awk '
|
|
# Section marker: a comment decorated with box-drawing dashes on both sides,
|
|
# `// ─── Name ───`. The dash is matched as a LITERAL and removed with gsub — never
|
|
# with a quantifier on the multibyte character. Under LC_ALL=C (cron, systemd units,
|
|
# agent shells) gawk works byte-wise, `─+` then means "the last byte of ─, repeated",
|
|
# and every header vanishes while the script still exits 0. Plain comments stay
|
|
# comments: only a dash-decorated one opens a section.
|
|
/^[[:space:]]*\/\/[[:space:]]*─/ {
|
|
s = $0
|
|
sub(/^[[:space:]]*\/\/[[:space:]]*/, "", s)
|
|
sub(/[[:space:]]+$/, "", s)
|
|
if (s ~ /─ .*─/) {
|
|
gsub(/─/, "", s)
|
|
gsub(/[[:space:]]+/, " ", s)
|
|
sub(/^ /, "", s); sub(/ $/, "", 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
|