Files
dotfiles/dot_local/bin/executable_tmux-sessions
T

96 lines
4.6 KiB
Bash
Executable File

#!/usr/bin/env bash
# tmux-sessions — tmux session switcher as a tmux-palette source (the
# "sessions" palette, ~/.config/tmux-palette/palettes/sessions.json).
#
# tmux-sessions print palette items (JSON): the other sessions
# (last one first), every window of every session,
# zoxide's directories, ~/.config's directories,
# and a Rename and a Kill item per session
# tmux-sessions --new QUERY the palette's query item (what was typed): switch
# to session QUERY, or start it in QUERY if that is
# a directory, else in zoxide's best match for it
# tmux-sessions --dir DIR switch to, or start in DIR, the session named
# after DIR's basename without dots
#
# pj-palette's background task sessions (@pj_task) are left out. Sessions are
# targeted by id since names may contain ':'.
set -uo pipefail
self=$(readlink -f "$0")
session_id() { # name
local id name
while IFS=$'\t' read -r id name; do
[ "$name" = "$1" ] && { printf '%s' "$id"; return 0; }
done < <(tmux list-sessions -F $'#{session_id}\t#{session_name}' 2>/dev/null)
return 1
}
# Switch to session NAME, first starting it in DIR (when given) if missing.
open() { # name [dir]
local id
id=$(session_id "$1") ||
id=$(tmux new-session -d -P -F '#{session_id}' -s "$1" ${2:+-c "$2"}) || exit 1
tmux switch-client -t "$id"
}
case ${1-} in
--dir)
dir=${2%/}
name=${dir##*/}
open "${name//./}" "$2"
exit
;;
--new)
query=$2
[ -d "${query/#\~/$HOME}" ] && exec "$self" --dir "${query/#\~/$HOME}"
dir=
if ! session_id "$query" >/dev/null; then
read -ra words <<<"$query"
dir=$(zoxide query -- "${words[@]}" 2>/dev/null)
fi
open "$query" "$dir"
exit
;;
esac
{
tmux list-sessions -F $'S\t#{session_id}\t#{session_name}\t#{@pj_task}\t#{session_attached}\t#{session_windows}\t#{session_path}'
tmux list-windows -a -F $'W\t#{session_id}\t#{session_name}\t#{@pj_task}\t#{window_id}\t#{window_index}\t#{window_name}\t#{pane_current_path}'
zoxide query -l 2>/dev/null | sed 's/^/Z\t/'
find -L "$HOME/.config" -mindepth 1 -maxdepth 1 -type d 2>/dev/null | sort | sed 's/^/C\t/'
} | jq -Rn --arg self "$self" --arg home "$HOME" \
--arg cur "$(tmux display -p '#{session_id}')" --arg last "$(tmux display -p '#{client_last_session}')" '
def tilde: if startswith($home) then "~" + .[($home | length):] else . end;
def session_name: rtrimstr("/") | split("/") | last | gsub("\\."; "");
[inputs | split("\t")] as $rows
| ($rows | map(select(.[0] == "S" and .[3] == ""))) as $sessions
| ($rows | map(select(.[0] == "S") | .[2])) as $names
| ($rows | map(select(.[0] == "Z") | .[1])) as $zoxide
| ($sessions | map(select(.[1] != $cur))) as $others
| def dir($category; $icon):
(.[1] | session_name) as $name
| {category: $category, icon: $icon, title: (.[1] | tilde),
description: (if $names | any(. == $name) then "switch to \($name)" else "new session \($name)" end),
action: {shell: "\($self | @sh) --dir \(.[1] | @sh)"}};
[
(($others | map(select(.[2] == $last)) + map(select(.[2] != $last)))[]
| {category: "Sessions", icon: "󱂬", title: .[2],
description: "\(.[5]) window\(if .[5] == "1" then "" else "s" end)\(if .[4] != "0" then " · attached" else "" end) · \(.[6] | tilde)",
action: {tmux: "switch-client -t \(.[1] | @sh)"}}
+ (if .[4] != "0" then {iconColor: "#5eff6c"} else {} end)),
($rows[] | select(.[0] == "W" and .[3] == "")
| (.[6] | capture("^(?<icon>[^\\x00-\\x7f]) (?<title>.*)$") // {icon: "", title: .}) as $w
| {category: "Windows", icon: $w.icon, title: $w.title,
description: "\(.[2]):\(.[5]) · \(.[7] | tilde)",
action: {tmux: "switch-client -t \("\(.[1]):\(.[4])" | @sh)"}}),
($rows[] | select(.[0] == "Z") | dir("Zoxide"; "")),
($rows[] | select(.[0] == "C" and (.[1] as $d | $zoxide | any(. == $d) | not)) | dir("Config"; "󱃖")),
($sessions[]
| {category: "Rename", icon: "󰑕", title: "Rename \(.[2])", description: "rename the session",
action: {tmux: "command-prompt -I \(.[2] | @sh) -p \("Rename \(.[2]):" | @sh) \("rename-session -t \(.[1] | @sh) -- \"%%%\"" | @sh)"}}),
($others[]
| {category: "Kill", icon: "󱂧", title: "Kill \(.[2])", description: "kill the session",
action: {tmux: "kill-session -t \(.[1] | @sh)"}})
]'