Keep copy-mode -c active for the entire visit

This commit is contained in:
Michael Grant
2026-10-05 19:20:26 +01:00
parent 6137fd04e9
commit ca35e3f820
4 changed files with 58 additions and 44 deletions

View File

@@ -1,7 +1,6 @@
CHANGES FROM 3.7c TO 3.8
* Add copy-mode -c to start with the current cursor column as the preferred
column, rather than initially following line ends.
* Add copy-mode -c to disable end-of-line following during vertical movement.
* Many improvements to floating panes:

View File

@@ -179,6 +179,27 @@ for entry_line in 'prompt> ' ' '; do
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

6
tmux.1
View File

@@ -2616,9 +2616,9 @@ command is:
Enter copy mode.
.Pp
.Fl c
initializes the preferred cursor column to the column at which copy mode is
entered, rather than initially following the end of each line.
Subsequent cursor movements use the normal copy mode behaviour.
disables end-of-line following during vertical movement for the duration of
copy mode.
Normal cursor limits and selection behaviour are unchanged.
.Pp
.Fl u
enters copy mode and scrolls one page up and

View File

@@ -106,8 +106,6 @@ 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 *);
@@ -332,6 +330,7 @@ struct window_copy_mode_data {
u_int lastcx; /* position in last line w/ content */
u_int lastsx; /* size of last line w/ content */
int columnflag; /* do not follow line ends */
u_int mx; /* mark position */
u_int my;
@@ -616,11 +615,9 @@ window_copy_init(struct window_mode_entry *wme,
window_copy_sync_snapshot(data, base->grid);
data->cx = cx;
if (args_has(args, 'c')) {
/* Preserve the entry column on the first vertical move. */
data->columnflag = args_has(args, 'c');
if (data->columnflag)
data->lastcx = cx;
data->lastsx = UINT_MAX;
}
if (cy < screen_hsize(data->backing)) {
data->cy = 0;
data->oy = screen_hsize(data->backing) - cy;
@@ -834,7 +831,10 @@ 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);
window_copy_update_preferred_column(data, ox);
if (data->cx != ox) {
data->lastcx = data->cx;
data->lastsx = ox;
}
data->cx = data->lastcx;
if (delta >= 0) {
@@ -865,8 +865,8 @@ window_copy_scroll1(struct window_mode_entry *wme, struct window_pane *wp,
if (data->screen.sel == NULL || !data->rectflag) {
py = screen_hsize(data->backing) + data->cy - data->oy;
px = window_copy_find_length(wme, py);
if ((data->cx >= data->lastsx && data->cx != px) ||
data->cx > px)
if ((!data->columnflag && data->cx >= data->lastsx &&
data->cx != px) || data->cx > px)
window_copy_cursor_end_of_line(wme);
}
@@ -898,7 +898,10 @@ 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);
window_copy_update_preferred_column(data, ox);
if (data->cx != ox) {
data->lastcx = data->cx;
data->lastsx = ox;
}
data->cx = data->lastcx;
n = 1;
@@ -921,8 +924,8 @@ window_copy_pageup1(struct window_mode_entry *wme, int half_page)
if (data->screen.sel == NULL || !data->rectflag) {
py = screen_hsize(data->backing) + data->cy - data->oy;
px = window_copy_find_length(wme, py);
if ((data->cx >= data->lastsx && data->cx != px) ||
data->cx > px)
if ((!data->columnflag && data->cx >= data->lastsx &&
data->cx != px) || data->cx > px)
window_copy_cursor_end_of_line(wme);
}
@@ -954,7 +957,10 @@ 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);
window_copy_update_preferred_column(data, ox);
if (data->cx != ox) {
data->lastcx = data->cx;
data->lastsx = ox;
}
data->cx = data->lastcx;
n = 1;
@@ -977,8 +983,8 @@ window_copy_pagedown1(struct window_mode_entry *wme, int half_page,
if (data->screen.sel == NULL || !data->rectflag) {
py = screen_hsize(data->backing) + data->cy - data->oy;
px = window_copy_find_length(wme, py);
if ((data->cx >= data->lastsx && data->cx != px) ||
data->cx > px)
if ((!data->columnflag && data->cx >= data->lastsx &&
data->cx != px) || data->cx > px)
window_copy_cursor_end_of_line(wme);
}
@@ -6310,22 +6316,6 @@ 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)
@@ -6512,8 +6502,10 @@ 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)
window_copy_update_preferred_column(data, ox);
if (norectsel && data->cx != ox) {
data->lastcx = data->cx;
data->lastsx = ox;
}
if (data->lineflag == LINE_SEL_LEFT_RIGHT && oy == data->sely)
window_copy_other_end(wme);
@@ -6550,8 +6542,8 @@ window_copy_cursor_up(struct window_mode_entry *wme, int scroll_only)
if (norectsel) {
py = screen_hsize(data->backing) + data->cy - data->oy;
px = window_copy_find_length(wme, py);
if ((data->cx >= data->lastsx && data->cx != px) ||
data->cx > px)
if ((!data->columnflag && data->cx >= data->lastsx &&
data->cx != px) || data->cx > px)
{
window_copy_update_cursor(wme, px, data->cy);
if (window_copy_update_selection(wme, 1, 0))
@@ -6590,8 +6582,10 @@ 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)
window_copy_update_preferred_column(data, ox);
if (norectsel && data->cx != ox) {
data->lastcx = data->cx;
data->lastsx = ox;
}
if (data->lineflag == LINE_SEL_RIGHT_LEFT && oy == data->endsely)
window_copy_other_end(wme);
@@ -6620,8 +6614,8 @@ window_copy_cursor_down(struct window_mode_entry *wme, int scroll_only)
if (norectsel) {
py = screen_hsize(data->backing) + data->cy - data->oy;
px = window_copy_find_length(wme, py);
if ((data->cx >= data->lastsx && data->cx != px) ||
data->cx > px)
if ((!data->columnflag && data->cx >= data->lastsx &&
data->cx != px) || data->cx > px)
{
window_copy_update_cursor(wme, px, data->cy);
if (window_copy_update_selection(wme, 1, 0))