diff options
| author | Robert Günzler <r@gnzler.io> | 2022-08-17 15:43:33 +0200 |
|---|---|---|
| committer | Robert Günzler <r@gnzler.io> | 2022-08-17 15:43:33 +0200 |
| commit | 22de37b2827266fe5e871d6a1e1943f4c27eff85 (patch) | |
| tree | 4b0c1f29ae89bc59bf72f2a014c6c221d11aa92a /bin/swq | |
| parent | 739d13bd9537490dbfe3fef967b963a300ba8fbb (diff) | |
bin/swq: refactor
Diffstat (limited to 'bin/swq')
| -rwxr-xr-x | bin/swq | 318 |
1 files changed, 185 insertions, 133 deletions
diff --git a/bin/swq b/bin/swq index 11128ee..4d8ac4c 100755 --- a/bin/swq +++ b/bin/swq @@ -4,157 +4,209 @@ # convenience queries into the sway container tree # -swtree() -{ - swaymsg -t get_tree +swtree() { + swaymsg -t get_tree } -has_appid() -{ - swtree | jq "[ .. | (select(.app_id?) | select(.app_id | test(\"$1\"))) // (select(.window_properties?.class?) | select(.window_properties.class | test(\"$1\"))) ]" +has_appid() { + swtree | jq "[ .. | (select(.app_id?) | select(.app_id | test(\"$1\"))) // (select(.window_properties?.class?) | select(.window_properties.class | test(\"$1\"))) ]" } -has_pid() -{ - q='' - IFS=$' '; for pid in $1; do - if [[ -n $q ]]; then - q=".pid?==$pid or $q" - else - q=".pid?==$pid" - fi - done - swtree | jq "[ .. | select($q) ]" +has_pid() { + q='' + IFS=$' ' + for pid in $1; do + if [[ -n $q ]]; then + q=".pid?==$pid or $q" + else + q=".pid?==$pid" + fi + done + swtree | jq "[ .. | select($q) ]" } -has_exe() -{ - pid_of_win="$(pgrep -x "$1" -d' ')" - if [[ -z "$pid_of_win" ]]; then - echo "process not found" >&2 - exit 1 - fi - - ppid_of_proc="$(ps -q "$(echo "$pid_of_win" | tr ' ' ',')" -o ppid= |tr -d ' '| tr '\n' ','| sed 's/,$//')" - if [[ -z "$ppid_of_proc" ]]; then - echo "parent process not found" >&2 - fi - IFS=$'\n'; for comm in $(ps -q "$ppid_of_proc" -o pid=,comm=); do - if [[ "$comm" =~ ^.*sh$ ]]; then - # parent process is a shell - # need to get parent process of shell (the terminal emulator) - pid_of_win="$pid_of_win $(ps -p "$(echo "$comm" | awk '{print $1}')" -o ppid= | tr -d ' ')" - fi - done - - if [[ -z "$pid_of_win" ]]; then - echo "process not found" >&2 - exit 1 - fi - has_pid "$pid_of_win" +has_exe() { + pid_of_win="$(pgrep -x "$1" -d' ')" + if [[ -z "$pid_of_win" ]]; then + echo "process not found" >&2 + exit 1 + fi + + ppid_of_proc="$(ps -q "$(echo "$pid_of_win" | tr ' ' ',')" -o ppid= | tr -d ' ' | tr '\n' ',' | sed 's/,$//')" + if [[ -z "$ppid_of_proc" ]]; then + echo "parent process not found" >&2 + fi + IFS=$'\n' + for comm in $(ps -q "$ppid_of_proc" -o pid=,comm=); do + if [[ "$comm" =~ ^.*sh$ ]]; then + # parent process is a shell + # need to get parent process of shell (the terminal emulator) + pid_of_win="$pid_of_win $(ps -p "$(echo "$comm" | awk '{print $1}')" -o ppid= | tr -d ' ')" + fi + done + + if [[ -z "$pid_of_win" ]]; then + echo "process not found" >&2 + exit 1 + fi + has_pid "$pid_of_win" } + has_ws() { - swtree | jq "[ .. | select(.type?==\"workspace\" and .name?==\"$1\") ]" + swtree | jq --arg name "$1" '[ .. | select(.type?=="workspace" and .name?==$name) ]' } -latest() -{ - type="$1" - swtree | jq "[ .. | select(.type?==\"$type\") ] | max_by(.id)" +has_id() { + swtree | jq --argjson arg "{\"id\":$1}" '[ .. | select(.id?==$arg.id) ]' } -list() -{ - swtree | jq "[ .. | select(.type?==\"$1\") | .nodes=[\"...\"] ]" +locate_output_for_con() { + swtree | jq --argjson arg "{\"con_id\":$1}" '[ .. | select(.type?=="output") as $o | .. | select(.id?==$arg.con_id) | $o ]' } -moveto() -{ - if [ ! -t 0 ]; then - read -r -i -e conId - sway [con_id="$conId"] move to workspace "$1" - else - sway [app_id="$1"] move to workspace "$2" - fi +latest() { + swtree | jq --arg type "$1" '[ .. | select(.type? and (.type|test($type))) ] | max_by(.id)' } -# meta commands - -_has() -{ - case "$1" in - appid) has_appid "$2" ;; - pid) has_pid "$2";; - exe) has_exe "$2";; - ws) has_ws "$2";; - *) - printf 'usage: swq has COMMAND <args>\n' - printf '\nCOMMANDS:\n' - printf ' appid: returns the json of the window filtered by app_id/class (fuzzy matching)\n' - printf ' pid: returns json of the window filtered by pid\n' - printf ' exe: returns json of the window filtered by process name\n' - printf ' ws: returns json of the window filtered by workspace\n' - printf '\n' - exit 2 ;; - esac -} -_latest() -{ - case "$1" in - workspace|ws) latest workspace ;; - container|con) latest con ;; - output) latest output ;; - *) - printf 'usage: swq latest <con|workspace|output>\n\n' - exit 2 ;; - esac +list() { + swtree | jq --arg type "$1" '[ .. | select(.type? and (.type|test($type))) ]' } -_list() -{ - [ -n "$1" ] || { echo "usage: swq list <con|workspace>"; exit 1; } - [ "$1" == "ws" ] && _list workspace - list "$1" -} -_current() -{ - case "$1" in - window) _current con ;; - con) swtree | jq '.. | select((.type? | test("con")?) and .focused?)' ;; - - ws) _current workspace ;; - workspace) swtree | jq '.. | select(.type?=="workspace") | . as $parent | .. | select(.focused?==true) | $parent' ;; - output) $0 current workspace | jq -r '.output' ;; - output-full) $0 list output | jq ".[] | select((.type?==\"output\") and (.name?==\"$($0 current output)\"))" ;; - *) - printf 'usage: swq current <con|workspace|output>\n\n' - exit 2 ;; - esac + +moveto() { + if [ ! -t 0 ]; then + read -r -i -e conId + sway [con_id="$conId"] move to workspace "$1" + else + sway [app_id="$1"] move to workspace "$2" + fi } case "$1" in - has) shift; _has $@ ;; - latest) shift; _latest $@ ;; - list|ls) shift; _list $@ ;; - current|cur) shift; _current $@ ;; - - focus-latest-con) sway [con_id="$(latest con | jq -r '.id')"] focus ;; - moveto) shift; moveto $@ ;; - - -h|--help|help) - printf 'usage: swq COMMAND\n' - printf '\n' - printf 'QUERY COMMANDS:\n' - printf ' has: get object by criteria\n' - printf ' latest: get newest objects\n' - printf ' list: list objects\n' - printf ' current: get focused objects\n' - - printf '\n' - printf 'ACTION COMMANDS:\n' - printf ' focus-latest-con\n' - printf ' moveto <appid> <ws>: move container with <appid> to <ws>\n' - printf '\n' - exit 2 ;; - - *) swtree ;; +has) + shift + case "$1" in + appid) has_appid "$2" ;; + pid) has_pid "$2" ;; + exe) has_exe "$2" ;; + ws) has_ws "$2" ;; + id) has_id "$2" ;; + *) + printf 'usage: swq has COMMAND <args>\n' + printf '\nCOMMANDS:\n' + printf ' appid: returns json of the window filtered by app_id/class (fuzzy matching)\n' + printf ' pid: returns json of the window filtered by pid\n' + printf ' exe: returns json of the window filtered by process name\n' + printf ' ws: returns json of the window filtered by workspace\n' + printf ' id: returns json of the window filtered by id\n' + printf '\n' + exit 2 + ;; + esac + ;; + +locate) + shift + case "$1" in + output-for-con) locate_output_for_con "$2" ;; + *) + printf 'usage: swq locate COMMAND <args>\n' + printf '\nCOMMANDS:\n' + printf ' output-for-con: returns output containing con_id\n' + printf '\n' + exit 2 + ;; + esac + ;; + +latest) + shift + case "$1" in + workspace | ws) latest workspace ;; + container | con) latest con ;; + output) latest output ;; + *) + printf 'usage: swq latest <con|workspace|output>\n\n' + exit 2 + ;; + esac + ;; + +list | ls) + shift + [ -n "$1" ] || { + echo "usage: swq list <con|workspace|output>" + exit 1 + } + [ "$1" == "ws" ] && list workspace + list "$1" + ;; + +current | cur) + shift + case "$1" in + window) _current con ;; + con) swtree | jq '.. | select((.type? | test("con")?) and .focused?)' ;; + + ws) _current workspace ;; + workspace) swtree | jq '.. | select(.type?=="workspace") | . as $parent | .. | select(.focused?==true) | $parent' ;; + output) $0 current workspace | jq -r '.output' ;; + output-full) $0 list output | jq ".[] | select((.type?==\"output\") and (.name?==\"$($0 current output)\"))" ;; + *) + printf 'usage: swq current <con|workspace|output|output-full>\n\n' + exit 2 + ;; + esac + ;; + +pick) + shift + pos=$(slurp -p -f '{"x":%x,"y":%y}') + case "${1:-con}" in + con) + swtree | jq --argjson p "$pos" '[.. | select((.type? | test("con")?) and .visible?==true and ($p.x >= .rect.x and $p.x <= (.rect.x + .rect.width)) and ($p.y >= .rect.y and $p.y <= (.rect.y + .rect.height)))]' + ;; + *) + printf 'usage: swq pick <con|workspace|output>\n\n' + exit 2 + ;; + esac + ;; + +geometry) + shift + first_or_last=${1:-last} + jq -r "[..|select(.type? and (.type|test(\"con\")))]|${first_or_last}|.rect|[([.x,.y]|join(\",\")),([.width,.height]|join(\"x\"))]|join(\" \")" + ;; + +focus) + shift + first_or_last=${1:-last} + jq -r "[..|select(.type? and (.type|test(\"con\")))]|${first_or_last}|.id" | xargs -I{} sway [con_id={}] focus + ;; + +moveto) + shift + moveto $@ + ;; + +-h | --help | help) + printf 'usage: swq COMMAND\n' + printf '\n' + printf 'QUERY COMMANDS:\n' + printf ' has: get object by criteria\n' + printf ' latest: get newest objects\n' + printf ' list: list objects\n' + printf ' current: get focused objects\n' + printf ' pick: use slurp to identify\n' + + printf '\n' + printf 'ACTION COMMANDS:\n' + printf ' focus: focus a container (takes stdin)\n' + printf ' moveto <appid> <ws>: move container with <appid> to <ws>\n' + printf ' geometry: print slurp-like `%%x,%%y %%w,%%h` expression (takes stdin)\n' + printf '\n' + exit 2 + ;; + +*) swtree ;; esac |