dotfiles/.local/bin/key-bindings

78 lines
2.5 KiB
Shell
Executable file

#!/bin/sh
# Show the key bindings from ~/.config/gnome-settings/key-bindings.ini,
# one binding per line, flattened from the comment tables in that file
#
# The key column comes first and the search input is prefilled with "^",
# so that a typed pattern only matches the key column
set -eu
INI="${XDG_CONFIG_HOME:-$HOME/.config}/gnome-settings/key-bindings.ini"
awk -F '|' '
/^# .*\|/ {
sub(/^# ?/, "")
for (i = 1; i <= NF; i++) gsub(/^[ \t]+|[ \t]+$/, "", $i)
key = $1
if (key == "Key(s)") { # Header of the <Super> table
mode = "layers"
for (i = 2; i <= NF; i++) mod[i] = $i
next
}
if (key == "Key") { # Header of the browser table
mode = "browser"
next
}
if (mode == "" || key ~ /^[-+]+$/) next
# Every line starts with a layer rank used by `sort` below:
# 1 <Super>, 2 <Super><Shift>, 3 <Super><Control>,
# 4 <Super><Alt>, 5 <Super><Alt><Shift>, 6 browser bindings
if (mode == "browser") {
if (key == "") next
k = split(key, parts, ">")
line[++n] = sprintf("6 %-17s %-20s %s: %s", parts[k],
substr(key, 1, length(key) - length(parts[k])), $2, $3)
next
}
if (key == "") { # Row without a key => prefix or continuation
for (i = 2; i <= NF; i++) {
cell = $i
if (cell == "") continue
if (cell ~ /^\.\.\./) { # Continues the row above
sub(/^\.\.\. */, "", cell)
sub(/ \.\.\.$/, "", line[last[i]])
line[last[i]] = line[last[i]] " " cell
} else { # Prefix for the rows below
sub(/ \.\.\.$/, "", cell)
prefix[i] = cell
}
}
next
}
for (i = 2; i <= NF; i++) {
cell = $i
if (cell == "") continue
if (cell ~ /^\.\.\./) {
sub(/^\.\.\. */, "", cell)
cell = prefix[i] " " cell
}
line[++n] = sprintf("%d %-17s %-20s %s", i - 1, key, mod[i], cell)
last[i] = n
}
}
END { for (i = 1; i <= n; i++) print line[i] }
' "$INI" \
| LC_ALL=C sort -s -f -k2,2 -k1,1n \
| cut -d ' ' -f 2- \
| rofi -dmenu -i -p keys -no-custom -matching regex -filter '^' -no-sort \
-theme-str '* { font: "FiraCode Nerd Font 10"; } window { width: 60em; } listview { lines: 20; }' \
>/dev/null