all repos

tmux-stare @ d25769b

session manager, but my session manager
5 files changed, 179 insertions(+), 160 deletions(-)
sessions stuff in sessions.sh
Author: Oleksandr Smirnov olexsmir@gmail.com
Committed at: 2026-02-09 02:08:42 +0200
Change ID: lmuukxpvwklurrsxpznlmxrzyykkyrrm
Parent: 0ef3399
M scripts/pick.sh

@@ -1,6 +1,7 @@

#!/usr/bin/env bash CURRENT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" source "$CURRENT_DIR/helpers.sh" +source "$CURRENT_DIR/sessions.sh" get_all_sessions() { local current_session="$1"

@@ -44,7 +45,7 @@

if tmux has-session -t "$session_name" 2>/dev/null; then tmux switch-client -t "$session_name" else - exec "$CURRENT_DIR/restore.sh" "$session_name" + restore_session "$session_name" fi }
M scripts/restore.sh

@@ -2,91 +2,11 @@ #!/usr/bin/env bash

CURRENT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" source "$CURRENT_DIR/helpers.sh" -# TODO: set the separator globally, or do whole sessions in one module -declare S=$'\t' - -restore_session_from_file() { - local session_file="$1" - local session_name=$(basename "$session_file" | sed 's/_last$//') - exec <"$session_file" - - start_spinner "Restoring session $session_name" - - local session_path="$(head -n1 | cut -d"$SEPARATOR" -f2)" - tmux new-session -ds "$session_name" -c "$session_path" - - declare -A window_layouts - declare active_window - while read -r line; do - case $line in - window*) - IFS=$S read -r _ window_index window_name window_layout window_active <<<"$line" - window_id="$session_name:$window_index" - tmux new-window -k -t "$window_id" -n "$window_name" - window_layouts["$window_id"]="$window_layout" - if [[ "$window_active" == "1" ]]; then - active_window="$window_id" - fi - ;; - - pane*) - IFS=$S read -r _ pane_index pane_current_path pane_active window_index command <<<"$line" - if [[ "$pane_index" == "$(get_tmux_option base-index 0)" ]]; then - tmux send-keys -t "$session_name:$window_index" "cd \"$pane_current_path\"" Enter "clear" Enter - else - tmux split-window -d -t "$session_name:$window_index" -c "$pane_current_path" - fi - if [[ "$pane_active" == "1" ]]; then - tmux select-pane -t "$session_name:$window_index.$pane_index" - fi - if [[ -n "$command" ]]; then - tmux send-keys -t "$session_name:$window_index.$pane_index" "$command" Enter - fi - ;; - esac - done - - for window in "${!window_layouts[@]}"; do - tmux select-layout -t "$window" "${window_layouts[$window]}" - done - - tmux select-window -t "$active_window" - tmux switch-client -t "$session_name" - stop_spinner "Session restored" -} - -restore_session() { - local name="$1" - if tmux has-session -t "$name" 2>/dev/null; then - tmux switch-client -t "$name" - return 0 - fi - - local session_file="$(get_opt_dir)/${name}_last" - if [[ ! -f "$session_file" ]]; then - tmux display-message "No saved session found for: $name" - return 1 - fi - - restore_session_from_file "$session_file" -} - -restore_last() { - local last_file="$(get_opt_dir)/last" - if [[ ! -e "$last_file" ]]; then - tmux display-message "No last session saved" - return 1 - fi - - local session_name=$(basename "$(readlink "$last_file")" | sed 's/_last$//') - restore_session "$session_name" -} - -main() { - if [[ -n "$1" ]]; then - restore_session "$1" - else - restore_last - fi -} -main "$@" +# main() { +# if [[ -n "$1" ]]; then +# restore_session "$1" +# else +# restore_last +# fi +# } +# main "$@"
M scripts/save.sh

@@ -2,74 +2,13 @@ #!/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) +# TODO: save all sessions - 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 +# # TODO: save all loaded sessions not only current +# main() { +# local session_name="${1:-$(get_current_session_name)}" +# start_spinner "Saving session: $session_name" +# save_session "$session_name" +# stop_spinner "Session saved" +# } +# main "$@"
A scripts/sessions.sh

@@ -0,0 +1,156 @@

