mirror of
				https://github.com/tmux/tmux.git
				synced 2025-11-04 09:26:05 +00:00 
			
		
		
		
	Try to search the entire history first for up to 200 ms so a search
count can be shown. If it takes too long, search the visible text only.
This commit is contained in:
		
							
								
								
									
										131
									
								
								window-copy.c
									
									
									
									
									
								
							
							
						
						
									
										131
									
								
								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 (stop != 0 && t > stop) {
 | 
			
		||||
			stopped = 1;
 | 
			
		||||
			break;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	if (data->timeout) {
 | 
			
		||||
		window_copy_clear_marks(wme);
 | 
			
		||||
		goto out;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	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;
 | 
			
		||||
		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(®);
 | 
			
		||||
	}
 | 
			
		||||
	if (data->timeout) {
 | 
			
		||||
		window_copy_clear_marks(wme);
 | 
			
		||||
		return (1);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (which != -1)
 | 
			
		||||
		data->searchthis = 1 + nfound - which;
 | 
			
		||||
	else
 | 
			
		||||
		data->searchthis = -1;
 | 
			
		||||
	data->searchcount = nfound;
 | 
			
		||||
 | 
			
		||||
	if (ssp == &ss)
 | 
			
		||||
		screen_free(&ss);
 | 
			
		||||
	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 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);
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user