Files
tmux/regress/copy-mode-entry-column.sh
2026-10-05 19:20:26 +01:00

257 lines
6.1 KiB
Bash

#!/bin/sh
PATH=/bin:/usr/bin
TERM=screen
LC_ALL=C.UTF-8
export PATH TERM LC_ALL
[ -z "$TEST_TMUX" ] && TEST_TMUX=$(readlink -f ../tmux)
TMUX="$TEST_TMUX -Lentry-column-$$ -f/dev/null"
fail()
{
echo "$mode: $*" >&2
exit 1
}
cleanup()
{
$TMUX kill-server 2>/dev/null
}
trap cleanup 0 1 15
x()
{
$TMUX send-keys -X "$@" || fail "copy command failed: $*"
}
check_cursor()
{
actual=$($TMUX display-message -p '#{copy_cursor_x},#{copy_cursor_y}')
[ "$actual" = "$1" ] || fail "expected cursor $1, got $actual"
}
wait_cursor()
{
i=0
while [ "$i" -lt 50 ]; do
actual=$($TMUX display-message -p '#{cursor_x},#{cursor_y}')
[ "$actual" = "$1" ] && return 0
sleep 0.1
i=$((i + 1))
done
fail "pane cursor did not reach $1"
}
mode=emacs
$TMUX new-session -d -x40 -y10 \
"printf '%s\r\n' ABCDEFGHIJKLMNOPQRST abc ABCDEFGHIJKLMNOPQRST \
abcdefgh ABCDEFGHIJKLMNOP ab 01234567890123456789; \
printf '\033[4;9H'; exec cat" ||
fail "new-session failed"
$TMUX set-option -g status off || fail "set status failed"
$TMUX set-option -g window-size manual || fail "set window-size failed"
wait_cursor 8,3
for mode in emacs vi; do
$TMUX set-window-option -g mode-keys "$mode" ||
fail "set mode-keys failed"
# Ordinary entry still follows line ends; -c starts at the same physical
# position but treats its column as a numeric preference.
for direction in up down; do
if [ "$direction" = up ]; then
row=2
end=20
else
row=4
end=16
fi
[ "$mode" = emacs ] || end=$((end - 1))
$TMUX copy-mode || fail "copy-mode failed"
check_cursor 8,3
x "cursor-$direction"
check_cursor "$end,$row"
x cancel
$TMUX copy-mode -c || fail "copy-mode -c failed"
check_cursor 8,3
x "cursor-$direction"
check_cursor "8,$row"
x cancel
done
# Short lines retain the existing emacs and vi movement rules. Emacs
# restores the preferred column; vi resumes from its last-character clamp.
$TMUX copy-mode -c || fail "copy-mode -c failed"
x cursor-up
check_cursor 8,2
x cursor-up
if [ "$mode" = emacs ]; then
check_cursor 3,1
restored=8
else
check_cursor 2,1
restored=2
fi
x cursor-up
check_cursor "$restored,0"
x cancel
$TMUX copy-mode -c || fail "copy-mode -c failed"
x cursor-down
check_cursor 8,4
x cursor-down
if [ "$mode" = emacs ]; then
check_cursor 2,5
restored=8
else
check_cursor 1,5
restored=1
fi
x cursor-down
check_cursor "$restored,6"
x cancel
# Horizontal movement before the first vertical move replaces the initial
# preference, rather than leaving the entry column permanently fixed.
$TMUX copy-mode -c || fail "copy-mode -c failed"
x cursor-left
check_cursor 7,3
x cursor-up
check_cursor 7,2
x cancel
done
# Passing -c while already in copy mode must not reinitialize its preference.
mode=emacs
$TMUX set-window-option -g mode-keys "$mode" || fail "set mode-keys failed"
$TMUX copy-mode -c || fail "copy-mode -c failed"
x cursor-left
x cursor-up
x cursor-up
check_cursor 3,1
$TMUX copy-mode -c || fail "second copy-mode -c failed"
check_cursor 3,1
x cursor-up
check_cursor 7,0
x cancel
# Trailing blanks must not replace the initial preference on the first move.
for entry_line in 'prompt> ' ' '; do
$TMUX respawn-pane -k \
"printf '\033[H\033[2J'; \
printf '%s\r\n' ABCDEFGHIJKLMNOPQRST abc ABCDEFGHIJKLMNOPQRST \
'$entry_line' ABCDEFGHIJKLMNOP ab 01234567890123456789; \
printf '\033[4;9H'; exec cat" || fail "respawn-pane failed"
wait_cursor 8,3
for mode in emacs vi; do
$TMUX set-window-option -g mode-keys "$mode" ||
fail "set mode-keys failed"
for direction in up down; do
if [ "$direction" = up ]; then
row=2
end=20
short=3
last=0
else
row=4
end=16
short=2
last=6
fi
[ "$mode" = emacs ] || end=$((end - 1))
$TMUX copy-mode || fail "copy-mode failed"
x "cursor-$direction"
check_cursor "$end,$row"
x cancel
$TMUX copy-mode -c || fail "copy-mode -c failed"
check_cursor 8,3
x "cursor-$direction"
check_cursor "8,$row"
x "cursor-$direction"
x "cursor-$direction"
if [ "$mode" = emacs ]; then
check_cursor "8,$last"
else
check_cursor "$((short - 1)),$last"
fi
x cancel
done
# Returning to the entry mark must not reenable EOL following.
$TMUX copy-mode -c || fail "copy-mode -c failed"
x cursor-up
check_cursor 8,2
x jump-to-mark
check_cursor 8,3
$TMUX copy-mode || fail "second copy-mode failed"
x cursor-up
check_cursor 8,2
x cancel
# A new ordinary visit restores the default. Adding -c to an already
# active visit does not change its policy.
$TMUX copy-mode || fail "copy-mode failed"
$TMUX copy-mode -c || fail "second copy-mode -c failed"
x cursor-up
end=20
[ "$mode" = emacs ] || end=19
check_cursor "$end,2"
x cancel
done
done
# An empty entry line has a numeric column zero with -c.
$TMUX respawn-pane -k \
"printf '\033[H\033[2JABCDEFGHIJKLMNOPQRST\033[2;1H'; exec cat" ||
fail "respawn-pane failed"
wait_cursor 0,1
for mode in emacs vi; do
$TMUX set-window-option -g mode-keys "$mode" ||
fail "set mode-keys failed"
$TMUX copy-mode -c || fail "copy-mode -c failed"
check_cursor 0,1
x cursor-up
check_cursor 0,0
x cancel
done
# The initial preference counts terminal columns, not characters.
$TMUX respawn-pane -k \
"printf '\033[H\033[2J'; \
printf '%s\r\n' ABCDEFGHIJKLMNOPQRST ABCDEFGHIJKLMNOPQRST; \
printf 'abc中def'; exec cat" ||
fail "respawn-pane failed"
wait_cursor 8,2
for mode in emacs vi; do
$TMUX set-window-option -g mode-keys "$mode" ||
fail "set mode-keys failed"
$TMUX copy-mode -c || fail "copy-mode -c failed"
check_cursor 8,2
x cursor-up
check_cursor 8,1
x cancel
done
# Initialize before the optional entry-time page movement.
$TMUX respawn-pane -k \
"printf '\033[H\033[2JABCDEFGHIJKLMNOPQRST'; \
printf '\033[9;1Hprompt> \033[10;1HABCDEFGHIJKLMNOP\033[9;9H'; \
exec cat" ||
fail "respawn-pane failed"
wait_cursor 8,8
for mode in emacs vi; do
$TMUX set-window-option -g mode-keys "$mode" ||
fail "set mode-keys failed"
$TMUX copy-mode -cu || fail "copy-mode -cu failed"
check_cursor 8,0
x cancel
$TMUX copy-mode -cd || fail "copy-mode -cd failed"
check_cursor 8,9
x cancel
done
exit 0