Copy mode search improvements:

- Add styles for the search marking styles (copy-mode-match-style and
  copy-mode-current-match-style).

- Show the current match (the one with the cursor on it) in a different style.

- Copying without a selection will copy the current match if there is one.
diff --git a/options-table.c b/options-table.c
index 5c36858..a89758c 100644
--- a/options-table.c
+++ b/options-table.c
@@ -656,6 +656,22 @@
 	  .default_num = 1
 	},
 
+	{ .name = "copy-mode-match-style",
+	  .type = OPTIONS_TABLE_STRING,
+	  .scope = OPTIONS_TABLE_WINDOW,
+	  .default_str = "bg=cyan,fg=black",
+	  .flags = OPTIONS_TABLE_IS_STYLE,
+	  .separator = ","
+	},
+
+	{ .name = "copy-mode-current-match-style",
+	  .type = OPTIONS_TABLE_STRING,
+	  .scope = OPTIONS_TABLE_WINDOW,
+	  .default_str = "bg=magenta,fg=black",
+	  .flags = OPTIONS_TABLE_IS_STYLE,
+	  .separator = ","
+	},
+
 	{ .name = "main-pane-height",
 	  .type = OPTIONS_TABLE_STRING,
 	  .scope = OPTIONS_TABLE_WINDOW,
diff --git a/screen-write.c b/screen-write.c
index afa1e96..e3e5102 100644
--- a/screen-write.c
+++ b/screen-write.c
@@ -344,44 +344,9 @@
 	free(msg);
 }
 
-/* Copy from another screen. Assumes target region is big enough. */
-void
-screen_write_copy(struct screen_write_ctx *ctx, struct screen *src, u_int px,
-    u_int py, u_int nx, u_int ny, bitstr_t *mbs, const struct grid_cell *mgc)
-{
-	struct screen		*s = ctx->s;
-	struct grid		*gd = src->grid;
-	struct grid_cell	 gc;
-	u_int		 	 xx, yy, cx, cy, b;
-
-	if (nx == 0 || ny == 0)
-		return;
-
-	cx = s->cx;
-	cy = s->cy;
-
-	for (yy = py; yy < py + ny; yy++) {
-		for (xx = px; xx < px + nx; xx++) {
-			grid_get_cell(gd, xx, yy, &gc);
-			if (mbs != NULL) {
-				b = (yy * screen_size_x(src)) + xx;
-				if (bit_test(mbs, b)) {
-					gc.attr = mgc->attr;
-					gc.fg = mgc->fg;
-					gc.bg = mgc->bg;
-				}
-			}
-			if (xx + gc.data.width <= px + nx)
-				screen_write_cell(ctx, &gc);
-		}
-		cy++;
-		screen_write_set_cursor(ctx, cx, cy);
-	}
-}
-
 /*
- * Copy from another screen but without the selection stuff. Also assumes the
- * target region is already big enough.
+ * Copy from another screen but without the selection stuff. Assumes the target
+ * region is already big enough.
  */
 void
 screen_write_fast_copy(struct screen_write_ctx *ctx, struct screen *src,
diff --git a/tmux.1 b/tmux.1
index 7918c78..5c873fd 100644
--- a/tmux.1
+++ b/tmux.1
@@ -3717,6 +3717,22 @@
 .Ql % ,
 this is a percentage of the window size.
 .Pp
+.It Ic copy-mode-match-style Ar style
+Set the style of search matches in copy mode.
+For how to specify
+.Ar style ,
+see the
+.Sx STYLES
+section.
+.Pp
+.It Ic copy-mode-current-match-style Ar style
+Set the style of the current search match in copy mode.
+For how to specify
+.Ar style ,
+see the
+.Sx STYLES
+section.
+.Pp
 .It Xo Ic mode-keys
 .Op Ic vi | emacs
 .Xc
diff --git a/tmux.h b/tmux.h
index 486b8b4..e244366 100644
--- a/tmux.h
+++ b/tmux.h
@@ -2434,8 +2434,6 @@
 	     const struct grid_cell *, const char *, va_list);
 void	 screen_write_putc(struct screen_write_ctx *, const struct grid_cell *,
 	     u_char);
