diff options
Diffstat (limited to 'window-copy.c')
-rw-r--r-- | window-copy.c | 311 |
1 files changed, 199 insertions, 112 deletions
diff --git a/window-copy.c b/window-copy.c index 8e3f63d1..fa2d2929 100644 --- a/window-copy.c +++ b/window-copy.c @@ -87,9 +87,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); @@ -122,7 +123,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 *, @@ -230,6 +231,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 */ @@ -254,6 +256,7 @@ struct window_copy_mode_data { u_int lastsx; /* size of last line w/ content */ int searchtype; + int searchregex; char *searchstr; bitstr_t *searchmark; u_int searchcount; @@ -304,12 +307,15 @@ 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; + data->searchregex = wp->searchregex; data->searchstr = xstrdup(wp->searchstr); } else { data->searchtype = WINDOW_COPY_OFF; + data->searchregex = 0; data->searchstr = NULL; } data->searchmark = NULL; @@ -345,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; @@ -502,7 +509,7 @@ window_copy_pageup1(struct window_mode_entry *wme, int half_page) window_copy_cursor_end_of_line(wme); } - window_copy_update_selection(wme, 1); + window_copy_update_selection(wme, 1, 0); window_copy_redraw_screen(wme); } @@ -550,7 +557,7 @@ 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); + window_copy_update_selection(wme, 1, 0); window_copy_redraw_screen(wme); return (0); } @@ -592,10 +599,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); @@ -615,13 +643,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); @@ -675,6 +703,35 @@ window_copy_key_table(struct window_mode_entry *wme) return ("copy-mode"); } +static int +window_copy_expand_search_string(struct window_copy_cmd_state *cs) +{ + struct window_mode_entry *wme = cs->wme; + struct window_copy_mode_data *data = wme->data; + const char *argument; + char *expanded; + + if (cs->args->argc == 2) { + argument = cs->args->argv[1]; + if (*argument != '\0') { + if (args_has(cs->args, 'F')) { + expanded = format_single(NULL, argument, NULL, + NULL, NULL, wme->wp); + if (*expanded == '\0') { + free(expanded); + return (0); + } + free(data->searchstr); + data->searchstr = expanded; + } else { + free(data->searchstr); + data->searchstr = xstrdup(argument); + } + } + } + return (1); +} + static enum window_copy_cmd_action window_copy_cmd_append_selection(struct window_copy_cmd_state *cs) { @@ -715,9 +772,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); @@ -725,6 +779,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); } @@ -737,6 +792,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); } @@ -749,7 +805,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); } @@ -806,12 +862,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--) @@ -991,7 +1049,7 @@ 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); + window_copy_update_selection(wme, 1, 0); return (WINDOW_COPY_CMD_REDRAW); } @@ -1010,7 +1068,7 @@ 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); + window_copy_update_selection(wme, 1, 0); return (WINDOW_COPY_CMD_REDRAW); } @@ -1079,7 +1137,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); } @@ -1236,7 +1294,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. */ @@ -1319,7 +1378,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); } @@ -1347,7 +1406,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); } @@ -1356,7 +1415,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); @@ -1496,10 +1557,10 @@ window_copy_cmd_search_again(struct window_copy_cmd_state *cs) if (data->searchtype == WINDOW_COPY_SEARCHUP) { for (; np != 0; np--) - window_copy_search_up(wme, 1); + window_copy_search_up(wme, data->searchregex); } else if (data->searchtype == WINDOW_COPY_SEARCHDOWN) { for (; np != 0; np--) - window_copy_search_down(wme, 1); + window_copy_search_down(wme, data->searchregex); } return (WINDOW_COPY_CMD_NOTHING); } @@ -1513,10 +1574,10 @@ window_copy_cmd_search_reverse(struct window_copy_cmd_state *cs) if (data->searchtype == WINDOW_COPY_SEARCHUP) { for (; np != 0; np--) - window_copy_search_down(wme, 1); + window_copy_search_down(wme, data->searchregex); } else if (data->searchtype == WINDOW_COPY_SEARCHDOWN) { for (; np != 0; np--) - window_copy_search_up(wme, 1); + window_copy_search_up(wme, data->searchregex); } return (WINDOW_COPY_CMD_NOTHING); } @@ -1537,12 +1598,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); } @@ -1553,7 +1614,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; @@ -1562,25 +1622,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); } @@ -1603,7 +1664,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); } @@ -1736,29 +1797,13 @@ window_copy_cmd_search_backward(struct window_copy_cmd_state *cs) struct window_mode_entry *wme = cs->wme; struct window_copy_mode_data *data = wme->data; u_int np = wme->prefix; - const char *argument; - char *expanded; - if (cs->args->argc == 2) { - argument = cs->args->argv[1]; - if (*argument != '\0') { - if (args_has(cs->args, 'F')) { - expanded = format_single(NULL, argument, NULL, - NULL, NULL, wme->wp); - if (*expanded == '\0') { - free(expanded); - return (WINDOW_COPY_CMD_NOTHING); - } - free(data->searchstr); - data->searchstr = expanded; - } else { - free(data->searchstr); - data->searchstr = xstrdup(argument); - } - } - } + if (!window_copy_expand_search_string(cs)) + return (WINDOW_COPY_CMD_NOTHING); + if (data->searchstr != NULL) { data->searchtype = WINDOW_COPY_SEARCHUP; + data->searchregex = 1; for (; np != 0; np--) window_copy_search_up(wme, 1); } @@ -1766,34 +1811,37 @@ window_copy_cmd_search_backward(struct window_copy_cmd_state *cs) } static enum window_copy_cmd_action -window_copy_cmd_search_forward(struct window_copy_cmd_state *cs) +window_copy_cmd_search_backward_text(struct window_copy_cmd_state *cs) { struct window_mode_entry *wme = cs->wme; struct window_copy_mode_data *data = wme->data; u_int np = wme->prefix; - const char *argument; - char *expanded; - if (cs->args->argc == 2) { - argument = cs->args->argv[1]; - if (*argument != '\0') { - if (args_has(cs->args, 'F')) { - expanded = format_single(NULL, argument, NULL, - NULL, NULL, wme->wp); - if (*expanded == '\0') { - free(expanded); - return (WINDOW_COPY_CMD_NOTHING); - } - free(data->searchstr); - data->searchstr = expanded; - } else { - free(data->searchstr); - data->searchstr = xstrdup(argument); - } - } + if (!window_copy_expand_search_string(cs)) + return (WINDOW_COPY_CMD_NOTHING); + + if (data->searchstr != NULL) { + data->searchtype = WINDOW_COPY_SEARCHUP; + data->searchregex = 0; + for (; np != 0; np--) + window_copy_search_up(wme, 0); } + return (WINDOW_COPY_CMD_NOTHING); +} + +static enum window_copy_cmd_action +window_copy_cmd_search_forward(struct window_copy_cmd_state *cs) +{ + struct window_mode_entry *wme = cs->wme; + struct window_copy_mode_data *data = wme->data; + u_int np = wme->prefix; + + if (!window_copy_expand_search_string(cs)) + return (WINDOW_COPY_CMD_NOTHING); + if (data->searchstr != NULL) { data->searchtype = WINDOW_COPY_SEARCHDOWN; + data->searchregex = 1; for (; np != 0; np--) window_copy_search_down(wme, 1); } @@ -1801,6 +1849,25 @@ window_copy_cmd_search_forward(struct window_copy_cmd_state *cs) } static enum window_copy_cmd_action +window_copy_cmd_search_forward_text(struct window_copy_cmd_state *cs) +{ + struct window_mode_entry *wme = cs->wme; + struct window_copy_mode_data *data = wme->data; + u_int np = wme->prefix; + + if (!window_copy_expand_search_string(cs)) + return (WINDOW_COPY_CMD_NOTHING); + + if (data->searchstr != NULL) { + data->searchtype = WINDOW_COPY_SEARCHDOWN; + data->searchregex = 0; + for (; np != 0; np--) + window_copy_search_down(wme, 0); + } + return (WINDOW_COPY_CMD_NOTHING); +} + +static enum window_copy_cmd_action window_copy_cmd_search_backward_incremental(struct window_copy_cmd_state *cs) { struct window_mode_entry *wme = cs->wme; @@ -1829,6 +1896,7 @@ window_copy_cmd_search_backward_incremental(struct window_copy_cmd_state *cs) case '=': case '-': data->searchtype = WINDOW_COPY_SEARCHUP; + data->searchregex = 0; free(data->searchstr); data->searchstr = xstrdup(argument); if (!window_copy_search_up(wme, 0)) { @@ -1838,6 +1906,7 @@ window_copy_cmd_search_backward_incremental(struct window_copy_cmd_state *cs) break; case '+': data->searchtype = WINDOW_COPY_SEARCHDOWN; + data->searchregex = 0; free(data->searchstr); data->searchstr = xstrdup(argument); if (!window_copy_search_down(wme, 0)) { @@ -1878,6 +1947,7 @@ window_copy_cmd_search_forward_incremental(struct window_copy_cmd_state *cs) case '=': case '+': data->searchtype = WINDOW_COPY_SEARCHDOWN; + data->searchregex = 0; free(data->searchstr); data->searchstr = xstrdup(argument); if (!window_copy_search_down(wme, 0)) { @@ -1887,6 +1957,7 @@ window_copy_cmd_search_forward_incremental(struct window_copy_cmd_state *cs) break; case '-': data->searchtype = WINDOW_COPY_SEARCHUP; + data->searchregex = 0; free(data->searchstr); data->searchstr = xstrdup(argument); if (!window_copy_search_up(wme, 0)) { @@ -2012,10 +2083,14 @@ static const struct { window_copy_cmd_search_again }, { "search-backward", 0, 1, 0, window_copy_cmd_search_backward }, + { "search-backward-text", 0, 1, 0, + window_copy_cmd_search_backward_text }, { "search-backward-incremental", 1, 1, 0, window_copy_cmd_search_backward_incremental }, { "search-forward", 0, 1, 0, window_copy_cmd_search_forward }, + { "search-forward-text", 0, 1, 0, + window_copy_cmd_search_forward_text }, { "search-forward-incremental", 1, 1, 0, window_copy_cmd_search_forward_incremental }, { "search-reverse", 0, 0, 0, @@ -2117,7 +2192,7 @@ 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); + window_copy_update_selection(wme, 1, 0); window_copy_redraw_screen(wme); } @@ -2624,6 +2699,7 @@ window_copy_search(struct window_mode_entry *wme, int direction, int regex) free(wp->searchstr); wp->searchstr = xstrdup(data->searchstr); + wp->searchregex = regex; fx = data->cx; fy = screen_hsize(data->backing) - data->oy + data->cy; @@ -2755,7 +2831,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); } @@ -2774,7 +2850,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) { size = xsnprintf(hdr, sizeof hdr, "[%u/%u]", data->oy, screen_hsize(data->backing)); @@ -2873,18 +2949,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, @@ -2907,6 +2984,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; @@ -2938,17 +3020,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; @@ -2990,7 +3071,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 @@ -3027,18 +3108,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; @@ -3048,7 +3131,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; @@ -3229,7 +3312,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; @@ -3239,7 +3322,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); } @@ -3358,6 +3441,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); @@ -3403,7 +3487,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); } @@ -3426,7 +3510,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); } @@ -3459,7 +3543,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); } @@ -3510,7 +3594,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); } @@ -3534,7 +3618,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); } } @@ -3566,7 +3650,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); } } @@ -3599,7 +3683,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 @@ -3645,7 +3729,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); } @@ -3680,7 +3764,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; } @@ -3707,7 +3791,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; } @@ -3734,7 +3818,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; } @@ -3764,7 +3848,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; } @@ -3813,7 +3897,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); } @@ -3868,7 +3952,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; @@ -3914,7 +3998,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); } @@ -4011,7 +4095,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); } @@ -4029,7 +4113,7 @@ window_copy_scroll_up(struct window_mode_entry *wme, u_int ny) return; data->oy -= ny; - window_copy_update_selection(wme, 0); + window_copy_update_selection(wme, 0, 0); screen_write_start(&ctx, wp, NULL); screen_write_cursormove(&ctx, 0, 0, 0); @@ -4063,7 +4147,7 @@ window_copy_scroll_down(struct window_mode_entry *wme, u_int ny) return; data->oy += ny; - window_copy_update_selection(wme, 0); + window_copy_update_selection(wme, 0, 0); screen_write_start(&ctx, wp, NULL); screen_write_cursormove(&ctx, 0, 0, 0); @@ -4090,7 +4174,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); } @@ -4122,7 +4206,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; @@ -4143,6 +4227,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) { @@ -4198,7 +4285,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) { |