#!/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 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 , 2 , 3 , # 4 , 5 , 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