Add keybindings help overlay

This commit is contained in:
Aleksey Samoilov 2024-01-27 23:26:08 +04:00
parent cdc68187e0
commit d96b91f97b
8 changed files with 228 additions and 48 deletions

View file

@ -0,0 +1,2 @@
#!/bin/sh
/usr/share/river/scripts/sbdp.py $HOME/.config/river/keybindings.sh | jq --raw-output 'sort_by(.category) | .[] | .action + ": <b>" + .keybinding + "</b>"'

View file

@ -0,0 +1,13 @@
window {
background-color: @theme_bg_color;
font-size: medium;
color: #cad3f5;
}
#box-inner {
border-radius: 0px;
border-style: solid;
border-width: 2px;
border-color: #8aadf4;
padding: 10px;
}

View file

@ -45,6 +45,9 @@ riverctl spawn $HOME/.azotebg
# Include keybindings # Include keybindings
riverctl spawn $HOME/.config/river/keybindings.sh riverctl spawn $HOME/.config/river/keybindings.sh
# Keybindings help overlay
riverctl spawn /usr/share/river/scripts/help.sh & disown
# Clipboard daemon # Clipboard daemon
pkill wl-paste pkill wl-paste
wl-paste --watch cliphist store & disown wl-paste --watch cliphist store & disown

View file

