mirror of
https://github.com/prdlk/dotfiles.git
synced 2026-11-02 19:32:43 +00:00
95 lines
4.6 KiB
Bash
95 lines
4.6 KiB
Bash
#!/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)"}})
|
||
|
|
]'
|