diff --git a/.github/workflows/regress.yml b/.github/workflows/regress.yml index 0b42dd688..33fe52896 100644 --- a/.github/workflows/regress.yml +++ b/.github/workflows/regress.yml @@ -77,3 +77,11 @@ jobs: cd regress export ASAN_OPTIONS="abort_on_error=1:detect_leaks=0" ${{ matrix.make }} + + - name: upload regress logs + if: failure() + uses: actions/upload-artifact@v4 + with: + name: regress-logs-${{ matrix.name }} + path: regress/logs/*.log + if-no-files-found: ignore diff --git a/.gitignore b/.gitignore index 46e3ad595..31ca7add0 100644 --- a/.gitignore +++ b/.gitignore @@ -21,6 +21,7 @@ configure core etc/ fuzz/*-fuzzer +regress/logs/ tags tmux tmux.1.* diff --git a/regress/Makefile b/regress/Makefile index c354a8187..6370c77c9 100644 --- a/regress/Makefile +++ b/regress/Makefile @@ -1,22 +1,30 @@ TESTS!= echo *.sh +LOGDIR=logs -.PHONY: all $(TESTS) -.NOTPARALLEL: all $(TESTS) +.PHONY: all +.NOTPARALLEL: all all: - @failed=0; failures=; \ + @mkdir -p "$(LOGDIR)"; \ + rm -f "$(LOGDIR)"/*.log; \ + failed=0; failures=; \ for test in $(TESTS); do \ + base=$${test##*/}; \ + log="$(LOGDIR)/$${base%.sh}.log"; \ + rm -f "$$log"; \ printf '%-40s ' "$$test"; \ start=$$(date +%s); \ ASAN_OPTIONS="abort_on_error=1:detect_leaks=0:$$ASAN_OPTIONS"; \ env -i LC_CTYPE=C.UTF-8 ASAN_OPTIONS="$$ASAN_OPTIONS" \ - sh "$$test" >/dev/null 2>&1; \ + sh -x "$$test" >"$$log" 2>&1; \ if [ $$? -eq 0 ]; then \ end=$$(date +%s); \ + rm -f "$$log"; \ echo "PASS ($$((end - start))s)"; \ else \ end=$$(date +%s); \ echo "FAIL ($$((end - start))s)"; \ + echo " log: $$log"; \ failed=1; \ failures="$$failures $$test"; \ fi; \ @@ -28,9 +36,7 @@ all: for test in $$failures; do \ echo " $$test"; \ done; \ + else \ + rmdir "$(LOGDIR)" 2>/dev/null || true; \ fi; \ exit $$failed - -$(TESTS): - sh $@ - sleep 1 diff --git a/regress/choose-buffer.sh b/regress/choose-buffer.sh index 7d689f523..a10d161eb 100644 --- a/regress/choose-buffer.sh +++ b/regress/choose-buffer.sh @@ -17,18 +17,23 @@ PATH=/bin:/usr/bin TERM=screen [ -z "$TEST_TMUX" ] && TEST_TMUX=$(readlink -f ../tmux) -TMUX="$TEST_TMUX -Ltest -f/dev/null" -TMUX2="$TEST_TMUX -Ltest2 -f/dev/null" +TMP=$(mktemp -d) || exit 1 +TMUX_TMPDIR="$TMP" +export TMUX_TMPDIR +TMUX="$TEST_TMUX -Ltest$$ -f/dev/null" +TMUX2="$TEST_TMUX -Ltest2$$ -f/dev/null" cleanup() { $TMUX kill-server 2>/dev/null $TMUX2 kill-server 2>/dev/null + rm -rf "$TMP" } +trap cleanup EXIT + fail() { - echo "$1" - cleanup + echo "$1" >&2 exit 1 } @@ -46,16 +51,33 @@ wait_for() { i=0 while [ "$i" -lt 50 ]; do - if capture | grep -q "$1"; then - sleep 0.5 + CAPTURED=$(capture) + if echo "$CAPTURED" | grep -q "$1"; then return 0 fi - sleep 0.5 + sleep 0.2 i=$((i + 1)) done fail "timed out waiting for '$1'" } +# wait_count $marker $n +# +# Wait (up to ~10s) until exactly $n rendered lines contain $marker. The +# matching capture is left in CAPTURED. +wait_count() +{ + i=0 + while [ "$i" -lt 50 ]; do + CAPTURED=$(capture) + c=$(echo "$CAPTURED" | grep -c "$1") + [ "$c" -eq "$2" ] && return 0 + sleep 0.2 + i=$((i + 1)) + done + fail "timed out waiting for $2 lines of '$1' (have $c)" +} + # wait_buffers $n # # Wait (up to ~10s) until the test server has exactly $n paste buffers. @@ -86,8 +108,30 @@ wait_clients() return 1 } -$TMUX kill-server 2>/dev/null -$TMUX2 kill-server 2>/dev/null +# wait_mode $target $state +# +# Wait (up to ~10s) until a pane enters or leaves mode. +wait_mode() +{ + t=$1 + want=$2 + + i=0 + while [ "$i" -lt 50 ]; do + got=$($TMUX display-message -p -t "$t" '#{pane_in_mode}' \ + 2>/dev/null) + [ "$got" = "$want" ] && return 0 + sleep 0.2 + i=$((i + 1)) + done + fail "pane $t mode state is $got, expected $want" +} + +exit_mode() +{ + $TMUX send-keys -t aaa:0 "$@" || fail "send-keys $* failed" + wait_mode aaa:0 0 +} $TMUX new-session -d -s aaa -x 80 -y 24 || exit 1 @@ -100,57 +144,57 @@ $TMUX set-buffer -b bufz "other buffer" || exit 1 # --- filter by buffer name --------------------------------------------------- $TMUX choose-buffer -t aaa:0 -F 'B1' -f '#{==:#{buffer_name},bufa}' || exit 1 -wait_for 'B1' -out=$(capture) +wait_count ': B1' 1 +out=$CAPTURED echo "$out" | grep -q 'bufa: B1' || fail "bufa missing when it matches" echo "$out" | grep -q 'bufz: B1' && fail "bufz shown but does not match" [ "$(echo "$out" | grep -c ': B1')" -eq 1 ] || fail "expected 1 buffer" -$TMUX send-keys -t aaa:0 q +exit_mode q # --- filter by buffer content ------------------------------------------------ $TMUX choose-buffer -t aaa:0 -F 'B2' -f '#{m:*hello*,#{buffer_sample}}' || \ exit 1 -wait_for 'B2' -out=$(capture) +wait_count ': B2' 1 +out=$CAPTURED echo "$out" | grep -q 'bufa: B2' || fail "bufa missing when content matches" echo "$out" | grep -q 'bufz: B2' && fail "bufz shown but content not matched" -$TMUX send-keys -t aaa:0 q +exit_mode q # --- no filter shows both buffers --------------------------------------------- $TMUX choose-buffer -t aaa:0 -F 'B3' || exit 1 -wait_for 'B3' -out=$(capture) +wait_count ': B3' 2 +out=$CAPTURED echo "$out" | grep -q 'bufa: B3' || fail "bufa missing with no filter" echo "$out" | grep -q 'bufz: B3' || fail "bufz missing with no filter" [ "$(echo "$out" | grep -c ': B3')" -eq 2 ] || fail "expected 2 buffers" -$TMUX send-keys -t aaa:0 q +exit_mode q # --- filter matching nothing --------------------------------------------------- # # Everything is shown and the filter indicator reports no matches. $TMUX choose-buffer -t aaa:0 -F 'B4' -f '#{==:#{buffer_name},nosuch}' || \ exit 1 -wait_for 'B4' -out=$(capture) +wait_count ': B4' 2 +out=$CAPTURED echo "$out" | grep -q 'bufa: B4' || fail "bufa missing with no-match filter" echo "$out" | grep -q 'bufz: B4' || fail "bufz missing with no-match filter" echo "$out" | grep -q 'no matches' || fail "no matches indicator missing" -$TMUX send-keys -t aaa:0 q +exit_mode q # --- sort orders --------------------------------------------------------------- # # By name bufa sorts first and -r reverses. $TMUX choose-buffer -t aaa:0 -F 'B5' -O name || exit 1 -wait_for 'B5' -capture | grep ': B5' | head -1 | grep -q 'bufa: B5' || \ +wait_count ': B5' 2 +echo "$CAPTURED" | grep ': B5' | head -1 | grep -q 'bufa: B5' || \ fail "bufa not first with -O name" -$TMUX send-keys -t aaa:0 q +exit_mode q $TMUX choose-buffer -t aaa:0 -F 'B6' -O name -r || exit 1 -wait_for 'B6' -capture | grep ': B6' | head -1 | grep -q 'bufz: B6' || \ +wait_count ': B6' 2 +echo "$CAPTURED" | grep ': B6' | head -1 | grep -q 'bufz: B6' || \ fail "bufz not first with -O name -r" -$TMUX send-keys -t aaa:0 q +exit_mode q # --- d deletes the selected buffer -------------------------------------------- # @@ -161,16 +205,16 @@ $TMUX send-keys -t aaa:0 d wait_buffers 1 $TMUX list-buffers -F '#{buffer_name}' | grep -q 'bufa' || \ fail "wrong buffer deleted" -$TMUX send-keys -t aaa:0 q +exit_mode q # --- C-t tags all buffers and D deletes the tagged ------------------------------ $TMUX set-buffer -b bufz "other buffer" || exit 1 $TMUX set-buffer -b bufb "third buffer" || exit 1 $TMUX choose-buffer -t aaa:0 -F 'G2' || exit 1 -wait_for ': G2' +wait_count ': G2' 3 $TMUX send-keys -t aaa:0 C-t D wait_buffers 0 -$TMUX send-keys -t aaa:0 q +exit_mode q # --- Enter runs the default command (paste-buffer) ------------------------------ # @@ -178,22 +222,14 @@ $TMUX send-keys -t aaa:0 q # into the shell in the pane, where it appears on the screen. $TMUX set-buffer -b bufa "hello buffer" || exit 1 $TMUX choose-buffer -t aaa:0 -F 'G3' || exit 1 -wait_for 'bufa: G3' -$TMUX send-keys -t aaa:0 Enter -i=0 -while [ "$i" -lt 50 ]; do - [ "$($TMUX display -p -t aaa:0 '#{pane_in_mode}')" = "0" ] && break - sleep 0.5 - i=$((i + 1)) -done -[ "$i" -lt 50 ] || fail "mode did not exit after Enter" +wait_count ': G3' 1 +exit_mode Enter i=0 while [ "$i" -lt 50 ]; do $TMUX capture-pane -p -t aaa:0 | grep -q 'hello buffer' && break - sleep 0.5 + sleep 0.2 i=$((i + 1)) done [ "$i" -lt 50 ] || fail "buffer not pasted into pane" -cleanup exit 0 diff --git a/regress/choose-client.sh b/regress/choose-client.sh index 1e8423415..9031f86bd 100644 --- a/regress/choose-client.sh +++ b/regress/choose-client.sh @@ -16,18 +16,23 @@ PATH=/bin:/usr/bin TERM=screen [ -z "$TEST_TMUX" ] && TEST_TMUX=$(readlink -f ../tmux) -TMUX="$TEST_TMUX -Ltest -f/dev/null" -TMUX2="$TEST_TMUX -Ltest2 -f/dev/null" +TMP=$(mktemp -d) || exit 1 +TMUX_TMPDIR="$TMP" +export TMUX_TMPDIR +TMUX="$TEST_TMUX -Ltest$$ -f/dev/null" +TMUX2="$TEST_TMUX -Ltest2$$ -f/dev/null" cleanup() { $TMUX kill-server 2>/dev/null $TMUX2 kill-server 2>/dev/null + rm -rf "$TMP" } +trap cleanup EXIT + fail() { - echo "$1" - cleanup + echo "$1" >&2 exit 1 } @@ -45,16 +50,33 @@ wait_for() { i=0 while [ "$i" -lt 50 ]; do - if capture | grep -q "$1"; then - sleep 0.5 + CAPTURED=$(capture) + if echo "$CAPTURED" | grep -q "$1"; then return 0 fi - sleep 0.5 + sleep 0.2 i=$((i + 1)) done fail "timed out waiting for '$1'" } +# wait_count $marker $n +# +# Wait (up to ~10s) until exactly $n rendered lines contain $marker. The +# matching capture is left in CAPTURED. +wait_count() +{ + i=0 + while [ "$i" -lt 50 ]; do + CAPTURED=$(capture) + c=$(echo "$CAPTURED" | grep -c "$1") + [ "$c" -eq "$2" ] && return 0 + sleep 0.2 + i=$((i + 1)) + done + fail "timed out waiting for $2 lines of '$1' (have $c)" +} + # wait_clients $n # # Wait (up to ~10s) until the test server has exactly $n clients attached. @@ -70,8 +92,30 @@ wait_clients() return 1 } -$TMUX kill-server 2>/dev/null -$TMUX2 kill-server 2>/dev/null +# wait_mode $target $state +# +# Wait (up to ~10s) until a pane enters or leaves mode. +wait_mode() +{ + t=$1 + want=$2 + + i=0 + while [ "$i" -lt 50 ]; do + got=$($TMUX display-message -p -t "$t" '#{pane_in_mode}' \ + 2>/dev/null) + [ "$got" = "$want" ] && return 0 + sleep 0.2 + i=$((i + 1)) + done + fail "pane $t mode state is $got, expected $want" +} + +exit_mode() +{ + $TMUX send-keys -t aaa:0 "$@" || fail "send-keys $* failed" + wait_mode aaa:0 0 +} # One client attached to each of two sessions; the mode is displayed on the # client attached to aaa (in window 0 of the outer server) and the filters @@ -86,43 +130,43 @@ wait_clients 2 || fail "expected two clients attached to test server" # --- filter keeping only the aaa client ------------------------------------- $TMUX choose-client -t aaa:0 -F 'C1=#{client_session}' \ -f '#{==:#{client_session},aaa}' || exit 1 -wait_for 'C1=' -out=$(capture) +wait_count 'C1=' 1 +out=$CAPTURED echo "$out" | grep -q 'C1=aaa' || fail "aaa client missing when it matches" echo "$out" | grep -q 'C1=bbb' && fail "bbb client shown but does not match" [ "$(echo "$out" | grep -c 'C1=')" -eq 1 ] || fail "expected 1 client" -$TMUX send-keys -t aaa:0 q +exit_mode q # --- filter keeping only the bbb client ------------------------------------- $TMUX choose-client -t aaa:0 -F 'C2=#{client_session}' \ -f '#{==:#{client_session},bbb}' || exit 1 -wait_for 'C2=' -out=$(capture) +wait_count 'C2=' 1 +out=$CAPTURED echo "$out" | grep -q 'C2=bbb' || fail "bbb client missing when it matches" echo "$out" | grep -q 'C2=aaa' && fail "aaa client shown but does not match" [ "$(echo "$out" | grep -c 'C2=')" -eq 1 ] || fail "expected 1 client" -$TMUX send-keys -t aaa:0 q +exit_mode q # --- no filter shows both clients ------------------------------------------- $TMUX choose-client -t aaa:0 -F 'C3=#{client_session}' || exit 1 -wait_for 'C3=' -out=$(capture) +wait_count 'C3=' 2 +out=$CAPTURED echo "$out" | grep -q 'C3=aaa' || fail "aaa client missing with no filter" echo "$out" | grep -q 'C3=bbb' || fail "bbb client missing with no filter" [ "$(echo "$out" | grep -c 'C3=')" -eq 2 ] || fail "expected 2 clients" -$TMUX send-keys -t aaa:0 q +exit_mode q # --- filter matching nothing ------------------------------------------------ # # Everything is shown and the filter indicator reports no matches. $TMUX choose-client -t aaa:0 -F 'C4=#{client_session}' \ -f '#{==:#{client_session},nosuch}' || exit 1 -wait_for 'C4=' -out=$(capture) +wait_count 'C4=' 2 +out=$CAPTURED echo "$out" | grep -q 'C4=aaa' || fail "aaa client missing with no-match filter" echo "$out" | grep -q 'C4=bbb' || fail "bbb client missing with no-match filter" echo "$out" | grep -q 'no matches' || fail "no matches indicator missing" -$TMUX send-keys -t aaa:0 q +exit_mode q # --- Enter runs the default command (detach-client) -------------------------- # @@ -131,10 +175,10 @@ $TMUX send-keys -t aaa:0 q $TMUX choose-client -t aaa:0 -F 'G1=#{client_session}' \ -f '#{==:#{client_session},bbb}' || exit 1 wait_for 'G1=bbb' -$TMUX send-keys -t aaa:0 Enter +$TMUX send-keys -t aaa:0 Enter || fail "send-keys Enter failed" wait_clients 1 || fail "bbb client did not detach" +wait_mode aaa:0 0 [ "$($TMUX list-clients -F '#{client_session}')" = "aaa" ] || \ fail "wrong client detached" -cleanup exit 0 diff --git a/regress/choose-tree.sh b/regress/choose-tree.sh index 15add9f3f..b34cc2bd2 100644 --- a/regress/choose-tree.sh +++ b/regress/choose-tree.sh @@ -24,18 +24,23 @@ PATH=/bin:/usr/bin TERM=screen [ -z "$TEST_TMUX" ] && TEST_TMUX=$(readlink -f ../tmux) -TMUX="$TEST_TMUX -Ltest -f/dev/null" -TMUX2="$TEST_TMUX -Ltest2 -f/dev/null" +TMP=$(mktemp -d) || exit 1 +TMUX_TMPDIR="$TMP" +export TMUX_TMPDIR +TMUX="$TEST_TMUX -Ltest$$ -f/dev/null" +TMUX2="$TEST_TMUX -Ltest2$$ -f/dev/null" cleanup() { $TMUX kill-server 2>/dev/null $TMUX2 kill-server 2>/dev/null + rm -rf "$TMP" } +trap cleanup EXIT + fail() { - echo "$1" - cleanup + echo "$1" >&2 exit 1 } @@ -53,11 +58,11 @@ wait_for() { i=0 while [ "$i" -lt 50 ]; do - if capture | grep -q "$1"; then - sleep 0.5 + CAPTURED=$(capture) + if echo "$CAPTURED" | grep -q "$1"; then return 0 fi - sleep 0.5 + sleep 0.2 i=$((i + 1)) done fail "timed out waiting for '$1'" @@ -70,11 +75,13 @@ wait_count() { i=0 while [ "$i" -lt 50 ]; do - [ "$(capture | grep -c "$1")" -eq "$2" ] && return 0 - sleep 0.5 + CAPTURED=$(capture) + c=$(echo "$CAPTURED" | grep -c "$1") + [ "$c" -eq "$2" ] && return 0 + sleep 0.2 i=$((i + 1)) done - fail "timed out waiting for $2 lines of '$1' (have $(capture | grep -c "$1"))" + fail "timed out waiting for $2 lines of '$1' (have $c)" } # wait_clients $n @@ -92,8 +99,30 @@ wait_clients() return 1 } -$TMUX kill-server 2>/dev/null -$TMUX2 kill-server 2>/dev/null +# wait_mode $target $state +# +# Wait (up to ~10s) until a pane enters or leaves mode. +wait_mode() +{ + t=$1 + want=$2 + + i=0 + while [ "$i" -lt 50 ]; do + got=$($TMUX display-message -p -t "$t" '#{pane_in_mode}' \ + 2>/dev/null) + [ "$got" = "$want" ] && return 0 + sleep 0.2 + i=$((i + 1)) + done + fail "pane $t mode state is $got, expected $want" +} + +exit_mode() +{ + $TMUX send-keys -t aaa:0 "$@" || fail "send-keys $* failed" + wait_mode aaa:0 0 +} # Session zzz is created first, so it sorts first by index, and has a # two-pane window 0 and a single-pane window 1. Session aaa has one window @@ -117,10 +146,10 @@ wait_clients 1 || fail "no client attached to test server" # (session, window, pane). $TMUX choose-tree -t aaa:0 -F 'F1' -f '#{==:#{session_name},aaa}' || exit 1 wait_count 'F1' 3 -out=$(capture) +out=$CAPTURED echo "$out" | grep -q 'aaa: F1' || fail "aaa missing when filter matches it" echo "$out" | grep -q 'zzz: F1' && fail "zzz shown but no pane matches" -$TMUX send-keys -t aaa:0 q +exit_mode q # --- filter keeping only zzz ------------------------------------------------ # @@ -128,10 +157,10 @@ $TMUX send-keys -t aaa:0 q # disappear. $TMUX choose-tree -t aaa:0 -F 'F2' -f '#{==:#{session_name},zzz}' || exit 1 wait_count 'F2' 6 -out=$(capture) +out=$CAPTURED echo "$out" | grep -q 'zzz: F2' || fail "zzz missing when filter matches it" echo "$out" | grep -q 'aaa: F2' && fail "aaa shown but no pane matches" -$TMUX send-keys -t aaa:0 q +exit_mode q # --- filter matching a single pane ------------------------------------------ # @@ -139,22 +168,22 @@ $TMUX send-keys -t aaa:0 q # and that pane; zzz:1 and all of aaa must disappear. $TMUX choose-tree -t aaa:0 -F 'F3' -f '#{==:#{pane_index},1}' || exit 1 wait_count 'F3' 3 -out=$(capture) +out=$CAPTURED echo "$out" | grep -q 'zzz: F3' || fail "zzz missing when its pane matches" echo "$out" | grep -q 'aaa: F3' && fail "aaa shown but no pane matches" echo "$out" | grep -q '1: F3' || fail "matching pane missing" -$TMUX send-keys -t aaa:0 q +exit_mode q # --- filter matching nothing ------------------------------------------------ # # Everything is shown and the filter indicator reports no matches. $TMUX choose-tree -t aaa:0 -F 'F4' -f '#{==:#{session_name},nosuch}' || exit 1 -wait_for 'F4' -out=$(capture) +wait_count 'F4' 9 +out=$CAPTURED echo "$out" | grep -q 'aaa: F4' || fail "aaa missing with no-match filter" echo "$out" | grep -q 'zzz: F4' || fail "zzz missing with no-match filter" echo "$out" | grep -q 'no matches' || fail "no matches indicator missing" -$TMUX send-keys -t aaa:0 q +exit_mode q # --- -h with the tree pane as the only match -------------------------------- # @@ -163,29 +192,29 @@ $TMUX send-keys -t aaa:0 q $TMUX choose-tree -h -t aaa:0 -F 'F5' -f '#{==:#{session_name},aaa}' || \ exit 1 wait_count 'F5' 2 -capture | grep -q 'aaa: F5' || fail "aaa missing with -h" -$TMUX send-keys -t aaa:0 q +echo "$CAPTURED" | grep -q 'aaa: F5' || fail "aaa missing with -h" +exit_mode q # --- sort orders ------------------------------------------------------------ # # By index zzz (created first) sorts first, by name aaa does, and -r reverses. $TMUX choose-tree -t aaa:0 -F 'F6' -O index || exit 1 -wait_for 'F6' -capture | grep 'F6' | head -1 | grep -q 'zzz: F6' || \ +wait_count 'F6' 9 +echo "$CAPTURED" | grep 'F6' | head -1 | grep -q 'zzz: F6' || \ fail "zzz not first with -O index" -$TMUX send-keys -t aaa:0 q +exit_mode q $TMUX choose-tree -t aaa:0 -F 'F7' -O name || exit 1 -wait_for 'F7' -capture | grep 'F7' | head -1 | grep -q 'aaa: F7' || \ +wait_count 'F7' 9 +echo "$CAPTURED" | grep 'F7' | head -1 | grep -q 'aaa: F7' || \ fail "aaa not first with -O name" -$TMUX send-keys -t aaa:0 q +exit_mode q $TMUX choose-tree -t aaa:0 -F 'F8' -O name -r || exit 1 -wait_for 'F8' -capture | grep 'F8' | head -1 | grep -q 'zzz: F8' || \ +wait_count 'F8' 9 +echo "$CAPTURED" | grep 'F8' | head -1 | grep -q 'zzz: F8' || \ fail "zzz not first with -O name -r" -$TMUX send-keys -t aaa:0 q +exit_mode q # --- collapse and expand with h and l ----------------------------------------- # @@ -193,41 +222,43 @@ $TMUX send-keys -t aaa:0 q # l expands it again. $TMUX choose-tree -t aaa:0 -F 'G1' -O index || exit 1 wait_count 'G1' 9 -$TMUX send-keys -t aaa:0 g h +$TMUX send-keys -t aaa:0 g h || fail "send-keys collapse failed" wait_count 'G1' 4 -$TMUX send-keys -t aaa:0 l +$TMUX send-keys -t aaa:0 l || fail "send-keys expand failed" wait_count 'G1' 9 -$TMUX send-keys -t aaa:0 q +exit_mode q # --- filter entered at the prompt with f, cleared with c ---------------------- $TMUX choose-tree -t aaa:0 -F 'G2' -O index || exit 1 wait_count 'G2' 9 -$TMUX send-keys -t aaa:0 f -$TMUX send-keys -t aaa:0 -l '#{==:#{session_name},aaa}' -$TMUX send-keys -t aaa:0 Enter +$TMUX send-keys -t aaa:0 f || fail "send-keys f failed" +$TMUX send-keys -t aaa:0 -l '#{==:#{session_name},aaa}' || \ + fail "send-keys filter failed" +$TMUX send-keys -t aaa:0 Enter || fail "send-keys Enter failed" wait_count 'G2' 3 -out=$(capture) +out=$CAPTURED echo "$out" | grep -q 'aaa: G2' || fail "aaa missing with prompt filter" echo "$out" | grep -q 'zzz: G2' && fail "zzz shown with prompt filter" -$TMUX send-keys -t aaa:0 c +$TMUX send-keys -t aaa:0 c || fail "send-keys c failed" wait_count 'G2' 9 -$TMUX send-keys -t aaa:0 q +exit_mode q # --- Enter runs the default command (switch-client) ---------------------------- # # g selects session zzz and Enter switches the client to it. $TMUX choose-tree -t aaa:0 -F 'G3' -O index || exit 1 wait_count 'G3' 9 -$TMUX send-keys -t aaa:0 g Enter +$TMUX send-keys -t aaa:0 g Enter || fail "send-keys Enter failed" i=0 while [ "$i" -lt 50 ]; do [ "$($TMUX list-clients -F '#{client_session}')" = "zzz" ] && break - sleep 0.5 + sleep 0.2 i=$((i + 1)) done [ "$i" -lt 50 ] || fail "client did not switch to zzz" $TMUX switch-client -c "$($TMUX list-clients -F '#{client_name}')" -t aaa || \ exit 1 +wait_mode aaa:0 0 # --- x kills the current item after confirmation ------------------------------- # @@ -235,13 +266,12 @@ $TMUX switch-client -c "$($TMUX list-clients -F '#{client_name}')" -t aaa || \ # kills it, leaving zzz with one window and the tree with seven lines. $TMUX choose-tree -t aaa:0 -F 'G4' -O index || exit 1 wait_count 'G4' 9 -$TMUX send-keys -t aaa:0 g j j j j x +$TMUX send-keys -t aaa:0 g j j j j x || fail "send-keys x failed" wait_for 'Kill window 1' -$TMUX send-keys -t aaa:0 y +$TMUX send-keys -t aaa:0 y || fail "send-keys y failed" wait_count 'G4' 7 [ "$($TMUX list-windows -t zzz -F x | grep -c x)" -eq 1 ] || \ fail "window 1 of zzz not killed" -$TMUX send-keys -t aaa:0 q +exit_mode q -cleanup exit 0