=================================================================== RCS file: /cvsrepo/anoncvs/cvs/src/usr.bin/tmux/window-copy.c,v retrieving revision 1.283 retrieving revision 1.284 diff -u -r1.283 -r1.284 --- src/usr.bin/tmux/window-copy.c 2020/05/16 15:34:08 1.283 +++ src/usr.bin/tmux/window-copy.c 2020/05/16 15:38:14 1.284 @@ -1,4 +1,4 @@ -/* $OpenBSD: window-copy.c,v 1.283 2020/05/16 15:34:08 nicm Exp $ */ +/* $OpenBSD: window-copy.c,v 1.284 2020/05/16 15:38:14 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott @@ -258,7 +258,8 @@ int searchregex; char *searchstr; u_char *searchmark; - u_int searchcount; + int searchcount; + int searchmore; int searchthis; int searchx; int searchy; @@ -266,7 +267,8 @@ u_char searchgen; int timeout; /* search has timed out */ -#define WINDOW_COPY_SEARCH_TIMEOUT 10 +#define WINDOW_COPY_SEARCH_TIMEOUT 10000 +#define WINDOW_COPY_SEARCH_ALL_TIMEOUT 200 int jumptype; char jumpchar; @@ -2847,6 +2849,15 @@ return (found); } +static uint64_t +window_copy_get_time(void) +{ + struct timeval tv; + + gettimeofday(&tv, NULL); + return ((tv.tv_sec * 1000ULL) + (tv.tv_usec / 1000ULL)); +} + static int window_copy_search_marks(struct window_mode_entry *wme, struct screen *ssp, int regex) @@ -2856,13 +2867,13 @@ struct screen_write_ctx ctx; struct grid *gd = s->grid; const struct grid_line *gl; - int found, cis, which = -1; + int found, cis, which = -1, stopped = 0; int cflags = REG_EXTENDED; u_int px, py, i, b, nfound = 0, width; - u_int ssize = 1; + u_int ssize = 1, start, end; char *sbuf; regex_t reg; - time_t tstart, t; + uint64_t stop = 0, tstart, t; if (ssp == NULL) { width = screen_write_strlen("%s", data->searchstr); @@ -2877,10 +2888,6 @@ cis = window_copy_is_lowercase(data->searchstr); - free(data->searchmark); - data->searchmark = xcalloc(gd->hsize + gd->sy, gd->sx); - data->searchgen = 1; - if (regex) { sbuf = xmalloc(ssize); sbuf[0] = '\0'; @@ -2893,13 +2900,18 @@ return (0); } } - time(&tstart); - for (py = gd->hsize - data->oy; py > 0; py--) { - gl = grid_peek_line(gd, py - 1); - if (~gl->flags & GRID_LINE_WRAPPED) - break; - } - for (; py < gd->hsize - data->oy + gd->sy; py++) { + tstart = window_copy_get_time(); + + start = 0; + end = gd->hsize + gd->sy; + stop = window_copy_get_time() + WINDOW_COPY_SEARCH_ALL_TIMEOUT; + +again: + free(data->searchmark); + data->searchmark = xcalloc(gd->hsize + gd->sy, gd->sx); + data->searchgen = 1; + + for (py = start; py < end; py++) { px = 0; for (;;) { if (regex) { @@ -2930,29 +2942,60 @@ px++; } - time(&t); + t = window_copy_get_time(); if (t - tstart > WINDOW_COPY_SEARCH_TIMEOUT) { data->timeout = 1; break; } + if (stop != 0 && t > stop) { + stopped = 1; + break; + } } - if (regex) { - free(sbuf); - regfree(®); - } if (data->timeout) { window_copy_clear_marks(wme); - return (1); + goto out; } - if (which != -1) - data->searchthis = 1 + nfound - which; - else + if (stopped && stop != 0) { + /* Try again but just the visible context. */ + for (start = gd->hsize - data->oy; start > 0; start--) { + gl = grid_peek_line(gd, start - 1); + if (~gl->flags & GRID_LINE_WRAPPED) + break; + } + end = gd->hsize - data->oy + gd->sy; + stop = 0; + goto again; + } + + if (stopped) { data->searchthis = -1; - data->searchcount = nfound; + if (nfound > 1000) + data->searchcount = 1000; + else if (nfound > 100) + data->searchcount = 100; + else if (nfound > 10) + data->searchcount = 10; + else + data->searchcount = -1; + data->searchmore = 1; + } else { + if (which != -1) + data->searchthis = 1 + nfound - which; + else + data->searchthis = -1; + data->searchcount = nfound; + data->searchmore = 0; + } +out: if (ssp == &ss) screen_free(&ss); + if (regex) { + free(sbuf); + regfree(®); + } return (1); } @@ -3057,25 +3100,28 @@ const struct grid_cell *cgc) { struct window_copy_mode_data *data = wme->data; - u_int mark, at, start, end, cy; + u_int mark, start, end, cy, cursor, current; u_int sx = screen_size_x(data->backing); if (data->searchmark == NULL) return; - mark = data->searchmark[(fy * sx) + fx]; + + current = (fy * sx) + fx; + + mark = data->searchmark[current]; if (mark == 0) return; cy = screen_hsize(data->backing) - data->oy + data->cy; - at = (cy * sx) + data->cx; - if (data->searchmark[at] == mark) { - window_copy_match_start_end(data, at, &start, &end); - if (at >= start && at <= end) { + cursor = (cy * sx) + data->cx; + if (data->searchmark[cursor] == mark) { + window_copy_match_start_end(data, cursor, &start, &end); + if (current >= start && current <= end) { gc->attr = cgc->attr; gc->fg = cgc->fg; gc->bg = cgc->bg; + return; } - return; } gc->attr = mgc->attr; @@ -3133,13 +3179,16 @@ "[%u/%u]", data->oy, hsize); } } else { - if (data->searchthis == -1) { + if (data->searchcount == -1) { size = xsnprintf(hdr, sizeof hdr, - "(%u results) [%d/%u]", data->searchcount, - data->oy, hsize); + "[%u/%u]", data->oy, hsize); + } else if (data->searchthis == -1) { + size = xsnprintf(hdr, sizeof hdr, + "(%d%s results) [%u/%u]", data->searchcount, + data->searchmore ? "+" : "", data->oy, hsize); } else { size = xsnprintf(hdr, sizeof hdr, - "(%u/%u results) [%d/%u]", data->searchthis, + "(%d/%d results) [%u/%u]", data->searchthis, data->searchcount, data->oy, hsize); } }