@ -25,106 +25,108 @@ riverctl map normal "$mod" Print spawn "/usr/bin/river-grimshot save area - | sw
# Set keyboard layout. See man riverctl # Set keyboard layout. See man riverctl
# riverctl keyboard-layout -options "grp:caps_toggle" "us,ru" # riverctl keyboard-layout -options "grp:caps_toggle" "us,ru"
# Binding to reload the configuration (good for edits on bindings or adding new stuff ## Action // Reload River Configuration // $mod+R ##
riverctl map normal $mod R spawn $HOME/.config/river/init riverctl map normal $mod R spawn $HOME/.config/river/init
# $mod+Shift+Return to start an instance of terminal ## Launch // Terminal // $mod+Return ##
riverctl map normal $mod Return spawn $term riverctl map normal $mod Return spawn $term
# $mod+D to start an instance of application launcher ## Launch // Launcher // $mod+D ##
riverctl map normal $mod D spawn "$launcher" riverctl map normal $mod D spawn "$launcher"
# $mod+Q to close the focused view ## Action // Exit River // $mod+Shift+E ##
riverctl map normal $mod+Shift Q close
# $mod+Shift+E to run nwg-bar (logout, restart, shutdown, etc)
riverctl map normal $mod+Shift E spawn nwg-bar riverctl map normal $mod+Shift E spawn nwg-bar
# $mod+J and $mod+K to focus the next/previous view in the layout stack ## Action // Kill focused window // $mod+Q ##
riverctl map normal $mod+Shift Q close
## Navigation // Focus the next/previous view in the layout stack // $mod+{J,K} ##
riverctl map normal $mod J focus-view next riverctl map normal $mod J focus-view next
riverctl map normal $mod K focus-view previous riverctl map normal $mod K focus-view previous
# $mod+Shift+J and $mod+Shift+K to swap the focused view with the next/previous ## Navigation // Swap the focused view in the layout stack // $mod+Shift+{J,K} ##
# view in the layout stack
riverctl map normal $mod+Shift J swap next riverctl map normal $mod+Shift J swap next
riverctl map normal $mod+Shift K swap previous riverctl map normal $mod+Shift K swap previous
# $mod+Period and $mod+Comma to focus the next/previous output ## Navigation // Focus the next/previous output // $mod+{, .} ##
riverctl map normal $mod Period focus-output next riverctl map normal $mod Period focus-output next
riverctl map normal $mod Comma focus-output previous riverctl map normal $mod Comma focus-output previous
# $mod+Shift+{Period,Comma} to send the focused view to the next/previous output ## Navigation // Send the focused view to the next/previous output // $mod+Shift+{, .} ##
riverctl map normal $mod+Shift Period send-to-output next riverctl map normal $mod+Shift Period send-to-output next
riverctl map normal $mod+Shift Comma send-to-output previous riverctl map normal $mod+Shift Comma send-to-output previous
# $mod+Return to bump the focused view to the top of the layout stack ## Navigation // Bump the focused view to the top of the layout stack // $mod+Shift+Return ##
riverctl map normal $mod+Shift Return zoom riverctl map normal $mod+Shift Return zoom
# $mod+H and $mod+L to decrease/increase the main ratio of rivertile(1) ## Navigation // Decrease/increase the main ratio of rivertile // $mod+{H,L} ##
riverctl map normal $mod H send-layout-cmd rivertile "main-ratio -0.05" riverctl map normal $mod H send-layout-cmd rivertile "main-ratio -0.05"
riverctl map normal $mod L send-layout-cmd rivertile "main-ratio +0.05" riverctl map normal $mod L send-layout-cmd rivertile "main-ratio +0.05"
# $mod+Shift+H and $mod+Shift+L to increment/decrement the main count of rivertile(1) ## Navigation // Increment/decrement the main count of rivertile // $mod+Shift+{H,L} ##
riverctl map normal $mod+Shift H send-layout-cmd rivertile "main-count +1" riverctl map normal $mod+Shift H send-layout-cmd rivertile "main-count +1"
riverctl map normal $mod+Shift L send-layout-cmd rivertile "main-count -1" riverctl map normal $mod+Shift L send-layout-cmd rivertile "main-count -1"
# $mod+Alt+{H,J,K,L} to move views ## Navigation // Move views // $mod+Alt+{H,J,K,L} ##
riverctl map normal $mod+Alt H move left 100 riverctl map normal $mod+Alt H move left 100
riverctl map normal $mod+Alt J move down 100 riverctl map normal $mod+Alt J move down 100
riverctl map normal $mod+Alt K move up 100 riverctl map normal $mod+Alt K move up 100
riverctl map normal $mod+Alt L move right 100 riverctl map normal $mod+Alt L move right 100
# $mod+Alt+Control+{H,J,K,L} to snap views to screen edges ## Navigation // Snap views to screen edges // $mod+Alt+Control+{H,J,K,L}##
riverctl map normal $mod+Alt+Control H snap left riverctl map normal $mod+Alt+Control H snap left
riverctl map normal $mod+Alt+Control J snap down riverctl map normal $mod+Alt+Control J snap down
riverctl map normal $mod+Alt+Control K snap up riverctl map normal $mod+Alt+Control K snap up
riverctl map normal $mod+Alt+Control L snap right riverctl map normal $mod+Alt+Control L snap right
# $mod+Alt+Shift+{H,J,K,L} to resize views ## Navigation // Resize views // $mod+Alt+Shift+{H,J,K,L} ##
riverctl map normal $mod+Alt+Shift H resize horizontal -100 riverctl map normal $mod+Alt+Shift H resize horizontal -100
riverctl map normal $mod+Alt+Shift J resize vertical 100 riverctl map normal $mod+Alt+Shift J resize vertical 100
riverctl map normal $mod+Alt+Shift K resize vertical -100 riverctl map normal $mod+Alt+Shift K resize vertical -100
riverctl map normal $mod+Alt+Shift L resize horizontal 100 riverctl map normal $mod+Alt+Shift L resize horizontal 100
# $mod + Left Mouse Button to move views ## Navigation // Move views with mouse // $mod + Left Mouse Button ##
riverctl map-pointer normal $mod BTN_LEFT move-view riverctl map-pointer normal $mod BTN_LEFT move-view
# $mod + Right Mouse Button to resize views ## Navigation // Resize views with mouse // $mod + Right Mouse Button ##
riverctl map-pointer normal $mod BTN_RIGHT resize-view riverctl map-pointer normal $mod BTN_RIGHT resize-view
# $mod + Middle Mouse Button to toggle float ## Navigation // Toggle float // $mod + Middle Mouse Button ##
riverctl map-pointer normal $mod BTN_MIDDLE toggle-float riverctl map-pointer normal $mod BTN_MIDDLE toggle-float
# Tags navigation
## Navigation // Focus tag [0-8] // $mod+[1-9] ##
## Navigation // Tag focused view with tag [0-8] // $mod+Shift+[1-9] ##
## Navigation // Toggle focus of tag [0-8] // mod+Control+[1-9] ##
## Navigation // Toggle tag [0-8] of focused view // $mod+Shift+Control+[1-9] ##
for i in $(seq 1 9) for i in $(seq 1 9)
do do
tags=$((1 << ($i - 1))) tags=$((1 << ($i - 1)))
# $mod+[1-9] to focus tag [0-8]
riverctl map normal $mod $i set-focused-tags $tags riverctl map normal $mod $i set-focused-tags $tags
# $mod+Shift+[1-9] to tag focused view with tag [0-8]
riverctl map normal $mod+Shift $i set-view-tags $tags riverctl map normal $mod+Shift $i set-view-tags $tags
# $mod+Control+[1-9] to toggle focus of tag [0-8]
riverctl map normal $mod+Control $i toggle-focused-tags $tags riverctl map normal $mod+Control $i toggle-focused-tags $tags
# $mod+Shift+Control+[1-9] to toggle tag [0-8] of focused view
riverctl map normal $mod+Shift+Control $i toggle-view-tags $tags riverctl map normal $mod+Shift+Control $i toggle-view-tags $tags
done done
# $mod+0 to focus all tags ## Navigation // Focus all tags // $mod+0 ##
# $mod+Shift+0 to tag focused view with all tags ## Navigation // Tag focused view with all tags // $mod+Shift+0 ##
all_tags=$(((1 << 32) - 1)) all_tags=$(((1 << 32) - 1))
riverctl map normal $mod 0 set-focused-tags $all_tags riverctl map normal $mod 0 set-focused-tags $all_tags
riverctl map normal $mod+Shift 0 set-view-tags $all_tags riverctl map normal $mod+Shift 0 set-view-tags $all_tags
# $mod+Space to toggle float ## Action // Toggle floating // $mod+Space ##
riverctl map normal $mod Space toggle-float riverctl map normal $mod Space toggle-float
# $mod+F to toggle fullscreen ## Action // Toggle fullscreen // $mod+F ##
riverctl map normal $mod F toggle-fullscreen riverctl map normal $mod F toggle-fullscreen
# $mod+{Up,Right,Down,Left} to change layout orientation ## Navigation // Change layout orientation // $mod+{↑ ↓ ← →} ##
riverctl map normal $mod Up send-layout-cmd rivertile "main-location top" riverctl map normal $mod Up send-layout-cmd rivertile "main-location top"
riverctl map normal $mod Right send-layout-cmd rivertile "main-location right" riverctl map normal $mod Right send-layout-cmd rivertile "main-location right"
riverctl map normal $mod Down send-layout-cmd rivertile "main-location bottom" riverctl map normal $mod Down send-layout-cmd rivertile "main-location bottom"
@ -134,10 +136,10 @@ riverctl map normal $mod Left send-layout-cmd rivertile "main-location left"
# normal mode. This makes it useful for testing a nested wayland compositor # normal mode. This makes it useful for testing a nested wayland compositor
riverctl declare-mode passthrough riverctl declare-mode passthrough
# $mod+F11 to enter passthrough mode ## Action // Enter passthrough mode // $mod+F11 ##
riverctl map normal $mod F11 enter-mode passthrough riverctl map normal $mod F11 enter-mode passthrough
# $mod+F11 to return to normal mode ## Action // Return to normal mode // $mod+F11 ##
riverctl map passthrough $mod F11 enter-mode normal riverctl map passthrough $mod F11 enter-mode normal
# Various media key mapping examples for both normal and locked mode which do # Various media key mapping examples for both normal and locked mode which do

