all repos

tmux-stare @ dee3c28

session manager, but my session manager
1 files changed, 70 insertions(+), 6 deletions(-)
fix process capture while saving sessions
Author: Oleksandr Smirnov olexsmir@gmail.com
Committed at: 2026-06-05 23:31:12 +0300
Authored at: 2026-06-03 17:23:46 +0300
Change ID: tmtmrpqsmkwkqtuzvlnynlslltkwsnxt
Parent: 5d25dc0
M scripts/sessions.sh
···
        47
        47
           local session_name="$1"

      
        48
        48
           local save_file="$2"

      
        49
        49
           local format="window$S#{window_index}$S#{window_name}$S#{window_layout}$S#{window_active}"

      
        50
        
        -  tmux list-windows -t "$session_name" -F "$format" >>"$save_file"

      
        51
        
        -

      
        
        50
        +  tmux list-windows -t "$session_name" -F "$format" | while IFS="$S" read -r line; do

      
        
        51
        +    IFS="$S" read -r _ window_index _ _ _ <<<"$line"

      
        
        52
        +    local auto_rename

      
        
        53
        +    auto_rename="$(tmux show-window-options -v -t "$session_name:$window_index" automatic-rename 2>/dev/null)"

      
        
        54
        +    printf "%s%s%s\n" "$line" "$S" "${auto_rename:-on}"

      
        
        55
        +  done >>"$save_file"

      
        52
        56
         }

      
        53
        57
         

      
        54
        58
         format_process_command() {

      
        55
        59
           local pid="$1"

      
        56
        60
           [[ -r "/proc/${pid}/cmdline" ]] || return 1

      
        57
        
        -  xargs -0 bash -c 'printf "%q " "$0" "$@"' <"/proc/${pid}/cmdline" 2>/dev/null | sed 's/[[:space:]]*$//'

      
        
        61
        +  xargs -0 bash -c 'printf "%q " "$0"; for a; do [[ -n "$a" ]] && printf "%q " "$a"; done' <"/proc/${pid}/cmdline" 2>/dev/null | sed 's/[[:space:]]*$//'

      
        58
        62
         }

      
        59
        63
         

      
        60
        64
         get_descendant_pids() {

      ···
        126
        130
           fi

      
        127
        131
         }

      
        128
        132
         

      
        
        133
        +_fd_is_pipe() {

      
        
        134
        +  [[ "$(readlink -f "/proc/${1}/fd/${2}" 2>/dev/null)" == pipe:* ]]

      
        
        135
        +}

      
        
        136
        +

      
        
        137
        +_order_pipeline() {

      
        
        138
        +  local first="" middle="" last=""

      
        
        139
        +  local pid

      
        
        140
        +  for pid; do

      
        
        141
        +    if ! _fd_is_pipe "$pid" 0 && _fd_is_pipe "$pid" 1; then

      
        
        142
        +      first+=" $pid"

      
        
        143
        +    elif _fd_is_pipe "$pid" 0 && ! _fd_is_pipe "$pid" 1; then

      
        
        144
        +      last+=" $pid"

      
        
        145
        +    else

      
        
        146
        +      middle+=" $pid"

      
        
        147
        +    fi

      
        
        148
        +  done

      
        
        149
        +  printf "%s %s %s" "$first" "$middle" "$last"

      
        
        150
        +}

      
        
        151
        +

      
        129
        152
         capture_running_command() {

      
        130
        153
           local pane_pid="$1"

      
        131
        154
           local pane_target="$2"

      ···
        133
        156
         

      
        134
        157
           command_pid="$(select_active_command_pid "$pane_pid" "$pane_target")"

      
        135
        158
           [[ -n "$command_pid" ]] || return 1

      
        136
        
        -  format_process_command "$command_pid"

      
        
        159
        +

      
        
        160
        +  local pgid

      
        
        161
        +  pgid="$(ps -o pgid= -p "$command_pid" 2>/dev/null | tr -d ' ')"

      
        
        162
        +

      
        
        163
        +  if [[ -z "$pgid" ]]; then

      
        
        164
        +    format_process_command "$command_pid"

      
        
        165
        +    return

      
        
        166
        +  fi

      
        
        167
        +

      
        
        168
        +  local pipeline_pids=""

      
        
        169
        +  local pid pid_pgid

      
        
        170
        +  for pid in $(get_descendant_pids "$pane_pid"); do

      
        
        171
        +    pid_pgid="$(ps -o pgid= -p "$pid" 2>/dev/null | tr -d ' ')"

      
        
        172
        +    [[ "$pid_pgid" == "$pgid" ]] || continue

      
        
        173
        +    pipeline_pids+=" $pid"

      
        
        174
        +  done

      
        
        175
        +

      
        
        176
        +  pipeline_pids="${pipeline_pids# }"

      
        
        177
        +

      
        
        178
        +  local commands=""

      
        
        179
        +  local cmd

      
        
        180
        +  # shellcheck disable=SC2086

      
        
        181
        +  set -- $pipeline_pids

      
        
        182
        +  for pid in $(_order_pipeline "$@"); do

      
        
        183
        +    [[ -z "$pid" ]] && continue

      
        
        184
        +    cmd="$(format_process_command "$pid")" || continue

      
        
        185
        +    [[ -n "$cmd" ]] || continue

      
        
        186
        +    [[ -n "$commands" ]] && commands+=" | "

      
        
        187
        +    commands+="$cmd"

      
        
        188
        +  done

      
        
        189
        +

      
        
        190
        +  if [[ -n "$commands" ]]; then

      
        
        191
        +    printf "%s" "$commands"

      
        
        192
        +  else

      
        
        193
        +    format_process_command "$command_pid"

      
        
        194
        +  fi

      
        137
        195
         }

      
        138
        196
         

      
        139
        197
         save_panes() {

      ···
        276
        334
           while read -r line; do

      
        277
        335
             case $line in

      
        278
        336
               window*)

      
        279
        
        -        IFS=$S read -r _ window_index window_name window_layout window_active <<<"$line"

      
        
        337
        +        IFS=$S read -r _ window_index window_name window_layout window_active auto_rename <<<"$line"

      
        
        338
        +        [[ -z "$auto_rename" ]] && auto_rename="on"

      
        280
        339
                 window_id="$session_name:$window_index"

      
        281
        340
                 tmux new-window -k -t "$window_id" -n "$window_name"

      
        282
        
        -        tmux set-window-option -t "$window_id" automatic-rename on

      
        
        341
        +        if [[ "$auto_rename" == "off" ]]; then

      
        
        342
        +          tmux set-window-option -t "$window_id" automatic-rename off

      
        
        343
        +          tmux rename-window -t "$window_id" "$window_name"

      
        
        344
        +        else

      
        
        345
        +          tmux set-window-option -t "$window_id" automatic-rename on

      
        
        346
        +        fi

      
        283
        347
                 [[ "$window_index" == "$initial_window_index" ]] && initial_window_restored=true

      
        284
        348
                 window_layouts["$window_id"]="$window_layout"

      
        285
        349
                 if [[ "$window_active" == "1" ]]; then