mirror of
https://github.com/tmux/tmux.git
synced 2026-07-10 03:19:31 +00:00
288 lines
8.2 KiB
Bash
288 lines
8.2 KiB
Bash
#!/bin/sh
|
|
|
|
# Tests of paste buffer command semantics, as implemented in cmd-set-buffer.c
|
|
# (set-buffer and delete-buffer), cmd-paste-buffer.c, cmd-load-buffer.c,
|
|
# cmd-save-buffer.c (save-buffer and show-buffer), cmd-list-buffers.c and
|
|
# paste.c.
|
|
#
|
|
# This exercises:
|
|
# - set-buffer creating automatic buffers (buffer0, buffer1, ... with the
|
|
# most recent first), -b creating/replacing a named buffer, -a appending,
|
|
# -n renaming and the error paths (no data, unknown buffer);
|
|
# - show-buffer for the top and for named buffers;
|
|
# - delete-buffer for the top and named buffers, and when nothing exists;
|
|
# - list-buffers -F custom formats and -f filters;
|
|
# - paste-buffer into a pane: newline-to-CR translation by default, -r raw,
|
|
# -s custom separator, -d delete-after-paste, unknown buffer error;
|
|
# - the buffer-limit option evicting the oldest automatic buffers but not
|
|
# named buffers;
|
|
# - load-buffer/save-buffer round trips including control characters and
|
|
# UTF-8, save-buffer -a appending and errors for missing files/buffers.
|
|
|
|
PATH=/bin:/usr/bin
|
|
TERM=screen
|
|
|
|
[ -z "$TEST_TMUX" ] && TEST_TMUX=$(readlink -f ../tmux)
|
|
TMUX="$TEST_TMUX -LtestA$$ -f/dev/null"
|
|
$TMUX kill-server 2>/dev/null
|
|
|
|
TMP=$(mktemp)
|
|
TMP2=$(mktemp)
|
|
trap 'rm -f "$TMP" "$TMP2"; $TMUX kill-server 2>/dev/null' 0 1 15
|
|
|
|
# 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_buffers $expected
|
|
#
|
|
# Compare the buffer list (as "name=content ...", most recent first) with
|
|
# $expected.
|
|
check_buffers()
|
|
{
|
|
out=$(echo $($TMUX list-buffers -F \
|
|
'#{buffer_name}=#{buffer_sample}'))
|
|
if [ "$out" != "$1" ]; then
|
|
echo "Buffer list wrong."
|
|
echo "Expected: '$1'"
|
|
echo "But got: '$out'"
|
|
exit 1
|
|
fi
|
|
}
|
|
|
|
# check_show $args $expected
|
|
#
|
|
# Compare show-buffer output with $expected.
|
|
check_show()
|
|
{
|
|
out=$($TMUX show-buffer $1 2>&1)
|
|
if [ "$out" != "$2" ]; then
|
|
echo "show-buffer $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
|
|
}
|
|
|
|
check_ok new-session -d -s B -x 80 -y 24
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# set-buffer, show-buffer, delete-buffer, list-buffers.
|
|
|
|
# Automatic buffers stack with the most recent first.
|
|
check_ok set-buffer one
|
|
check_ok set-buffer two
|
|
check_buffers 'buffer1=two buffer0=one'
|
|
check_show '' 'two'
|
|
check_show '-b buffer0' 'one'
|
|
|
|
# -a only appends to a buffer named with -b: without -b it creates a new
|
|
# automatic buffer. Empty data is silently ignored.
|
|
check_ok set-buffer -a '!'
|
|
check_buffers 'buffer2=! buffer1=two buffer0=one'
|
|
check_ok delete-buffer
|
|
check_ok set-buffer ''
|
|
check_buffers 'buffer1=two buffer0=one'
|
|
|
|
# -b names a buffer explicitly; setting it again replaces the content;
|
|
# -a appends to it.
|
|
check_ok set-buffer -b named abc
|
|
check_buffers 'named=abc buffer1=two buffer0=one'
|
|
check_ok set-buffer -b named xyz
|
|
check_ok set-buffer -a -b named 123
|
|
check_buffers 'named=xyz123 buffer1=two buffer0=one'
|
|
check_show '-b named' 'xyz123'
|
|
|
|
# -n renames; renaming to a bad source is an error, as is no data at all.
|
|
check_ok set-buffer -b named -n other
|
|
check_buffers 'other=xyz123 buffer1=two buffer0=one'
|
|
check_fail 'unknown buffer: nosuch' set-buffer -b nosuch -n foo
|
|
check_fail 'no data specified' set-buffer -b other
|
|
check_fail 'no buffer nosuch' show-buffer -b nosuch
|
|
|
|
# list-buffers -f filters.
|
|
out=$($TMUX list-buffers -f '#{==:#{buffer_name},other}' -F '#{buffer_name}')
|
|
if [ "$out" != "other" ]; then
|
|
echo "list-buffers -f wrong: '$out'"
|
|
exit 1
|
|
fi
|
|
|
|
# delete-buffer -b removes one buffer; without -b the most recent automatic
|
|
# buffer goes - named buffers are not candidates for the top, for
|
|
# show-buffer and delete-buffer alike.
|
|
check_ok delete-buffer -b buffer1
|
|
check_buffers 'other=xyz123 buffer0=one'
|
|
check_fail 'unknown buffer: buffer1' delete-buffer -b buffer1
|
|
check_ok delete-buffer
|
|
check_buffers 'other=xyz123'
|
|
check_fail 'no buffers' show-buffer
|
|
check_fail 'no buffer' delete-buffer
|
|
check_ok delete-buffer -b other
|
|
check_fail 'no buffers' show-buffer
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# buffer-limit.
|
|
|
|
# Only automatic buffers count against buffer-limit and the oldest are
|
|
# evicted; named buffers survive. (Automatic buffer numbers keep counting
|
|
# up over the life of the server, so compare content only.)
|
|
check_ok set-option -g buffer-limit 3
|
|
check_ok set-buffer -b keepme precious
|
|
check_ok set-buffer a1
|
|
check_ok set-buffer a2
|
|
check_ok set-buffer a3
|
|
check_ok set-buffer a4
|
|
out=$(echo $($TMUX list-buffers -F '#{buffer_sample}'))
|
|
if [ "$out" != 'a4 a3 a2 precious' ]; then
|
|
echo "buffer-limit eviction wrong: '$out'"
|
|
exit 1
|
|
fi
|
|
check_ok set-option -g buffer-limit 50
|
|
check_ok delete-buffer -b keepme
|
|
check_ok delete-buffer; check_ok delete-buffer; check_ok delete-buffer
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# paste-buffer.
|
|
|
|
# Paste into a raw, echo-free pane running cat -v so control characters are
|
|
# visible; a fresh window per paste keeps assertions simple.
|
|
|
|
# paste_line $bufdata $pasteargs $expected
|
|
#
|
|
# Set a buffer, paste it into a fresh cat -v pane and compare the first
|
|
# screen line with $expected.
|
|
paste_line()
|
|
{
|
|
$TMUX kill-window -t B:9 2>/dev/null
|
|
check_ok new-window -d -t B:9 'stty raw -echo && exec cat -v'
|
|
i=0
|
|
while [ "$($TMUX display-message -p -t B:9.0 \
|
|
'#{pane_current_command}')" != "cat" ]; do
|
|
i=$((i + 1))
|
|
[ $i -gt 50 ] && { echo "cat did not start."; exit 1; }
|
|
sleep 0.1
|
|
done
|
|
check_ok set-buffer -b paste "$1"
|
|
check_ok paste-buffer $2 -b paste -t B:9.0
|
|
i=0
|
|
while out=$($TMUX capture-pane -p -t B:9.0 | sed -n 1p) && \
|
|
[ "$out" != "$3" ]; do
|
|
i=$((i + 1))
|
|
if [ $i -gt 50 ]; then
|
|
echo "Paste of '$1' ($2) wrong."
|
|
echo "Expected: '$3'"
|
|
echo "But got: '$out'"
|
|
exit 1
|
|
fi
|
|
sleep 0.1
|
|
done
|
|
}
|
|
|
|
# By default linefeeds are replaced with carriage returns (shown as ^M by
|
|
# cat -v); -r pastes raw and -s sets an explicit separator.
|
|
paste_line 'one
|
|
two' '' 'one^Mtwo'
|
|
paste_line 'one
|
|
two' '-r' 'one'
|
|
paste_line 'one
|
|
two' '-s |' 'one|two'
|
|
paste_line 'one
|
|
two' '-s XX' 'oneXXtwo'
|
|
|
|
# -d deletes the buffer after pasting.
|
|
paste_line 'gone' '-d' 'gone'
|
|
check_fail 'no buffer paste' show-buffer -b paste
|
|
|
|
# Unknown buffer is an error.
|
|
check_fail 'no buffer nosuch' paste-buffer -b nosuch -t B:9.0
|
|
check_ok kill-window -t B:9
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# load-buffer and save-buffer.
|
|
|
|
# Round trip a file with control characters and UTF-8 through load-buffer
|
|
# and save-buffer.
|
|
printf 'line1\tx\033[31m\001\002\303\251\n' >"$TMP"
|
|
check_ok load-buffer -b file "$TMP"
|
|
check_ok save-buffer -b file "$TMP2"
|
|
if ! cmp -s "$TMP" "$TMP2"; then
|
|
echo "load-buffer/save-buffer round trip differs."
|
|
exit 1
|
|
fi
|
|
|
|
# save-buffer -a appends.
|
|
check_ok save-buffer -a -b file "$TMP2"
|
|
cat "$TMP" "$TMP" >"$TMP".x
|
|
if ! cmp -s "$TMP".x "$TMP2"; then
|
|
rm -f "$TMP".x
|
|
echo "save-buffer -a did not append."
|
|
exit 1
|
|
fi
|
|
rm -f "$TMP".x
|
|
|
|
# show-buffer prints the loaded content (text form).
|
|
check_ok delete-buffer -b file
|
|
|
|
# load-buffer of a missing file and save-buffer of a missing buffer or to a
|
|
# bad path are errors.
|
|
check_fail "No such file or directory: $TMP.nosuch" \
|
|
load-buffer -b x "$TMP.nosuch"
|
|
check_fail 'no buffer nosuch' save-buffer -b nosuch "$TMP2"
|
|
check_ok set-buffer -b sb data
|
|
out=$($TMUX save-buffer -b sb /nonexistent/dir/file 2>&1)
|
|
if [ $? -eq 0 ]; then
|
|
echo "save-buffer to bad path succeeded."
|
|
exit 1
|
|
fi
|
|
|
|
# save-buffer - writes to stdout and load-buffer - reads from stdin.
|
|
out=$($TMUX save-buffer -b sb -)
|
|
if [ "$out" != "data" ]; then
|
|
echo "save-buffer - wrong: '$out'"
|
|
exit 1
|
|
fi
|
|
check_ok delete-buffer -b sb
|
|
printf 'from stdin' | $TMUX load-buffer -b stdinbuf -
|
|
check_show '-b stdinbuf' 'from stdin'
|
|
check_ok delete-buffer -b stdinbuf
|
|
|
|
assert_alive
|
|
|
|
$TMUX kill-server 2>/dev/null
|
|
exit 0
|