View file

@ -7,6 +7,7 @@
"modules-right": [ "modules-right": [
"tray", "tray",
"custom/playerctl", "custom/playerctl",
"custom/help",
"custom/wlsunset", "custom/wlsunset",
"idle_inhibitor", "idle_inhibitor",
"custom/dunst", "custom/dunst",
@ -51,6 +52,12 @@
"signal": 5 "signal": 5
}, },
"custom/help": {
"format": "",
"on-click": "/usr/share/river/scripts/help.sh --toggle",
"tooltip": "false"
},
"custom/wlsunset": { "custom/wlsunset": {
"interval": "once", "interval": "once",
"tooltip": true, "tooltip": true,
@ -73,7 +80,6 @@
"activated": "", "activated": "",
"deactivated": "" "deactivated": ""
}, },
"start-activated": true,
"tooltip": true, "tooltip": true,
"tooltip-format-activated": "power-saving disabled", "tooltip-format-activated": "power-saving disabled",
"tooltip-format-deactivated": "power-saving enabled" "tooltip-format-deactivated": "power-saving enabled"

View file

@ -76,6 +76,7 @@ window#waybar.hidden {
} }
#clock, #clock,
#custom-help,
#custom-playerctl, #custom-playerctl,
#custom-power, #custom-power,
#custom-wlsunset, #custom-wlsunset,
@ -113,42 +114,46 @@ window#waybar.hidden {
#tray { #tray {
padding-left: 5px; padding-left: 5px;
padding-right: 5px; padding-right: 5px;
color: @rosewater;
}
#custom-playerctl {
color: @flamingo; color: @flamingo;
} }
#custom-wlsunset { #custom-playerctl {
color: @pink; color: @pink;
} }
#idle_inhibitor { #custom-help {
color: @mauve; color: @mauve;
} }
#custom-dunst { #custom-wlsunset {
color: @red; color: @red;
} }
#custom-clipboard { #idle_inhibitor {
color: @maroon; color: @maroon;
} }
#cpu { #custom-dunst {
color: @peach; color: @peach;
} }
#memory { #custom-clipboard {
color: @yellow; color: @yellow;
} }
#cpu {
color: @green;
}
#memory {
color: @teal;
}
#battery { #battery {
animation-timing-function: linear; animation-timing-function: linear;
animation-iteration-count: infinite; animation-iteration-count: infinite;
animation-direction: alternate; animation-direction: alternate;
color: @green; color: @sky;
} }
#battery.warning { #battery.warning {
@ -174,7 +179,7 @@ label:focus {
} }
#network { #network {
color: @teal; color: @sapphire;
} }
#network.disconnected { #network.disconnected {
@ -182,7 +187,7 @@ label:focus {
} }
#bluetooth { #bluetooth {
color: @sky; color: @blue;
} }
#bluetooth.disabled { #bluetooth.disabled {
@ -190,7 +195,7 @@ label:focus {
} }
#pulseaudio { #pulseaudio {
color: @sapphire; color: @lavender;
} }
#pulseaudio.muted { #pulseaudio.muted {
@ -198,5 +203,5 @@ label:focus {
} }
#custom-power { #custom-power {
color: @lavender; color: @text;
} }

