Various fixes for copy mode from master.

This commit is contained in:
Nicholas Marriott 2020-04-06 16:09:49 +01:00
parent bc36b473f1
commit a4e19bcd80
3 changed files with 114 additions and 64 deletions

View File

@ -30,8 +30,8 @@ const struct cmd_entry cmd_copy_mode_entry = {
.name = "copy-mode", .name = "copy-mode",
.alias = NULL, .alias = NULL,
.args = { "Met:u", 0, 0 }, .args = { "eHMt:uq", 0, 0 },
.usage = "[-Mu] " CMD_TARGET_PANE_USAGE, .usage = "[-eHMuq] " CMD_TARGET_PANE_USAGE,
.target = { 't', CMD_FIND_PANE, 0 }, .target = { 't', CMD_FIND_PANE, 0 },
@ -61,6 +61,11 @@ cmd_copy_mode_exec(struct cmd *self, struct cmdq_item *item)
struct session *s; struct session *s;
struct window_pane *wp = item->target.wp; struct window_pane *wp = item->target.wp;
if (args_has(args, 'q')) {
window_pane_reset_mode_all(wp);
return (CMD_RETURN_NORMAL);
}
if (args_has(args, 'M')) { if (args_has(args, 'M')) {
if ((wp = cmd_mouse_pane(&shared->mouse, &s, NULL)) == NULL) if ((wp = cmd_mouse_pane(&shared->mouse, &s, NULL)) == NULL)
return (CMD_RETURN_NORMAL); return (CMD_RETURN_NORMAL);

7
tmux.1
View File

@ -1590,7 +1590,7 @@ The synopsis for the
command is: command is:
.Bl -tag -width Ds .Bl -tag -width Ds
.It Xo Ic copy-mode .It Xo Ic copy-mode
.Op Fl Meu .Op Fl eHMqu
.Op Fl t Ar target-pane .Op Fl t Ar target-pane
.Xc .Xc
Enter copy mode. Enter copy mode.
@ -1600,6 +1600,11 @@ option scrolls one page up.
.Fl M .Fl M
begins a mouse drag (only valid if bound to a mouse key binding, see begins a mouse drag (only valid if bound to a mouse key binding, see
.Sx MOUSE SUPPORT ) . .Sx MOUSE SUPPORT ) .
.Fl H
hides the position indicator in the top right.
.Fl q
cancels copy mode and any other modes.
.Pp
.Fl e .Fl e
specifies that scrolling to the bottom of the history (to the visible screen) specifies that scrolling to the bottom of the history (to the visible screen)
should exit copy mode. should exit copy mode.

View File

@ -83,9 +83,10 @@ static void window_copy_update_cursor(struct window_mode_entry *, u_int,
static void window_copy_start_selection(struct window_mode_entry *); static void window_copy_start_selection(struct window_mode_entry *);
static int window_copy_adjust_selection(struct window_mode_entry *, static int window_copy_adjust_selection(struct window_mode_entry *,
u_int *, u_int *); u_int *, u_int *);
static int window_copy_set_selection(struct window_mode_entry *, int); static int window_copy_set_selection(struct window_mode_entry *, int, int);
static int window_copy_update_selection(struct window_mode_entry *, int); static int window_copy_update_selection(struct window_mode_entry *, int,
static void window_copy_synchronize_cursor(struct window_mode_entry *); int);
static void window_copy_synchronize_cursor(struct window_mode_entry *, int);
static void *window_copy_get_selection(struct window_mode_entry *, size_t *); static void *window_copy_get_selection(struct window_mode_entry *, size_t *);
static void window_copy_copy_buffer(struct window_mode_entry *, static void window_copy_copy_buffer(struct window_mode_entry *,
const char *, void *, size_t); const char *, void *, size_t);
@ -118,7 +119,7 @@ static void window_copy_cursor_next_word(struct window_mode_entry *,
static void window_copy_cursor_next_word_end_pos(struct window_mode_entry *, static void window_copy_cursor_next_word_end_pos(struct window_mode_entry *,
const char *, u_int *, u_int *); const char *, u_int *, u_int *);
static void window_copy_cursor_next_word_end(struct window_mode_entry *, static void window_copy_cursor_next_word_end(struct window_mode_entry *,
const char *); const char *, int);
static void window_copy_cursor_previous_word_pos(struct window_mode_entry *, static void window_copy_cursor_previous_word_pos(struct window_mode_entry *,
const char *, int, u_int *, u_int *); const char *, int, u_int *, u_int *);
static void window_copy_cursor_previous_word(struct window_mode_entry *, static void window_copy_cursor_previous_word(struct window_mode_entry *,
@ -226,6 +227,7 @@ struct window_copy_mode_data {
} lineflag; /* line selection mode */ } lineflag; /* line selection mode */
int rectflag; /* in rectangle copy mode? */ int rectflag; /* in rectangle copy mode? */
int scroll_exit; /* exit on scroll to end? */ int scroll_exit; /* exit on scroll to end? */
int hide_position; /* hide position marker */
enum { enum {
SEL_CHAR, /* select one char at a time */ SEL_CHAR, /* select one char at a time */
@ -304,6 +306,7 @@ window_copy_common_init(struct window_mode_entry *wme)
data->cursordrag = CURSORDRAG_NONE; data->cursordrag = CURSORDRAG_NONE;
data->lineflag = LINE_SEL_NONE; data->lineflag = LINE_SEL_NONE;
data->selflag = SEL_CHAR;
if (wp->searchstr != NULL) { if (wp->searchstr != NULL) {
data->searchtype = WINDOW_COPY_SEARCHUP; data->searchtype = WINDOW_COPY_SEARCHUP;
@ -348,6 +351,7 @@ window_copy_init(struct window_mode_entry *wme,
data->cy = data->backing->cy; data->cy = data->backing->cy;
data->scroll_exit = args_has(args, 'e'); data->scroll_exit = args_has(args, 'e');
data->hide_position = args_has(args, 'H');
data->screen.cx = data->cx; data->screen.cx = data->cx;
data->screen.cy = data->cy; data->screen.cy = data->cy;
@ -599,10 +603,31 @@ window_copy_next_paragraph(struct window_mode_entry *wme)
window_copy_scroll_to(wme, ox, oy); window_copy_scroll_to(wme, ox, oy);
} }
char *
window_copy_get_word(struct window_pane *wp, u_int x, u_int y)
{
struct window_mode_entry *wme = TAILQ_FIRST(&wp->modes);
struct window_copy_mode_data *data = wme->data;
struct grid *gd = data->screen.grid;
return (format_grid_word(gd, x, gd->hsize + y));
}
char *
window_copy_get_line(struct window_pane *wp, u_int y)
{
struct window_mode_entry *wme = TAILQ_FIRST(&wp->modes);
struct window_copy_mode_data *data = wme->data;
struct grid *gd = data->screen.grid;
return (format_grid_line(gd, gd->hsize + y));
}
static void static void
window_copy_formats(struct window_mode_entry *wme, struct format_tree *ft) window_copy_formats(struct window_mode_entry *wme, struct format_tree *ft)
{ {
struct window_copy_mode_data *data = wme->data; struct window_copy_mode_data *data = wme->data;
struct grid *gd = data->screen.grid;
char *s; char *s;
format_add(ft, "scroll_position", "%d", data->oy); format_add(ft, "scroll_position", "%d", data->oy);
@ -622,13 +647,13 @@ window_copy_formats(struct window_mode_entry *wme, struct format_tree *ft)
} else } else
format_add(ft, "selection_active", "%d", 0); format_add(ft, "selection_active", "%d", 0);
s = format_grid_word(data->screen.grid, data->cx, data->cy); s = format_grid_word(gd, data->cx, gd->hsize + data->cy);
if (s != NULL) { if (s != NULL) {
format_add(ft, "copy_cursor_word", "%s", s); format_add(ft, "copy_cursor_word", "%s", s);
free(s); free(s);
} }
s = format_grid_line(data->screen.grid, data->cy); s = format_grid_line(gd, gd->hsize + data->cy);
if (s != NULL) { if (s != NULL) {
format_add(ft, "copy_cursor_line", "%s", s); format_add(ft, "copy_cursor_line", "%s", s);
free(s); free(s);
@ -751,9 +776,6 @@ window_copy_cmd_begin_selection(struct window_copy_cmd_state *cs)
struct client *c = cs->c; struct client *c = cs->c;
struct mouse_event *m = cs->m; struct mouse_event *m = cs->m;
struct window_copy_mode_data *data = wme->data; struct window_copy_mode_data *data = wme->data;
struct options *oo = cs->s->options;
data->ws = options_get_string(oo, "word-separators");
if (m != NULL) { if (m != NULL) {
window_copy_start_drag(c, m); window_copy_start_drag(c, m);
@ -761,6 +783,7 @@ window_copy_cmd_begin_selection(struct window_copy_cmd_state *cs)
} }
data->lineflag = LINE_SEL_NONE; data->lineflag = LINE_SEL_NONE;
data->selflag = SEL_CHAR;
window_copy_start_selection(wme); window_copy_start_selection(wme);
return (WINDOW_COPY_CMD_REDRAW); return (WINDOW_COPY_CMD_REDRAW);
} }
@ -773,6 +796,7 @@ window_copy_cmd_stop_selection(struct window_copy_cmd_state *cs)
data->cursordrag = CURSORDRAG_NONE; data->cursordrag = CURSORDRAG_NONE;
data->lineflag = LINE_SEL_NONE; data->lineflag = LINE_SEL_NONE;
data->selflag = SEL_CHAR;
return (WINDOW_COPY_CMD_NOTHING); return (WINDOW_COPY_CMD_NOTHING);
} }
@ -785,7 +809,7 @@ window_copy_cmd_bottom_line(struct window_copy_cmd_state *cs)
data->cx = 0; data->cx = 0;
data->cy = screen_size_y(&data->screen) - 1; data->cy = screen_size_y(&data->screen) - 1;
window_copy_update_selection(wme, 1); window_copy_update_selection(wme, 1, 0);
return (WINDOW_COPY_CMD_REDRAW); return (WINDOW_COPY_CMD_REDRAW);
} }
@ -842,12 +866,14 @@ window_copy_cmd_copy_line(struct window_copy_cmd_state *cs)
struct session *s = cs->s; struct session *s = cs->s;
struct winlink *wl = cs->wl; struct winlink *wl = cs->wl;
struct window_pane *wp = wme->wp; struct window_pane *wp = wme->wp;
struct window_copy_mode_data *data = wme->data;
u_int np = wme->prefix; u_int np = wme->prefix;
char *prefix = NULL; char *prefix = NULL;
if (cs->args->argc == 2) if (cs->args->argc == 2)
prefix = format_single(NULL, cs->args->argv[1], c, s, wl, wp); prefix = format_single(NULL, cs->args->argv[1], c, s, wl, wp);
data->selflag = SEL_CHAR;
window_copy_cursor_start_of_line(wme); window_copy_cursor_start_of_line(wme);
window_copy_start_selection(wme); window_copy_start_selection(wme);
for (; np > 1; np--) for (; np > 1; np--)
@ -1119,7 +1145,7 @@ window_copy_cmd_middle_line(struct window_copy_cmd_state *cs)
data->cx = 0; data->cx = 0;
data->cy = (screen_size_y(&data->screen) - 1) / 2; data->cy = (screen_size_y(&data->screen) - 1) / 2;
window_copy_update_selection(wme, 1); window_copy_update_selection(wme, 1, 0);
return (WINDOW_COPY_CMD_REDRAW); return (WINDOW_COPY_CMD_REDRAW);
} }
@ -1276,7 +1302,8 @@ window_copy_cmd_next_matching_bracket(struct window_copy_cmd_state *cs)
tried = 1; tried = 1;
goto retry; goto retry;
} }
window_copy_cursor_next_word_end(wme, "{[( "); window_copy_cursor_next_word_end(wme, "{[( ",
0);
continue; continue;
} }
/* For vi, continue searching for bracket until EOL. */ /* For vi, continue searching for bracket until EOL. */
@ -1359,7 +1386,7 @@ window_copy_cmd_next_space_end(struct window_copy_cmd_state *cs)
u_int np = wme->prefix; u_int np = wme->prefix;
for (; np != 0; np--) for (; np != 0; np--)
window_copy_cursor_next_word_end(wme, " "); window_copy_cursor_next_word_end(wme, " ", 0);
return (WINDOW_COPY_CMD_NOTHING); return (WINDOW_COPY_CMD_NOTHING);
} }
@ -1387,7 +1414,7 @@ window_copy_cmd_next_word_end(struct window_copy_cmd_state *cs)
ws = options_get_string(s->options, "word-separators"); ws = options_get_string(s->options, "word-separators");
for (; np != 0; np--) for (; np != 0; np--)
window_copy_cursor_next_word_end(wme, ws); window_copy_cursor_next_word_end(wme, ws, 0);
return (WINDOW_COPY_CMD_NOTHING); return (WINDOW_COPY_CMD_NOTHING);
} }
@ -1396,7 +1423,9 @@ window_copy_cmd_other_end(struct window_copy_cmd_state *cs)
{ {
struct window_mode_entry *wme = cs->wme; struct window_mode_entry *wme = cs->wme;
u_int np = wme->prefix; u_int np = wme->prefix;
struct window_copy_mode_data *data = wme->data;
data->selflag = SEL_CHAR;
if ((np % 2) != 0) if ((np % 2) != 0)
window_copy_other_end(wme); window_copy_other_end(wme);
return (WINDOW_COPY_CMD_NOTHING); return (WINDOW_COPY_CMD_NOTHING);
@ -1577,12 +1606,12 @@ window_copy_cmd_select_line(struct window_copy_cmd_state *cs)
window_copy_cursor_start_of_line(wme); window_copy_cursor_start_of_line(wme);
data->selrx = data->cx; data->selrx = data->cx;
data->selry = screen_hsize(data->backing) + data->cy - data->oy; data->selry = screen_hsize(data->backing) + data->cy - data->oy;
data->endselrx = window_copy_find_length(wme, data->selry);
data->endselry = data->selry;
window_copy_start_selection(wme); window_copy_start_selection(wme);
for (; np > 1; np--) for (; np > 1; np--)
window_copy_cursor_down(wme, 0); window_copy_cursor_down(wme, 0);
window_copy_cursor_end_of_line(wme); window_copy_cursor_end_of_line(wme);
data->endselrx = data->cx;
data->endselry = screen_hsize(data->backing) + data->cy - data->oy;
return (WINDOW_COPY_CMD_REDRAW); return (WINDOW_COPY_CMD_REDRAW);
} }
@ -1593,7 +1622,6 @@ window_copy_cmd_select_word(struct window_copy_cmd_state *cs)
struct window_mode_entry *wme = cs->wme; struct window_mode_entry *wme = cs->wme;
struct session *s = cs->s; struct session *s = cs->s;
struct window_copy_mode_data *data = wme->data; struct window_copy_mode_data *data = wme->data;
const char *ws;
u_int px, py; u_int px, py;
data->lineflag = LINE_SEL_LEFT_RIGHT; data->lineflag = LINE_SEL_LEFT_RIGHT;
@ -1602,25 +1630,26 @@ window_copy_cmd_select_word(struct window_copy_cmd_state *cs)
data->dx = data->cx; data->dx = data->cx;
data->dy = screen_hsize(data->backing) + data->cy - data->oy; data->dy = screen_hsize(data->backing) + data->cy - data->oy;
data->ws = options_get_string(s->options, "word-separators");
window_copy_cursor_previous_word(wme, data->ws, 0);
px = data->cx; px = data->cx;
py = screen_hsize(data->backing) + data->cy - data->oy; py = screen_hsize(data->backing) + data->cy - data->oy;
data->selrx = px;
ws = options_get_string(s->options, "word-separators"); data->selry = py;
window_copy_cursor_previous_word(wme, ws, 0);
data->selrx = data->cx;
data->selry = screen_hsize(data->backing) + data->cy - data->oy;
window_copy_start_selection(wme); window_copy_start_selection(wme);
if (px >= window_copy_find_length(wme, py) || if (px >= window_copy_find_length(wme, py) ||
!window_copy_in_set(wme, px + 1, py, ws)) !window_copy_in_set(wme, px + 1, py, data->ws))
window_copy_cursor_next_word_end(wme, ws); window_copy_cursor_next_word_end(wme, data->ws, 1);
else { else {
window_copy_update_cursor(wme, px, data->cy); window_copy_update_cursor(wme, px, data->cy);
if (window_copy_update_selection(wme, 1)) if (window_copy_update_selection(wme, 1, 1))
window_copy_redraw_lines(wme, data->cy, 1); window_copy_redraw_lines(wme, data->cy, 1);
} }
data->endselrx = data->cx; data->endselrx = data->cx;
data->endselry = screen_hsize(data->backing) + data->cy - data->oy; data->endselry = screen_hsize(data->backing) + data->cy - data->oy;
if (data->dx > data->endselrx)
data->dx = data->endselrx;
return (WINDOW_COPY_CMD_REDRAW); return (WINDOW_COPY_CMD_REDRAW);
} }
@ -1643,7 +1672,7 @@ window_copy_cmd_top_line(struct window_copy_cmd_state *cs)
data->cx = 0; data->cx = 0;
data->cy = 0; data->cy = 0;
window_copy_update_selection(wme, 1); window_copy_update_selection(wme, 1, 0);
return (WINDOW_COPY_CMD_REDRAW); return (WINDOW_COPY_CMD_REDRAW);
} }
@ -2888,7 +2917,7 @@ window_copy_goto_line(struct window_mode_entry *wme, const char *linestr)
lineno = screen_hsize(data->backing); lineno = screen_hsize(data->backing);
data->oy = lineno; data->oy = lineno;
window_copy_update_selection(wme, 1); window_copy_update_selection(wme, 1, 0);
window_copy_redraw_screen(wme); window_copy_redraw_screen(wme);
} }
@ -2907,7 +2936,7 @@ window_copy_write_line(struct window_mode_entry *wme,
style_apply(&gc, oo, "mode-style"); style_apply(&gc, oo, "mode-style");
gc.flags |= GRID_FLAG_NOPALETTE; gc.flags |= GRID_FLAG_NOPALETTE;
if (py == 0 && s->rupper < s->rlower) { if (py == 0 && s->rupper < s->rlower && !data->hide_position) {
if (data->searchmark == NULL) { if (data->searchmark == NULL) {
if (data->timeout) { if (data->timeout) {
size = xsnprintf(hdr, sizeof hdr, size = xsnprintf(hdr, sizeof hdr,
@ -3013,18 +3042,19 @@ window_copy_redraw_screen(struct window_mode_entry *wme)
} }
static void static void
window_copy_synchronize_cursor_end(struct window_mode_entry *wme) window_copy_synchronize_cursor_end(struct window_mode_entry *wme, int begin,
int no_reset)
{ {
struct window_copy_mode_data *data = wme->data; struct window_copy_mode_data *data = wme->data;
u_int xx, yy; u_int xx, yy;
int begin = 0;
yy = screen_hsize(data->backing) + data->cy - data->oy; yy = screen_hsize(data->backing) + data->cy - data->oy;
switch (data->selflag) { switch (data->selflag) {
case SEL_WORD: case SEL_WORD:
xx = data->cx; xx = data->cx;
if (data->ws == NULL) if (no_reset)
break; break;
begin = 0;
if (data->dy > yy || (data->dy == yy && data->dx > xx)) { if (data->dy > yy || (data->dy == yy && data->dx > xx)) {
/* Right to left selection. */ /* Right to left selection. */
window_copy_cursor_previous_word_pos(wme, data->ws, 0, window_copy_cursor_previous_word_pos(wme, data->ws, 0,
@ -3047,6 +3077,11 @@ window_copy_synchronize_cursor_end(struct window_mode_entry *wme)
} }
break; break;
case SEL_LINE: case SEL_LINE:
if (no_reset) {
xx = data->cx;
break;
}
begin = 0;
if (data->dy > yy) { if (data->dy > yy) {
/* Right to left selection. */ /* Right to left selection. */
xx = 0; xx = 0;
@ -3078,17 +3113,16 @@ window_copy_synchronize_cursor_end(struct window_mode_entry *wme)
} }
static void static void
window_copy_synchronize_cursor(struct window_mode_entry *wme) window_copy_synchronize_cursor(struct window_mode_entry *wme, int no_reset)
{ {
struct window_copy_mode_data *data = wme->data; struct window_copy_mode_data *data = wme->data;
switch (data->cursordrag) { switch (data->cursordrag) {
case CURSORDRAG_ENDSEL: case CURSORDRAG_ENDSEL:
window_copy_synchronize_cursor_end(wme); window_copy_synchronize_cursor_end(wme, 0, no_reset);
break; break;
case CURSORDRAG_SEL: case CURSORDRAG_SEL:
data->selx = data->cx; window_copy_synchronize_cursor_end(wme, 1, no_reset);
data->sely = screen_hsize(data->backing) + data->cy - data->oy;
break; break;
case CURSORDRAG_NONE: case CURSORDRAG_NONE:
break; break;
@ -3130,7 +3164,7 @@ window_copy_start_selection(struct window_mode_entry *wme)
data->cursordrag = CURSORDRAG_ENDSEL; data->cursordrag = CURSORDRAG_ENDSEL;
window_copy_set_selection(wme, 1); window_copy_set_selection(wme, 1, 0);
} }
static int static int
@ -3167,18 +3201,20 @@ window_copy_adjust_selection(struct window_mode_entry *wme, u_int *selx,
} }
static int static int
window_copy_update_selection(struct window_mode_entry *wme, int may_redraw) window_copy_update_selection(struct window_mode_entry *wme, int may_redraw,
int no_reset)
{ {
struct window_copy_mode_data *data = wme->data; struct window_copy_mode_data *data = wme->data;
struct screen *s = &data->screen; struct screen *s = &data->screen;
if (s->sel == NULL && data->lineflag == LINE_SEL_NONE) if (s->sel == NULL && data->lineflag == LINE_SEL_NONE)
return (0); return (0);
return (window_copy_set_selection(wme, may_redraw)); return (window_copy_set_selection(wme, may_redraw, no_reset));
} }
static int static int
window_copy_set_selection(struct window_mode_entry *wme, int may_redraw) window_copy_set_selection(struct window_mode_entry *wme, int may_redraw,
int no_reset)
{ {
struct window_pane *wp = wme->wp; struct window_pane *wp = wme->wp;
struct window_copy_mode_data *data = wme->data; struct window_copy_mode_data *data = wme->data;
@ -3188,7 +3224,7 @@ window_copy_set_selection(struct window_mode_entry *wme, int may_redraw)
u_int sx, sy, cy, endsx, endsy; u_int sx, sy, cy, endsx, endsy;
int startrelpos, endrelpos; int startrelpos, endrelpos;
window_copy_synchronize_cursor(wme); window_copy_synchronize_cursor(wme, no_reset);
/* Adjust the selection. */ /* Adjust the selection. */
sx = data->selx; sx = data->selx;
@ -3369,7 +3405,7 @@ window_copy_copy_buffer(struct window_mode_entry *wme, const char *prefix,
static void static void
window_copy_copy_pipe(struct window_mode_entry *wme, struct session *s, window_copy_copy_pipe(struct window_mode_entry *wme, struct session *s,
const char *prefix, const char *command) const char *prefix, const char *cmd)
{ {
void *buf; void *buf;
size_t len; size_t len;
@ -3379,7 +3415,7 @@ window_copy_copy_pipe(struct window_mode_entry *wme, struct session *s,
if (buf == NULL) if (buf == NULL)
return; return;
job = job_run(command, s, NULL, NULL, NULL, NULL, NULL, JOB_NOWAIT); job = job_run(cmd, s, NULL, NULL, NULL, NULL, NULL, JOB_NOWAIT, -1, -1);
bufferevent_write(job_get_event(job), buf, len); bufferevent_write(job_get_event(job), buf, len);
window_copy_copy_buffer(wme, prefix, buf, len); window_copy_copy_buffer(wme, prefix, buf, len);
} }
@ -3498,6 +3534,7 @@ window_copy_clear_selection(struct window_mode_entry *wme)
data->cursordrag = CURSORDRAG_NONE; data->cursordrag = CURSORDRAG_NONE;
data->lineflag = LINE_SEL_NONE; data->lineflag = LINE_SEL_NONE;
data->selflag = SEL_CHAR;
py = screen_hsize(data->backing) + data->cy - data->oy; py = screen_hsize(data->backing) + data->cy - data->oy;
px = window_copy_find_length(wme, py); px = window_copy_find_length(wme, py);
@ -3543,7 +3580,7 @@ window_copy_cursor_start_of_line(struct window_mode_entry *wme)
} }
} }
window_copy_update_cursor(wme, 0, data->cy); window_copy_update_cursor(wme, 0, data->cy);
if (window_copy_update_selection(wme, 1)) if (window_copy_update_selection(wme, 1, 0))
window_copy_redraw_lines(wme, data->cy, 1); window_copy_redraw_lines(wme, data->cy, 1);
} }
@ -3566,7 +3603,7 @@ window_copy_cursor_back_to_indentation(struct window_mode_entry *wme)
} }
window_copy_update_cursor(wme, px, data->cy); window_copy_update_cursor(wme, px, data->cy);
if (window_copy_update_selection(wme, 1)) if (window_copy_update_selection(wme, 1, 0))
window_copy_redraw_lines(wme, data->cy, 1); window_copy_redraw_lines(wme, data->cy, 1);
} }
@ -3599,7 +3636,7 @@ window_copy_cursor_end_of_line(struct window_mode_entry *wme)
} }
window_copy_update_cursor(wme, px, data->cy); window_copy_update_cursor(wme, px, data->cy);
if (window_copy_update_selection(wme, 1)) if (window_copy_update_selection(wme, 1, 0))
window_copy_redraw_lines(wme, data->cy, 1); window_copy_redraw_lines(wme, data->cy, 1);
} }
@ -3650,7 +3687,7 @@ window_copy_other_end(struct window_mode_entry *wme)
} else } else
data->cy = cy + sely - yy; data->cy = cy + sely - yy;
window_copy_update_selection(wme, 1); window_copy_update_selection(wme, 1, 1);
window_copy_redraw_screen(wme); window_copy_redraw_screen(wme);
} }
@ -3674,7 +3711,7 @@ window_copy_cursor_left(struct window_mode_entry *wme)
window_copy_cursor_end_of_line(wme); window_copy_cursor_end_of_line(wme);
} else if (cx > 0) { } else if (cx > 0) {
window_copy_update_cursor(wme, cx - 1, data->cy); window_copy_update_cursor(wme, cx - 1, data->cy);
if (window_copy_update_selection(wme, 1)) if (window_copy_update_selection(wme, 1, 0))
window_copy_redraw_lines(wme, data->cy, 1); window_copy_redraw_lines(wme, data->cy, 1);
} }
} }
@ -3706,7 +3743,7 @@ window_copy_cursor_right(struct window_mode_entry *wme)
cx++; cx++;
} }
window_copy_update_cursor(wme, cx, data->cy); window_copy_update_cursor(wme, cx, data->cy);
if (window_copy_update_selection(wme, 1)) if (window_copy_update_selection(wme, 1, 0))
window_copy_redraw_lines(wme, data->cy, 1); window_copy_redraw_lines(wme, data->cy, 1);
} }
} }
@ -3739,7 +3776,7 @@ window_copy_cursor_up(struct window_mode_entry *wme, int scroll_only)
} }
} else { } else {
window_copy_update_cursor(wme, data->lastcx, data->cy - 1); window_copy_update_cursor(wme, data->lastcx, data->cy - 1);
if (window_copy_update_selection(wme, 1)) { if (window_copy_update_selection(wme, 1, 0)) {
if (data->cy == screen_size_y(s) - 1) if (data->cy == screen_size_y(s) - 1)
window_copy_redraw_lines(wme, data->cy, 1); window_copy_redraw_lines(wme, data->cy, 1);
else else
@ -3785,7 +3822,7 @@ window_copy_cursor_down(struct window_mode_entry *wme, int scroll_only)
window_copy_redraw_lines(wme, data->cy - 1, 2); window_copy_redraw_lines(wme, data->cy - 1, 2);
} else { } else {
window_copy_update_cursor(wme, data->lastcx, data->cy + 1); window_copy_update_cursor(wme, data->lastcx, data->cy + 1);
if (window_copy_update_selection(wme, 1)) if (window_copy_update_selection(wme, 1, 0))
window_copy_redraw_lines(wme, data->cy - 1, 2); window_copy_redraw_lines(wme, data->cy - 1, 2);
} }
@ -3820,7 +3857,7 @@ window_copy_cursor_jump(struct window_mode_entry *wme)
if (!(gc.flags & GRID_FLAG_PADDING) && if (!(gc.flags & GRID_FLAG_PADDING) &&
gc.data.size == 1 && *gc.data.data == data->jumpchar) { gc.data.size == 1 && *gc.data.data == data->jumpchar) {
window_copy_update_cursor(wme, px, data->cy); window_copy_update_cursor(wme, px, data->cy);
if (window_copy_update_selection(wme, 1)) if (window_copy_update_selection(wme, 1, 0))
window_copy_redraw_lines(wme, data->cy, 1); window_copy_redraw_lines(wme, data->cy, 1);
return; return;
} }
@ -3847,7 +3884,7 @@ window_copy_cursor_jump_back(struct window_mode_entry *wme)
if (!(gc.flags & GRID_FLAG_PADDING) && if (!(gc.flags & GRID_FLAG_PADDING) &&
gc.data.size == 1 && *gc.data.data == data->jumpchar) { gc.data.size == 1 && *gc.data.data == data->jumpchar) {
window_copy_update_cursor(wme, px, data->cy); window_copy_update_cursor(wme, px, data->cy);
if (window_copy_update_selection(wme, 1)) if (window_copy_update_selection(wme, 1, 0))
window_copy_redraw_lines(wme, data->cy, 1); window_copy_redraw_lines(wme, data->cy, 1);
return; return;
} }
@ -3874,7 +3911,7 @@ window_copy_cursor_jump_to(struct window_mode_entry *wme)
if (!(gc.flags & GRID_FLAG_PADDING) && if (!(gc.flags & GRID_FLAG_PADDING) &&
gc.data.size == 1 && *gc.data.data == data->jumpchar) { gc.data.size == 1 && *gc.data.data == data->jumpchar) {
window_copy_update_cursor(wme, px - 1, data->cy); window_copy_update_cursor(wme, px - 1, data->cy);
if (window_copy_update_selection(wme, 1)) if (window_copy_update_selection(wme, 1, 0))
window_copy_redraw_lines(wme, data->cy, 1); window_copy_redraw_lines(wme, data->cy, 1);
return; return;
} }
@ -3904,7 +3941,7 @@ window_copy_cursor_jump_to_back(struct window_mode_entry *wme)
if (!(gc.flags & GRID_FLAG_PADDING) && if (!(gc.flags & GRID_FLAG_PADDING) &&
gc.data.size == 1 && *gc.data.data == data->jumpchar) { gc.data.size == 1 && *gc.data.data == data->jumpchar) {
window_copy_update_cursor(wme, px + 1, data->cy); window_copy_update_cursor(wme, px + 1, data->cy);
if (window_copy_update_selection(wme, 1)) if (window_copy_update_selection(wme, 1, 0))
window_copy_redraw_lines(wme, data->cy, 1); window_copy_redraw_lines(wme, data->cy, 1);
return; return;
} }
@ -3953,7 +3990,7 @@ window_copy_cursor_next_word(struct window_mode_entry *wme,
} while (expected == 1); } while (expected == 1);
window_copy_update_cursor(wme, px, data->cy); window_copy_update_cursor(wme, px, data->cy);
if (window_copy_update_selection(wme, 1)) if (window_copy_update_selection(wme, 1, 0))
window_copy_redraw_lines(wme, data->cy, 1); window_copy_redraw_lines(wme, data->cy, 1);
} }
@ -4008,7 +4045,7 @@ window_copy_cursor_next_word_end_pos(struct window_mode_entry *wme,
static void static void
window_copy_cursor_next_word_end(struct window_mode_entry *wme, window_copy_cursor_next_word_end(struct window_mode_entry *wme,
const char *separators) const char *separators, int no_reset)
{ {
struct window_pane *wp = wme->wp; struct window_pane *wp = wme->wp;
struct window_copy_mode_data *data = wme->data; struct window_copy_mode_data *data = wme->data;
@ -4054,7 +4091,7 @@ window_copy_cursor_next_word_end(struct window_mode_entry *wme,
px--; px--;
window_copy_update_cursor(wme, px, data->cy); window_copy_update_cursor(wme, px, data->cy);
if (window_copy_update_selection(wme, 1)) if (window_copy_update_selection(wme, 1, no_reset))
window_copy_redraw_lines(wme, data->cy, 1); window_copy_redraw_lines(wme, data->cy, 1);
} }
@ -4151,7 +4188,7 @@ window_copy_cursor_previous_word(struct window_mode_entry *wme,
out: out:
window_copy_update_cursor(wme, px, data->cy); window_copy_update_cursor(wme, px, data->cy);
if (window_copy_update_selection(wme, 1)) if (window_copy_update_selection(wme, 1, 0))
window_copy_redraw_lines(wme, data->cy, 1); window_copy_redraw_lines(wme, data->cy, 1);
} }
@ -4234,7 +4271,7 @@ window_copy_rectangle_toggle(struct window_mode_entry *wme)
if (data->cx > px) if (data->cx > px)
window_copy_update_cursor(wme, px, data->cy); window_copy_update_cursor(wme, px, data->cy);
window_copy_update_selection(wme, 1); window_copy_update_selection(wme, 1, 0);
window_copy_redraw_screen(wme); window_copy_redraw_screen(wme);
} }
@ -4266,7 +4303,7 @@ window_copy_start_drag(struct client *c, struct mouse_event *m)
struct window_pane *wp; struct window_pane *wp;
struct window_mode_entry *wme; struct window_mode_entry *wme;
struct window_copy_mode_data *data; struct window_copy_mode_data *data;
u_int x, y; u_int x, y, yg;
if (c == NULL) if (c == NULL)
return; return;
@ -4287,6 +4324,9 @@ window_copy_start_drag(struct client *c, struct mouse_event *m)
c->tty.mouse_drag_release = window_copy_drag_release; c->tty.mouse_drag_release = window_copy_drag_release;
data = wme->data; data = wme->data;
yg = screen_hsize(data->backing) + y - data->oy;
if (x < data->selrx || x > data->endselrx || yg != data->selry)
data->selflag = SEL_CHAR;
switch (data->selflag) { switch (data->selflag) {
case SEL_WORD: case SEL_WORD:
if (data->ws) { if (data->ws) {
@ -4342,7 +4382,7 @@ window_copy_drag_update(struct client *c, struct mouse_event *m)
old_cy = data->cy; old_cy = data->cy;
window_copy_update_cursor(wme, x, y); window_copy_update_cursor(wme, x, y);
if (window_copy_update_selection(wme, 1)) if (window_copy_update_selection(wme, 1, 0))
window_copy_redraw_selection(wme, old_cy); window_copy_redraw_selection(wme, old_cy);
if (old_cy != data->cy || old_cx == data->cx) { if (old_cy != data->cy || old_cx == data->cx) {
if (y == 0) { if (y == 0) {