From cb5f09c41473a0e96e8a5fcfe0224f7445a9c563 Mon Sep 17 00:00:00 2001 From: Marty Oehme Date: Tue, 26 May 2020 11:46:53 +0200 Subject: [PATCH] [sxhkd] Add script to show current sxhkd mode Script can be used in a statusbar or otherwise and will return the currently active sxhkd mode. Look into the README for further explanation. --- README.md | 2 +- sxhkd/.config/sh/alias.d/sxhkd.sh | 30 +++++ sxhkd/.config/sxhkd/chain-labels.conf | 7 ++ sxhkd/.config/sxhkd/sxhkdrc | 4 + sxhkd/.local/bin/sxhkd-chain-labels | 156 ++++++++++++++++++++++++++ sxhkd/README.md | 46 ++++++++ 6 files changed, 244 insertions(+), 1 deletion(-) create mode 100644 sxhkd/.config/sh/alias.d/sxhkd.sh create mode 100644 sxhkd/.config/sxhkd/chain-labels.conf create mode 100755 sxhkd/.local/bin/sxhkd-chain-labels create mode 100644 sxhkd/README.md diff --git a/README.md b/README.md index 3ed7396..3af5508 100644 --- a/README.md +++ b/README.md @@ -50,7 +50,7 @@ Enjoy! * [`polybar`](polybar/README.md) - Easy to customize statusbar * [`qutebrowser`](https://github.com/qutebrowser/qutebrowser) - vim-key enabled web browser * [`rofi`](https://github.com/davatorium/rofi) - Application launcher, dmenu replacement -* [`sxhkd`](https://github.com/baskerville/sxhkd) - X11 hotkey manager +* [`sxhkd`](sxhkd/README.md) - X11 hotkey manager * [`tmux`](https://github.com/tmux/tmux/) - terminal multiplexer * [`vifm`](https://github.com/vifm/vifm) - vim-like file-manager diff --git a/sxhkd/.config/sh/alias.d/sxhkd.sh b/sxhkd/.config/sh/alias.d/sxhkd.sh new file mode 100644 index 0000000..b55d616 --- /dev/null +++ b/sxhkd/.config/sh/alias.d/sxhkd.sh @@ -0,0 +1,30 @@ +#!/usr/bin/env sh +# Starting sxhkd without arguments automatically creates +# a fifo pipe in XDG_RUNTIME_DIR, to enable IPC for sxhkd. +# Mostly used for sxhkd-chain-labels script. + +type sxhkd >/dev/null 2>&1 || { + return 1 +} + +# get the complete path to sxhkd to avoid +# recursion later on +PROG="$(type sxhkd)" +PROG="${PROG##* }" + +FIFO="$XDG_RUNTIME_DIR"/sxhkd_fifo + +# create a fifo and start sxhkd with it +sxhkd() { + exist "$PROG" critical + + if [ -n "$1" ]; then + "$PROG" "$@" + else + [ -e "$FIFO" ] && rm "$FIFO" + + mkfifo "$FIFO" + "$PROG" -s "$FIFO" + fi + +} diff --git a/sxhkd/.config/sxhkd/chain-labels.conf b/sxhkd/.config/sxhkd/chain-labels.conf new file mode 100644 index 0000000..b081524 --- /dev/null +++ b/sxhkd/.config/sxhkd/chain-labels.conf @@ -0,0 +1,7 @@ +# for sxhkd-chain-labels script + +# media manipulation mode: playing, pausing, skipping,.. +media:super + alt + m + +# academia mode: opening bibtex readings, annotating,.. +academia:super + alt + a diff --git a/sxhkd/.config/sxhkd/sxhkdrc b/sxhkd/.config/sxhkd/sxhkdrc index 9a943e7..1ffdb37 100644 --- a/sxhkd/.config/sxhkd/sxhkdrc +++ b/sxhkd/.config/sxhkd/sxhkdrc @@ -60,3 +60,7 @@ super + alt + m : shift + {j,k} # pause/stop player super + alt + m : {_,shift} + p playerctl {play-pause,stop} + +# academia mode +super + alt + a : d + echo noice diff --git a/sxhkd/.local/bin/sxhkd-chain-labels b/sxhkd/.local/bin/sxhkd-chain-labels new file mode 100755 index 0000000..9de6208 --- /dev/null +++ b/sxhkd/.local/bin/sxhkd-chain-labels @@ -0,0 +1,156 @@ +#!/usr/bin/env sh + +# output is to stdout unless explicitly set through -o +OUTPUTF="" + +# set fifo input file, according (somewhat) to xdg +[ -n "$SXHKD_FIFO" ] && FIFO="$SXHKD_FIFO" +[ ! -e "$FIFO" ] && FIFO="${XDG_RUNTIME_DIR}"/sxhkd_fifo +[ ! -e "$FIFO" ] && FIFO="${XDG_CACHE_HOME:-$HOME/.cache}"/sxhkd_fifo +[ ! -e "$FIFO" ] && FIFO="$HOME/.sxhkd_fifo" + +# set label config file, according (somewhat) to xdg +[ -n "$SXHKD_LABELCONFIG" ] && LABELCONFIG="$SXHKD_LABELCONFIG" +[ ! -f "$LABELCONFIG" ] && LABELCONFIG="${XDG_CONFIG_HOME:-$HOME/.config}"/sxhkd/chain-labels.conf +[ ! -f "$LABELCONFIG" ] && LABELCONFIG="$HOME/.chain-labels.conf" + +main() { + while read -r event; do + detect_event "$event" + done <"$FIFO" +} + +detect_event() { + ev="$(echo "$1" | sed -e 's/^H.*$/hotkey/;s/^C.*$/command/;s/^BBegin chain.*$/chainstart/;s/^EEnd chain.*$/chainend/;')" + + case $ev in + hotkey) ev_hotkey "$(echo "$1" | sed -e 's/^H//')" ;; + # command) ev_command "$(echo "$1" | sed -e 's/^C//')" ;; + chainstart) ev_chainstart "$(echo "$1" | sed -e 's/^B//')" ;; + chainend) ev_chainend "$(echo "$1" | sed -e 's/^E//')" ;; + *) ;; + esac +} + +send_msg() { + if [ -n "$OUTPUTF" ]; then + echo "$1" >"$OUTPUTF" + else + echo "$1" + fi +} + +ev_hotkey() { + LAST_HOTKEY="$1" +} + +# compare labels to last hotkey, return mode name +ev_chainstart() { + [ -z "$LAST_HOTKEY" ] && return 1 + found=$(echo "$LABELS" | sed -e "/$LAST_HOTKEY/!d;s/^\(.\+\):.*$/\1/") + send_msg "$found" +} + +ev_chainend() { + send_msg "" +} + +# TODO add option to also display last command done in chain +# ev_command() { +# send_msg "command: $1" +# } + +# read config from file, remove comments (lines starting with #) and empty lines +read_config() { + [ -f "$1" ] && LABELS="$(sed -e '/^#/d;/^[[:blank:]]*$/d' <"$1")" || LABELS="" +} + +get_help() { + printf \ + "Usage: sxhkd-chain-labels [-c config file][-o output file][-s input pipe] + + By default will take the input from the input pipe (at XDG_RUNTIME_DIR/sxhkd_fifo) and + print the current sxhkd chain mode to stdout. That means, sxhkd needs to be started + with a fifo pipe running, ideally to the XDG_RUNTIME_DIR: + + mkfifo \$XDG_RUNTIME_DIR/sxhkd_fifo && sxhkd -s \$XDG_RUNTIME_DIR/sxhkd_fifo + + When given a key combination which maps to a specific mode, it will print out the name + of the mode instead. These maps can be passed with -c flag, specifying an options file. + By default it will look in \$XDG_CONFIG_HOME/sxhkd/sxhkd-chain-labels.conf + + When passed the -o flag it will replace the contents of the file passed in with the + current sxhkd chain mode, emptying the file when no mode is active. + + Default lookup places for files, in descending order: + :input fifo + \$SXHKD_FIFO (env variable) + \$XDG_RUNTIME_DIR/sxhkd_fifo + \$XDG_CACHE_HOME/sxhkd_fifo + ~/.cache/sxhkd_fifo + ~/.sxhkd_fifo + + :label configuration + \$SXHKD_LABELCONFIG (env variable) + \$XDG_CONFIG_HOME/sxhkd/chain-labels.conf + ~/.config/sxhkd/chain-labels.conf + ~/.chain-labels.conf + + The label configuration file uses the following format: + mode-name:chain activation combination + + Lines beginning with a # will be ignored. Whitespace is + important, sxhkd will, by default, put a single space + between any component of the key combination. + + An example file: + + media:super + alt + m + system:super + backspace + + \n" +} + +get_version() { + printf \ + "%s: 0.1 + + fifo input pipe: + %s + label configuration file: + %s + output: + %s \n" \ + "$0" \ + "$FIFO" \ + "$LABELCONFIG" \ + "${OUTPUTF:-stdout}" +} + +while getopts "vho:s:c:" opt; do + case "$opt" in + \?) + printf "Usage: sxhkd-chain-labels [-c config file][-o output file][-s input pipe]\n" + exit 0 + ;; + h) + get_help + exit 0 + ;; + v) + get_version + exit 0 + ;; + o) OUTPUTF="$OPTARG" ;; + s) FIFO="$OPTARG" ;; + c) LABELCONFIG="$OPTARG" ;; + esac +done +shift $((OPTIND - 1)) + +[ "${1:-}" = "--" ] && shift + +# look for default label config +[ -z "$LABELS" ] && read_config "$LABELCONFIG" + +main "$@" diff --git a/sxhkd/README.md b/sxhkd/README.md new file mode 100644 index 0000000..72b34a7 --- /dev/null +++ b/sxhkd/README.md @@ -0,0 +1,46 @@ +# sxhkd + +[sxhkd](https://github.com/baskerville/sxhkd) -- simple X hotkey daemon + +sxhkd is set up to manage most of the key bindings in this dotfile configuraition. It is primarily used for three things: system control, to invoke rofi, and to switch between different desktop operating modes. + +## system control + +* super+x: lock the system, i.e. put a lockscreen in front of it, unlocked with your password +* media keys: control the Brightness, Volume, Mute of the system +* super+return: open a terminal + +## rofi invocations + +* super+backspace: system management (shutdown,reboot,logout,..) +* super+space: app launching +* super+r: extended run menu +* super+p: password/secret autofill menu +* super+F8: theme setting menu +* super+q: quick access to bookmarks and search bangs + +## modal desktop + +The modal setup of this desktop allows to first invoke an operating mode and then open the possibility for additional keybindings. +For example, `alt + m` will invoke the `media` mode and then media playback can be controlled through the hjkl keys. +Think of it like invoking the insert mode, or visual mode in a modal editor like vim. + +The idea behind the modal system is to not overload normal system operation with key binds that are only needed every now and again, and mostly as a coherent package. +If I want to control my media playback, by seeking forward or backward, having quick access to controlling the volume seems logical. +But I may not want to open a scholarly pdf, or programming project at the same time, so these actions don't need to be included in a coherent 'media' mode. + +The modes currently are: + +* media, for controlling playback and volume +* academia, for opening pdf, seeing upcoming readings, and editing references + +They are still in flux and may change every now and again as I put this modal setup to the test. To get a closer look at the actual key binds, look into `.config/sxhkd/sxhkdrc` for now. + +## modal notifications + +To know which mode is currently active on the desktop, this module includes a script which will print sxhkd's current mode to stdout, or a file. +This script can be used to show the active mode in a status bar, for example (as the polybar module in these dotfiles does). + +The script lives in `.local/bin/sxhkd-chain-labels` and can be invoked from the path by default. To see available options and the configuration file format use `sxhkd-chain-labels -h`, or take look at the script itself. + +This module overwrites the usual sxhkd program invocation using an alias, which makes sxhkd always (if no options are passed) create and use a named pipe in the XDG_RUNTIME_DIR directory. This is the default location the script will pick it up in.