diff --git a/etc/skel/.config/nwg-wrapper/help.sh b/etc/skel/.config/nwg-wrapper/help.sh new file mode 100755 index 0000000..c7a7f90 --- /dev/null +++ b/etc/skel/.config/nwg-wrapper/help.sh @@ -0,0 +1,2 @@ +#!/bin/sh +/usr/share/sway/scripts/sbdp.py $HOME/.config/sway/config | jq --raw-output 'sort_by(.category) | .[] | .action + ": " + .keybinding + ""' diff --git a/etc/skel/.config/nwg-wrapper/style.css b/etc/skel/.config/nwg-wrapper/style.css new file mode 100644 index 0000000..5b0309c --- /dev/null +++ b/etc/skel/.config/nwg-wrapper/style.css @@ -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; +} diff --git a/etc/sway/config.d/40-autostart-applications.conf b/etc/sway/config.d/40-autostart-applications.conf index 3da6ac4..e81453a 100644 --- a/etc/sway/config.d/40-autostart-applications.conf +++ b/etc/sway/config.d/40-autostart-applications.conf @@ -8,6 +8,7 @@ exec { $wlsunset $autotiling $term_server + $help_menu $cliphist_store $cliphist_watch $autoname_workspaces diff --git a/etc/sway/variables b/etc/sway/variables index 8c6849a..d21d124 100644 --- a/etc/sway/variables +++ b/etc/sway/variables @@ -15,7 +15,7 @@ set $term_cwd $term -D "$(/usr/share/sway/scripts/swaycwd.sh 2>/dev/null || echo set $term_server foot --server set $term_float footclient -a floating_shell -# rofi theme +# Rofi theme set $rofi_theme "* {lightbg: $base; background: $base; lightfg: $blue; foreground: $text; border-color: $blue;} window {border: 2;}" # Your preferred application launcher @@ -33,7 +33,7 @@ set $volume_bar /usr/share/sway/scripts/volume-notify.sh # Brightness notification set $brightness_bar /usr/share/sway/scripts/brightness-notify.sh -# brightness control +# Brightness control set $brightness_step bash -c 'echo $(( $(light -Mr) / 100 * 5 < 1 ? 1 : $(( $(light -Mr) / 100 * 5 )) ))' set $brightness_up light -r -A $($brightness_step) && $brightness_bar set $brightness_down light -r -U $($brightness_step) && $brightness_bar @@ -43,16 +43,22 @@ set $volume_down pulsemixer --change-volume -5 && $volume_bar set $volume_up pulsemixer --change-volume +5 && $volume_bar set $volume_mute pulsemixer --toggle-mute && $volume_bar -# clipboard history +# Clipboard history set $clipboard cliphist list | rofi -dmenu -font "$gui-font" -p "Select item to copy:" -lines 10 -width 35 | cliphist decode | wl-copy set $clipboard-del cliphist list | rofi -dmenu -font "$gui-font" -p "Select item to delete:" -lines 10 -width 35 | cliphist delete # Pulseaudo command set $pulseaudio $term_float pulsemixer -# calendar application +# Calendar application set $calendar $term_float calcurse +# Help overlay +set $help_menu '[ -x "$(command -v nwg-wrapper)" ] && [ -f $HOME/.config/nwg-wrapper/help.sh ] && /usr/share/sway/scripts/help.sh' + +# Help overlay command +set $help /usr/share/sway/scripts/help.sh --toggle + ### Idle configuration # This will lock your screen after 300 seconds of inactivity, then turn off # your displays after another 300 seconds, and turn your screens back on when @@ -71,7 +77,7 @@ set $idle swayidle -w \ before-sleep $lock \ lock $lock & -# workspace names +# Workspace names set $ws1 number 1 set $ws2 number 2 set $ws3 number 3 @@ -83,7 +89,7 @@ set $ws8 number 8 set $ws9 number 9 set $ws10 number 10 -# screenshot +# Screenshot set $grimshot /usr/bin/grimshot set $pipe_output $grimshot save output - set $pipe_selection $grimshot save window - diff --git a/usr/share/sway/scripts/help.sh b/usr/share/sway/scripts/help.sh new file mode 100755 index 0000000..4e4e455 --- /dev/null +++ b/usr/share/sway/scripts/help.sh @@ -0,0 +1,15 @@ +#!/bin/sh +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 + for output in $(swaymsg -t get_outputs --raw | jq -r '.[].name'); do + nwg-wrapper -o "$output" -sv ${VISIBILITY_SIGNAL} -sq ${QUIT_SIGNAL} -s help.sh -p left -a end & + done +fi diff --git a/usr/share/sway/scripts/sbdp.py b/usr/share/sway/scripts/sbdp.py new file mode 100755 index 0000000..4a0a09c --- /dev/null +++ b/usr/share/sway/scripts/sbdp.py @@ -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 = '/etc/sway/config' + + +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(' ')[1] + + +class DocsConfig: + category: Text + action: Text + keybinding: Text + + +def getDocsConfig(lines: list[str]): + docsLineRegex = r"^## (?P.+?) // (?P.+?)\s+(// (?P.+?))*##" + 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\$.+?)\s(?P.+)?" + 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))