From 938ad5a98c2a37938ea726a910e640a2a8aa8d26 Mon Sep 17 00:00:00 2001 From: nicm Date: Fri, 3 Apr 2020 13:54:31 +0000 Subject: [PATCH 1/8] Use new window and new pane as well for -P to new-session or new-window. --- cmd-new-session.c | 2 +- cmd-new-window.c | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/cmd-new-session.c b/cmd-new-session.c index c76b564e..a75fc972 100644 --- a/cmd-new-session.c +++ b/cmd-new-session.c @@ -334,7 +334,7 @@ cmd_new_session_exec(struct cmd *self, struct cmdq_item *item) if (args_has(args, 'P')) { if ((template = args_get(args, 'F')) == NULL) template = NEW_SESSION_TEMPLATE; - cp = format_single(item, template, c, s, NULL, NULL); + cp = format_single(item, template, c, s, s->curw, NULL); cmdq_print(item, "%s", cp); free(cp); } diff --git a/cmd-new-window.c b/cmd-new-window.c index 9a1025e9..2fb92830 100644 --- a/cmd-new-window.c +++ b/cmd-new-window.c @@ -108,7 +108,8 @@ cmd_new_window_exec(struct cmd *self, struct cmdq_item *item) if (args_has(args, 'P')) { if ((template = args_get(args, 'F')) == NULL) template = NEW_WINDOW_TEMPLATE; - cp = format_single(item, template, c, s, new_wl, NULL); + cp = format_single(item, template, c, s, new_wl, + new_wl->window->active); cmdq_print(item, "%s", cp); free(cp); } From 32340172603f03e55fe21071ede93652e560b29a Mon Sep 17 00:00:00 2001 From: nicm Date: Sun, 5 Apr 2020 08:40:31 +0000 Subject: [PATCH 2/8] Add an argument to list-commands to show only a single command. --- cmd-list-keys.c | 14 +++++++++++--- tmux.1 | 7 +++++-- 2 files changed, 16 insertions(+), 5 deletions(-) diff --git a/cmd-list-keys.c b/cmd-list-keys.c index 34ed43bf..7e340516 100644 --- a/cmd-list-keys.c +++ b/cmd-list-keys.c @@ -47,8 +47,8 @@ const struct cmd_entry cmd_list_commands_entry = { .name = "list-commands", .alias = "lscm", - .args = { "F:", 0, 0 }, - .usage = "[-F format]", + .args = { "F:", 0, 1 }, + .usage = "[-F format] [command]", .flags = CMD_STARTSERVER|CMD_AFTERHOOK, .exec = cmd_list_keys_exec @@ -317,9 +317,12 @@ cmd_list_keys_commands(struct cmd *self, struct cmdq_item *item) const struct cmd_entry **entryp; const struct cmd_entry *entry; struct format_tree *ft; - const char *template, *s; + const char *template, *s, *command = NULL; char *line; + if (args->argc != 0) + command = args->argv[0]; + if ((template = args_get(args, 'F')) == NULL) { template = "#{command_list_name}" "#{?command_list_alias, (#{command_list_alias}),} " @@ -331,6 +334,11 @@ cmd_list_keys_commands(struct cmd *self, struct cmdq_item *item) for (entryp = cmd_table; *entryp != NULL; entryp++) { entry = *entryp; + if (command != NULL && + (strcmp(entry->name, command) != 0 && + (entry->alias == NULL || + strcmp(entry->alias, command) != 0))) + continue; format_add(ft, "command_list_name", "%s", entry->name); if (entry->alias != NULL) diff --git a/tmux.1 b/tmux.1 index 03950c60..c7b40c16 100644 --- a/tmux.1 +++ b/tmux.1 @@ -1036,9 +1036,12 @@ If is specified, list only clients connected to that session. .It Xo Ic list-commands .Op Fl F Ar format +.Op Ar command .Xc .D1 (alias: Ic lscm ) -List the syntax of all commands supported by +List the syntax of +.Ar command +or - if omitted - of all commands supported by .Nm . .It Ic list-sessions Op Fl F Ar format .D1 (alias: Ic ls ) @@ -2710,7 +2713,7 @@ command. .It Xo Ic list-keys .Op Fl 1aN .Op Fl P Ar prefix-string Fl T Ar key-table -.Op key +.Op Ar key .Xc .D1 (alias: Ic lsk ) List key bindings. From ac050b2583685d105f3dfe8ae7161925f30e889e Mon Sep 17 00:00:00 2001 From: nicm Date: Fri, 3 Apr 2020 12:59:22 +0000 Subject: [PATCH 3/8] Stop logging the entire command queue every time we add something, spotted by tb & sthen. --- cmd-queue.c | 8 -------- 1 file changed, 8 deletions(-) diff --git a/cmd-queue.c b/cmd-queue.c index 59c7a35c..a9e1dd3a 100644 --- a/cmd-queue.c +++ b/cmd-queue.c @@ -59,10 +59,6 @@ cmdq_append(struct client *c, struct cmdq_item *item) struct cmdq_list *queue = cmdq_get(c); struct cmdq_item *next; - TAILQ_FOREACH(next, queue, entry) { - log_debug("%s %s: queue %s (%u)", __func__, cmdq_name(c), - next->name, next->group); - } do { next = item->next; item->next = NULL; @@ -88,10 +84,6 @@ cmdq_insert_after(struct cmdq_item *after, struct cmdq_item *item) struct cmdq_list *queue = after->queue; struct cmdq_item *next; - TAILQ_FOREACH(next, queue, entry) { - log_debug("%s %s: queue %s (%u)", __func__, cmdq_name(c), - next->name, next->group); - } do { next = item->next; item->next = after->next; From 8d2af4fb547edf55ffb34c8cf1c6ab0d179fd074 Mon Sep 17 00:00:00 2001 From: nicm Date: Wed, 1 Apr 2020 09:36:37 +0000 Subject: [PATCH 4/8] Add a 10 second timeout to prevent searches taking too much time, from Anindya Mukherjee. --- window-copy.c | 44 +++++++++++++++++++++++++++++++++++++++----- 1 file changed, 39 insertions(+), 5 deletions(-) diff --git a/window-copy.c b/window-copy.c index 8cf499ca..8f33914a 100644 --- a/window-copy.c +++ b/window-copy.c @@ -259,6 +259,9 @@ struct window_copy_mode_data { int searchy; int searcho; + int timeout; /* search has timed out */ +#define WINDOW_COPY_SEARCH_TIMEOUT 10 + int jumptype; char jumpchar; @@ -313,6 +316,7 @@ window_copy_common_init(struct window_mode_entry *wme) } data->searchmark = NULL; data->searchx = data->searchy = data->searcho = -1; + data->timeout = 0; data->jumptype = WINDOW_COPY_OFF; data->jumpchar = '\0'; @@ -655,8 +659,8 @@ window_copy_resize(struct window_mode_entry *wme, u_int sx, u_int sy) window_copy_write_lines(wme, &ctx, 0, screen_size_y(s) - 1); screen_write_stop(&ctx); - if (search) - window_copy_search_marks(wme, NULL, 1); + if (search && !data->timeout) + window_copy_search_marks(wme, NULL, data->searchregex); data->searchx = data->cx; data->searchy = data->cy; data->searcho = data->oy; @@ -1771,6 +1775,7 @@ window_copy_cmd_search_backward(struct window_copy_cmd_state *cs) if (data->searchstr != NULL) { data->searchtype = WINDOW_COPY_SEARCHUP; data->searchregex = 1; + data->timeout = 0; for (; np != 0; np--) window_copy_search_up(wme, 1); } @@ -1790,6 +1795,7 @@ window_copy_cmd_search_backward_text(struct window_copy_cmd_state *cs) if (data->searchstr != NULL) { data->searchtype = WINDOW_COPY_SEARCHUP; data->searchregex = 0; + data->timeout = 0; for (; np != 0; np--) window_copy_search_up(wme, 0); } @@ -1809,6 +1815,7 @@ window_copy_cmd_search_forward(struct window_copy_cmd_state *cs) if (data->searchstr != NULL) { data->searchtype = WINDOW_COPY_SEARCHDOWN; data->searchregex = 1; + data->timeout = 0; for (; np != 0; np--) window_copy_search_down(wme, 1); } @@ -1828,6 +1835,7 @@ window_copy_cmd_search_forward_text(struct window_copy_cmd_state *cs) if (data->searchstr != NULL) { data->searchtype = WINDOW_COPY_SEARCHDOWN; data->searchregex = 0; + data->timeout = 0; for (; np != 0; np--) window_copy_search_down(wme, 0); } @@ -1844,6 +1852,8 @@ window_copy_cmd_search_backward_incremental(struct window_copy_cmd_state *cs) char prefix; enum window_copy_cmd_action action = WINDOW_COPY_CMD_NOTHING; + data->timeout = 0; + prefix = *argument++; if (data->searchx == -1 || data->searchy == -1) { data->searchx = data->cx; @@ -1895,6 +1905,8 @@ window_copy_cmd_search_forward_incremental(struct window_copy_cmd_state *cs) char prefix; enum window_copy_cmd_action action = WINDOW_COPY_CMD_NOTHING; + data->timeout = 0; + prefix = *argument++; if (data->searchx == -1 || data->searchy == -1) { data->searchx = data->cx; @@ -2692,6 +2704,9 @@ window_copy_search(struct window_mode_entry *wme, int direction, int regex) if (regex && str[strcspn(str, "^$*+()?[].\\")] == '\0') regex = 0; + if (data->timeout) + return (0); + free(wp->searchstr); wp->searchstr = xstrdup(str); wp->searchregex = regex; @@ -2739,6 +2754,7 @@ window_copy_search_marks(struct window_mode_entry *wme, struct screen *ssp, u_int ssize = 1; char *sbuf; regex_t reg; + time_t tstart, t; if (ssp == NULL) { width = screen_write_strlen("%s", data->searchstr); @@ -2768,6 +2784,7 @@ window_copy_search_marks(struct window_mode_entry *wme, struct screen *ssp, return (0); } } + time(&tstart); for (py = 0; py < gd->hsize + gd->sy; py++) { px = 0; for (;;) { @@ -2793,11 +2810,21 @@ window_copy_search_marks(struct window_mode_entry *wme, struct screen *ssp, px++; } + + time(&t); + if (t - tstart > WINDOW_COPY_SEARCH_TIMEOUT) { + data->timeout = 1; + break; + } } if (regex) { free(sbuf); regfree(®); } + if (data->timeout) { + window_copy_clear_marks(wme); + return (1); + } if (which != -1) data->searchthis = 1 + nfound - which; @@ -2807,7 +2834,7 @@ window_copy_search_marks(struct window_mode_entry *wme, struct screen *ssp, if (ssp == &ss) screen_free(&ss); - return (nfound); + return (1); } static void @@ -2866,8 +2893,15 @@ window_copy_write_line(struct window_mode_entry *wme, if (py == 0 && s->rupper < s->rlower) { if (data->searchmark == NULL) { - size = xsnprintf(hdr, sizeof hdr, - "[%u/%u]", data->oy, screen_hsize(data->backing)); + if (data->timeout) { + size = xsnprintf(hdr, sizeof hdr, + "(timed out) [%u/%u]", data->oy, + screen_hsize(data->backing)); + } else { + size = xsnprintf(hdr, sizeof hdr, + "[%u/%u]", data->oy, + screen_hsize(data->backing)); + } } else { if (data->searchthis == -1) { size = xsnprintf(hdr, sizeof hdr, From 10975961de95ef3ef7066d6d6cc97ba207b88e6f Mon Sep 17 00:00:00 2001 From: nicm Date: Thu, 2 Apr 2020 17:03:10 +0000 Subject: [PATCH 5/8] Only search the visible part of the history when marking (highlighting) search terms, much faster than searching the whole history. --- window-copy.c | 39 +++++++++++++++++++++++++++++++-------- 1 file changed, 31 insertions(+), 8 deletions(-) diff --git a/window-copy.c b/window-copy.c index 8f33914a..cbf63cc7 100644 --- a/window-copy.c +++ b/window-copy.c @@ -505,7 +505,9 @@ window_copy_pageup1(struct window_mode_entry *wme, int half_page) window_copy_cursor_end_of_line(wme); } - window_copy_update_selection(wme, 1); + if (data->searchmark != NULL && !data->timeout) + window_copy_search_marks(wme, NULL, data->searchregex); + window_copy_update_selection(wme, 1, 0); window_copy_redraw_screen(wme); } @@ -553,7 +555,9 @@ window_copy_pagedown(struct window_mode_entry *wme, int half_page, if (scroll_exit && data->oy == 0) return (1); - window_copy_update_selection(wme, 1); + if (data->searchmark != NULL && !data->timeout) + window_copy_search_marks(wme, NULL, data->searchregex); + window_copy_update_selection(wme, 1, 0); window_copy_redraw_screen(wme); return (0); } @@ -1023,7 +1027,9 @@ window_copy_cmd_history_bottom(struct window_copy_cmd_state *cs) data->cx = window_copy_find_length(wme, data->cy); data->oy = 0; - window_copy_update_selection(wme, 1); + if (data->searchmark != NULL && !data->timeout) + window_copy_search_marks(wme, NULL, data->searchregex); + window_copy_update_selection(wme, 1, 0); return (WINDOW_COPY_CMD_REDRAW); } @@ -1042,7 +1048,9 @@ window_copy_cmd_history_top(struct window_copy_cmd_state *cs) data->cx = 0; data->oy = screen_hsize(data->backing); - window_copy_update_selection(wme, 1); + if (data->searchmark != NULL && !data->timeout) + window_copy_search_marks(wme, NULL, data->searchregex); + window_copy_update_selection(wme, 1, 0); return (WINDOW_COPY_CMD_REDRAW); } @@ -2171,7 +2179,9 @@ window_copy_scroll_to(struct window_mode_entry *wme, u_int px, u_int py) data->oy = gd->hsize - offset; } - window_copy_update_selection(wme, 1); + if (data->searchmark != NULL && !data->timeout) + window_copy_search_marks(wme, NULL, data->searchregex); + window_copy_update_selection(wme, 1, 0); window_copy_redraw_screen(wme); } @@ -2748,6 +2758,7 @@ window_copy_search_marks(struct window_mode_entry *wme, struct screen *ssp, struct screen *s = data->backing, ss; struct screen_write_ctx ctx; struct grid *gd = s->grid; + const struct grid_line *gl; int found, cis, which = -1; int cflags = REG_EXTENDED; u_int px, py, b, nfound = 0, width; @@ -2785,7 +2796,15 @@ window_copy_search_marks(struct window_mode_entry *wme, struct screen *ssp, } } time(&tstart); - for (py = 0; py < gd->hsize + gd->sy; py++) { + py = gd->hsize - data->oy; + if (py > 0) + py--; + for (; py > 0; py--) { + gl = grid_peek_line(gd, py); + if (~gl->flags & GRID_LINE_WRAPPED) + break; + } + for (; py < gd->hsize - data->oy + gd->sy; py++) { px = 0; for (;;) { if (regex) { @@ -4153,7 +4172,9 @@ window_copy_scroll_up(struct window_mode_entry *wme, u_int ny) return; data->oy -= ny; - window_copy_update_selection(wme, 0); + if (data->searchmark != NULL && !data->timeout) + window_copy_search_marks(wme, NULL, data->searchregex); + window_copy_update_selection(wme, 0, 0); screen_write_start(&ctx, wp, NULL); screen_write_cursormove(&ctx, 0, 0, 0); @@ -4187,7 +4208,9 @@ window_copy_scroll_down(struct window_mode_entry *wme, u_int ny) return; data->oy += ny; - window_copy_update_selection(wme, 0); + if (data->searchmark != NULL && !data->timeout) + window_copy_search_marks(wme, NULL, data->searchregex); + window_copy_update_selection(wme, 0, 0); screen_write_start(&ctx, wp, NULL); screen_write_cursormove(&ctx, 0, 0, 0); From bc36b473f1d33f92bb70e5bd68d31924b59be70c Mon Sep 17 00:00:00 2001 From: nicm Date: Fri, 3 Apr 2020 05:18:02 +0000 Subject: [PATCH 6/8] Check previous line rather than an extra line, from Anindya Mukherjee. --- window-copy.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/window-copy.c b/window-copy.c index cbf63cc7..7f3c0277 100644 --- a/window-copy.c +++ b/window-copy.c @@ -2796,11 +2796,8 @@ window_copy_search_marks(struct window_mode_entry *wme, struct screen *ssp, } } time(&tstart); - py = gd->hsize - data->oy; - if (py > 0) - py--; - for (; py > 0; py--) { - gl = grid_peek_line(gd, py); + for (py = gd->hsize - data->oy; py > 0; py--) { + gl = grid_peek_line(gd, py - 1); if (~gl->flags & GRID_LINE_WRAPPED) break; } From a4e19bcd8020f655f613604361d0f30384edbdc0 Mon Sep 17 00:00:00 2001 From: Nicholas Marriott Date: Mon, 6 Apr 2020 16:09:49 +0100 Subject: [PATCH 7/8] Various fixes for copy mode from master. --- cmd-copy-mode.c | 9 ++- tmux.1 | 7 ++- window-copy.c | 162 ++++++++++++++++++++++++++++++------------------ 3 files changed, 114 insertions(+), 64 deletions(-) diff --git a/cmd-copy-mode.c b/cmd-copy-mode.c index b35d0af1..bdb8245e 100644 --- a/cmd-copy-mode.c +++ b/cmd-copy-mode.c @@ -30,8 +30,8 @@ const struct cmd_entry cmd_copy_mode_entry = { .name = "copy-mode", .alias = NULL, - .args = { "Met:u", 0, 0 }, - .usage = "[-Mu] " CMD_TARGET_PANE_USAGE, + .args = { "eHMt:uq", 0, 0 }, + .usage = "[-eHMuq] " CMD_TARGET_PANE_USAGE, .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 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 ((wp = cmd_mouse_pane(&shared->mouse, &s, NULL)) == NULL) return (CMD_RETURN_NORMAL); diff --git a/tmux.1 b/tmux.1 index c7b40c16..615274bf 100644 --- a/tmux.1 +++ b/tmux.1 @@ -1590,7 +1590,7 @@ The synopsis for the command is: .Bl -tag -width Ds .It Xo Ic copy-mode -.Op Fl Meu +.Op Fl eHMqu .Op Fl t Ar target-pane .Xc Enter copy mode. @@ -1600,6 +1600,11 @@ option scrolls one page up. .Fl M begins a mouse drag (only valid if bound to a mouse key binding, see .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 specifies that scrolling to the bottom of the history (to the visible screen) should exit copy mode. diff --git a/window-copy.c b/window-copy.c index 7f3c0277..149287b5 100644 --- a/window-copy.c +++ b/window-copy.c @@ -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 int window_copy_adjust_selection(struct window_mode_entry *, u_int *, u_int *); -static int window_copy_set_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 *); +static int window_copy_set_selection(struct window_mode_entry *, int, int); +static int window_copy_update_selection(struct window_mode_entry *, int, + 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_copy_buffer(struct window_mode_entry *, 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 *, const char *, u_int *, u_int *); 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 *, const char *, int, u_int *, u_int *); static void window_copy_cursor_previous_word(struct window_mode_entry *, @@ -226,6 +227,7 @@ struct window_copy_mode_data { } lineflag; /* line selection mode */ int rectflag; /* in rectangle copy mode? */ int scroll_exit; /* exit on scroll to end? */ + int hide_position; /* hide position marker */ enum { 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->lineflag = LINE_SEL_NONE; + data->selflag = SEL_CHAR; if (wp->searchstr != NULL) { data->searchtype = WINDOW_COPY_SEARCHUP; @@ -348,6 +351,7 @@ window_copy_init(struct window_mode_entry *wme, data->cy = data->backing->cy; data->scroll_exit = args_has(args, 'e'); + data->hide_position = args_has(args, 'H'); data->screen.cx = data->cx; 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); } +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 window_copy_formats(struct window_mode_entry *wme, struct format_tree *ft) { struct window_copy_mode_data *data = wme->data; + struct grid *gd = data->screen.grid; char *s; 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 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) { format_add(ft, "copy_cursor_word", "%s", s); free(s); } - s = format_grid_line(data->screen.grid, data->cy); + s = format_grid_line(gd, gd->hsize + data->cy); if (s != NULL) { format_add(ft, "copy_cursor_line", "%s", s); free(s); @@ -751,9 +776,6 @@ window_copy_cmd_begin_selection(struct window_copy_cmd_state *cs) struct client *c = cs->c; struct mouse_event *m = cs->m; 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) { 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->selflag = SEL_CHAR; window_copy_start_selection(wme); 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->lineflag = LINE_SEL_NONE; + data->selflag = SEL_CHAR; return (WINDOW_COPY_CMD_NOTHING); } @@ -785,7 +809,7 @@ window_copy_cmd_bottom_line(struct window_copy_cmd_state *cs) data->cx = 0; 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); } @@ -842,12 +866,14 @@ window_copy_cmd_copy_line(struct window_copy_cmd_state *cs) struct session *s = cs->s; struct winlink *wl = cs->wl; struct window_pane *wp = wme->wp; + struct window_copy_mode_data *data = wme->data; u_int np = wme->prefix; char *prefix = NULL; if (cs->args->argc == 2) 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_start_selection(wme); for (; np > 1; np--) @@ -1119,7 +1145,7 @@ window_copy_cmd_middle_line(struct window_copy_cmd_state *cs) data->cx = 0; 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); } @@ -1276,7 +1302,8 @@ window_copy_cmd_next_matching_bracket(struct window_copy_cmd_state *cs) tried = 1; goto retry; } - window_copy_cursor_next_word_end(wme, "{[( "); + window_copy_cursor_next_word_end(wme, "{[( ", + 0); continue; } /* 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; for (; np != 0; np--) - window_copy_cursor_next_word_end(wme, " "); + window_copy_cursor_next_word_end(wme, " ", 0); 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"); 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); } @@ -1396,7 +1423,9 @@ window_copy_cmd_other_end(struct window_copy_cmd_state *cs) { struct window_mode_entry *wme = cs->wme; u_int np = wme->prefix; + struct window_copy_mode_data *data = wme->data; + data->selflag = SEL_CHAR; if ((np % 2) != 0) window_copy_other_end(wme); 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); data->selrx = data->cx; 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); for (; np > 1; np--) window_copy_cursor_down(wme, 0); 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); } @@ -1593,7 +1622,6 @@ window_copy_cmd_select_word(struct window_copy_cmd_state *cs) struct window_mode_entry *wme = cs->wme; struct session *s = cs->s; struct window_copy_mode_data *data = wme->data; - const char *ws; u_int px, py; 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->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; py = screen_hsize(data->backing) + data->cy - data->oy; - - ws = options_get_string(s->options, "word-separators"); - window_copy_cursor_previous_word(wme, ws, 0); - data->selrx = data->cx; - data->selry = screen_hsize(data->backing) + data->cy - data->oy; + data->selrx = px; + data->selry = py; window_copy_start_selection(wme); if (px >= window_copy_find_length(wme, py) || - !window_copy_in_set(wme, px + 1, py, ws)) - window_copy_cursor_next_word_end(wme, ws); + !window_copy_in_set(wme, px + 1, py, data->ws)) + window_copy_cursor_next_word_end(wme, data->ws, 1); else { 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); } data->endselrx = data->cx; data->endselry = screen_hsize(data->backing) + data->cy - data->oy; + if (data->dx > data->endselrx) + data->dx = data->endselrx; return (WINDOW_COPY_CMD_REDRAW); } @@ -1643,7 +1672,7 @@ window_copy_cmd_top_line(struct window_copy_cmd_state *cs) data->cx = 0; data->cy = 0; - window_copy_update_selection(wme, 1); + window_copy_update_selection(wme, 1, 0); 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); data->oy = lineno; - window_copy_update_selection(wme, 1); + window_copy_update_selection(wme, 1, 0); window_copy_redraw_screen(wme); } @@ -2907,7 +2936,7 @@ window_copy_write_line(struct window_mode_entry *wme, style_apply(&gc, oo, "mode-style"); 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->timeout) { size = xsnprintf(hdr, sizeof hdr, @@ -3013,18 +3042,19 @@ window_copy_redraw_screen(struct window_mode_entry *wme) } 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; u_int xx, yy; - int begin = 0; yy = screen_hsize(data->backing) + data->cy - data->oy; switch (data->selflag) { case SEL_WORD: xx = data->cx; - if (data->ws == NULL) + if (no_reset) break; + begin = 0; if (data->dy > yy || (data->dy == yy && data->dx > xx)) { /* Right to left selection. */ 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; case SEL_LINE: + if (no_reset) { + xx = data->cx; + break; + } + begin = 0; if (data->dy > yy) { /* Right to left selection. */ xx = 0; @@ -3078,17 +3113,16 @@ window_copy_synchronize_cursor_end(struct window_mode_entry *wme) } 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; switch (data->cursordrag) { case CURSORDRAG_ENDSEL: - window_copy_synchronize_cursor_end(wme); + window_copy_synchronize_cursor_end(wme, 0, no_reset); break; case CURSORDRAG_SEL: - data->selx = data->cx; - data->sely = screen_hsize(data->backing) + data->cy - data->oy; + window_copy_synchronize_cursor_end(wme, 1, no_reset); break; case CURSORDRAG_NONE: break; @@ -3130,7 +3164,7 @@ window_copy_start_selection(struct window_mode_entry *wme) data->cursordrag = CURSORDRAG_ENDSEL; - window_copy_set_selection(wme, 1); + window_copy_set_selection(wme, 1, 0); } static int @@ -3167,18 +3201,20 @@ window_copy_adjust_selection(struct window_mode_entry *wme, u_int *selx, } 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 screen *s = &data->screen; if (s->sel == NULL && data->lineflag == LINE_SEL_NONE) return (0); - return (window_copy_set_selection(wme, may_redraw)); + return (window_copy_set_selection(wme, may_redraw, no_reset)); } 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_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; int startrelpos, endrelpos; - window_copy_synchronize_cursor(wme); + window_copy_synchronize_cursor(wme, no_reset); /* Adjust the selection. */ sx = data->selx; @@ -3369,7 +3405,7 @@ window_copy_copy_buffer(struct window_mode_entry *wme, const char *prefix, static void 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; size_t len; @@ -3379,7 +3415,7 @@ window_copy_copy_pipe(struct window_mode_entry *wme, struct session *s, if (buf == NULL) 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); 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->lineflag = LINE_SEL_NONE; + data->selflag = SEL_CHAR; py = screen_hsize(data->backing) + data->cy - data->oy; 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); - if (window_copy_update_selection(wme, 1)) + if (window_copy_update_selection(wme, 1, 0)) 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); - if (window_copy_update_selection(wme, 1)) + if (window_copy_update_selection(wme, 1, 0)) 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); - if (window_copy_update_selection(wme, 1)) + if (window_copy_update_selection(wme, 1, 0)) window_copy_redraw_lines(wme, data->cy, 1); } @@ -3650,7 +3687,7 @@ window_copy_other_end(struct window_mode_entry *wme) } else data->cy = cy + sely - yy; - window_copy_update_selection(wme, 1); + window_copy_update_selection(wme, 1, 1); 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); } else if (cx > 0) { 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); } } @@ -3706,7 +3743,7 @@ window_copy_cursor_right(struct window_mode_entry *wme) cx++; } 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); } } @@ -3739,7 +3776,7 @@ window_copy_cursor_up(struct window_mode_entry *wme, int scroll_only) } } else { 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) window_copy_redraw_lines(wme, data->cy, 1); 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); } else { 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); } @@ -3820,7 +3857,7 @@ window_copy_cursor_jump(struct window_mode_entry *wme) if (!(gc.flags & GRID_FLAG_PADDING) && gc.data.size == 1 && *gc.data.data == data->jumpchar) { 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); return; } @@ -3847,7 +3884,7 @@ window_copy_cursor_jump_back(struct window_mode_entry *wme) if (!(gc.flags & GRID_FLAG_PADDING) && gc.data.size == 1 && *gc.data.data == data->jumpchar) { 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); return; } @@ -3874,7 +3911,7 @@ window_copy_cursor_jump_to(struct window_mode_entry *wme) if (!(gc.flags & GRID_FLAG_PADDING) && gc.data.size == 1 && *gc.data.data == data->jumpchar) { 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); return; } @@ -3904,7 +3941,7 @@ window_copy_cursor_jump_to_back(struct window_mode_entry *wme) if (!(gc.flags & GRID_FLAG_PADDING) && gc.data.size == 1 && *gc.data.data == data->jumpchar) { 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); return; } @@ -3953,7 +3990,7 @@ window_copy_cursor_next_word(struct window_mode_entry *wme, } while (expected == 1); 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); } @@ -4008,7 +4045,7 @@ window_copy_cursor_next_word_end_pos(struct window_mode_entry *wme, static void 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_copy_mode_data *data = wme->data; @@ -4054,7 +4091,7 @@ window_copy_cursor_next_word_end(struct window_mode_entry *wme, px--; 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); } @@ -4151,7 +4188,7 @@ window_copy_cursor_previous_word(struct window_mode_entry *wme, out: 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); } @@ -4234,7 +4271,7 @@ window_copy_rectangle_toggle(struct window_mode_entry *wme) if (data->cx > px) 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); } @@ -4266,7 +4303,7 @@ window_copy_start_drag(struct client *c, struct mouse_event *m) struct window_pane *wp; struct window_mode_entry *wme; struct window_copy_mode_data *data; - u_int x, y; + u_int x, y, yg; if (c == NULL) 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; 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) { case SEL_WORD: if (data->ws) { @@ -4342,7 +4382,7 @@ window_copy_drag_update(struct client *c, struct mouse_event *m) old_cy = data->cy; 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); if (old_cy != data->cy || old_cx == data->cx) { if (y == 0) { From 9077b212c3a210cf1764cf0662e98e3af5fcd3ef Mon Sep 17 00:00:00 2001 From: Nicholas Marriott Date: Mon, 6 Apr 2020 16:14:09 +0100 Subject: [PATCH 8/8] job_run needs fewer arguments. --- window-copy.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/window-copy.c b/window-copy.c index 149287b5..2a47e9b0 100644 --- a/window-copy.c +++ b/window-copy.c @@ -3415,7 +3415,7 @@ window_copy_copy_pipe(struct window_mode_entry *wme, struct session *s, if (buf == NULL) return; - job = job_run(cmd, s, NULL, NULL, NULL, NULL, NULL, JOB_NOWAIT, -1, -1); + job = job_run(cmd, s, NULL, NULL, NULL, NULL, NULL, JOB_NOWAIT); bufferevent_write(job_get_event(job), buf, len); window_copy_copy_buffer(wme, prefix, buf, len); }