+#!/usr/bin/env bash +CURRENT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +source "$CURRENT_DIR/helpers.sh" + +declare S=$'\t' + +# === common + +# === save +save_cwd() { + local session_name="$1" + local save_file="$2" + tmux display-message -p -t "$session_name" -F "#{session_path}" >>"$save_file" +} + +save_windows() { + local session_name="$1" + local save_file="$2" + local format="window$S#{window_index}$S#{window_name}$S#{window_layout}$S#{window_active}" + tmux list-windows -t "$session_name" -F "$format" >>"$save_file" + +} + +save_panes() { + local session_name="$1" + local save_file="$2" + local format="pane$S#{pane_index}$S#{pane_current_path}$S#{pane_active}$S#{window_index}$S#{pane_pid}" + tmux list-panes -s -t "$session_name" -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 2>/dev/null)" + 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 +} + +save_session() { + local session_name="$1" + local save_dir="$(get_opt_dir)" + local save_file="${save_dir}/${session_name}_$(get_time)" + local last_file="${save_dir}/${session_name}_last" + + save_cwd "$session_name" "$save_file" + save_windows "$session_name" "$save_file" + save_panes "$session_name" "$save_file" + link_session_last "$save_file" "$last_file" + link_last "$last_file" "$save_dir" +} + +# === restore +restore_session_from_file() { + local session_file="$1" + local session_name=$(basename "$session_file" | sed 's/_last$//') + exec <"$session_file" + + start_spinner "Restoring session $session_name" + + local session_path="$(head -n1 | cut -d"$SEPARATOR" -f2)" + tmux new-session -ds "$session_name" -c "$session_path" + + declare -A window_layouts + declare active_window + while read -r line; do + case $line in + window*) + IFS=$S read -r _ window_index window_name window_layout window_active <<<"$line" + window_id="$session_name:$window_index" + tmux new-window -k -t "$window_id" -n "$window_name" + window_layouts["$window_id"]="$window_layout" + if [[ "$window_active" == "1" ]]; then + active_window="$window_id" + fi + ;; + + pane*) + IFS=$S read -r _ pane_index pane_current_path pane_active window_index command <<<"$line" + if [[ "$pane_index" == "$(get_tmux_option base-index 0)" ]]; then + tmux send-keys -t "$session_name:$window_index" "cd \"$pane_current_path\"" Enter "clear" Enter + else + tmux split-window -d -t "$session_name:$window_index" -c "$pane_current_path" + fi + if [[ "$pane_active" == "1" ]]; then + tmux select-pane -t "$session_name:$window_index.$pane_index" + fi + if [[ -n "$command" ]]; then + tmux send-keys -t "$session_name:$window_index.$pane_index" "$command" Enter + fi + ;; + esac + done + + for window in "${!window_layouts[@]}"; do + tmux select-layout -t "$window" "${window_layouts[$window]}" + done + + tmux select-window -t "$active_window" + tmux switch-client -t "$session_name" + stop_spinner "Session restored" +} + +restore_session() { + local session_name="$1" + if tmux has-session -t "$session_name" 2>/dev/null; then + tmux switch-client -t "$session_name" + return 0 + fi + + local session_file="$(get_opt_dir)/${session_name}_last" + if [[ ! -f "$session_file" ]]; then + tmux display-message "No saved session found for: $session_name" + return 1 + fi + + restore_session_from_file "$session_file" +} + +restore_last() { + local last_file="$(get_opt_dir)/last" + if [[ ! -e "$last_file" ]]; then + tmux display-message "No last session saved" + return 1 + fi + + local session_name=$(basename "$(readlink "$last_file")" | sed 's/_last$//') + restore_session "$session_name" +}
M stare.tmux

@@ -4,9 +4,12 @@

CURRENT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" source "$CURRENT_DIR/scripts/helpers.sh" +# TODO: add interval saves (tmux-continuum like) + main() { local pick_key="$(get_opt_pick)" - [[ -n "$pick_key" ]] && tmux bind-key "$pick_key" run-shell "tmux display-popup -E -w 25% -h 30% '$CURRENT_DIR/scripts/pick.sh'" + [[ -n "$pick_key" ]] && tmux bind-key "$pick_key" run-shell \ + "tmux display-popup -E -w 25% -h 40% '$CURRENT_DIR/scripts/pick.sh'" local save_key="$(get_opt_save)" [[ -n "$save_key" ]] && tmux bind-key "$save_key" run-shell "$CURRENT_DIR/scripts/save.sh"