all repos

tmux-stare @ f520da92b99c9e4f7525d96ef89c6eef3c741bab

session manager, but my session manager
2 files changed, 133 insertions(+), 0 deletions(-)
save.sh
Author: Oleksandr Smirnov olexsmir@gmail.com
Committed at: 2026-02-09 02:08:41 +0200
Change ID: qyrptuzqlkvvpymwkzoxuspxtklzmkzz
A scripts/helpers.sh

@@ -0,0 +1,58 @@

+get_tmux_option() { + local option="$1" + local default_value="$2" + local option_value=$(tmux show-option -gqv "$option") + if [ -z "$option_value" ]; then + echo "$default_value" + else + echo "$option_value" + fi +} + +set_tmux_option() { + local option="$1" + local value="$2" + tmux set-option -gq "$option" "$value" +} + +get_time() { date +"%Y%m%dT%H%M%S"; } + +# === options +get_opt_interval() { get_tmux_option "@stare-interval" "10"; } +get_opt_save() { get_tmux_option "@stare-save" "C-s"; } +get_opt_pick() { get_tmux_option "@stare-pick" ""; } +get_opt_dir() { + local dir="$(get_tmux_option "@stare-dir" "${HOME}/.local/share/tmux/stare" | sed "s,\$HOME,$HOME,g; s,\~,$HOME,g")" + mkdir -p "$dir" + echo "$dir" +} + +# === spiner +# TODO: use one of those briael fonts +new_spinner() { + local current=0 + local -r chars="/-\|" + while true; do + tmux display-message -- "${chars:$current:1} $1" + current=$(((current + 1) % 4)) + sleep 0.1 + done +} + +start_spinner() { + new_spinner "$1" & + export SPINNER_PID=$! +} + +stop_spinner() { + kill "$SPINNER_PID" + tmux display-message "$1" +} + +get_current_session_name() { + if [ "$(tmux display-message -p "#{session_grouped}")" = 0 ]; then + tmux display-message -p "#{session_name}" 2>/dev/null || true + else + tmux display-message -p "#{session_group}" 2>/dev/null || true + fi +}
A scripts/save.sh

@@ -0,0 +1,75 @@

+#!/usr/bin/env bash +CURRENT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +source "$CURRENT_DIR/helpers.sh" + +declare S=$'\t' + +save_cwd() { + local save_file="$1" + tmux -c pwd >>"$save_file" +} + +save_windows() { + local save_file="$1" + local format="window$S#{window_index}$S#{window_name}$S#{window_layout}$S#{window_active}" + tmux list-windows -F "$format" >>"$save_file" +} + +save_panes() { + local save_file="$1" + local format="pane$S#{pane_index}$S#{pane_current_path}$S#{pane_active}$S#{window_index}$S#{pane_pid}" + tmux list-panes -s -F "$format" | + while IFS="$S" read -r line; do + pids=$(ps -ao "ppid,pid" | + sed "s/^ *//" | + grep "^$(cut -f6 <<<"$line")" | + rev | + cut -d' ' -f1 | + rev) + + command="$( + for pid in $pids; do + while read -r arg; do + echo -n "'$arg' " + done <<<"$(xargs -0L1 </proc/"$pid"/cmdline)" + done + )" + + awk -v command="$command" \ + 'BEGIN {FS=OFS="\t"} {$6=command; print}' \ + <<<"$line" >>"$save_file" + done +} + +link_session_last() { + local save_file="$1" + local last_file="$2" + if ! cmp -s "$save_file" "$last_file"; then + ln -sf "$save_file" "$last_file" + else + rm "$save_file" + fi +} + +link_last() { + local save_file="$1" + local save_dir="$2" + ln -sf "$save_file" "$save_dir"/last +} + +# TODO: add interval saves (tmux-continuum like) +# TODO: save all loaded sessions not only current +# TODO: link last session saved as last +main() { + start_spinner "Saving current session" + local save_dir="$(get_opt_dir)" + local save_file="${save_dir}/$(get_current_session_name)_$(get_time)" + local last_file="${save_dir}/$(get_current_session_name)_last" + save_cwd "$save_file" + save_windows "$save_file" + save_panes "$save_file" + link_session_last "$save_file" "$last_file" + link_last "$last_file" "$save_dir" + stop_spinner "Session saved" +} +main