Speedup keybindings show by using caching

Co-authored-by: @davidwinter
This commit is contained in:
David Heinemeier Hansson
2025-10-04 17:55:27 +02:00
parent 4283533858
commit bba224e9a5

View File

@@ -3,6 +3,69 @@
# A script to display Hyprland keybindings defined in your configuration # A script to display Hyprland keybindings defined in your configuration
# using walker for an interactive search menu. # using walker for an interactive search menu.
declare -A KEYCODE_SYM_MAP
build_keymap_cache() {
local keymap
keymap="$(xkbcli compile-keymap)" || {
echo "Failed to compile keymap" >&2
return 1
}
while IFS=, read -r code sym; do
[[ -z "$code" || -z "$sym" ]] && continue
KEYCODE_SYM_MAP["$code"]="$sym"
done < <(
awk '
BEGIN { sec = "" }
/xkb_keycodes/ { sec = "codes"; next }
/xkb_symbols/ { sec = "syms"; next }
sec == "codes" {
if (match($0, /<([A-Za-z0-9_]+)>\s*=\s*([0-9]+)\s*;/, m)) code_by_name[m[1]] = m[2]
}
sec == "syms" {
if (match($0, /key\s*<([A-Za-z0-9_]+)>\s*\{\s*\[\s*([^, \]]+)/, m)) sym_by_name[m[1]] = m[2]
}
END {
for (k in code_by_name) {
c = code_by_name[k]
s = sym_by_name[k]
if (c != "" && s != "" && s != "NoSymbol") print c "," s
}
}
' <<<"$keymap"
)
}
lookup_keycode_cached() {
printf '%s\n' "${KEYCODE_SYM_MAP[$1]}"
}
parse_keycodes() {
local start end elapsed
[[ "${DEBUG:-0}" == "1" ]] && start=$(date +%s.%N)
while IFS= read -r line; do
if [[ "$line" =~ code:([0-9]+) ]]; then
code="${BASH_REMATCH[1]}"
symbol=$(lookup_keycode_cached "$code" "$XKB_KEYMAP_CACHE")
echo "${line/code:${code}/$symbol}"
else
echo "$line"
fi
done
if [[ "$DEBUG" == "1" ]]; then
end=$(date +%s.%N)
# fall back to awk if bc is missing
if command -v bc >/dev/null 2>&1; then
elapsed=$(echo "$end - $start" | bc)
else
elapsed=$(awk -v s="$start" -v e="$end" 'BEGIN{printf "%.6f", (e - s)}')
fi
echo "[DEBUG] parse_keycodes elapsed: ${elapsed}s" >&2
fi
}
# Fetch dynamic keybindings from Hyprland # Fetch dynamic keybindings from Hyprland
# #
# Also do some pre-processing: # Also do some pre-processing:
@@ -19,21 +82,7 @@ dynamic_bindings() {
-e 's,uwsm app -- ,,' \ -e 's,uwsm app -- ,,' \
-e 's/@0//' \ -e 's/@0//' \
-e 's/,@/,code:/' \ -e 's/,@/,code:/' \
-e 's/,code:10,/,1,/' \
-e 's/,code:11,/,2,/' \
-e 's/,code:12,/,3,/' \
-e 's/,code:13,/,4,/' \
-e 's/,code:14,/,5,/' \
-e 's/,code:15,/,6,/' \
-e 's/,code:16,/,7,/' \
-e 's/,code:17,/,8,/' \
-e 's/,code:18,/,9,/' \
-e 's/,code:19,/,0,/' \
-e 's/,code:20,/,-,/' \
-e 's/,code:21,/,=,/' \
-e 's/^0,/,/' \ -e 's/^0,/,/' \
-e 's/,mouse:272,/,MOUSE LEFT,/' \
-e 's/,mouse:273,/,MOUSE RIGHT,/' \
-e 's/^1,/SHIFT,/' \ -e 's/^1,/SHIFT,/' \
-e 's/^4,/CTRL,/' \ -e 's/^4,/CTRL,/' \
-e 's/^5,/SHIFT CTRL,/' \ -e 's/^5,/SHIFT CTRL,/' \
@@ -100,7 +149,10 @@ parse_bindings() {
monitor_height=$(hyprctl monitors -j | jq -r '.[] | select(.focused == true) | .height') monitor_height=$(hyprctl monitors -j | jq -r '.[] | select(.focused == true) | .height')
menu_height=$((monitor_height * 40 / 100)) menu_height=$((monitor_height * 40 / 100))
build_keymap_cache
dynamic_bindings | dynamic_bindings |
sort -u | sort -u |
parse_keycodes |
parse_bindings | parse_bindings |
walker --dmenu --theme keybindings -p 'Keybindings' -w 800 -h "$menu_height" walker --dmenu --theme keybindings -p 'Keybindings' -w 800 -h "$menu_height"