NoSignal-OS/os updates/nosignal-keybinds-gen
28allday 19fd794b6b NoSignal — fully-offline Arch → Hyprland desktop installer
Single-script builder (nosignal.sh) that turns a stock Arch Linux ISO into a
fully-offline installer for a themed Hyprland + caelestia (Quickshell) desktop:
matching SDDM greeter, Btrfs/Limine bootable snapshots, chwd-style GPU
detection, and a curated "os updates" layer (keybind cheatsheet, settings
panels, system polish, on-box management skill). See README.md.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-21 11:03:10 +01:00

81 lines
3.1 KiB
Bash
Executable file

#!/bin/sh
# nosignal-keybinds-gen — parse the NoSignal keymap markdown and emit display-ready
# cheatsheet lines on stdout. The markdown is the SINGLE SOURCE OF TRUTH; the
# on-screen help (nosignal-keybinds) is always derived from it, so the two cannot
# drift. Reads every "| keys | action |" table row except the "Source map"
# section.
#
# Panel format: two columns only — key, action — sized so every
# line fits the fuzzel panel:
# - no section tag column (visual noise in the popup; the markdown keeps it)
# - doc-only parentheticals are stripped from actions: provenance notes like
# "(Omarchy key)", "(was hover-only)" belong in the doc,
# not the panel. Meaningful ones ("(logout / shutdown / reboot)") stay.
# - actions are ellipsis-truncated so no line exceeds $NOSIGNAL_KEYS_COLS
# characters (default 98 — the nosignal-keybinds fuzzel width of 100 minus
# margin). Keep the two in sync.
#
# Usage: nosignal-keybinds-gen [path-to-markdown]
# Source resolution order: $1 arg → $NOSIGNAL_KEYMAP_MD → known locations.
set -eu
MD="${1:-${NOSIGNAL_KEYMAP_MD:-}}"
if [ -z "$MD" ]; then
for cand in "$HOME/.local/share/nosignal/NoSignal-keybindings.md"; do
[ -f "$cand" ] && { MD="$cand"; break; }
done
fi
[ -n "${MD:-}" ] && [ -f "$MD" ] || {
echo "nosignal-keybinds-gen: keymap markdown not found (set \$NOSIGNAL_KEYMAP_MD)" >&2
exit 1
}
awk -v cols="${NOSIGNAL_KEYS_COLS:-98}" '
function trim(s){ gsub(/\*\*/, "", s); gsub(/^[ \t]+|[ \t]+$/, "", s); return s }
# ---- section headings -------------------------------------------------------
/^## / {
insrc = (substr($0, 4) ~ /^Source map/) # not keybinds: skip the section
next
}
insrc { next }
# ---- table rows -------------------------------------------------------------
/^\|/ {
if ($0 ~ /^[|: -]+$/) next # markdown separator row
n = split($0, c, "|") # c[1] is empty (text before first |)
keys = c[2]; gsub(/`/, "", keys); keys = trim(keys)
if (keys == "" || keys == "Keys" || keys == "File") next
desc = ""
for (i = 3; i < n; i++) { # join any remaining columns
cell = c[i]; gsub(/`/, "", cell); cell = trim(cell)
if (cell != "") desc = (desc == "") ? cell : desc " — " cell
}
# strip doc-only parentheticals (provenance/changelog), keep the rest
out = ""; rest = desc
while (match(rest, /\([^()]*\)/)) {
pre = substr(rest, 1, RSTART - 1)
par = substr(rest, RSTART, RLENGTH)
rest = substr(rest, RSTART + RLENGTH)
if (par ~ /Omarchy|change [0-9]+|^\(was |moved |NoSignal|dev\/debug/) par = ""
out = out pre par
}
desc = out rest
gsub(/ +/, " ", desc) # collapse gaps left by stripping
gsub(/[ \t]+$/, "", desc)
sub(/ — $/, "", desc)
KEY[++r] = keys; DSC[r] = desc
if (length(keys) > wk) wk = length(keys)
}
END {
budget = cols - wk - 2 # action space after the key column
for (i = 1; i <= r; i++) {
d = DSC[i]
if (length(d) > budget) d = substr(d, 1, budget - 1) "…"
printf "%-*s %s\n", wk, KEY[i], d
}
}
' "$MD"