Marty Oehme
7be23bb4b8
Can now parse the usual sxhkdrc file in looking for mode chain combinations. Will prefer explicit configuration files if they exist. Read the -h to learn more.
193 lines
5.1 KiB
Bash
Executable file
193 lines
5.1 KiB
Bash
Executable file
#!/usr/bin/env sh
|
|
|
|
# output is to stdout unless explicitly set through -o or env var
|
|
OUTPUTF="$SXHKD_OUTPUTF"
|
|
|
|
# set fifo input file, according (somewhat) to xdg
|
|
if [ -n "$SXHKD_FIFO" ]; then
|
|
FIFO="$SXHKD_FIFO"
|
|
elif [ -p "${XDG_RUNTIME_DIR}"/sxhkd_fifo ]; then
|
|
FIFO="${XDG_RUNTIME_DIR}"/sxhkd_fifo
|
|
elif [ -p "${XDG_CACHE_HOME:-$HOME/.cache}"/sxhkd_fifo ]; then
|
|
FIFO="${XDG_CACHE_HOME:-$HOME/.cache}"/sxhkd_fifo
|
|
elif [ -p "$HOME/.sxhkd_fifo" ]; then
|
|
FIFO="$HOME/.sxhkd_fifo"
|
|
fi
|
|
|
|
# set label config file, according (somewhat) to xdg
|
|
if [ -n "$SXHKD_LABELCONFIG" ]; then
|
|
LABELCONFIG="$SXHKD_LABELCONFIG"
|
|
elif [ -f "${XDG_CONFIG_HOME:-$HOME/.config}"/sxhkd/chain-labels.conf ]; then
|
|
LABELCONFIG="${XDG_CONFIG_HOME:-$HOME/.config}"/sxhkd/chain-labels.conf
|
|
elif [ -f "$HOME/.chain-labels.conf" ]; then
|
|
LABELCONFIG="$HOME/.chain-labels.conf"
|
|
fi
|
|
|
|
SXHKDRC_FILE="$XDG_CONFIG_HOME"/sxhkd/sxhkdrc
|
|
|
|
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" ] && return 1
|
|
|
|
parse_labels "$(cat "$1")"
|
|
}
|
|
|
|
# parse sxhkdrc for mode compatible comments
|
|
read_sxhkdrc() {
|
|
[ ! -f "$1" ] && return 1
|
|
|
|
_sxhkdrc_content="$(sed -e '/^# mode:/!d;s/^# mode://' <"$1")"
|
|
parse_labels "$_sxhkdrc_content"
|
|
}
|
|
|
|
# append
|
|
parse_labels() {
|
|
LABELS="${LABELS}$(echo "$1" | sed -e '/^#/d;/^[[:blank:]]*$/d')"
|
|
}
|
|
|
|
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
|
|
\$XDG_CONFIG_HOME/sxhkd/sxhkdrc (parsing)
|
|
|
|
The label configuration file uses the following format:
|
|
mode name:key chain
|
|
|
|
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 chain-labels.conf:
|
|
media:super + alt + m
|
|
system:super + backspace
|
|
|
|
Instead of using an explicit configuration file, you can put the chain mode
|
|
information into the regular sxhkdrc as comments. They need to follow this exact format:
|
|
# mode:mode name:key chain
|
|
|
|
They can occur anywhere in the file. The space before mode is necessary, and # needs to
|
|
be the first character on the line. The above example file as written into the sxhkdrc:
|
|
# mode:media:super + alt + m
|
|
# mode:system:super + backspace
|
|
|
|
If an explicit configuration file exists, it will supersede any mode information in the
|
|
sxhkdrc file.
|
|
\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, prefer config file to parsing sxhkdrc
|
|
[ -z "$LABELS" ] && read_config "$LABELCONFIG"
|
|
[ -z "$LABELS" ] && read_sxhkdrc "$SXHKDRC_FILE"
|
|
|
|
main "$@"
|