2 files changed,
133 insertions(+),
0 deletions(-)
Author:
Oleksandr Smirnov
olexsmir@gmail.com
Committed at:
2026-02-09 02:08:41 +0200
Authored at:
2026-02-08 19:15:08 +0200
Change ID:
qyrptuzqlkvvpymwkzoxuspxtklzmkzz
jump to
| A | scripts/helpers.sh |
| A | scripts/save.sh |
A
scripts/helpers.sh
··· 1 +get_tmux_option() { 2 + local option="$1" 3 + local default_value="$2" 4 + local option_value=$(tmux show-option -gqv "$option") 5 + if [ -z "$option_value" ]; then 6 + echo "$default_value" 7 + else 8 + echo "$option_value" 9 + fi 10 +} 11 + 12 +set_tmux_option() { 13 + local option="$1" 14 + local value="$2" 15 + tmux set-option -gq "$option" "$value" 16 +} 17 + 18 +get_time() { date +"%Y%m%dT%H%M%S"; } 19 + 20 +# === options 21 +get_opt_interval() { get_tmux_option "@stare-interval" "10"; } 22 +get_opt_save() { get_tmux_option "@stare-save" "C-s"; } 23 +get_opt_pick() { get_tmux_option "@stare-pick" ""; } 24 +get_opt_dir() { 25 + local dir="$(get_tmux_option "@stare-dir" "${HOME}/.local/share/tmux/stare" | sed "s,\$HOME,$HOME,g; s,\~,$HOME,g")" 26 + mkdir -p "$dir" 27 + echo "$dir" 28 +} 29 + 30 +# === spiner 31 +# TODO: use one of those briael fonts 32 +new_spinner() { 33 + local current=0 34 + local -r chars="/-\|" 35 + while true; do 36 + tmux display-message -- "${chars:$current:1} $1" 37 + current=$(((current + 1) % 4)) 38 + sleep 0.1 39 + done 40 +} 41 + 42 +start_spinner() { 43 + new_spinner "$1" & 44 + export SPINNER_PID=$! 45 +} 46 + 47 +stop_spinner() { 48 + kill "$SPINNER_PID" 49 + tmux display-message "$1" 50 +} 51 + 52 +get_current_session_name() { 53 + if [ "$(tmux display-message -p "#{session_grouped}")" = 0 ]; then 54 + tmux display-message -p "#{session_name}" 2>/dev/null || true 55 + else 56 + tmux display-message -p "#{session_group}" 2>/dev/null || true 57 + fi 58 +}
A
scripts/save.sh
··· 1 +#!/usr/bin/env bash 2 +CURRENT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" 3 +source "$CURRENT_DIR/helpers.sh" 4 + 5 +declare S=$'\t' 6 + 7 +save_cwd() { 8 + local save_file="$1" 9 + tmux -c pwd >>"$save_file" 10 +} 11 + 12 +save_windows() { 13 + local save_file="$1" 14 + local format="window$S#{window_index}$S#{window_name}$S#{window_layout}$S#{window_active}" 15 + tmux list-windows -F "$format" >>"$save_file" 16 +} 17 + 18 +save_panes() { 19 + local save_file="$1" 20 + local format="pane$S#{pane_index}$S#{pane_current_path}$S#{pane_active}$S#{window_index}$S#{pane_pid}" 21 + tmux list-panes -s -F "$format" | 22 + while IFS="$S" read -r line; do 23 + pids=$(ps -ao "ppid,pid" | 24 + sed "s/^ *//" | 25 + grep "^$(cut -f6 <<<"$line")" | 26 + rev | 27 + cut -d' ' -f1 | 28 + rev) 29 + 30 + command="$( 31 + for pid in $pids; do 32 + while read -r arg; do 33 + echo -n "'$arg' " 34 + done <<<"$(xargs -0L1 </proc/"$pid"/cmdline)" 35 + done 36 + )" 37 + 38 + awk -v command="$command" \ 39 + 'BEGIN {FS=OFS="\t"} {$6=command; print}' \ 40 + <<<"$line" >>"$save_file" 41 + done 42 +} 43 + 44 +link_session_last() { 45 + local save_file="$1" 46 + local last_file="$2" 47 + if ! cmp -s "$save_file" "$last_file"; then 48 + ln -sf "$save_file" "$last_file" 49 + else 50 + rm "$save_file" 51 + fi 52 +} 53 + 54 +link_last() { 55 + local save_file="$1" 56 + local save_dir="$2" 57 + ln -sf "$save_file" "$save_dir"/last 58 +} 59 + 60 +# TODO: add interval saves (tmux-continuum like) 61 +# TODO: save all loaded sessions not only current 62 +# TODO: link last session saved as last 63 +main() { 64 + start_spinner "Saving current session" 65 + local save_dir="$(get_opt_dir)" 66 + local save_file="${save_dir}/$(get_current_session_name)_$(get_time)" 67 + local last_file="${save_dir}/$(get_current_session_name)_last" 68 + save_cwd "$save_file" 69 + save_windows "$save_file" 70 + save_panes "$save_file" 71 + link_session_last "$save_file" "$last_file" 72 + link_last "$last_file" "$save_dir" 73 + stop_spinner "Session saved" 74 +} 75 +main