1 files changed,
75 insertions(+),
13 deletions(-)
Author:
Oleksandr Smirnov
olexsmir@gmail.com
Committed at:
2026-04-14 16:52:19 +0300
Authored at:
2026-02-10 16:01:22 +0200
Change ID:
zxvwuwolyoyqzmlswwvvnzulyuwowykt
Parent:
02f8aba
M
scripts/sessions.sh
ยทยทยท 49 49 50 50 } 51 51 52 +get_pane_child_pids() { 53 + local pane_pid="$1" 54 + ps -ao ppid=,pid= | awk -v pane_pid="$pane_pid" '$1 == pane_pid { print $2 }' 55 +} 56 + 57 +format_process_command() { 58 + local pid="$1" 59 + [[ -r "/proc/${pid}/cmdline" ]] || return 1 60 + xargs -0 bash -c 'printf "%q " "$0" "$@"' <"/proc/${pid}/cmdline" 2>/dev/null | sed 's/[[:space:]]*$//' 61 +} 62 + 63 +build_command_from_pids() { 64 + local pids="$1" 65 + local pid 66 + local formatted 67 + local command="" 68 + for pid in $pids; do 69 + formatted="$(format_process_command "$pid")" 70 + [[ -z "$formatted" ]] && continue 71 + [[ -n "$command" ]] && command+=" | " 72 + command+="$formatted" 73 + done 74 + printf "%s" "$command" 75 +} 76 + 77 +collect_process_names() { 78 + local pids="$1" 79 + local pid 80 + local first_arg 81 + local name 82 + for pid in $pids; do 83 + [[ -r "/proc/${pid}/cmdline" ]] || continue 84 + first_arg="$(tr '\0' '\n' <"/proc/${pid}/cmdline" 2>/dev/null | head -n1)" 85 + [[ -z "$first_arg" ]] && continue 86 + name="$(basename "$first_arg")" 87 + [[ -n "$name" ]] && printf "%s\n" "$name" 88 + done | sort -u 89 +} 90 + 91 +strip_prompt_prefix() { 92 + local line="$1" 93 + if [[ "$line" =~ [\$\#\%\>][[:space:]]+.+$ ]]; then 94 + sed -E 's/^.*[#$%>][[:space:]]+//' <<<"$line" 95 + fi 96 +} 97 + 98 +find_command_from_pane_history() { 99 + local pane_target="$1" 100 + local process_names="$2" 101 + local line 102 + local candidate 103 + local name 104 + while IFS= read -r line; do 105 + [[ -z "$line" ]] && continue 106 + candidate="$(strip_prompt_prefix "$line")" 107 + [[ -z "$candidate" ]] && continue 108 + while IFS= read -r name; do 109 + [[ -z "$name" ]] && continue 110 + if [[ "$candidate" == *"$name"* ]]; then 111 + printf "%s" "$candidate" 112 + return 0 113 + fi 114 + done <<<"$process_names" 115 + done < <(tmux capture-pane -pJ -S -200 -t "$pane_target" 2>/dev/null | tac) 116 +} 117 + 52 118 save_panes() { 53 119 local session_name="$1" 54 120 local save_file="$2" 55 121 local format="pane$S#{pane_index}$S#{pane_current_path}$S#{pane_active}$S#{window_index}$S#{pane_pid}" 56 122 tmux list-panes -s -t "$session_name" -F "$format" | 57 123 while IFS="$S" read -r line; do 58 - pids=$(ps -ao "ppid,pid" | 59 - sed "s/^ *//" | 60 - grep "^$(cut -f6 <<<"$line")" | 61 - rev | 62 - cut -d' ' -f1 | 63 - rev) 124 + IFS="$S" read -r _ pane_index _ _ window_index pane_pid <<<"$line" 125 + pids="$(get_pane_child_pids "$pane_pid")" 126 + command="$(build_command_from_pids "$pids")" 64 127 65 - command="$( 66 - for pid in $pids; do 67 - while read -r arg; do 68 - echo -n "'$arg' " 69 - done <<<"$(xargs -0L1 </proc/"$pid"/cmdline 2>/dev/null)" 70 - done 71 - )" 128 + if [[ -n "$command" ]]; then 129 + process_names="$(collect_process_names "$pids")" 130 + pane_target="${session_name}:${window_index}.${pane_index}" 131 + pane_command="$(find_command_from_pane_history "$pane_target" "$process_names")" 132 + [[ -n "$pane_command" ]] && command="$pane_command" 133 + fi 72 134 73 135 awk -v command="$command" \ 74 136 'BEGIN {FS=OFS="\t"} {$6=command; print}' \