-void	 screen_write_copy(struct screen_write_ctx *, struct screen *, u_int,
-	     u_int, u_int, u_int, bitstr_t *, const struct grid_cell *);
 void	 screen_write_fast_copy(struct screen_write_ctx *, struct screen *,
 	     u_int, u_int, u_int, u_int);
 void	 screen_write_hline(struct screen_write_ctx *, u_int, int, int);
diff --git a/window-copy.c b/window-copy.c
index 2c50a1c..f5a07a1 100644
--- a/window-copy.c
+++ b/window-copy.c
@@ -257,12 +257,13 @@
 	int		 searchtype;
 	int		 searchregex;
 	char		*searchstr;
-	bitstr_t	*searchmark;
+	u_char		*searchmark;
 	u_int		 searchcount;
 	int		 searchthis;
 	int		 searchx;
 	int		 searchy;
 	int		 searcho;
+	u_char		 searchgen;
 
 	int		 timeout;	/* search has timed out */
 #define WINDOW_COPY_SEARCH_TIMEOUT 10
@@ -362,10 +363,7 @@
 		data->searchregex = 0;
 		data->searchstr = NULL;
 	}
-	data->searchmark = NULL;
 	data->searchx = data->searchy = data->searcho = -1;
-	data->timeout = 0;
-	data->viewmode = 0;
 
 	data->jumptype = WINDOW_COPY_OFF;
 	data->jumpchar = '\0';
@@ -2860,7 +2858,7 @@
 	const struct grid_line		*gl;
 	int				 found, cis, which = -1;
 	int				 cflags = REG_EXTENDED;
-	u_int				 px, py, b, nfound = 0, width;
+	u_int				 px, py, i, b, nfound = 0, width;
 	u_int				 ssize = 1;
 	char				*sbuf;
 	regex_t				 reg;
@@ -2880,7 +2878,8 @@
 	cis = window_copy_is_lowercase(data->searchstr);
 
 	free(data->searchmark);
-	data->searchmark = bit_alloc((gd->hsize + gd->sy) * gd->sx);
+	data->searchmark = xcalloc(gd->hsize + gd->sy, gd->sx);
+	data->searchgen = 1;
 
 	if (regex) {
 		sbuf = xmalloc(ssize);
@@ -2921,7 +2920,12 @@
 				which = nfound;
 
 			b = (py * gd->sx) + px;
-			bit_nset(data->searchmark, b, b + width - 1);
+			for (i = b; i < b + width; i++)
+				data->searchmark[i] = data->searchgen;
+			if (data->searchgen == UCHAR_MAX)
+				data->searchgen = 1;
+			else
+				data->searchgen++;
 
 			px++;
 		}
@@ -2992,6 +2996,114 @@
 }
 
 static void
