Files
tmux/regress/pane-ops.sh
Nicholas Marriott e77d9ad043 -k/empty panes tests.
2026-07-08 09:07:48 +01:00

641 lines
21 KiB
Bash

#!/bin/sh
# Tests of pane management command semantics (not parsing), as implemented in
# cmd-split-window.c, cmd-break-pane.c, cmd-join-pane.c (join-pane and
# move-pane), cmd-swap-pane.c, cmd-kill-pane.c, cmd-respawn-pane.c,
# cmd-respawn-window.c, cmd-resize-pane.c and cmd-select-pane.c.
#
# This exercises:
# - split-window -h/-v with -l in cells and percent, -b placing the new pane
# before (left/top of) the target and -f spanning the full window size;
# - break-pane moving a pane into a new window (-d, -n name, -a after, -P -F
# printing the new location);
# - join-pane moving a window's only pane into another window (destroying the
# source window), -b before, -l size, and the identical-panes error;
# - move-pane as an alias for join-pane;
# - swap-pane -U/-D/-s/-t, -d keeping the active pane, and the marked pane
# (select-pane -m/-M) as the default swap source;
# - kill-pane, kill-pane -a keeping only the target;
# - respawn-pane/respawn-window refusing a live pane without -k, working on a
# dead pane (remain-on-exit) and killing with -k;
# - resize-pane -x/-y in cells and percent, -L/-R/-U/-D adjustments and -Z
# zoom/unzoom (including implicit unzoom on split).
#
# window-ops.sh covers window-level commands and buffers.sh paste buffers.
PATH=/bin:/usr/bin
TERM=screen
LANG=C.UTF-8
LC_ALL=C.UTF-8
export TERM LANG LC_ALL
[ -z "$TEST_TMUX" ] && TEST_TMUX=$(readlink -f ../tmux)
TMUX="$TEST_TMUX -LtestA$$ -f/dev/null"
$TMUX kill-server 2>/dev/null
# check_ok $cmd...
#
# Run a command and require that it succeeds.
check_ok()
{
if ! $TMUX "$@"; then
echo "Command failed (expected success): $*"
exit 1
fi
}
# check_fail $expected_error $cmd...
#
# Run a command and require that it fails with the given error message.
check_fail()
{
exp="$1"
shift
out=$($TMUX "$@" 2>&1)
if [ $? -eq 0 ]; then
echo "Command succeeded (expected failure): $*"
exit 1
fi
if [ "$out" != "$exp" ]; then
echo "Wrong error for: $*"
echo "Expected: '$exp'"
echo "But got: '$out'"
exit 1
fi
}
# check_fmt $target $format $expected
#
# Expand a format in a target's context and compare with $expected.
check_fmt()
{
out=$($TMUX display-message -p -t "$1" "$2" 2>&1)
if [ "$out" != "$3" ]; then
echo "Format '$2' for '$1' wrong."
echo "Expected: '$3'"
echo "But got: '$out'"
exit 1
fi
}
# check_panes $target $expected
#
# Compare the pane list of a window (as "index:id ...", in index order) with
# $expected.
check_panes()
{
out=$(echo $($TMUX list-panes -t "$1" -F '#{pane_index}:#{pane_id}'))
if [ "$out" != "$2" ]; then
echo "Pane list of '$1' wrong."
echo "Expected: '$2'"
echo "But got: '$out'"
exit 1
fi
}
assert_alive()
{
if [ "$($TMUX display-message -p alive 2>&1)" != "alive" ]; then
echo "Server died: $1"
exit 1
fi
}
# ---------------------------------------------------------------------------
# split-window geometry.
check_ok new-session -d -s P -x 80 -y 24 -n main
p0=$($TMUX display-message -p -t P:0.0 '#{pane_id}')
# Horizontal split with -l in cells: new pane gets exactly that width and the
# old pane the rest minus the separator line.
check_ok split-window -d -h -l 20 -t "$p0"
p1=$($TMUX display-message -p -t P:0.1 '#{pane_id}')
check_fmt "$p1" '#{pane_width}x#{pane_height}' '20x24'
check_fmt "$p0" '#{pane_width}x#{pane_height}' '59x24'
# Vertical split with a percentage of the pane being split.
check_ok split-window -d -v -l 25% -t "$p0"
p2=$($TMUX display-message -p -t P:0.1 '#{pane_id}')
check_fmt "$p2" '#{pane_width}x#{pane_height}' '59x6'
check_fmt "$p0" '#{pane_width}x#{pane_height}' '59x17'
# -b puts the new pane to the left of the target; -f makes it span the full
# window height.
check_ok split-window -d -h -b -f -l 10 -t "$p0"
p3=$($TMUX display-message -p -t P:0.0 '#{pane_id}')
check_fmt "$p3" '#{pane_width}x#{pane_height}' '10x24'
check_fmt "$p3" '#{pane_left},#{pane_top}' '0,0'
check_fmt "$p0" '#{pane_width}x#{pane_height}' '50x17'
check_panes P:0 "0:$p3 1:$p0 2:$p2 3:$p1"
# The new pane becomes active unless -d is given.
check_ok select-pane -t "$p0"
check_ok split-window -d -v -t "$p0"
check_fmt 'P:0' '#{pane_id}' "$p0"
p4=$($TMUX display-message -p -t P:0.2 '#{pane_id}')
check_ok split-window -v -t "$p4"
p5=$($TMUX display-message -p -t 'P:0' '#{pane_id}')
check_ok kill-pane -t "$p5"
check_ok kill-pane -t "$p4"
check_panes P:0 "0:$p3 1:$p0 2:$p2 3:$p1"
# ---------------------------------------------------------------------------
# break-pane and join-pane.
# break-pane moves a pane to a new window; -P -F prints where it went and -n
# names the new window.
out=$($TMUX break-pane -d -P -F '#{window_index}:#{pane_id}' -n broken \
-s "$p1" -t P:)
if [ "$out" != "1:$p1" ]; then
echo "break-pane -P output wrong: '$out'"
exit 1
fi
check_fmt 'P:1' '#{window_name}:#{window_panes}' 'broken:1'
check_fmt 'P:0' '#{window_panes}' '3'
# join-pane -v moves it back (the source window, left empty, is destroyed).
check_ok join-pane -d -v -s P:broken.0 -t "$p2"
check_fmt 'P:0' '#{window_panes}' '4'
if $TMUX has-session -t P:broken 2>/dev/null; then
echo "Window 'broken' still exists after join-pane."
exit 1
fi
# The joined pane is below the target (-v, no -b).
top=$($TMUX display-message -p -t "$p2" '#{pane_bottom}')
joined=$($TMUX display-message -p -t "$p1" '#{pane_top}')
if [ "$joined" -le "$top" ]; then
echo "Joined pane is not below target ($joined <= $top)."
exit 1
fi
# join-pane -h -b puts the source to the left of the target; -l sets size.
check_ok break-pane -d -n broken -s "$p1" -t P:
check_ok join-pane -d -h -b -l 30 -s P:broken.0 -t "$p2"
check_fmt "$p1" '#{pane_width}' '30'
l1=$($TMUX display-message -p -t "$p1" '#{pane_left}')
l2=$($TMUX display-message -p -t "$p2" '#{pane_left}')
if [ "$l1" -ge "$l2" ]; then
echo "Joined pane is not left of target ($l1 >= $l2)."
exit 1
fi
# Joining a pane to itself is an error.
check_fail 'source and target panes must be different' \
join-pane -d -s "$p0" -t "$p0"
# break-pane to an occupied window index or with an invalid (non-UTF-8) name
# is an error.
check_fail 'index in use: 0' break-pane -d -s "$p1" -t P:0
check_fail "invalid window name: $(printf 'a\377b')" \
break-pane -d -n "$(printf 'a\377b')" -s "$p1" -t P:
# join-pane can move a pane from one window to another without destroying
# the source window if other panes remain. (On this branch move-pane is
# reserved for floating panes, covered by floating-pane-geometry.sh.)
check_ok new-window -d -t P:5 -n other
check_ok join-pane -d -s "$p1" -t P:5.0
check_fmt 'P:5' '#{window_panes}' '2'
check_fmt 'P:0' '#{window_panes}' '3'
check_ok join-pane -d -v -s "$p1" -t "$p2"
check_fmt 'P:0' '#{window_panes}' '4'
check_fmt 'P:5' '#{window_panes}' '1'
# ---------------------------------------------------------------------------
# swap-pane.
check_panes P:0 "0:$p3 1:$p0 2:$p2 3:$p1"
# -s/-t swap two panes.
check_ok swap-pane -d -s "$p3" -t "$p1"
check_panes P:0 "0:$p1 1:$p0 2:$p2 3:$p3"
check_ok swap-pane -d -s "$p3" -t "$p1"
check_panes P:0 "0:$p3 1:$p0 2:$p2 3:$p1"
# -U swaps the target pane with the previous pane, -D with the next; without
# -s the target is the active pane.
check_ok swap-pane -d -U -t "$p0"
check_panes P:0 "0:$p0 1:$p3 2:$p2 3:$p1"
check_ok swap-pane -d -D -t "$p0"
check_panes P:0 "0:$p3 1:$p0 2:$p2 3:$p1"
# Without -d the target pane becomes the active pane (it arrives at the
# source pane's position).
check_ok select-pane -t "$p0"
check_ok swap-pane -s "$p0" -t "$p2"
check_fmt 'P:0' '#{pane_id}' "$p2"
check_panes P:0 "0:$p3 1:$p2 2:$p0 3:$p1"
check_ok swap-pane -s "$p2" -t "$p0"
check_fmt 'P:0' '#{pane_id}' "$p0"
check_panes P:0 "0:$p3 1:$p0 2:$p2 3:$p1"
# With a marked pane and no -s, the marked pane is the swap source.
check_ok select-pane -m -t "$p3"
check_fmt "$p3" '#{pane_marked}' '1'
check_ok swap-pane -d -t "$p1"
check_panes P:0 "0:$p1 1:$p0 2:$p2 3:$p3"
check_ok swap-pane -d -t "$p1"
check_panes P:0 "0:$p3 1:$p0 2:$p2 3:$p1"
# select-pane -M clears the mark.
check_ok select-pane -M
check_fmt "$p3" '#{pane_marked}' '0'
check_fmt 'P:0' '#{pane_marked_set}' '0'
# ---------------------------------------------------------------------------
# resize-pane and zoom.
# Absolute -x on a horizontal split and percentage.
check_ok resize-pane -t "$p3" -x 20
check_fmt "$p3" '#{pane_width}' '20'
check_ok resize-pane -t "$p3" -x 25%
check_fmt "$p3" '#{pane_width}' '20'
check_ok resize-pane -t "$p3" -x 10
check_fmt "$p3" '#{pane_width}' '10'
# Relative adjustments: -R grows a left pane, -L shrinks it back; a count may
# be given.
check_ok resize-pane -t "$p3" -R
check_fmt "$p3" '#{pane_width}' '11'
check_ok resize-pane -t "$p3" -L
check_fmt "$p3" '#{pane_width}' '10'
check_ok resize-pane -t "$p3" -R 5
check_fmt "$p3" '#{pane_width}' '15'
check_ok resize-pane -t "$p3" -L 5
check_fmt "$p3" '#{pane_width}' '10'
# -y on a vertical split.
check_ok resize-pane -t "$p2" -y 10
check_fmt "$p2" '#{pane_height}' '10'
# p2 is the bottom pane, so its bottom border cannot move down: -D instead
# grows it by taking lines from the pane above and -U gives them back.
check_ok resize-pane -t "$p2" -D 2
check_fmt "$p2" '#{pane_height}' '12'
check_ok resize-pane -t "$p2" -U 2
check_fmt "$p2" '#{pane_height}' '10'
# Bad adjustment, width and height are errors.
check_fail 'adjustment invalid' resize-pane -t "$p2" -U nonsense
check_fail 'width invalid' resize-pane -t "$p2" -x nonsense
check_fail 'height invalid' resize-pane -t "$p2" -y nonsense
# -Z zooms: the pane temporarily fills the window and the flags show it.
check_ok resize-pane -Z -t "$p0"
check_fmt "$p0" '#{window_zoomed_flag}:#{pane_width}x#{pane_height}' \
'1:80x24'
# Zoom is transparent to pane commands on other panes, and -Z again unzooms.
check_ok resize-pane -Z -t "$p0"
check_fmt "$p0" '#{window_zoomed_flag}' '0'
# Splitting while zoomed unzooms first.
check_ok resize-pane -Z -t "$p0"
check_fmt 'P:0' '#{window_zoomed_flag}' '1'
check_ok split-window -d -v -t "$p0"
check_fmt 'P:0' '#{window_zoomed_flag}' '0'
check_fmt 'P:0' '#{window_panes}' '5'
p6=$($TMUX display-message -p -t P:0.2 '#{pane_id}')
check_ok kill-pane -t "$p6"
# ---------------------------------------------------------------------------
# kill-pane.
check_fmt 'P:0' '#{window_panes}' '4'
check_ok kill-pane -t "$p3"
check_panes P:0 "0:$p0 1:$p2 2:$p1"
# -a kills every pane except the target.
check_ok kill-pane -a -t "$p0"
check_panes P:0 "0:$p0"
# Killing the last pane in a window kills the window.
check_ok new-window -d -t P:7 -n goner
check_ok kill-pane -t P:7.0
if $TMUX has-session -t P:goner 2>/dev/null; then
echo "Window 'goner' still exists after killing its only pane."
exit 1
fi
# ---------------------------------------------------------------------------
# respawn-pane and respawn-window.
# Respawning a pane whose process is alive fails without -k.
check_fail "respawn pane failed: pane P:0.0 still active" \
respawn-pane -t P:0.0
check_fail "respawn window failed: window P:0 still active" \
respawn-window -t P:0
# With remain-on-exit a pane whose command exited stays as a dead pane and
# may be respawned without -k.
check_ok set-option -g remain-on-exit on
check_ok new-window -d -t P:8 -n dead 'true'
i=0
while [ "$($TMUX display-message -p -t P:8.0 '#{pane_dead}')" != "1" ]; do
i=$((i + 1))
[ $i -gt 50 ] && { echo "Pane did not die."; exit 1; }
sleep 0.1
done
check_ok respawn-pane -t P:8.0 'sleep 100'
check_fmt 'P:8.0' '#{pane_dead}' '0'
# -k kills the live process and respawns.
check_ok respawn-pane -k -t P:8.0 'sleep 200'
check_fmt 'P:8.0' '#{pane_dead}' '0'
# respawn-window -k replaces the whole window (all panes) with one pane.
check_ok split-window -d -t P:8
check_fmt 'P:8' '#{window_panes}' '2'
check_ok respawn-window -k -t P:8 'sleep 300'
check_fmt 'P:8' '#{window_panes}' '1'
check_fmt 'P:8.0' '#{pane_dead}' '0'
check_ok set-option -g remain-on-exit off
# ---------------------------------------------------------------------------
# select-pane.
# A 2x2-ish arrangement: q0 on top, q1 bottom-left, q2 bottom-right.
check_ok new-window -d -t P:2 -n sel
q0=$($TMUX display-message -p -t P:2.0 '#{pane_id}')
check_ok split-window -d -v -t "$q0"
q1=$($TMUX display-message -p -t P:2.1 '#{pane_id}')
check_ok split-window -d -h -t "$q1"
q2=$($TMUX display-message -p -t P:2.2 '#{pane_id}')
# Directional selection: -D, -R and -U move by pane position.
check_ok select-pane -t "$q0"
check_ok select-pane -D -t P:2
check_fmt 'P:2' '#{pane_id}' "$q1"
check_ok select-pane -R -t P:2
check_fmt 'P:2' '#{pane_id}' "$q2"
check_ok select-pane -U -t P:2
check_fmt 'P:2' '#{pane_id}' "$q0"
# -l returns to the previously active pane; a window that never had another
# active pane has no last pane.
check_ok select-pane -l -t P:2
check_fmt 'P:2' '#{pane_id}' "$q2"
check_fail 'no last pane' select-pane -l -t P:8.0
# -d disables input to a pane, -e enables it again and -T sets the title.
check_ok select-pane -d -t "$q0"
check_fmt "$q0" '#{pane_input_off}' '1'
check_ok select-pane -e -t "$q0"
check_fmt "$q0" '#{pane_input_off}' '0'
check_ok select-pane -T mytitle -t "$q0"
check_fmt "$q0" '#{pane_title}' 'mytitle'
check_ok kill-window -t P:2
# ---------------------------------------------------------------------------
# more split-window variants.
check_ok new-window -d -t P:2 -n splits
# new-window -E creates an empty initial pane, running no command.
check_ok new-window -d -E -t P:9 -n empty
check_fmt 'P:9.0' '#{pane_dead}' '0'
check_fmt 'P:9.0' '#{pane_pid}' ''
check_fail 'command cannot be given for empty pane' \
new-window -d -E -t P:10 -n empty 'true'
# An empty string as the sole argument is equivalent to -E: the pane is
# created empty, running no command.
check_ok new-window -d -t P:12 -n empty-str ''
check_fmt 'P:12.0' '#{pane_dead}' '0'
check_fmt 'P:12.0' '#{pane_pid}' ''
check_ok kill-window -t P:12
# A missing command (rather than an empty one) runs the default command, so
# the pane is not empty and has a process.
check_ok new-window -d -t P:12 -n default-cmd
check_fmt 'P:12.0' '#{?pane_pid,live,empty}' 'live'
check_ok kill-window -t P:12
# respawn-pane -E stores the command and cwd without starting it.
tmp=${TMPDIR:-/tmp}/tmux-pane-ops-empty-$$
rm -f "$tmp"
check_ok new-window -d -E -t P:10 -n empty-respawn
check_ok respawn-pane -E -c /tmp -t P:10.0 "pwd > $tmp"
if [ -e "$tmp" ]; then
echo "respawn-pane -E started command unexpectedly"
exit 1
fi
check_ok respawn-pane -t P:10.0
i=0
while [ ! -e "$tmp" ]; do
i=$((i + 1))
[ $i -gt 50 ] && echo "respawn-pane did not start stored command" && \
exit 1
sleep 0.1
done
if [ "$(cat "$tmp")" != "/tmp" ]; then
echo "respawn-pane did not use stored cwd"
exit 1
fi
rm -f "$tmp"
check_ok kill-window -t P:9
# respawn-window -E stores the command and cwd without starting it.
tmp=${TMPDIR:-/tmp}/tmux-window-ops-empty-$$
rm -f "$tmp"
check_ok new-window -d -E -t P:11 -n empty-respawn-window
check_ok respawn-window -E -c /tmp -t P:11 "pwd > $tmp"
check_fmt 'P:11.0' '#{pane_pid}' ''
if [ -e "$tmp" ]; then
echo "respawn-window -E started command unexpectedly"
exit 1
fi
check_ok respawn-window -t P:11
i=0
while [ ! -e "$tmp" ]; do
i=$((i + 1))
[ $i -gt 50 ] && echo "respawn-window did not start stored command" && \
exit 1
sleep 0.1
done
if [ "$(cat "$tmp")" != "/tmp" ]; then
echo "respawn-window did not use stored cwd"
exit 1
fi
rm -f "$tmp"
# -E splits with an empty pane, running no command; giving one is an error.
check_ok split-window -d -E -t P:2.0
check_fmt 'P:2' '#{window_panes}' '2'
check_fail 'command cannot be given for empty pane' \
split-window -d -E -t P:2.0 'sleep 5'
# An empty string as the sole argument splits with an empty pane, like -E.
eid=$($TMUX split-window -d -P -F '#{pane_id}' -t P:2.0 '')
check_fmt "$eid" '#{pane_dead}' '0'
check_fmt "$eid" '#{pane_pid}' ''
check_ok kill-pane -t "$eid"
check_fmt 'P:2' '#{window_panes}' '2'
# -e adds to the new pane's environment.
eid=$($TMUX split-window -d -P -F '#{pane_id}' -e GREETING=hello -t P:2.0 \
'echo $GREETING; exec cat')
i=0
while out=$($TMUX capture-pane -p -t "$eid" | sed -n 1p) && \
[ "$out" != "hello" ]; do
i=$((i + 1))
[ $i -gt 50 ] && { echo "split-window -e wrong: '$out'"; exit 1; }
sleep 0.1
done
# A bad -l size is an error.
check_fail 'invalid tiled geometry invalid' \
split-window -d -v -l invalid -t P:2.0
# -Z zooms the new pane.
check_ok split-window -d -Z -t P:2.0
check_fmt 'P:2' '#{window_zoomed_flag}' '1'
check_ok kill-window -t P:2
# ---------------------------------------------------------------------------
# more swap-pane: wrapping, cross-window, self and zoomed swaps.
check_ok new-window -d -t P:3 -n swaps
check_ok split-window -d -v -t P:3.0
check_ok split-window -d -v -t P:3.0
r0=$($TMUX display-message -p -t P:3.0 '#{pane_id}')
r1=$($TMUX display-message -p -t P:3.1 '#{pane_id}')
r2=$($TMUX display-message -p -t P:3.2 '#{pane_id}')
o0=$($TMUX display-message -p -t P:5.0 '#{pane_id}')
# -D on the last pane and -U on the first wrap around to the other end.
check_ok swap-pane -d -D -t "$r2"
check_panes P:3 "0:$r2 1:$r1 2:$r0"
check_ok swap-pane -d -s "$r0" -t "$r2"
check_ok swap-pane -d -U -t "$r0"
check_panes P:3 "0:$r2 1:$r1 2:$r0"
check_ok swap-pane -d -s "$r0" -t "$r2"
check_panes P:3 "0:$r0 1:$r1 2:$r2"
# Swapping a pane with itself quietly does nothing.
check_ok swap-pane -d -s "$r1" -t "$r1"
check_panes P:3 "0:$r0 1:$r1 2:$r2"
# Panes can be swapped between different windows.
check_ok swap-pane -d -s "$o0" -t "$r1"
check_panes P:3 "0:$r0 1:$o0 2:$r2"
check_panes P:5 "0:$r1"
check_ok swap-pane -d -s "$r1" -t "$o0"
check_panes P:3 "0:$r0 1:$r1 2:$r2"
check_panes P:5 "0:$o0"
# -Z keeps the window zoomed across the swap.
check_ok resize-pane -Z -t "$r0"
check_ok swap-pane -d -Z -s "$r0" -t "$r1"
check_fmt 'P:3' '#{window_zoomed_flag}' '1'
check_ok resize-pane -Z -t P:3
check_panes P:3 "0:$r1 1:$r0 2:$r2"
# kill-pane -a -f only kills other panes matching the filter.
check_ok kill-pane -a -f '#{==:#{pane_id},'"$r2"'}' -t "$r1"
check_panes P:3 "0:$r1 1:$r0"
check_ok kill-window -t P:3
# ---------------------------------------------------------------------------
# split-window -I and -s.
check_ok new-window -d -t P:3 -n splits2
# -I fills the new (empty) pane from standard input.
printf 'stdin-stuff' | $TMUX split-window -d -I -t P:3.0
if [ $? -ne 0 ]; then
echo "split-window -I failed."
exit 1
fi
i=0
while out=$($TMUX capture-pane -p -t P:3.1 | sed -n 1p) && \
[ "$out" != "stdin-stuff" ]; do
i=$((i + 1))
[ $i -gt 50 ] && { echo "split-window -I wrong: '$out'"; exit 1; }
sleep 0.1
done
# -s sets the new pane's window-style.
sid=$($TMUX split-window -d -P -F '#{pane_id}' -s 'bg=red' -t P:3.0)
out=$($TMUX show-options -v -p -t "$sid" window-style)
if [ "$out" != "bg=red" ]; then
echo "split-window -s style wrong: '$out'"
exit 1
fi
check_ok kill-window -t P:3
# ---------------------------------------------------------------------------
# more break-pane: -a insertion, selection and single-pane windows.
# check_windows $session $expected
#
# Compare the window list of a session (as "index:name ...") with $expected.
check_windows()
{
out=$(echo $($TMUX list-windows -t "$1" -F \
'#{window_index}:#{window_name}'))
if [ "$out" != "$2" ]; then
echo "Window list of '$1' wrong."
echo "Expected: '$2'"
echo "But got: '$out'"
exit 1
fi
}
check_ok new-session -d -s Q -x 80 -y 24 -n q0
# -a breaks into a new window inserted after the target index, shuffling the
# following windows up.
check_ok new-window -d -t Q:1 -n q1
check_ok split-window -d -t Q:1
check_ok break-pane -d -a -s Q:1.1 -n qa -t Q:0
check_windows Q '0:q0 1:qa 2:q1'
# Without -d the new window is selected.
check_ok split-window -d -t Q:2
check_ok select-window -t Q:0
check_ok break-pane -s Q:2.1 -n qcur -t Q:
check_fmt 'Q:' '#{window_name}' 'qcur'
check_windows Q '0:q0 1:qa 2:q1 3:qcur'
# Breaking the only pane of a window relinks the window at a new index; -n
# still renames it.
check_ok new-window -d -t Q:5 -n qsolo
out=$($TMUX break-pane -d -P -F '#{window_name}' -s Q:5.0 -n qmoved -t Q:)
if [ "$out" != "qmoved" ]; then
echo "single-pane break-pane output wrong: '$out'"
exit 1
fi
if $TMUX has-session -t Q:qsolo 2>/dev/null; then
echo "Window 'qsolo' still exists after single-pane break-pane."
exit 1
fi
check_ok has-session -t Q:qmoved
check_ok kill-session -t Q
# ---------------------------------------------------------------------------
# resize-pane -T.
# -T trims the history: lines below the cursor position are removed and the
# cursor moves to the bottom. seq writes 100 lines (leaving 77 in history on
# a 24-line screen) and the escape sequence puts the cursor on line 5.
check_ok new-window -d -t P:2 'seq 1 100; printf "\033[5;1H"; exec cat'
i=0
while [ "$($TMUX display-message -p -t P:2.0 '#{history_size}')" != "77" ]
do
i=$((i + 1))
[ $i -gt 50 ] && { echo "History did not fill."; exit 1; }
sleep 0.1
done
check_fmt 'P:2.0' '#{cursor_y}' '4'
check_ok resize-pane -T -t P:2.0
check_fmt 'P:2.0' '#{history_size}' '58'
check_fmt 'P:2.0' '#{cursor_y}' '23'
check_ok kill-window -t P:2
assert_alive
$TMUX kill-server 2>/dev/null
exit 0