mirror of
https://github.com/tmux/tmux.git
synced 2026-07-10 03:19:31 +00:00
172 lines
5.1 KiB
Bash
Executable File
172 lines
5.1 KiB
Bash
Executable File
#!/bin/sh
|
|
|
|
# Tests of the -k flag on the mode-entering commands (cmd-copy-mode.c and
|
|
# cmd-choose-tree.c). With -k the pane is killed when the mode is exited: this
|
|
# is stored on the mode entry in window_pane_set_mode() and acted on in
|
|
# window_pane_reset_mode() (window.c). It is exercised here for:
|
|
#
|
|
# - copy-mode -k (window-copy.c);
|
|
# - choose-tree -k (window-tree.c);
|
|
# - choose-buffer -k (window-buffer.c).
|
|
#
|
|
# choose-tree and choose-buffer share cmd_choose_tree_exec(), which also backs
|
|
# choose-client and customize-mode, so those are not repeated.
|
|
#
|
|
# Each mode is entered in the active pane of a two-pane window: exiting with
|
|
# -k must remove that pane and leave the other. copy-mode is left with the
|
|
# server-side "-X cancel" and needs no client, so those tests run first. The
|
|
# tree modes only act on a key once the client has drawn the mode, so - as in
|
|
# choose-tree.sh - a second server then provides a client (an inner "tmux
|
|
# attach") and its pane is captured to wait until the mode has rendered before
|
|
# the exit key is sent.
|
|
|
|
PATH=/bin:/usr/bin
|
|
TERM=screen
|
|
|
|
[ -z "$TEST_TMUX" ] && TEST_TMUX=$(readlink -f ../tmux)
|
|
TMP=$(mktemp -d) || exit 1
|
|
TMUX_TMPDIR="$TMP"
|
|
export TMUX_TMPDIR
|
|
TMUX="$TEST_TMUX -LtestA$$ -f/dev/null"
|
|
TMUX2="$TEST_TMUX -LtestB$$ -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" >&2
|
|
exit 1
|
|
}
|
|
|
|
# capture the screen rendered by the inner client.
|
|
capture()
|
|
{
|
|
$TMUX2 capture-pane -p -t out:0 2>/dev/null
|
|
}
|
|
|
|
# wait_clients $n: wait until the test server has exactly $n clients.
|
|
wait_clients()
|
|
{
|
|
i=0
|
|
while [ "$i" -lt 50 ]; do
|
|
c=$($TMUX list-clients -F x 2>/dev/null | grep -c x)
|
|
[ "$c" -eq "$1" ] && return 0
|
|
sleep 0.2
|
|
i=$((i + 1))
|
|
done
|
|
fail "expected $1 clients, have $c"
|
|
}
|
|
|
|
# wait_mode $target $state: wait until a pane enters (1) or leaves (0) mode.
|
|
wait_mode()
|
|
{
|
|
i=0
|
|
while [ "$i" -lt 50 ]; do
|
|
got=$($TMUX display-message -p -t "$1" '#{pane_in_mode}' \
|
|
2>/dev/null)
|
|
[ "$got" = "$2" ] && return 0
|
|
sleep 0.2
|
|
i=$((i + 1))
|
|
done
|
|
fail "pane $1 mode state is '$got', expected '$2'"
|
|
}
|
|
|
|
# wait_for $marker: wait until the rendered screen contains $marker.
|
|
wait_for()
|
|
{
|
|
i=0
|
|
while [ "$i" -lt 50 ]; do
|
|
capture | grep -F -q "$1" && return 0
|
|
sleep 0.2
|
|
i=$((i + 1))
|
|
done
|
|
fail "timed out waiting for '$1' to render"
|
|
}
|
|
|
|
# pane_gone $pane-id: true if the pane no longer exists. (display-message -t
|
|
# on a missing pane id falls back to a default target and succeeds, so the
|
|
# pane list is searched instead.)
|
|
pane_gone()
|
|
{
|
|
! $TMUX list-panes -s -t m -F '#{pane_id}' 2>/dev/null | \
|
|
grep -q -x "$1"
|
|
}
|
|
|
|
# open_window: make a fresh two-pane window and leave the new (active) pane
|
|
# as $active and the other as $other.
|
|
open_window()
|
|
{
|
|
$TMUX new-window -t m: -n w 'cat' || fail "new-window failed"
|
|
$TMUX split-window -t m:w 'cat' || fail "split-window failed"
|
|
other=$($TMUX display-message -p -t m:w.0 '#{pane_id}')
|
|
active=$($TMUX display-message -p -t m:w '#{pane_id}')
|
|
}
|
|
|
|
# check_killed $label: wait for the active pane to be killed, leaving only the
|
|
# other pane, then drop the window.
|
|
check_killed()
|
|
{
|
|
i=0
|
|
while [ "$i" -lt 50 ]; do
|
|
pane_gone "$active" && break
|
|
sleep 0.2
|
|
i=$((i + 1))
|
|
done
|
|
pane_gone "$active" || fail "$1: pane not killed on exit"
|
|
panes=$($TMUX list-panes -t m:w -F '#{pane_id}' | tr '\n' ' ')
|
|
[ "$panes" = "$other " ] || \
|
|
fail "$1: expected only $other left, have $panes"
|
|
$TMUX kill-window -t m:w 2>/dev/null
|
|
}
|
|
|
|
# Session m; window 0 keeps a live pane so the session (and later the client)
|
|
# survives each test killing a pane.
|
|
$TMUX new-session -d -s m -x 80 -y 24 'cat' || exit 1
|
|
|
|
# --- copy-mode -k kills the pane, plain copy-mode does not -------------------
|
|
#
|
|
# copy-mode is exited with the server-side "-X cancel", so no client is needed
|
|
# and none is attached yet.
|
|
open_window
|
|
$TMUX copy-mode -k -t m:w || fail "copy-mode -k failed"
|
|
wait_mode "$active" 1
|
|
$TMUX send-keys -t m:w -X cancel || fail "copy cancel failed"
|
|
check_killed 'copy-mode -k'
|
|
|
|
open_window
|
|
$TMUX copy-mode -t m:w || fail "copy-mode failed"
|
|
wait_mode "$active" 1
|
|
$TMUX send-keys -t m:w -X cancel || fail "copy cancel failed"
|
|
wait_mode "$active" 0
|
|
pane_gone "$active" && fail 'copy-mode: pane killed without -k'
|
|
$TMUX kill-window -t m:w 2>/dev/null
|
|
|
|
# --- choose-tree -k and choose-buffer -k kill the pane ----------------------
|
|
#
|
|
# These need the client to draw the mode before a key acts, so attach one now.
|
|
# A paste buffer is needed for choose-buffer to have something to show, and a
|
|
# distinct -F marker per call is waited for in the capture so the exit key is
|
|
# only sent once the mode is drawn.
|
|
$TMUX set-buffer 'mode-kill buffer' || exit 1
|
|
$TMUX2 new-session -d -s out -x 80 -y 24 "$TMUX attach -t m" || exit 1
|
|
wait_clients 1
|
|
open_window
|
|
$TMUX choose-tree -k -F 'TREEMARK' -t m:w || fail "choose-tree -k failed"
|
|
wait_for 'TREEMARK'
|
|
$TMUX send-keys -t m:w q || fail "choose-tree exit failed"
|
|
check_killed 'choose-tree -k'
|
|
|
|
open_window
|
|
$TMUX choose-buffer -k -F 'BUFMARK' -t m:w || fail "choose-buffer -k failed"
|
|
wait_for 'BUFMARK'
|
|
$TMUX send-keys -t m:w q || fail "choose-buffer exit failed"
|
|
check_killed 'choose-buffer -k'
|
|
|
|
exit 0
|