summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--menu.c1
-rw-r--r--window-copy.c123
2 files changed, 87 insertions, 37 deletions
diff --git a/menu.c b/menu.c
index 07fc8fa8..62010a58 100644
--- a/menu.c
+++ b/menu.c
@@ -351,6 +351,7 @@ menu_display(struct menu *menu, int flags, struct cmdq_item *item, u_int px,
screen_init(&md->s, menu->width + 4, menu->count + 2, 0);
if (~md->flags & MENU_NOMOUSE)
md->s.mode |= MODE_MOUSE_ALL;
+ md->s.mode &= ~MODE_CURSOR;
md->px = px;
md->py = py;
diff --git a/window-copy.c b/window-copy.c
index 9f84ade9..38e87b67 100644
--- a/window-copy.c
+++ b/window-copy.c
@@ -258,7 +258,8 @@ struct window_copy_mode_data {
int searchregex;
char *searchstr;
u_char *searchmark;
- u_int searchcount;
+ int searchcount;
+ int searchmore;
int searchthis;
int searchx;
int searchy;
@@ -266,7 +267,8 @@ struct window_copy_mode_data {
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 @@ window_copy_search(struct window_mode_entry *wme, int direction, int regex)
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 @@ window_copy_search_marks(struct window_mode_entry *wme, struct screen *ssp,
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 @@ window_copy_search_marks(struct window_mode_entry *wme, struct screen *ssp,
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 @@ window_copy_search_marks(struct window_mode_entry *wme, struct screen *ssp,
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 @@ window_copy_search_marks(struct window_mode_entry *wme, struct screen *ssp,
px++;
}
- time(&t);
+ t = window_copy_get_time();
if (t - tstart > WINDOW_COPY_SEARCH_TIMEOUT) {
data->timeout = 1;
break;
}
- }
- if (regex) {
- free(sbuf);
- regfree(&reg);
+ if (stop != 0 && t > stop) {
+ stopped = 1;
+ break;
+ }
}
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(&reg);
+ }
return (1);
}
@@ -3057,25 +3100,28 @@ window_copy_update_style(struct window_mode_entry *wme, u_int fx, u_int fy,
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 @@ window_copy_write_line(struct window_mode_entry *wme,
"[%u/%u]", data->oy, hsize);
}
} else {
- if (data->searchthis == -1) {
+ if (data->searchcount == -1) {
+ size = xsnprintf(hdr, sizeof hdr,
+ "[%u/%u]", data->oy, hsize);
+ } else if (data->searchthis == -1) {
size = xsnprintf(hdr, sizeof hdr,
- "(%u results) [%d/%u]", data->searchcount,
- data->oy, hsize);
+ "(%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);
}
}