mirror of
https://github.com/tmux/tmux.git
synced 2026-10-09 03:34:25 +00:00
202 lines
6.2 KiB
Bash
202 lines
6.2 KiB
Bash
#!/bin/sh
|
|
|
|
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"
|
|
|
|
TMPDIR=${TMPDIR:-/tmp}/tmux-local-pane.$$
|
|
mkdir -p "$TMPDIR" || exit 1
|
|
IN1="$TMPDIR/in1"
|
|
IN2="$TMPDIR/in2"
|
|
OUT1="$TMPDIR/out1"
|
|
OUT2="$TMPDIR/out2"
|
|
|
|
cleanup()
|
|
{
|
|
$TMUX kill-server 2>/dev/null
|
|
rm -rf "$TMPDIR"
|
|
}
|
|
trap cleanup 0 1 15
|
|
|
|
fail()
|
|
{
|
|
echo "$1"
|
|
exit 1
|
|
}
|
|
|
|
wait_for()
|
|
{
|
|
file=$1
|
|
pattern=$2
|
|
i=0
|
|
while [ "$i" -lt 20 ]; do
|
|
if grep -q "$pattern" "$file"; then
|
|
return 0
|
|
fi
|
|
sleep 1
|
|
i=$((i + 1))
|
|
done
|
|
echo "missing '$pattern' in $file"
|
|
cat "$file"
|
|
return 1
|
|
}
|
|
|
|
send1()
|
|
{
|
|
printf '%s\n' "$*" >&3
|
|
}
|
|
|
|
send2()
|
|
{
|
|
printf '%s\n' "$*" >&4
|
|
}
|
|
|
|
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
|
|
}
|
|
|
|
$TMUX kill-server 2>/dev/null
|
|
$TMUX new-session -d -s active -x 80 -y 24 || exit 1
|
|
$TMUX split-window -d -h -t active:0 || exit 1
|
|
$TMUX split-window -d -v -t active:0.0 || exit 1
|
|
style=$($TMUX show-options -wgv pane-active-border-style) || exit 1
|
|
case "$style" in
|
|
*pane_local_active*themecyan*) ;;
|
|
*) fail "pane-active-border-style does not include local active colour" ;;
|
|
esac
|
|
|
|
p0=$($TMUX display-message -p -t active:0.0 '#{pane_id}') || exit 1
|
|
p1=$($TMUX display-message -p -t active:0.1 '#{pane_id}') || exit 1
|
|
p2=$($TMUX display-message -p -t active:0.2 '#{pane_id}') || exit 1
|
|
$TMUX select-pane -t "$p0" || exit 1
|
|
check_fmt active:0 '#{pane_id}' "$p0"
|
|
|
|
mkfifo "$IN1" "$IN2" || exit 1
|
|
: >"$OUT1"
|
|
: >"$OUT2"
|
|
$TMUX -C attach-session -t active <"$IN1" >"$OUT1" 2>&1 &
|
|
PID1=$!
|
|
exec 3>"$IN1"
|
|
|
|
send1 'display-message -p C1_READY'
|
|
wait_for "$OUT1" 'C1_READY' || exit 1
|
|
|
|
# One attached client cannot enter local mode.
|
|
send1 'select-pane -s'
|
|
send1 "select-pane -t $p1"
|
|
send1 'display-message -p "C1_SINGLE:#{pane_id}:#{pane_active}:#{pane_local_active}"'
|
|
wait_for "$OUT1" "C1_SINGLE:$p1:1:" || exit 1
|
|
check_fmt active:0 '#{pane_id}' "$p1"
|
|
send1 "select-pane -t $p0"
|
|
check_fmt active:0 '#{pane_id}' "$p0"
|
|
|
|
$TMUX -C attach-session -t active <"$IN2" >"$OUT2" 2>&1 &
|
|
PID2=$!
|
|
exec 4>"$IN2"
|
|
|
|
send2 'display-message -p C2_READY'
|
|
wait_for "$OUT2" 'C2_READY' || exit 1
|
|
|
|
# Both clients start in shared mode and see the window active pane.
|
|
send1 'display-message -p "C1_START:#{pane_id}:#{pane_active}:#{pane_local_active}"'
|
|
send2 'display-message -p "C2_START:#{pane_id}:#{pane_active}:#{pane_local_active}"'
|
|
wait_for "$OUT1" "C1_START:$p0:1:" || exit 1
|
|
wait_for "$OUT2" "C2_START:$p0:1:" || exit 1
|
|
|
|
# Client 1 enters local mode and selects a pane without changing shared state.
|
|
send1 'select-pane -s'
|
|
send1 "select-pane -t $p1"
|
|
send1 'display-message -p "C1_LOCAL:#{pane_id}:#{pane_active}:#{pane_local_active}:#{pane_local_mode}"'
|
|
send1 "display-message -p -t $p0 \"C1_LOCAL_INACTIVE:#{pane_id}:#{pane_active}:#{pane_local_active}\""
|
|
wait_for "$OUT1" "C1_LOCAL:$p1:1:1:1" || exit 1
|
|
wait_for "$OUT1" "C1_LOCAL_INACTIVE:$p0:0:0" || exit 1
|
|
check_fmt active:0 '#{pane_id}' "$p0"
|
|
send2 'display-message -p "C2_SHARED:#{pane_id}:#{pane_active}:#{pane_local_active}"'
|
|
wait_for "$OUT2" "C2_SHARED:$p0:1:" || exit 1
|
|
|
|
# Client 2 can keep an independent local pane in the same window.
|
|
send2 'select-pane -s'
|
|
send2 "select-pane -t $p2"
|
|
send2 'display-message -p "C2_LOCAL:#{pane_id}:#{pane_active}:#{pane_local_active}"'
|
|
wait_for "$OUT2" "C2_LOCAL:$p2:1:1" || exit 1
|
|
send1 'display-message -p "C1_STILL:#{pane_id}:#{pane_active}:#{pane_local_active}"'
|
|
wait_for "$OUT1" "C1_STILL:$p1:1:1" || exit 1
|
|
|
|
# Local last-pane history is independent of the shared window history.
|
|
send1 "select-pane -t $p2"
|
|
send1 'last-pane'
|
|
send1 'display-message -p "C1_LAST:#{pane_id}:#{pane_last}"'
|
|
wait_for "$OUT1" "C1_LAST:$p1:0" || exit 1
|
|
check_fmt active:0 '#{pane_id}' "$p0"
|
|
|
|
# Switching back to shared mode immediately follows window->active.
|
|
send1 'select-pane -S'
|
|
send1 'display-message -p "C1_SHARED_AGAIN:#{pane_id}:#{pane_active}"'
|
|
wait_for "$OUT1" "C1_SHARED_AGAIN:$p0:1" || exit 1
|
|
send1 "select-pane -t $p1"
|
|
check_fmt active:0 '#{pane_id}' "$p1"
|
|
send2 'display-message -p "C2_STILL_LOCAL:#{pane_id}:#{pane_active}"'
|
|
wait_for "$OUT2" "C2_STILL_LOCAL:$p2:1" || exit 1
|
|
|
|
# Local selection survives switching away and back to the window.
|
|
send2 'new-window -n other'
|
|
send2 'previous-window'
|
|
send2 'display-message -p "C2_AFTER_WINDOW_SWITCH:#{pane_id}:#{pane_active}"'
|
|
wait_for "$OUT2" "C2_AFTER_WINDOW_SWITCH:$p2:1" || exit 1
|
|
|
|
# Removing a locally active pane recovers to the shared active pane.
|
|
$TMUX kill-pane -t "$p2" || exit 1
|
|
send2 'display-message -p "C2_AFTER_KILL:#{pane_id}:#{pane_active}"'
|
|
wait_for "$OUT2" "C2_AFTER_KILL:$p1:1" || exit 1
|
|
|
|
# Local selection of a floating pane does not raise it unless requested.
|
|
f1=$($TMUX new-pane -dPF '#{pane_id}' -x 20 -y 6 -X 8 -Y 3 \
|
|
-t active:0 'sleep 100') || exit 1
|
|
f2=$($TMUX new-pane -dPF '#{pane_id}' -x 20 -y 6 -X 12 -Y 5 \
|
|
-t active:0 'sleep 100') || exit 1
|
|
check_fmt "$f1" '#{pane_z}' 1
|
|
check_fmt "$f2" '#{pane_z}' 0
|
|
send1 'select-pane -s'
|
|
send1 "select-pane -t $f1"
|
|
send1 "display-message -p -t $f1 \"C1_FLOAT_LOCAL:#{pane_id}:#{pane_active}:#{pane_z}\""
|
|
wait_for "$OUT1" "C1_FLOAT_LOCAL:$f1:1:1" || exit 1
|
|
check_fmt "$f1" '#{pane_z}' 1
|
|
send1 "select-pane -M -t $f1"
|
|
send1 "display-message -p -t $f1 \"C1_FLOAT_BORDER:#{pane_id}:#{pane_active}:#{pane_z}\""
|
|
wait_for "$OUT1" "C1_FLOAT_BORDER:$f1:1:1" || exit 1
|
|
check_fmt "$f1" '#{pane_z}' 1
|
|
send1 "move-pane -P front -t $f1"
|
|
send1 "display-message -p -t $f1 \"C1_FLOAT_RAISE:#{pane_z}\""
|
|
wait_for "$OUT1" "C1_FLOAT_RAISE:0" || exit 1
|
|
check_fmt "$f1" '#{pane_z}' 0
|
|
$TMUX kill-pane -t "$f1" || exit 1
|
|
$TMUX kill-pane -t "$f2" || exit 1
|
|
|
|
# When only one client remains, local mode is cleared.
|
|
send1 'select-pane -s'
|
|
send1 "select-pane -t $p0"
|
|
send1 'display-message -p "C1_LOCAL_BEFORE_DETACH:#{pane_id}:#{pane_local_active}"'
|
|
wait_for "$OUT1" "C1_LOCAL_BEFORE_DETACH:$p0:1" || exit 1
|
|
kill "$PID2" 2>/dev/null
|
|
wait "$PID2" 2>/dev/null
|
|
send1 'display-message -p "C1_AFTER_DETACH:#{pane_id}:#{pane_local_active}"'
|
|
wait_for "$OUT1" "C1_AFTER_DETACH:$p1:" || exit 1
|
|
|
|
kill "$PID1" 2>/dev/null
|
|
wait "$PID1" 2>/dev/null
|
|
$TMUX display-message -p alive >/dev/null 2>&1 || fail "server died"
|
|
|
|
exit 0
|