Preserve the copy-mode entry column after trailing blanks

This commit is contained in:
Michael Grant
2026-10-05 16:55:22 +01:00
parent a1825146ee
commit 6137fd04e9
2 changed files with 73 additions and 23 deletions

View File

@@ -137,6 +137,51 @@ 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
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" ||
@@ -172,7 +217,7 @@ done
# Initialize before the optional entry-time page movement.
$TMUX respawn-pane -k \
"printf '\033[H\033[2JABCDEFGHIJKLMNOPQRST'; \
printf '\033[9;1Habcdefgh\033[10;1HABCDEFGHIJKLMNOP\033[9;9H'; \
printf '\033[9;1Hprompt> \033[10;1HABCDEFGHIJKLMNOP\033[9;9H'; \
exec cat" ||
fail "respawn-pane failed"
wait_cursor 8,8

View File

@@ -106,6 +106,8 @@ static int window_copy_search_down(struct window_mode_entry *, int);
static void window_copy_goto_line(struct window_mode_entry *, const char *);
static void window_copy_update_cursor(struct window_mode_entry *, u_int,
u_int);
static void window_copy_update_preferred_column(
struct window_copy_mode_data *, u_int);
static void window_copy_start_selection(struct window_mode_entry *);
static int window_copy_mouse_in_selection(struct window_mode_entry *,
u_int, u_int, int *, int *);
@@ -615,9 +617,9 @@ window_copy_init(struct window_mode_entry *wme,
data->cx = cx;
if (args_has(args, 'c')) {
/* Start with a preferred column rather than end of line. */
/* Preserve the entry column on the first vertical move. */
data->lastcx = cx;
data->lastsx = cx + 1;
data->lastsx = UINT_MAX;
}
if (cy < screen_hsize(data->backing)) {
data->cy = 0;
@@ -832,10 +834,7 @@ window_copy_scroll1(struct window_mode_entry *wme, struct window_pane *wp,
oy = screen_hsize(data->backing) + data->cy - data->oy;
ox = window_copy_find_length(wme, oy);
if (data->cx != ox) {
data->lastcx = data->cx;
data->lastsx = ox;
}
window_copy_update_preferred_column(data, ox);
data->cx = data->lastcx;
if (delta >= 0) {
@@ -899,10 +898,7 @@ window_copy_pageup1(struct window_mode_entry *wme, int half_page)
oy = screen_hsize(data->backing) + data->cy - data->oy;
ox = window_copy_find_length(wme, oy);
if (data->cx != ox) {
data->lastcx = data->cx;
data->lastsx = ox;
}
window_copy_update_preferred_column(data, ox);
data->cx = data->lastcx;
n = 1;
@@ -958,10 +954,7 @@ window_copy_pagedown1(struct window_mode_entry *wme, int half_page,
oy = screen_hsize(data->backing) + data->cy - data->oy;
ox = window_copy_find_length(wme, oy);
if (data->cx != ox) {
data->lastcx = data->cx;
data->lastsx = ox;
}
window_copy_update_preferred_column(data, ox);
data->cx = data->lastcx;
n = 1;
@@ -6317,6 +6310,22 @@ window_copy_find_length(struct window_mode_entry *wme, u_int py)
return (grid_line_length(data->backing->grid, py));
}
static void
window_copy_update_preferred_column(struct window_copy_mode_data *data,
u_int sx)
{
if (data->lastsx == UINT_MAX) {
/* Treat the entry column as inside a line. */
data->lastsx = data->lastcx + 1;
if (data->cx == data->lastcx)
return;
}
if (data->cx != sx) {
data->lastcx = data->cx;
data->lastsx = sx;
}
}
static u_int
window_copy_cursor_limit(struct window_mode_entry *wme, u_int py,
int allow_onemore)
@@ -6503,10 +6512,8 @@ window_copy_cursor_up(struct window_mode_entry *wme, int scroll_only)
norectsel = data->screen.sel == NULL || !data->rectflag;
oy = screen_hsize(data->backing) + data->cy - data->oy;
ox = window_copy_find_length(wme, oy);
if (norectsel && data->cx != ox) {
data->lastcx = data->cx;
data->lastsx = ox;
}
if (norectsel)
window_copy_update_preferred_column(data, ox);
if (data->lineflag == LINE_SEL_LEFT_RIGHT && oy == data->sely)
window_copy_other_end(wme);
@@ -6583,10 +6590,8 @@ window_copy_cursor_down(struct window_mode_entry *wme, int scroll_only)
norectsel = data->screen.sel == NULL || !data->rectflag;
oy = screen_hsize(data->backing) + data->cy - data->oy;
ox = window_copy_find_length(wme, oy);
if (norectsel && data->cx != ox) {
data->lastcx = data->cx;
data->lastsx = ox;
}
if (norectsel)
window_copy_update_preferred_column(data, ox);
if (data->lineflag == LINE_SEL_RIGHT_LEFT && oy == data->endsely)
window_copy_other_end(wme);