mirror of
https://github.com/tmux/tmux.git
synced 2026-10-14 06:44:28 +00:00
Fix output folding across resize and refresh
Keep backing row mappings and selection endpoints correct after wrapping. Preserve exit status during reflow and collapsed state during refresh. Clip the gutter to fit narrow panes. Add regression coverage for these cases.
This commit is contained in:
89
regress/collapse-output-resize.sh
Normal file
89
regress/collapse-output-resize.sh
Normal file
@@ -0,0 +1,89 @@
|
||||
#!/bin/sh
|
||||
|
||||
# Keep output mappings and individual folds across resize and refresh.
|
||||
|
||||
. ./input-common.inc
|
||||
|
||||
first=$(printf '%060d' 0 | tr 0 F)
|
||||
second=SECOND-OUTPUT
|
||||
seq="\033]133;A\007P0> \033]133;B\007first\r\n"
|
||||
seq="${seq}\033]133;C\007${first}\r\n\033]133;D;7\007"
|
||||
seq="${seq}\033]133;A\007P1> \033]133;B\007second\r\n"
|
||||
seq="${seq}\033]133;C\007${second}\r\n\033]133;D;0\007"
|
||||
seq="${seq}\033]133;A\007P2> \033]133;B\007"
|
||||
commands_seq=$seq
|
||||
|
||||
# Narrow output can create more backing rows than there are source rows.
|
||||
for hlimit in 2000 1; do
|
||||
start_pane_hlimit mapping 80 8 "$commands_seq" "$hlimit"
|
||||
$TMUX copy-mode -t mapping: -U || exit 1
|
||||
$TMUX resize-window -t mapping: -x 5 || exit 1
|
||||
$TMUX send -t mapping: -X search-backward-text FFFFF || exit 1
|
||||
$TMUX set-buffer sentinel || exit 1
|
||||
$TMUX send -t mapping: -X copy-output || exit 1
|
||||
$TMUX save-buffer "$TMP" || exit 1
|
||||
printf '%s\n' "$first" >"$EXP"
|
||||
cmp "$TMP" "$EXP" || fail "copy-output with history-limit $hlimit"
|
||||
done
|
||||
|
||||
# Selection endpoints must land on the appropriate wrapped segment.
|
||||
for keys in emacs vi; do
|
||||
for length in 60 61; do
|
||||
payload=$(printf "%0${length}d" 0 | tr 0 F)
|
||||
selection_seq="\033]133;A\007p> \033]133;B\007first\r\n"
|
||||
selection_seq="${selection_seq}\033]133;C\007${payload}"
|
||||
selection_seq="${selection_seq}\033]133;D;7\007\r\n"
|
||||
selection_seq="${selection_seq}\033]133;A\007p> \033]133;B\007"
|
||||
for width in 5 20 100; do
|
||||
start_pane_history selection 80 12 "$selection_seq"
|
||||
$TMUX set -w -t selection: mode-keys "$keys" || exit 1
|
||||
$TMUX copy-mode -t selection: -U || exit 1
|
||||
$TMUX resize-window -t selection: -x "$width" || exit 1
|
||||
$TMUX send -t selection: -X search-backward-text FFF || exit 1
|
||||
$TMUX set-buffer sentinel || exit 1
|
||||
$TMUX send -t selection: -X select-output || exit 1
|
||||
$TMUX send -t selection: -X copy-selection || exit 1
|
||||
$TMUX save-buffer "$TMP" || exit 1
|
||||
printf '%s' "$payload" >"$EXP"
|
||||
cmp "$TMP" "$EXP" || \
|
||||
fail "$keys $length cells at width $width"
|
||||
done
|
||||
done
|
||||
done
|
||||
|
||||
# Refresh must keep a mixture of collapsed and expanded commands.
|
||||
for refresh in refresh-now refresh-on; do
|
||||
start_cmd refresh 80 12 \
|
||||
"printf '$commands_seq'; sleep 1; printf LIVE; sleep 1; printf LIVE; $INPUT_HOLD"
|
||||
$TMUX copy-mode -t refresh: -c || exit 1
|
||||
$TMUX send -t refresh: -X search-backward-text second || exit 1
|
||||
$TMUX send -t refresh: -X expand-output || exit 1
|
||||
for width in 20 100; do
|
||||
$TMUX resize-window -t refresh: -x "$width" || exit 1
|
||||
$TMUX send -t refresh: -X "$refresh" || exit 1
|
||||
sleep 1
|
||||
$TMUX send -t refresh: -X history-top || exit 1
|
||||
$TMUX capture-pane -t refresh: -Mp >"$TMP" || exit 1
|
||||
grep -q FFFFF "$TMP" && fail "$refresh expanded the first command"
|
||||
grep -q "$second" "$TMP" || \
|
||||
fail "$refresh collapsed the second command"
|
||||
done
|
||||
done
|
||||
|
||||
# Initial output and commands without C use different fold anchors.
|
||||
seq='initial-control\r\nHIDDEN-INITIAL\r\n'
|
||||
seq="${seq}\033]133;A\007p> \033]133;B\007silent\r\n"
|
||||
seq="${seq}\033]133;D;7\007HIDDEN-SEPARATOR\r\n"
|
||||
seq="${seq}\033]133;A\007p> \033]133;B\007"
|
||||
start_pane_history initial 80 12 "$seq"
|
||||
$TMUX copy-mode -t initial: -c || exit 1
|
||||
for width in 20 100; do
|
||||
$TMUX resize-window -t initial: -x "$width" || exit 1
|
||||
$TMUX send -t initial: -X refresh-now || exit 1
|
||||
$TMUX send -t initial: -X history-top || exit 1
|
||||
$TMUX capture-pane -t initial: -Mp >"$TMP" || exit 1
|
||||
grep -q HIDDEN "$TMP" && fail "initial folds lost at width $width"
|
||||
grep -q initial-control "$TMP" || fail 'initial control line lost'
|
||||
done
|
||||
|
||||
exit "$exit_status"
|
||||
70
regress/copy-mode-gutter-resize.sh
Normal file
70
regress/copy-mode-gutter-resize.sh
Normal file
@@ -0,0 +1,70 @@
|
||||
#!/bin/sh
|
||||
|
||||
# Exercise clipped gutter drawing through a real client.
|
||||
|
||||
PATH=/bin:/usr/bin
|
||||
TERM=screen
|
||||
export TERM
|
||||
|
||||
[ -z "$TEST_TMUX" ] && TEST_TMUX=$(readlink -f ../tmux)
|
||||
INNER="$TEST_TMUX -Li$$ -f/dev/null"
|
||||
OUTER="$TEST_TMUX -Lo$$ -f/dev/null"
|
||||
TMP=$(mktemp)
|
||||
exit_status=0
|
||||
trap 'rm -f "$TMP"; $INNER kill-server 2>/dev/null; $OUTER kill-server 2>/dev/null' 0 1 15
|
||||
|
||||
$INNER new-session -d -x 80 -y 12 \
|
||||
"printf '\033]133;A\007p> \033]133;B\007failed\r\n\033]133;C\007012345678901234567890123456789012345678901234567890123456789\033]133;D;7\007\r\n\033]133;A\007p> \033]133;B\007'; exec sleep 100" || exit 1
|
||||
$INNER set -g status off || exit 1
|
||||
$INNER set -g window-size manual || exit 1
|
||||
$INNER set -g copy-mode-position-format '' || exit 1
|
||||
$INNER set -g copy-mode-exit-status-format \
|
||||
'#{?exit_status_present,RC=#{exit_status},}' || exit 1
|
||||
$OUTER new-session -d -x 80 -y 12 "$INNER attach" || exit 1
|
||||
$OUTER set -g status off || exit 1
|
||||
sleep 1
|
||||
|
||||
# Reflow must move the exit status presence flag with its numeric value.
|
||||
for width in 20 100; do
|
||||
$INNER resize-window -x "$width" || exit 1
|
||||
$INNER copy-mode -U || exit 1
|
||||
$INNER send -X history-top || exit 1
|
||||
sleep 0.3
|
||||
$OUTER capture-pane -p >"$TMP" || exit 1
|
||||
if ! grep -q RC=7 "$TMP"; then
|
||||
echo "exit status disappeared at width $width"
|
||||
exit_status=1
|
||||
fi
|
||||
$INNER send -X cancel || exit 1
|
||||
done
|
||||
|
||||
# A gutter wider than the pane must not wrap or scroll the displayed rows.
|
||||
$INNER resize-window -x 20 || exit 1
|
||||
$INNER set -g copy-mode-exit-status-format \
|
||||
'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX' || exit 1
|
||||
$INNER copy-mode -c || exit 1
|
||||
$INNER send -X history-top || exit 1
|
||||
sleep 0.3
|
||||
$OUTER capture-pane -p >"$TMP" || exit 1
|
||||
if ! grep -q '^XXXXXXXXXXXXXXX' "$TMP"; then
|
||||
echo 'wide gutter scrolled the displayed rows'
|
||||
exit_status=1
|
||||
fi
|
||||
$INNER display -p '#{copy_cursor_y}' | \
|
||||
awk '$1 < 12 { found = 1 } END { exit !found }' || exit 1
|
||||
|
||||
# Line numbers must also fit when the gutter leaves no room for them.
|
||||
$INNER send -X line-numbers-on || exit 1
|
||||
for width in 3 1; do
|
||||
$INNER resize-window -x "$width" || exit 1
|
||||
$INNER send -X history-top || exit 1
|
||||
sleep 0.3
|
||||
$OUTER capture-pane -p >"$TMP" || exit 1
|
||||
if [ "$width" = 3 ]; then
|
||||
grep -q '^1 p' "$TMP" || exit 1
|
||||
else
|
||||
grep -q '^p' "$TMP" || exit 1
|
||||
fi
|
||||
done
|
||||
|
||||
exit "$exit_status"
|
||||
Reference in New Issue
Block a user