#!/usr/bin/env bash set -euo pipefail file="${1:-$HOME/.config/hypr/conf/keybinds.lua}" awk ' function trim(s) { sub(/^[[:space:]]+/, "", s) sub(/[[:space:]]+$/, "", s) return s } function escape_markup(s) { gsub(/&/, "\\&", s) gsub(//, "\\>", s) return s } function print_group_header(name) { if (printed_any_group) { print "" } pretty_group = escape_markup(name) printf "%s\n", pretty_group printed_any_group = 1 } function parse_first_arg(s, depth, in_string, out, i, c, prev) { depth = 0 in_string = 0 out = "" for (i = 1; i <= length(s); i++) { c = substr(s, i, 1) prev = (i > 1 ? substr(s, i - 1, 1) : "") if (c == "\"" && prev != "\\") { in_string = !in_string } if (!in_string) { if (c == "(") depth++ else if (c == ")") depth-- else if (c == "," && depth == 0) break } out = out c } return trim(out) } BEGIN { in_keybinds = 0 group = "" last_group = "" mainMod = "mainMod" printed_any_group = 0 } { line = $0 if (match(line, /^[[:space:]]*local[[:space:]]+mainMod[[:space:]]*=[[:space:]]*"[^"]+"/)) { tmp = line sub(/^[^"]*"/, "", tmp) sub(/".*$/, "", tmp) mainMod = tmp } if (line ~ /^[[:space:]]*--[[:space:]]*KeyBinds[[:space:]]*$/) { in_keybinds = 1 next } if (!in_keybinds) next if (line ~ /^[[:space:]]*--[[:space:]]*[^-].*$/) { group = line sub(/^[[:space:]]*--[[:space:]]*/, "", group) group = trim(group) next } if (line ~ /hl\.bind[[:space:]]*\(/ && line ~ /--/) { if (group != last_group) { print_group_header(group) last_group = group } desc = line sub(/^.*--[[:space:]]*/, "", desc) desc = trim(desc) bind = line sub(/^[[:space:]]*hl\.bind[[:space:]]*\(/, "", bind) key = parse_first_arg(bind) gsub(/[[:space:]]*\.\.[[:space:]]*/, "", key) gsub(/"/, "", key) gsub(/mainMod/, mainMod, key) key = trim(key) pretty_key = escape_markup(key) pretty_desc = escape_markup(desc) printf " %s — %s\n", pretty_key, pretty_desc } } ' "$file" | rofi -dmenu -markup-rows -i -p "Keybinds" >/dev/null