#!/bin/bash # Fake tmux for testing tmux-util. # # State file: $FAKE_TMUX_DIR/sessions.txt # One line per session, space-separated: # [ [ []]] # pids_csv is a comma-separated list of pane PIDs (or '-' for none) # cwd cannot contain spaces in test data. # # Log file: $FAKE_TMUX_DIR/calls.log # Each invocation appended as a single line: tmux : "${FAKE_TMUX_DIR:?FAKE_TMUX_DIR must be set}" STATE="$FAKE_TMUX_DIR/sessions.txt" LOG="$FAKE_TMUX_DIR/calls.log" # Log every invocation printf 'tmux %s\n' "$*" >> "$LOG" cmd="$1" shift read_state() { [ -f "$STATE" ] || return 0 grep -v '^[[:space:]]*$' "$STATE" || true } # Render a tmux format string against one session's fields. # Args: format, name, attached, activity, windows, cwd render_format() { local out="$1" name="$2" attached="$3" activity="$4" windows="$5" cwd="$6" out="${out//\#\{session_name\}/$name}" out="${out//\#\{session_attached\}/$attached}" out="${out//\#\{session_activity\}/$activity}" out="${out//\#\{session_windows\}/$windows}" out="${out//\#\{pane_current_path\}/$cwd}" echo "$out" } # Render a tmux format string against one pane's fields. # Args: format, name, pid, cmd, idx, cwd render_pane_format() { local out="$1" name="$2" pid="$3" cmd="$4" idx="$5" cwd="$6" out="${out//\#\{pane_pid\}/$pid}" out="${out//\#\{pane_current_command\}/$cmd}" out="${out//\#\{pane_current_path\}/$cwd}" out="${out//\#\{session_name\}/$name}" out="${out//\#\{window_index\}/0}" out="${out//\#\{pane_index\}/$idx}" echo "$out" } case "$cmd" in list-sessions) fmt="" while [ "$#" -gt 0 ]; do case "$1" in -F) shift; fmt="${1:-}"; shift ;; *) shift ;; esac done [ -n "$fmt" ] || fmt='#{session_name} #{session_attached}' read_state | while IFS=' ' read -r name attached pids activity windows cwd; do [ -n "$name" ] || continue render_format "$fmt" "$name" "$attached" "${activity:-0}" "${windows:-1}" "${cwd:-/tmp}" done ;; list-panes) all=0 fmt="" session="" while [ "$#" -gt 0 ]; do case "$1" in -t) shift; session="$1"; shift ;; -F) shift; fmt="${1:-}"; shift ;; -s) shift ;; -a) all=1; shift ;; *) shift ;; esac done [ -n "$fmt" ] || fmt='#{pane_pid}' read_state | while IFS=' ' read -r name attached pids activity windows cwd; do [ -n "$name" ] || continue if [ "$all" -eq 0 ] && [ "$name" != "$session" ]; then continue fi [ "$pids" = "-" ] && continue idx=0 for entry in $(echo "$pids" | tr ',' ' '); do pid="${entry%%:*}" cmd="${entry##*:}" [ "$cmd" = "$entry" ] && cmd="shell" render_pane_format "$fmt" "$name" "$pid" "$cmd" "$idx" "${cwd:-/tmp}" idx=$((idx + 1)) done done ;; display) fmt="" target="" while [ "$#" -gt 0 ]; do case "$1" in -p) shift ;; -t) shift; target="$1"; shift ;; *) fmt="$1"; shift ;; esac done while IFS=' ' read -r name attached pids activity windows cwd; do [ -n "$name" ] || continue if [ "$name" = "$target" ]; then render_format "$fmt" "$name" "$attached" "${activity:-0}" "${windows:-1}" "${cwd:-/tmp}" exit 0 fi done < "$STATE" exit 1 ;; has-session) session="" while [ "$#" -gt 0 ]; do case "$1" in -t) shift; session="$1"; shift ;; *) shift ;; esac done # tmux accepts a `=name` form to force exact match; strip the prefix. session="${session#=}" while IFS=' ' read -r name attached pids _rest; do if [ "$name" = "$session" ]; then exit 0 fi done < "$STATE" exit 1 ;; new-session) detached=0 name="" cwd="" while [ "$#" -gt 0 ]; do case "$1" in -s) shift; name="$1"; shift ;; -c) shift; cwd="$1"; shift ;; -d) detached=1; shift ;; *) shift ;; esac done attached=1 [ "$detached" -eq 1 ] && attached=0 printf '%s %s - 0 1 %s\n' "$name" "$attached" "${cwd:-/tmp}" >> "$STATE" ;; attach-session|switch-client) # No state mutation needed — the call log already records intent. ;; rename-session) # Forms: rename-session -t OR rename-session old="" new="" while [ "$#" -gt 0 ]; do case "$1" in -t) shift; old="$1"; shift ;; *) new="$1"; shift ;; esac done if [ -z "$old" ] || [ -z "$new" ]; then echo "fake-tmux rename-session: need both -t and " >&2 exit 1 fi tmp="$STATE.tmp" : > "$tmp" while IFS= read -r line; do [ -n "$line" ] || continue first="${line%% *}" rest="${line#* }" if [ "$first" = "$old" ]; then printf '%s %s\n' "$new" "$rest" >> "$tmp" else printf '%s\n' "$line" >> "$tmp" fi done < "$STATE" mv "$tmp" "$STATE" ;; kill-session) session="" while [ "$#" -gt 0 ]; do case "$1" in -t) shift; session="$1"; shift ;; *) shift ;; esac done tmp="$STATE.tmp" : > "$tmp" while IFS= read -r line; do [ -n "$line" ] || continue first="${line%% *}" if [ "$first" != "$session" ]; then printf '%s\n' "$line" >> "$tmp" fi done < "$STATE" mv "$tmp" "$STATE" ;; *) echo "fake-tmux: unknown command '$cmd'" >&2 exit 1 ;; esac