mirror of
https://github.com/basecamp/omarchy.git
synced 2026-02-17 15:25:37 +00:00
Speedup keybindings show by using caching
Co-authored-by: @davidwinter
This commit is contained in:
@@ -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,/' \
|
||||||
@@ -60,7 +109,7 @@ dynamic_bindings() {
|
|||||||
# - Prints everything in a nicely aligned format.
|
# - Prints everything in a nicely aligned format.
|
||||||
parse_bindings() {
|
parse_bindings() {
|
||||||
awk -F, '
|
awk -F, '
|
||||||
{
|
{
|
||||||
# Combine the modifier and key (first two fields)
|
# Combine the modifier and key (first two fields)
|
||||||
key_combo = $1 " + " $2;
|
key_combo = $1 " + " $2;
|
||||||
|
|
||||||
@@ -72,35 +121,38 @@ parse_bindings() {
|
|||||||
action = $3;
|
action = $3;
|
||||||
|
|
||||||
if (action == "") {
|
if (action == "") {
|
||||||
# Reconstruct the command from the remaining fields
|
# Reconstruct the command from the remaining fields
|
||||||
for (i = 4; i <= NF; i++) {
|
for (i = 4; i <= NF; i++) {
|
||||||
action = action $i (i < NF ? "," : "");
|
action = action $i (i < NF ? "," : "");
|
||||||
}
|
}
|
||||||
|
|
||||||
# Clean up trailing commas, remove leading "exec, ", and trim
|
# Clean up trailing commas, remove leading "exec, ", and trim
|
||||||
sub(/,$/, "", action);
|
sub(/,$/, "", action);
|
||||||
gsub(/(^|,)[[:space:]]*exec[[:space:]]*,?/, "", action);
|
gsub(/(^|,)[[:space:]]*exec[[:space:]]*,?/, "", action);
|
||||||
gsub(/^[ \t]+|[ \t]+$/, "", action);
|
gsub(/^[ \t]+|[ \t]+$/, "", action);
|
||||||
gsub(/[ \t]+/, " ", key_combo); # Collapse multiple spaces to one
|
gsub(/[ \t]+/, " ", key_combo); # Collapse multiple spaces to one
|
||||||
|
|
||||||
# Escape XML entities
|
# Escape XML entities
|
||||||
gsub(/&/, "\\&", action);
|
gsub(/&/, "\\&", action);
|
||||||
gsub(/</, "\\<", action);
|
gsub(/</, "\\<", action);
|
||||||
gsub(/>/, "\\>", action);
|
gsub(/>/, "\\>", action);
|
||||||
gsub(/"/, "\\"", action);
|
gsub(/"/, "\\"", action);
|
||||||
gsub(/'"'"'/, "\\'", action);
|
gsub(/'"'"'/, "\\'", action);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (action != "") {
|
if (action != "") {
|
||||||
printf "%-35s → %s\n", key_combo, action;
|
printf "%-35s → %s\n", key_combo, action;
|
||||||
}
|
}
|
||||||
}'
|
}'
|
||||||
}
|
}
|
||||||
|
|
||||||
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"
|
||||||
|
|||||||
Reference in New Issue
Block a user