+window_copy_match_start_end(struct window_copy_mode_data *data, u_int at,
+    u_int *start, u_int *end)
+{
+	struct grid	*gd = data->backing->grid;
+	u_int		 last = (gd->hsize + gd->sy) * gd->sx - 1;
+	u_char		 mark = data->searchmark[at];
+
+	*start = *end = at;
+	while (*start != 0 && data->searchmark[*start] == mark)
+		(*start)--;
+	if (data->searchmark[*start] != mark)
+		(*start)++;
+	while (*end != last && data->searchmark[*end] == mark)
+		(*end)++;
+	if (data->searchmark[*end] != mark)
+		(*end)--;
+}
+
+static char *
+window_copy_match_at_cursor(struct window_copy_mode_data *data)
+{
+	struct grid	*gd = data->backing->grid;
+	struct grid_cell gc;
+	u_int		 at, start, end, cy, px, py;
+	u_int		 sx = screen_size_x(data->backing);
+	char		*buf = NULL;
+	size_t		 len = 0;
+
+	if (data->searchmark == NULL)
+		return (NULL);
+
+	cy = screen_hsize(data->backing) - data->oy + data->cy;
+	at = (cy * sx) + data->cx;
+	if (data->searchmark[at] == 0)
+		return (NULL);
+	window_copy_match_start_end(data, at, &start, &end);
+
+	/*
+	 * Cells will not be set in the marked array unless they are valid text
+	 * and wrapping will be taken care of, so we can just copy.
+ 	 */
+	for (at = start; at <= end; at++) {
+		py = at / sx;
+		px = at % (py * sx);
+
+		grid_get_cell(gd, px, py, &gc);
+		buf = xrealloc(buf, len + gc.data.size + 1);
+		memcpy(buf + len, gc.data.data, gc.data.size);
+		len += gc.data.size;
+	}
+	if (len != 0)
+		buf[len] = '\0';
+	return (buf);
+}
+
+static void
+window_copy_update_style(struct window_mode_entry *wme, u_int fx, u_int fy,
+    struct grid_cell *gc, const struct grid_cell *mgc,
+    const struct grid_cell *cgc)
+{
+	struct window_copy_mode_data	*data = wme->data;
+	u_int				 mark, at, start, end, cy;
+	u_int				 sx = screen_size_x(data->backing);
+
+	if (data->searchmark == NULL)
+		return;
+	mark = data->searchmark[(fy * sx) + fx];
+	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) {
+			gc->attr = cgc->attr;
+			gc->fg = cgc->fg;
+			gc->bg = cgc->bg;
+		}
+		return;
+	}
+
+	gc->attr = mgc->attr;
+	gc->fg = mgc->fg;
+	gc->bg = mgc->bg;
+}
+
+static void
+window_copy_write_one(struct window_mode_entry *wme,
+    struct screen_write_ctx *ctx, u_int py, u_int fy, u_int nx,
+    const struct grid_cell *mgc, const struct grid_cell *cgc)
+{
+	struct window_copy_mode_data	*data = wme->data;
+	struct grid			*gd = data->backing->grid;
+	struct grid_cell		 gc;
+	u_int		 		 fx;
+
+	screen_write_cursormove(ctx, 0, py, 0);
+	for (fx = 0; fx < nx; fx++) {
+		grid_get_cell(gd, fx, fy, &gc);
+		if (fx + gc.data.width <= nx) {
+			window_copy_update_style(wme, fx, fy, &gc, mgc, cgc);
+			screen_write_cell(ctx, &gc);
+		}
+	}
+}
+
+static void
 window_copy_write_line(struct window_mode_entry *wme,
     struct screen_write_ctx *ctx, u_int py)
 {
@@ -2999,13 +3111,17 @@
 	struct window_copy_mode_data	*data = wme->data;
 	struct screen			*s = &data->screen;
 	struct options			*oo = wp->window->options;
-	struct grid_cell		 gc;
+	struct grid_cell		 gc, mgc, cgc;
 	char				 hdr[512];
 	size_t				 size = 0;
 	u_int				 hsize = screen_hsize(data->backing);
 
 	style_apply(&gc, oo, "mode-style", NULL);
 	gc.flags |= GRID_FLAG_NOPALETTE;
+	style_apply(&mgc, oo, "copy-mode-match-style", NULL);
+	mgc.flags |= GRID_FLAG_NOPALETTE;
+	style_apply(&cgc, oo, "copy-mode-current-match-style", NULL);
+	cgc.flags |= GRID_FLAG_NOPALETTE;
 
 	if (py == 0 && s->rupper < s->rlower && !data->hide_position) {
 		if (data->searchmark == NULL) {
@@ -3035,15 +3151,13 @@
 		size = 0;
 
 	if (size < screen_size_x(s)) {
-		screen_write_cursormove(ctx, 0, py, 0);
-		screen_write_copy(ctx, data->backing, 0, hsize - data->oy + py,
-		    screen_size_x(s) - size, 1, data->searchmark, &gc);
+		window_copy_write_one(wme, ctx, py, hsize - data->oy + py,
+		    screen_size_x(s) - size, &mgc, &cgc);
 	}
 
 	if (py == data->cy && data->cx == screen_size_x(s)) {
-		memcpy(&gc, &grid_default_cell, sizeof gc);
 		screen_write_cursormove(ctx, screen_size_x(s) - 1, py, 0);
-		screen_write_putc(ctx, &gc, '$');
+		screen_write_putc(ctx, &grid_default_cell, '$');
 	}
 }
 
@@ -3354,8 +3468,12 @@
 	u_int				 firstsx, lastex, restex, restsx, selx;
 	int				 keys;
 
-	if (data->screen.sel == NULL && data->lineflag == LINE_SEL_NONE)
-		return (NULL);
+	if (data->screen.sel == NULL && data->lineflag == LINE_SEL_NONE) {
+		buf = window_copy_match_at_cursor(data);
+		if (buf != NULL)
+			*len = strlen(buf);
+		return (buf);
+	}
 
 	buf = xmalloc(1);
 	off = 0;