13
usr/share/river/scripts/help.sh Executable file
View file

@ -0,0 +1,13 @@
#!/bin/bash
set -x
# toggles the help wrapper state
VISIBILITY_SIGNAL=30
QUIT_SIGNAL=31
if [ "$1" = "--toggle" ]; then
pkill -f -${VISIBILITY_SIGNAL} nwg-wrapper
else
pkill -f -${QUIT_SIGNAL} nwg-wrapper
nwg-wrapper -i -sv ${VISIBILITY_SIGNAL} -sq ${QUIT_SIGNAL} -s help.sh -p left -a end &
fi

136
usr/share/river/scripts/sbdp.py Executable file
View file

@ -0,0 +1,136 @@
#!/usr/bin/python3
import sys
import glob
import re
from typing import Text
import json
if len(sys.argv) >= 2:
rootPath = sys.argv[1]
else:
rootPath = './keybindings.sh'
def readFile(filePath):
try:
paths = glob.glob(filePath)
except (Exception, IndexError):
print("couldn't resolve glob:", filePath)
paths = []
allLines: list[str] = []
for path in paths:
allLines = allLines + open(path, "r").readlines()
finalLines: list[str] = []
for line in allLines:
if re.search(r'^include\s+(.+?)$', line):
nextPath = re.findall(r'^include\s+(.+?)$', line)[0]
finalLines = finalLines + readFile(nextPath)
else:
finalLines = finalLines + [line]
return finalLines
lines = readFile(rootPath)
def findKeybindingForLine(lineNumber: int, lines: list[str]):
return lines[lineNumber + 1].split(' ')[3]
class DocsConfig:
category: Text
action: Text
keybinding: Text
def getDocsConfig(lines: list[str]):
docsLineRegex = r"^## (?P<category>.+?) // (?P<action>.+?)\s+(// (?P<keybinding>.+?))*##"
docsConfig: list[DocsConfig] = []
for index, line in enumerate(lines):
match = re.match(docsLineRegex, line)
if match:
config = DocsConfig()
config.category = match.group('category')
config.action = match.group('action')
config.keybinding = match.group('keybinding')
if config.keybinding is None:
config.keybinding = findKeybindingForLine(index, lines)
docsConfig = docsConfig + [config]
return docsConfig
def getSymbolDict(lines: list[str]):
setRegex = r"^set\s+(?P<variable>\$.+?)\s(?P<value>.+)?"
dictionary = {}
for line in lines:
match = re.match(setRegex, line)
if match:
if match.group('variable'):
dictionary[match.group('variable')] = match.group('value')
return dict(dictionary)
translations = {
'Mod1': "Alt",
'Mod2': "NumLk",
'Mod3': "",
'Mod4': "",
'Mod5': "Scroll",
'question': "?",
'space': "",
'minus': "-",
'plus': '+',
'Return': "Enter",
'XF86AudioRaiseVolume': "",
'XF86AudioLowerVolume': "",
'XF86AudioMute': "",
'XF86AudioMicMute': '',
'XF86MonBrightnessUp': "",
'XF86MonBrightnessDown': "",
'XF86PowerOff': "",
'XF86TouchpadToggle': "Toggle Touchpad"
}
def translate(word: Text, dictionary: dict):
try:
return dictionary[word.strip()]
except KeyError:
return word.strip()
def replaceBindingFromMap(binding: Text, dictionary: dict):
elements = binding.split('+')
resultElements = []
for el in elements:
translation = translate(translate(el, dictionary), translations)
resultElements = resultElements + [translation]
return " + ".join(resultElements)
def sanitize(configs: list[DocsConfig], symbolDict: dict):
for index, config in enumerate(configs):
config.keybinding = replaceBindingFromMap(
config.keybinding, symbolDict)
configs[index] = config
return configs
def getDocsList(lines: list[str]):
docsConfig = getDocsConfig(lines)
symbolDict = getSymbolDict(lines)
sanitizedConfig = sanitize(docsConfig, symbolDict)
return sanitizedConfig
docsList = getDocsList(lines)
result = []
for config in docsList:
result = result + [{'category': config.category,
'action': config.action, 'keybinding': config.keybinding}]
print(json.dumps(result))