mirror of
https://github.com/tmux/tmux.git
synced 2026-10-06 17:49:52 +00:00
254 lines
6.2 KiB
Bash
254 lines
6.2 KiB
Bash
#!/bin/sh
|
|
|
|
# Exercise the broad non-mouse copy-mode command surface: navigation, search,
|
|
# jumps, state toggles, line/end-of-line copies, append, and pipe variants.
|
|
|
|
PATH=/bin:/usr/bin
|
|
TERM=screen
|
|
LC_ALL=C.UTF-8
|
|
export PATH TERM LC_ALL
|
|
|
|
[ -z "$TEST_TMUX" ] && TEST_TMUX=$(readlink -f ../tmux)
|
|
DIR=$(mktemp -d) || exit 1
|
|
TMUX_TMPDIR=$DIR
|
|
export TMUX_TMPDIR
|
|
TMUX="$TEST_TMUX -Ltest$$ -f/dev/null"
|
|
|
|
fail()
|
|
{
|
|
echo "$*" >&2
|
|
exit 1
|
|
}
|
|
|
|
cleanup()
|
|
{
|
|
$TMUX kill-server 2>/dev/null
|
|
rm -rf "$DIR"
|
|
}
|
|
trap cleanup 0 1 15
|
|
|
|
x()
|
|
{
|
|
$TMUX send-keys -t copy:0 -X "$@" || fail "copy command failed: $*"
|
|
}
|
|
|
|
wait_mode()
|
|
{
|
|
want=$1
|
|
i=0
|
|
while [ "$i" -lt 50 ]; do
|
|
got=$($TMUX display-message -p -t copy:0 '#{pane_in_mode}' 2>/dev/null)
|
|
[ "$got" = "$want" ] && return 0
|
|
sleep 0.1
|
|
i=$((i + 1))
|
|
done
|
|
fail "pane_in_mode is '$got', expected '$want'"
|
|
}
|
|
|
|
fresh()
|
|
{
|
|
$TMUX copy-mode -t copy:0 || exit 1
|
|
wait_mode 1
|
|
x history-top
|
|
x start-of-line
|
|
}
|
|
|
|
select_text()
|
|
{
|
|
fresh
|
|
x begin-selection
|
|
x cursor-right
|
|
x cursor-right
|
|
}
|
|
|
|
$TMUX new-session -d -s copy -x40 -y8 \
|
|
"sh -c 'i=0; while [ \$i -lt 40 ]; do printf \" line-%02d needle (a[b]c) end\\n\" \$i; i=\$((i + 1)); done; printf \"\\nparagraph two needle\\n\\nparagraph three\\n\"; printf \"\\033]133;A\\007prompt-one\\n\\033]133;C\\007output-one\\n\\033]133;A\\007prompt-two\\n\\033]133;C\\007output-two\\n\"; exec sleep 100'" ||
|
|
exit 1
|
|
$TMUX set-option -g status off || exit 1
|
|
$TMUX set-option -g history-limit 200 || exit 1
|
|
|
|
i=0
|
|
while [ "$i" -lt 50 ]; do
|
|
history=$($TMUX display-message -p -t copy:0 '#{history_size}')
|
|
[ "$history" -ge 30 ] && break
|
|
sleep 0.1
|
|
i=$((i + 1))
|
|
done
|
|
[ "$i" -lt 50 ] || fail "history did not fill"
|
|
|
|
fresh
|
|
|
|
# Copy-mode-specific format callbacks expose the word, line, hyperlink and
|
|
# active search match at the cursor.
|
|
formats=$($TMUX display-message -p -t copy:0 \
|
|
'#{copy_cursor_word}|#{copy_cursor_line}|#{copy_cursor_hyperlink}|#{search_match}') ||
|
|
exit 1
|
|
[ -n "$formats" ] || fail "copy-mode cursor formats were empty"
|
|
|
|
# Cursor, viewport and paragraph commands. Each is asserted by successful
|
|
# dispatch and the final mode-liveness check; detailed word/selection geometry
|
|
# is covered by the existing copy-mode tests.
|
|
for command in back-to-indentation bottom-line top-line middle-line \
|
|
cursor-centre-vertical cursor-centre-horizontal end-of-line history-bottom \
|
|
history-top halfpage-down halfpage-up page-down page-up next-paragraph \
|
|
previous-paragraph next-matching-bracket previous-matching-bracket; do
|
|
x "$command"
|
|
done
|
|
x goto-line 15
|
|
x set-mark
|
|
x cursor-down
|
|
x jump-to-mark
|
|
|
|
# OSC 133 prompt and output markers support shell-integration navigation.
|
|
x history-top
|
|
x next-prompt
|
|
case "$($TMUX display-message -p -t copy:0 '#{copy_cursor_line}')" in
|
|
*prompt-one*) ;;
|
|
*) fail "next-prompt did not find prompt-one" ;;
|
|
esac
|
|
x next-prompt
|
|
x previous-prompt
|
|
case "$($TMUX display-message -p -t copy:0 '#{copy_cursor_line}')" in
|
|
*prompt-one*) ;;
|
|
*) fail "previous-prompt did not return to prompt-one" ;;
|
|
esac
|
|
x next-prompt -o
|
|
case "$($TMUX display-message -p -t copy:0 '#{copy_cursor_line}')" in
|
|
*output-one*) ;;
|
|
*) fail "next-prompt -o did not find output-one" ;;
|
|
esac
|
|
|
|
# Character jumps remember their direction and character for repeat/reverse.
|
|
x jump-forward e
|
|
x jump-again
|
|
x jump-reverse
|
|
x jump-backward e
|
|
x jump-to-forward e
|
|
x jump-to-backward e
|
|
|
|
# Direct, text and incremental searches cover both directions and the saved
|
|
# search used by again/reverse.
|
|
x search-forward needle
|
|
x search-again
|
|
x search-reverse
|
|
x search-backward needle
|
|
x search-forward-text needle
|
|
x search-backward-text needle
|
|
x search-forward-incremental '=needle'
|
|
x search-forward-incremental '+needle'
|
|
x search-backward-incremental '=needle'
|
|
x search-backward-incremental '-needle'
|
|
|
|
# Stateful display and behaviour toggles.
|
|
for command in rectangle-on rectangle-off rectangle-toggle \
|
|
line-numbers-on line-numbers-off line-numbers-toggle \
|
|
refresh-on refresh-now refresh-off refresh-toggle \
|
|
scroll-exit-on scroll-exit-off scroll-exit-toggle toggle-position; do
|
|
x "$command"
|
|
done
|
|
wait_mode 1
|
|
x cancel
|
|
wait_mode 0
|
|
|
|
# Line and end-of-line copy commands work without an explicit selection.
|
|
fresh
|
|
x select-line
|
|
x copy-selection-and-cancel
|
|
case "$($TMUX show-buffer)" in
|
|
*line-00*) ;;
|
|
*) fail "select-line did not select the current line" ;;
|
|
esac
|
|
|
|
fresh
|
|
x copy-line
|
|
[ -n "$($TMUX show-buffer)" ] || fail "copy-line produced an empty buffer"
|
|
x cancel
|
|
|
|
fresh
|
|
x copy-end-of-line
|
|
[ -n "$($TMUX show-buffer)" ] || fail "copy-end-of-line produced an empty buffer"
|
|
x cancel
|
|
|
|
# Append variants retain or close the mode as advertised.
|
|
$TMUX set-buffer -b append-buffer prefix || exit 1
|
|
select_text
|
|
x append-selection
|
|
appended=$($TMUX show-buffer -b append-buffer)
|
|
case "$appended" in
|
|
prefix*) ;;
|
|
*) fail "append-selection produced '$appended'" ;;
|
|
esac
|
|
x cancel
|
|
|
|
$TMUX set-buffer -b append-cancel-buffer prefix || exit 1
|
|
select_text
|
|
x append-selection-and-cancel
|
|
wait_mode 0
|
|
appended=$($TMUX show-buffer -b append-cancel-buffer)
|
|
case "$appended" in
|
|
prefix*) ;;
|
|
*) fail "append-selection-and-cancel produced '$appended'" ;;
|
|
esac
|
|
|
|
# The explicit cancel variants close copy mode.
|
|
fresh
|
|
x copy-line-and-cancel
|
|
wait_mode 0
|
|
fresh
|
|
x copy-end-of-line-and-cancel
|
|
wait_mode 0
|
|
select_text
|
|
x copy-selection-and-cancel
|
|
wait_mode 0
|
|
|
|
# Pipe wrappers have distinct command handlers. /dev/null keeps the test
|
|
# deterministic while exercising asynchronous pipe job creation and cleanup.
|
|
fresh
|
|
x copy-pipe-line 'cat >/dev/null'
|
|
x cancel
|
|
fresh
|
|
x copy-pipe-line-and-cancel 'cat >/dev/null'
|
|
wait_mode 0
|
|
fresh
|
|
x copy-pipe-end-of-line 'cat >/dev/null'
|
|
x cancel
|
|
fresh
|
|
x copy-pipe-end-of-line-and-cancel 'cat >/dev/null'
|
|
wait_mode 0
|
|
|
|
select_text
|
|
x copy-pipe-no-clear 'cat >/dev/null'
|
|
x pipe-no-clear 'cat >/dev/null'
|
|
x copy-pipe 'cat >/dev/null'
|
|
x pipe 'cat >/dev/null'
|
|
x cancel
|
|
select_text
|
|
x copy-pipe-and-cancel 'cat >/dev/null'
|
|
wait_mode 0
|
|
select_text
|
|
x pipe-and-cancel 'cat >/dev/null'
|
|
wait_mode 0
|
|
|
|
# Commands which cancel on downward movement have separate handlers.
|
|
fresh
|
|
x history-bottom
|
|
x bottom-line
|
|
x cursor-down-and-cancel
|
|
wait_mode 0
|
|
fresh
|
|
x history-bottom
|
|
x halfpage-down-and-cancel
|
|
wait_mode 0
|
|
fresh
|
|
x history-bottom
|
|
x page-down-and-cancel
|
|
wait_mode 0
|
|
fresh
|
|
x history-bottom
|
|
x bottom-line
|
|
x scroll-down-and-cancel
|
|
wait_mode 0
|
|
|
|
$TMUX has-session -t copy || fail "server died during copy-mode commands"
|
|
exit 0
|