Discussion:
[PATCH] Adding incremental search and search highlighting
(too old to reply)
Łukasz Piątkowski
2014-08-05 02:47:28 UTC
Permalink
I have split up my changes into 3 diffs, first is refactoring search code
in window-copy.c, second is adding incremental search and the last one is
adding search highlighting.

Cheers
Lukas

--
I am providing code in this repository to you under an open source license.
Because this is my personal repository, the license you receive to my code
is from me and not from my employer (Facebook).
--


Refactor window-copy search functions
============================

diff --git window-copy.c window-copy.c
index 0775bcb..1213380 100644
--- window-copy.c
+++ window-copy.c
@@ -47,8 +47,16 @@ int window_copy_search_lr(
struct grid *, struct grid *, u_int *, u_int, u_int, u_int, int);
int window_copy_search_rl(
struct grid *, struct grid *, u_int *, u_int, u_int, u_int, int);
-void window_copy_search_up(struct window_pane *, const char *);
-void window_copy_search_down(struct window_pane *, const char *);
+void window_copy_move_coordinates(
+ struct screen *, u_int *, u_int *, const int);
+int window_copy_is_lowercase(const char *);
+void window_copy_jump_to_searched_string(
+ struct window_pane *, struct grid *, struct grid *, u_int, u_int,
+ u_int, int, int, const int);
+void window_copy_search(struct window_pane *, const char *,
+ const int, const int);
+void window_copy_search_up(struct window_pane *, const char *, const int);
+void window_copy_search_down(struct window_pane *, const char *, const
int);
void window_copy_goto_line(struct window_pane *, const char *);
void window_copy_update_cursor(struct window_pane *, u_int, u_int);
void window_copy_start_selection(struct window_pane *);
@@ -685,12 +693,12 @@ window_copy_key(struct window_pane *wp, struct
session *sess, int key)
if (cmd == MODEKEYCOPY_SEARCHAGAIN) {
for (; np != 0; np--) {
window_copy_search_up(
- wp, data->searchstr);
+ wp, data->searchstr, 1);
}
} else {
for (; np != 0; np--) {
window_copy_search_down(
- wp, data->searchstr);
+ wp, data->searchstr, 1);
}
}
break;
@@ -698,12 +706,12 @@ window_copy_key(struct window_pane *wp, struct
session *sess, int key)
if (cmd == MODEKEYCOPY_SEARCHAGAIN) {
for (; np != 0; np--) {
window_copy_search_down(
- wp, data->searchstr);
+ wp, data->searchstr, 1);
}
} else {
for (; np != 0; np--) {
window_copy_search_up(
- wp, data->searchstr);
+ wp, data->searchstr, 1);
}
}
break;
@@ -811,16 +819,16 @@ window_copy_key_input(struct window_pane *wp, int key)
case WINDOW_COPY_NUMERICPREFIX:
break;
case WINDOW_COPY_SEARCHUP:
- for (; np != 0; np--)
- window_copy_search_up(wp, data->inputstr);
data->searchtype = data->inputtype;
data->searchstr = xstrdup(data->inputstr);
+ for (; np != 0; np--)
+ window_copy_search_up(wp, data->inputstr, 0);
break;
case WINDOW_COPY_SEARCHDOWN:
- for (; np != 0; np--)
- window_copy_search_down(wp, data->inputstr);
data->searchtype = data->inputtype;
data->searchstr = xstrdup(data->inputstr);
+ for (; np != 0; np--)
+ window_copy_search_down(wp, data->inputstr, 0);
break;
case WINDOW_COPY_NAMEDBUFFER:
window_copy_copy_selection(wp, data->inputstr);
@@ -1033,88 +1041,97 @@ window_copy_search_rl(struct grid *gd,
return (0);
}

+/* For direction == 0 move left, otherwise right; jump line if needed */
void
-window_copy_search_up(struct window_pane *wp, const char *searchstr)
+window_copy_move_coordinates(struct screen *s,
+ u_int *fx, u_int *fy, const int direction)
{
- struct window_copy_mode_data *data = wp->modedata;
- struct screen *s = data->backing, ss;
- struct screen_write_ctx ctx;
- struct grid *gd = s->grid, *sgd;
- struct grid_cell gc;
- size_t searchlen;
- u_int i, last, fx, fy, px;
- int utf8flag, n, wrapped, wrapflag, cis;
- const char *ptr;
-
- if (*searchstr == '\0')
- return;
- utf8flag = options_get_number(&wp->window->options, "utf8");
- wrapflag = options_get_number(&wp->window->options, "wrap-search");
- searchlen = screen_write_strlen(utf8flag, "%s", searchstr);
-
- screen_init(&ss, searchlen, 1, 0);
- screen_write_start(&ctx, NULL, &ss);
- memcpy(&gc, &grid_default_cell, sizeof gc);
- screen_write_nputs(&ctx, -1, &gc, utf8flag, "%s", searchstr);
- screen_write_stop(&ctx);
-
- fx = data->cx;
- fy = gd->hsize - data->oy + data->cy;
-
- if (fx == 0) {
- if (fy == 0)
+ /* If on left/right border */
+ if (*fx == (direction ? screen_size_x(s) - 1 : 0)) {
+ /* If on top/bottom border */
+ if (*fy == (direction ? screen_hsize(s) + screen_size_y(s) : 0))
+ /* Nowhere to go */
return;
- fx = gd->sx - 1;
- fy--;
- } else
- fx--;
- n = wrapped = 0;
+ /* Jump to beggin/end of lower/upper line */
+ *fx = direction ? 0 : screen_size_x(s) - 1;
+ *fy = direction ? *fy + 1 : *fy - 1;
+ } else {
+ *fx = direction ? *fx + 1 : *fx - 1;
+ }
+}

- cis = 1;
- for (ptr = searchstr; *ptr != '\0'; ptr++) {
+int
+window_copy_is_lowercase(const char *ptr)
+{
+ while (*ptr != '\0') {
if (*ptr != tolower((u_char)*ptr)) {
- cis = 0;
- break;
+ return 0;
}
+ ++ptr;
}
+ return 1;
+}

-retry:
- sgd = ss.grid;
- for (i = fy + 1; i > 0; i--) {
- last = screen_size_x(s);
- if (i == fy + 1)
- last = fx;
- n = window_copy_search_rl(gd, sgd, &px, i - 1, 0, last, cis);
- if (n) {
- window_copy_scroll_to(wp, px, i - 1);
- break;
+/* Search in grid `gd` for text stored in grid `sgd` starting from position
+ * (`fx`, `fy`) up to line `endline` and if found then jump to it.
+ * If `cis` do it case-insensitive.
+ * `direction` 0 for searching up, down otherwise
+ * If `wrap` then go to begin/end of grid and try again up to line `fy` */
+void
+window_copy_jump_to_searched_string(struct window_pane *wp,
+ struct grid *gd, struct grid *sgd, u_int fx, u_int fy,
+ u_int endline, int cis, int wrap, const int direction)
+{
+ u_int i, px;
+ int firstIteration, found;
+
+ firstIteration = 1;
+ if (direction) {
+ for (i = fy; i <= endline; ++i) {
+ found = window_copy_search_lr(gd, sgd, &px, i,
+ firstIteration ? fx : 0, gd->sx, cis);
+ if (found) break;
+ firstIteration = 0;
+ }
+ } else {
+ for (i = fy + 1; endline < i; --i) {
+ found = window_copy_search_rl(gd, sgd, &px, i - 1,
+ 0, firstIteration ? fx : gd->sx, cis);
+ if (found) {
+ --i;
+ break;
+ }
+ firstIteration = 0;
}
}
- if (wrapflag && !n && !wrapped) {
- fx = gd->sx - 1;
- fy = gd->hsize + gd->sy - 1;
- wrapped = 1;
- goto retry;
+ if (found) {
+ window_copy_scroll_to(wp, px, i);
+ } else if (wrap) {
+ /* Start searching from begin/end of grid up to `fy` line */
+ window_copy_jump_to_searched_string(wp, gd, sgd,
+ direction ? 0 : gd->sx - 1,
+ direction ? 0 : gd->hsize + gd->sy - 1,
+ fy, cis, 0, direction);
}
-
- screen_free(&ss);
}

void
-window_copy_search_down(struct window_pane *wp, const char *searchstr)
+window_copy_search(struct window_pane *wp,
+ const char *searchstr, const int direction, const int move)
{
struct window_copy_mode_data *data = wp->modedata;
struct screen *s = data->backing, ss;
struct screen_write_ctx ctx;
- struct grid *gd = s->grid, *sgd;
- struct grid_cell gc;
+ struct grid *gd = s->grid;
+ struct grid_cell gc;
size_t searchlen;
- u_int i, first, fx, fy, px;
- int utf8flag, n, wrapped, wrapflag, cis;
- const char *ptr;
+ u_int fx, fy;
+ int utf8flag, wrapflag, cis;
+
+ /* current cursor coordinates */
+ fx = data->cx;
+ fy = screen_hsize(data->backing) - data->oy + data->cy;

- if (*searchstr == '\0')
- return;
utf8flag = options_get_number(&wp->window->options, "utf8");
wrapflag = options_get_number(&wp->window->options, "wrap-search");
searchlen = screen_write_strlen(utf8flag, "%s", searchstr);
@@ -1125,50 +1142,35 @@ window_copy_search_down(struct window_pane *wp,
const char *searchstr)
screen_write_nputs(&ctx, -1, &gc, utf8flag, "%s", searchstr);
screen_write_stop(&ctx);

- fx = data->cx;
- fy = gd->hsize - data->oy + data->cy;
-
- if (fx == gd->sx - 1) {
- if (fy == gd->hsize + gd->sy)
- return;
- fx = 0;
- fy++;
- } else
- fx++;
- n = wrapped = 0;
-
- cis = 1;
- for (ptr = searchstr; *ptr != '\0'; ptr++) {
- if (*ptr != tolower((u_char)*ptr)) {
- cis = 0;
- break;
- }
+ if (move) {
+ window_copy_move_coordinates(s, &fx, &fy, direction);
}

-retry:
- sgd = ss.grid;
- for (i = fy + 1; i < gd->hsize + gd->sy + 1; i++) {
- first = 0;
- if (i == fy + 1)
- first = fx;
- n = window_copy_search_lr(gd, sgd, &px, i - 1, first, gd->sx,
- cis);
- if (n) {
- window_copy_scroll_to(wp, px, i - 1);
- break;
- }
- }
- if (wrapflag && !n && !wrapped) {
- fx = 0;
- fy = 0;
- wrapped = 1;
- goto retry;
- }
+ cis = window_copy_is_lowercase(searchstr);
+ window_copy_clear_selection(wp);
+
+ window_copy_jump_to_searched_string(wp, gd, ss.grid, fx, fy,
+ direction ? gd->hsize + gd->sy - 1 : 0,
+ cis, wrapflag, direction);

screen_free(&ss);
}

void
+window_copy_search_up(struct window_pane *wp, const char *searchstr,
+ const int move)
+{
+ window_copy_search(wp, searchstr, 0, move);
+}
+
+void
+window_copy_search_down(struct window_pane *wp, const char *searchstr,
+ const int move)
+{
+ window_copy_search(wp, searchstr, 1, move);
+}
+
+void
window_copy_goto_line(struct window_pane *wp, const char *linestr)
{
struct window_copy_mode_data *data = wp->modedata;


Incremental search in window-copy mode
==============================

diff --git window-copy.c window-copy.c
index 1213380..243c755 100644
--- window-copy.c
+++ window-copy.c
@@ -53,6 +53,9 @@ int window_copy_is_lowercase(const char *);
void window_copy_jump_to_searched_string(
struct window_pane *, struct grid *, struct grid *, u_int, u_int,
u_int, int, int, const int);
+int window_copy_coord_from_hist(struct window_pane *wp,
+ const size_t searchlen, u_int *fx, u_int *fy);
+void window_copy_clear_search_hist(struct window_pane *, u_int *, u_int *);
void window_copy_search(struct window_pane *, const char *,
const int, const int);
void window_copy_search_up(struct window_pane *, const char *, const int);
@@ -115,6 +118,22 @@ enum window_copy_input_type {
};

/*
+ * x, y - coordinates from which the search was made
+ * found - if the text was found
+ * searchlen - lenght of text that was searched
+ * prev - data of previous searches
+ */
+struct window_copy_search_hist {
+ u_int x;
+ u_int y;
+ int found;
+
+ size_t searchlen;
+
+ struct window_copy_search_hist *prev;
+};
+
+/*
* Copy-mode's visible screen (the "screen" field) is filled from one of
* two sources: the original contents of the pane (used when we
* actually enter via the "copy-mode" command, to copy the contents of
@@ -159,6 +178,7 @@ struct window_copy_mode_data {

enum window_copy_input_type searchtype;
char *searchstr;
+ struct window_copy_search_hist *searchhist;

enum window_copy_input_type jumptype;
char jumpchar;
@@ -190,6 +210,7 @@ window_copy_init(struct window_pane *wp)

data->searchtype = WINDOW_COPY_OFF;
data->searchstr = NULL;
+ data->searchhist = NULL;

if (wp->fd != -1)
bufferevent_disable(wp->event, EV_READ|EV_WRITE);
@@ -259,6 +280,7 @@ window_copy_free(struct window_pane *wp)

free(data->searchstr);
free(data->inputstr);
+ window_copy_clear_search_hist(wp, NULL, NULL);

if (data->backing != &wp->base) {
screen_free(data->backing);
@@ -672,10 +694,12 @@ window_copy_key(struct window_pane *wp, struct
session *sess, int key)
case MODEKEYCOPY_SEARCHUP:
data->inputtype = WINDOW_COPY_SEARCHUP;
data->inputprompt = "Search Up";
+ *data->inputstr = '\0';
goto input_on;
case MODEKEYCOPY_SEARCHDOWN:
data->inputtype = WINDOW_COPY_SEARCHDOWN;
data->inputprompt = "Search Down";
+ *data->inputstr = '\0';
goto input_on;
case MODEKEYCOPY_SEARCHAGAIN:
case MODEKEYCOPY_SEARCHREVERSE:
@@ -778,6 +802,7 @@ window_copy_key_input(struct window_pane *wp, int key)
int np;
struct paste_buffer *pb;
u_char ch;
+ u_int fx, fy;

switch (mode_key_lookup(&data->mdata, key, NULL)) {
case MODEKEYEDIT_CANCEL:
@@ -787,9 +812,29 @@ window_copy_key_input(struct window_pane *wp, int key)
inputlen = strlen(data->inputstr);
if (inputlen > 0)
data->inputstr[inputlen - 1] = '\0';
+ switch (data->inputtype) {
+ case WINDOW_COPY_SEARCHUP:
+ data->searchtype = data->inputtype;
+ free(data->searchstr);
+ data->searchstr = xstrdup(data->inputstr);
+ window_copy_search_up(wp, data->inputstr, 0);
+ break;
+ case WINDOW_COPY_SEARCHDOWN:
+ data->searchtype = data->inputtype;
+ free(data->searchstr);
+ data->searchstr = xstrdup(data->inputstr);
+ window_copy_search_down(wp, data->inputstr, 0);
+ break;
+ default:
+ break;
+ }
break;
case MODEKEYEDIT_DELETELINE:
*data->inputstr = '\0';
+ fx = data->cx;
+ fy = screen_hsize(data->backing) - data->oy + data->cy;
+ window_copy_clear_search_hist(wp, &fx, &fy);
+ window_copy_scroll_to(wp, fx, fy);
break;
case MODEKEYEDIT_PASTE:
if ((pb = paste_get_top()) == NULL)
@@ -820,15 +865,17 @@ window_copy_key_input(struct window_pane *wp, int key)
break;
case WINDOW_COPY_SEARCHUP:
data->searchtype = data->inputtype;
+ free(data->searchstr);
data->searchstr = xstrdup(data->inputstr);
- for (; np != 0; np--)
- window_copy_search_up(wp, data->inputstr, 0);
+ for (; np > 1; np--)
+ window_copy_search_up(wp, data->inputstr, 1);
break;
case WINDOW_COPY_SEARCHDOWN:
data->searchtype = data->inputtype;
+ free(data->searchstr);
data->searchstr = xstrdup(data->inputstr);
- for (; np != 0; np--)
- window_copy_search_down(wp, data->inputstr, 0);
+ for (; np > 1; np--)
+ window_copy_search_down(wp, data->inputstr, 1);
break;
case WINDOW_COPY_NAMEDBUFFER:
window_copy_copy_selection(wp, data->inputstr);
@@ -850,6 +897,22 @@ window_copy_key_input(struct window_pane *wp, int key)
data->inputstr = xrealloc(data->inputstr, 1, inputlen);
data->inputstr[inputlen - 2] = key;
data->inputstr[inputlen - 1] = '\0';
+ switch (data->inputtype) {
+ case WINDOW_COPY_SEARCHUP:
+ data->searchtype = data->inputtype;
+ free(data->searchstr);
+ data->searchstr = xstrdup(data->inputstr);
+ window_copy_search_up(wp, data->inputstr, 0);
+ break;
+ case WINDOW_COPY_SEARCHDOWN:
+ data->searchtype = data->inputtype;
+ free(data->searchstr);
+ data->searchstr = xstrdup(data->inputstr);
+ window_copy_search_down(wp, data->inputstr, 0);
+ break;
+ default:
+ break;
+ }
break;
default:
break;
@@ -1082,6 +1145,8 @@ window_copy_jump_to_searched_string(struct
window_pane *wp,
struct grid *gd, struct grid *sgd, u_int fx, u_int fy,
u_int endline, int cis, int wrap, const int direction)
{
+ struct window_copy_mode_data *data = wp->modedata;
+ struct window_copy_search_hist *searchhist = data->searchhist;
u_int i, px;
int firstIteration, found;

@@ -1112,6 +1177,60 @@ window_copy_jump_to_searched_string(struct
window_pane *wp,
direction ? 0 : gd->sx - 1,
direction ? 0 : gd->hsize + gd->sy - 1,
fy, cis, 0, direction);
+ } else {
+ if (searchhist != NULL) {
+ searchhist->found = 0;
+ }
+ }
+}
+
+/* If it returns 0 then, according to search history, last time we searched
+ * a shorter string we haven't found anything, so there is no point in
+ * incremental-searching a longer string (just an optimization) */
+int
+window_copy_coord_from_hist(struct window_pane *wp,
+ const size_t searchlen, u_int *fx, u_int *fy)
+{
+ struct window_copy_mode_data *data = wp->modedata;
+ struct window_copy_search_hist *searchhist = data->searchhist;
+
+ if (searchhist == NULL || searchhist->searchlen < searchlen) {
+ searchhist = xmalloc(sizeof (struct window_copy_search_hist));
+ searchhist->x = data->cx;
+ searchhist->y =
+ screen_hsize(data->backing) - data->oy + data->cy;
+ searchhist->searchlen = searchlen;
+ searchhist->found = data->searchhist == NULL ?
+ 1 : data->searchhist->found;
+
+ searchhist->prev = data->searchhist;
+ data->searchhist = searchhist;
+
+ *fx = searchhist->x;
+ *fy = searchhist->y;
+ } else {
+ *fx = searchhist->x;
+ *fy = searchhist->y;
+ searchhist = data->searchhist->prev;
+ free(data->searchhist);
+ data->searchhist = searchhist;
+ }
+
+ return searchhist == NULL ? 1 : searchhist->found;
+}
+
+void
+window_copy_clear_search_hist(struct window_pane *wp, u_int *fx, u_int *fy)
+{
+ struct window_copy_mode_data *data = wp->modedata;
+ struct window_copy_search_hist *searchhist = data->searchhist;
+
+ while (searchhist != NULL) {
+ if (fx != NULL) *fx = searchhist->x;
+ if (fy != NULL) *fy = searchhist->y;
+ searchhist = searchhist->prev;
+ free(data->searchhist);
+ data->searchhist = searchhist;
}
}

@@ -1132,6 +1251,14 @@ window_copy_search(struct window_pane *wp,
fx = data->cx;
fy = screen_hsize(data->backing) - data->oy + data->cy;

+ /* User deleted all searched text, jump to the initial cursor
+ * position and delete the searchhistory */
+ if ((searchstr == NULL) || (*searchstr == '\0')) {
+ window_copy_clear_search_hist(wp, &fx, &fy);
+ window_copy_scroll_to(wp, fx, fy);
+ return;
+ }
+
utf8flag = options_get_number(&wp->window->options, "utf8");
wrapflag = options_get_number(&wp->window->options, "wrap-search");
searchlen = screen_write_strlen(utf8flag, "%s", searchstr);
@@ -1142,8 +1269,19 @@ window_copy_search(struct window_pane *wp,
screen_write_nputs(&ctx, -1, &gc, utf8flag, "%s", searchstr);
screen_write_stop(&ctx);

+ /*
+ * `move` is useful for incremental searching. When we do incremental,
+ * we don't want to jump to the next matching word if we already stand
+ * on one, so `move=0`.
+ * But when user wants the next result, then we use `move=1`, so
+ * we start searching from the place next to the current cursor
+ * position */
if (move) {
window_copy_move_coordinates(s, &fx, &fy, direction);
+ } else {
+ if (!window_copy_coord_from_hist(wp, searchlen, &fx, &fy)) {
+ return;
+ }
}

cis = window_copy_is_lowercase(searchstr);


Highlight last search in window-copy mode
===============================

diff --git options-table.c options-table.c
index 8d680b3..79ecae3 100644
--- options-table.c
+++ options-table.c
@@ -619,6 +619,11 @@ const struct options_table_entry
window_options_table[] = {
.default_str = "bg=yellow,fg=black"
},

+ { .name = "highlight-style",
+ .type = OPTIONS_TABLE_STYLE,
+ .default_str = "bg=green,fg=black"
+ },
+
{ .name = "monitor-activity",
.type = OPTIONS_TABLE_FLAG,
.default_num = 0
@@ -802,6 +807,11 @@ const struct options_table_entry
window_options_table[] = {
.default_num = 1
},

+ { .name = "highlight-search",
+ .type = OPTIONS_TABLE_FLAG,
+ .default_num = 1
+ },
+
{ .name = "xterm-keys",
.type = OPTIONS_TABLE_FLAG,
.default_num = 0
diff --git screen-write.c screen-write.c
index 325fb9a..a36a1f2 100644
--- screen-write.c
+++ screen-write.c
@@ -902,7 +902,7 @@ screen_write_cell(struct screen_write_ctx *ctx, const
struct grid_cell *gc)
struct grid *gd = s->grid;
struct tty_ctx ttyctx;
u_int width, xx, last;
- struct grid_cell tmp_gc, *tmp_gcp;
+ struct grid_cell tmp_gc, *tmp_gcp, *cell = NULL;
struct utf8_data ud;
int insert;

@@ -995,6 +995,15 @@ screen_write_cell(struct screen_write_ctx *ctx, const
struct grid_cell *gc)
(GRID_FLAG_FG256|GRID_FLAG_BG256);
ttyctx.cell = &tmp_gc;
tty_write(tty_cmd_cell, &ttyctx);
+ } else if (screen_check_highlight(s, s->cx - width, s->cy, &cell)) {
+ memcpy(&tmp_gc, cell, sizeof tmp_gc);
+ grid_cell_get(gc, &ud);
+ grid_cell_set(&tmp_gc, &ud);
+ tmp_gc.flags = gc->flags & ~(GRID_FLAG_FG256|GRID_FLAG_BG256);
+ tmp_gc.flags |= cell->flags &
+ (GRID_FLAG_FG256|GRID_FLAG_BG256);
+ ttyctx.cell = &tmp_gc;
+ tty_write(tty_cmd_cell, &ttyctx);
} else {
ttyctx.cell = gc;
tty_write(tty_cmd_cell, &ttyctx);
diff --git screen.c screen.c
index 7bfc015..734b38e 100644
--- screen.c
+++ screen.c
@@ -44,6 +44,7 @@ screen_init(struct screen *s, u_int sx, u_int sy, u_int
hlimit)
s->cstyle = 0;
s->ccolour = xstrdup("");
s->tabs = NULL;
+ s->hls = NULL;

screen_reinit(s);
}
@@ -65,6 +66,7 @@ screen_reinit(struct screen *s)
grid_clear_lines(s->grid, s->grid->hsize, s->grid->sy);

screen_clear_selection(s);
+ screen_clear_highlight(s);
}

/* Destroy a screen. */
@@ -75,6 +77,7 @@ screen_free(struct screen *s)
free(s->title);
free(s->ccolour);
grid_destroy(s->grid);
+ screen_clear_highlight(s);
}

/* Reset tabs to default, eight spaces apart. */
@@ -357,6 +360,56 @@ screen_check_selection(struct screen *s, u_int px,
u_int py)
return (1);
}

+/* Set highlight. */
+void
+screen_set_highlight(struct screen *s,
+ u_int sx, u_int ex, u_int y, struct grid_cell *gc)
+{
+ struct screen_hls *hls = xmalloc(sizeof (struct screen_hls));
+
+ hls->sx = sx;
+ hls->ex = ex;
+ hls->y = y;
+ hls->next = s->hls;
+
+ memcpy(&hls->cell, gc, sizeof hls->cell);
+
+ s->hls = hls;
+}
+
+/* Clear highlights. */
+void
+screen_clear_highlight(struct screen *s)
+{
+ struct screen_hls *hls = s->hls, *hlsPrev;
+
+ while (hls != NULL) {
+ hlsPrev = hls;
+ hls = hls->next;
+ free(hlsPrev);
+ }
+
+ s->hls = NULL;
+}
+
+/* Check if cell in highlight. */
+int
+screen_check_highlight(struct screen *s, u_int px, u_int py,
+ struct grid_cell **cell)
+{
+ struct screen_hls *hls = s->hls;
+
+ while (hls != NULL) {
+ if (hls->sx <= px && px <= hls->ex && hls->y == py) {
+ *cell = &hls->cell;
+ return 1;
+ }
+ hls = hls->next;
+ }
+
+ return 0;
+}
+
/* Reflow wrapped lines. */
void
screen_reflow(struct screen *s, u_int new_x)
diff --git tmux.h tmux.h
index c4c5236..6fc5fd0 100644
--- tmux.h
+++ tmux.h
@@ -766,6 +766,17 @@ struct screen_sel {
struct grid_cell cell;
};

+/* Screen highlights. */
+struct screen_hls {
+ u_int sx;
+ u_int ex;
+
+ u_int y;
+
+ struct grid_cell cell;
+ struct screen_hls *next;
+};
+
/* Virtual screen. */
struct screen {
char *title;
@@ -786,6 +797,7 @@ struct screen {
bitstr_t *tabs;

struct screen_sel sel;
+ struct screen_hls *hls;
};

/* Screen write context. */
@@ -2118,6 +2130,11 @@ void screen_set_selection(struct screen *,
u_int, u_int, u_int, u_int, u_int, struct grid_cell *);
void screen_clear_selection(struct screen *);
int screen_check_selection(struct screen *, u_int, u_int);
+void screen_set_highlight(struct screen *,
+ u_int, u_int, u_int, struct grid_cell *);
+void screen_clear_highlight(struct screen *);
+int screen_check_highlight(struct screen *, u_int, u_int,
+ struct grid_cell **);
void screen_reflow(struct screen *, u_int);

/* window.c */
diff --git tty.c tty.c
index 7688e90..4511533 100644
--- tty.c
+++ tty.c
@@ -614,7 +614,7 @@ tty_draw_line(struct tty *tty, struct screen *s, u_int
py, u_int ox, u_int oy)
{
const struct grid_cell *gc;
struct grid_line *gl;
- struct grid_cell tmpgc;
+ struct grid_cell tmpgc, *cell = NULL;
struct utf8_data ud;
u_int i, sx;

@@ -649,6 +649,15 @@ tty_draw_line(struct tty *tty, struct screen *s, u_int
py, u_int ox, u_int oy)
tmpgc.flags |= s->sel.cell.flags &
(GRID_FLAG_FG256|GRID_FLAG_BG256);
tty_cell(tty, &tmpgc);
+ } else if (screen_check_highlight(s, i, py, &cell)) {
+ memcpy(&tmpgc, cell, sizeof tmpgc);
+ grid_cell_get(gc, &ud);
+ grid_cell_set(&tmpgc, &ud);
+ tmpgc.flags = gc->flags &
+ ~(GRID_FLAG_FG256|GRID_FLAG_BG256);
+ tmpgc.flags |= cell->flags &
+ (GRID_FLAG_FG256|GRID_FLAG_BG256);
+ tty_cell(tty, &tmpgc);
} else
tty_cell(tty, gc);
}
diff --git window-copy.c window-copy.c
index 243c755..00cdc3f 100644
--- window-copy.c
+++ window-copy.c
@@ -28,10 +28,13 @@ struct screen *window_copy_init(struct window_pane *);
void window_copy_free(struct window_pane *);
void window_copy_resize(struct window_pane *, u_int, u_int);
void window_copy_key(struct window_pane *, struct session *, int);
+void window_copy_key_internal(struct window_pane *, struct session *, int);
int window_copy_key_input(struct window_pane *, int);
int window_copy_key_numeric_prefix(struct window_pane *, int);
void window_copy_mouse(
struct window_pane *, struct session *, struct mouse_event *);
+void window_copy_mouse_internal(
+ struct window_pane *, struct session *, struct mouse_event *);

void window_copy_redraw_lines(struct window_pane *, u_int, u_int);
void window_copy_redraw_screen(struct window_pane *);
@@ -53,6 +56,7 @@ int window_copy_is_lowercase(const char *);
void window_copy_jump_to_searched_string(
struct window_pane *, struct grid *, struct grid *, u_int, u_int,
u_int, int, int, const int);
+void window_copy_highlight_search(struct window_pane *);
int window_copy_coord_from_hist(struct window_pane *wp,
const size_t searchlen, u_int *fx, u_int *fy);
void window_copy_clear_search_hist(struct window_pane *, u_int *, u_int *);
@@ -397,6 +401,16 @@ window_copy_resize(struct window_pane *wp, u_int sx,
u_int sy)
void
window_copy_key(struct window_pane *wp, struct session *sess, int key)
{
+ window_copy_key_internal(wp, sess, key);
+
+ if (wp->mode != NULL) {
+ window_copy_highlight_search(wp);
+ }
+}
+
+void
+window_copy_key_internal(struct window_pane *wp, struct session *sess, int
key)
+{
const char *word_separators;
struct window_copy_mode_data *data = wp->modedata;
struct screen *s = &data->screen;
@@ -944,6 +958,17 @@ void
window_copy_mouse(
struct window_pane *wp, struct session *sess, struct mouse_event *m)
{
+ window_copy_mouse_internal(wp, sess, m);
+
+ if (wp->mode != NULL) {
+ window_copy_highlight_search(wp);
+ }
+}
+
+void
+window_copy_mouse_internal(
+ struct window_pane *wp, struct session *sess, struct mouse_event *m)
+{
struct window_copy_mode_data *data = wp->modedata;
struct screen *s = &data->screen;
u_int i;
@@ -1184,6 +1209,68 @@ window_copy_jump_to_searched_string(struct
window_pane *wp,
}
}

+void
+window_copy_highlight_search(struct window_pane *wp)
+{
+ struct window_copy_mode_data *data = wp->modedata;
+ struct screen *s = data->backing, ss;
+ struct screen_write_ctx ctx;
+ struct grid *gd = s->grid;
+ struct grid_cell gc;
+ struct options *oo = &wp->window->options;
+ const char *searchstr = data->searchstr;
+ size_t searchlen;
+ u_int i, px, last, beginline, endline;
+ int found, utf8flag, cis, highlight;
+
+ highlight = options_get_number(
+ &wp->window->options, "highlight-search");
+ if (!highlight) {
+ return;
+ }
+
+ screen_clear_highlight(&data->screen);
+
+ if ((searchstr != NULL) && (*searchstr != '\0')) {
+ utf8flag = options_get_number(&wp->window->options, "utf8");
+ searchlen = screen_write_strlen(utf8flag, "%s", searchstr);
+
+ screen_init(&ss, searchlen, 1, 0);
+ screen_write_start(&ctx, NULL, &ss);
+ memcpy(&gc, &grid_default_cell, sizeof gc);
+ screen_write_nputs(&ctx, -1, &gc, utf8flag, "%s", searchstr);
+ screen_write_stop(&ctx);
+
+ cis = window_copy_is_lowercase(searchstr);
+
+ /* Set colours. */
+ style_apply(&gc, oo, "highlight-style");
+
+ beginline = screen_hsize(s) - data->oy;
+ endline = screen_hsize(s) - data->oy + screen_size_y(s) - 1;
+
+ for (i = beginline; i <= endline; ++i) {
+ last = 0;
+ do {
+ found = window_copy_search_lr(gd, ss.grid, &px,
+ i, last, gd->sx, cis);
+ if (found) {
+ screen_set_highlight(
+ &data->screen,
+ px,
+ px + searchlen - 1,
+ i - (screen_hsize(s)
+ - data->oy),
+ &gc);
+ last += searchlen;
+ }
+ } while (found);
+ }
+ }
+
+ window_copy_redraw_screen(wp);
+}
+
/* If it returns 0 then, according to search history, last time we searched
* a shorter string we haven't found anything, so there is no point in
* incremental-searching a longer string (just an optimization) */
Nicholas Marriott
2014-08-08 18:21:41 UTC
Permalink
Hi

Your mailer has mangled the diffs, if you can't fix it so it works
inline please send them as attachments instead.
Post by Łukasz Piątkowski
I have split up my changes into 3 diffs, first is refactoring search code
in window-copy.c, second is adding incremental search and the last one is
adding search highlighting.
Cheers
Lukas
--
I**am**providing**code**in**this**repository**to**you**under**an**open**source**license.**Because**this**is**my**personal
repository,**the**license**you**receive**to**my**code**is**from**me**and**not**from**my**employer**(Facebook).
All contributions must be under the ISC license that is at the top of
each file you modify.

Thanks
Post by Łukasz Piątkowski
--
Refactor window-copy search functions
============================
diff --git window-copy.c window-copy.c
index 0775bcb..1213380 100644
--- window-copy.c
+++ window-copy.c
@@ -47,8 +47,16 @@ int window_copy_search_lr(
** ** **struct grid *, struct grid *, u_int *, u_int, u_int, u_int,
int);
**int window_copy_search_rl(
** ** **struct grid *, struct grid *, u_int *, u_int, u_int, u_int,
int);
-void window_copy_search_up(struct window_pane *, const char *);
-void window_copy_search_down(struct window_pane *, const char *);
+void window_copy_move_coordinates(
+ ** **struct screen *, u_int *, u_int *, const int);
+int window_copy_is_lowercase(const char *);
+void window_copy_jump_to_searched_string(
+ ** **struct window_pane *, struct grid *, struct grid *, u_int,
u_int,
+ ** **u_int, int, int, const int);
+void window_copy_search(struct window_pane *, const char *,
+ ** **const int, const int);
+void window_copy_search_up(struct window_pane *, const char *, const
int);
+void window_copy_search_down(struct window_pane *, const char *, const
int);
**void window_copy_goto_line(struct window_pane *, const char *);
**void window_copy_update_cursor(struct window_pane *, u_int, u_int);
**void window_copy_start_selection(struct window_pane *);
@@ -685,12 +693,12 @@ window_copy_key(struct window_pane *wp, struct
session *sess, int key)
** if (cmd == MODEKEYCOPY_SEARCHAGAIN) {
** for (; np != 0; np--) {
** window_copy_search_up(
- ** **wp, data->searchstr);
+ wp, data->searchstr, 1);
** }
** } else {
** for (; np != 0; np--) {
** window_copy_search_down(
- ** **wp, data->searchstr);
+ wp, data->searchstr, 1);
** }
** }
** break;
@@ -698,12 +706,12 @@ window_copy_key(struct window_pane *wp, struct
session *sess, int key)
** if (cmd == MODEKEYCOPY_SEARCHAGAIN) {
** for (; np != 0; np--) {
** window_copy_search_down(
- ** **wp, data->searchstr);
+ wp, data->searchstr, 1);
** }
** } else {
** for (; np != 0; np--) {
** window_copy_search_up(
- ** **wp, data->searchstr);
+ wp, data->searchstr, 1);
** }
** }
** break;
@@ -811,16 +819,16 @@ window_copy_key_input(struct window_pane *wp, int key)
** break;
- for (; np != 0; np--)
- window_copy_search_up(wp, data->inputstr);
** data->searchtype = data->inputtype;
** data->searchstr = xstrdup(data->inputstr);
+ for (; np != 0; np--)
+ window_copy_search_up(wp, data->inputstr,
0);
** break;
- for (; np != 0; np--)
- window_copy_search_down(wp,
data->inputstr);
** data->searchtype = data->inputtype;
** data->searchstr = xstrdup(data->inputstr);
+ for (; np != 0; np--)
+ window_copy_search_down(wp,
data->inputstr, 0);
** break;
** window_copy_copy_selection(wp, data->inputstr);
@@ -1033,88 +1041,97 @@ window_copy_search_rl(struct grid *gd,
** return (0);
**}
+/* For direction == 0 move left, otherwise right; jump line if needed */
**void
-window_copy_search_up(struct window_pane *wp, const char *searchstr)
+window_copy_move_coordinates(struct screen *s,
+ u_int *fx, u_int *fy, const int direction)
**{
- struct window_copy_mode_data *data = wp->modedata;
- struct screen *s = data->backing, ss;
- struct screen_write_ctx ctx;
- struct grid *gd = s->grid, *sgd;
- struct grid_cell gc;
- size_t searchlen;
- u_int i, last, fx, fy, px;
- int utf8flag, n, wrapped, wrapflag,
cis;
- const char *ptr;
-
- if (*searchstr == '\0')
- return;
- utf8flag = options_get_number(&wp->window->options, "utf8");
- wrapflag = options_get_number(&wp->window->options,
"wrap-search");
- searchlen = screen_write_strlen(utf8flag, "%s", searchstr);
-
- screen_init(&ss, searchlen, 1, 0);
- screen_write_start(&ctx, NULL, &ss);
- memcpy(&gc, &grid_default_cell, sizeof gc);
- screen_write_nputs(&ctx, -1, &gc, utf8flag, "%s", searchstr);
- screen_write_stop(&ctx);
-
- fx = data->cx;
- fy = gd->hsize - data->oy + data->cy;
-
- if (fx == 0) {
- if (fy == 0)
+ /* If on left/right border */
+ if (*fx == (direction ? screen_size_x(s) - 1 : 0)) {
+ /* If on top/bottom border */
+ if (*fy == (direction ? screen_hsize(s) + screen_size_y(s)
: 0))
+ /* Nowhere to go */
** return;
- fx = gd->sx - 1;
- fy--;
- } else
- fx--;
- n = wrapped = 0;
+ /* Jump to beggin/end of lower/upper line */
+ *fx = direction ? 0 : screen_size_x(s) - 1;
+ *fy = direction ? *fy + 1 : *fy - 1;
+ } else {
+ *fx = direction ? *fx + 1 : *fx - 1;
+ }
+}
- cis = 1;
- for (ptr = searchstr; *ptr != '\0'; ptr++) {
+int
+window_copy_is_lowercase(const char *ptr)
+{
+ while (*ptr != '\0') {
** if (*ptr != tolower((u_char)*ptr)) {
- cis = 0;
- break;
+ return 0;
** }
+ ++ptr;
** }
+ return 1;
+}
- sgd = ss.grid;
- for (i = fy + 1; i > 0; i--) {
- last = screen_size_x(s);
- if (i == fy + 1)
- last = fx;
- n = window_copy_search_rl(gd, sgd, &px, i - 1, 0, last,
cis);
- if (n) {
- window_copy_scroll_to(wp, px, i - 1);
- break;
+/* Search in grid `gd` for text stored in grid `sgd` starting from position
+ * (`fx`, `fy`) up to line `endline` and if found then jump to it.
+ * If `cis` do it case-insensitive.
+ * `direction` 0 for searching up, down otherwise
+ * If `wrap` then go to begin/end of grid and try again up to line `fy` */
+void
+window_copy_jump_to_searched_string(struct window_pane *wp,
+ ** **struct grid *gd, struct grid *sgd, u_int fx, u_int fy,
+ ** **u_int endline, int cis, int wrap, const int direction)
+{
+ u_int i, px;
+ int firstIteration, found;
+
+ firstIteration = 1;
+ if (direction) {
+ for (i = fy; i <= endline; ++i) {
+ found = window_copy_search_lr(gd, sgd, &px, i,
+ firstIteration ? fx : 0, gd->sx, cis);
+ if (found) break;
+ firstIteration = 0;
+ }
+ } else {
+ for (i = fy + 1; endline < i; --i) {
+ found = window_copy_search_rl(gd, sgd, &px, i - 1,
+ 0, firstIteration ? fx : gd->sx, cis);
+ if (found) {
+ --i;
+ break;
+ }
+ firstIteration = 0;
** }
** }
- if (wrapflag && !n && !wrapped) {
- fx = gd->sx - 1;
- fy = gd->hsize + gd->sy - 1;
- wrapped = 1;
- goto retry;
+ if (found) {
+ window_copy_scroll_to(wp, px, i);
+ } else if (wrap) {
+ /* Start searching from begin/end of grid up to `fy` line
*/
+ window_copy_jump_to_searched_string(wp, gd, sgd,
+ direction ? 0 : gd->sx - 1,
+ direction ? 0 : gd->hsize + gd->sy - 1,
+ fy, cis, 0, direction);
** }
-
- screen_free(&ss);
**}
**void
-window_copy_search_down(struct window_pane *wp, const char *searchstr)
+window_copy_search(struct window_pane *wp,
+ ** **const char *searchstr, const int direction, const int move)
**{
** struct window_copy_mode_data *data = wp->modedata;
** struct screen *s = data->backing, ss;
** struct screen_write_ctx ctx;
- struct grid *gd = s->grid, *sgd;
- struct grid_cell gc;
+ struct grid *gd = s->grid;
+ struct grid_cell gc;
** size_t searchlen;
- u_int i, first, fx, fy, px;
- int utf8flag, n, wrapped, wrapflag,
cis;
- const char *ptr;
+ u_int fx, fy;
+ int utf8flag, wrapflag, cis;
+
+ /* current cursor coordinates */
+ fx = data->cx;
+ fy = screen_hsize(data->backing) - data->oy + data->cy;
- if (*searchstr == '\0')
- return;
** utf8flag = options_get_number(&wp->window->options, "utf8");
** wrapflag = options_get_number(&wp->window->options,
"wrap-search");
** searchlen = screen_write_strlen(utf8flag, "%s", searchstr);
@@ -1125,50 +1142,35 @@ window_copy_search_down(struct window_pane *wp,
const char *searchstr)
** screen_write_nputs(&ctx, -1, &gc, utf8flag, "%s", searchstr);
** screen_write_stop(&ctx);
- fx = data->cx;
- fy = gd->hsize - data->oy + data->cy;
-
- if (fx == gd->sx - 1) {
- if (fy == gd->hsize + gd->sy)
- return;
- fx = 0;
- fy++;
- } else
- fx++;
- n = wrapped = 0;
-
- cis = 1;
- for (ptr = searchstr; *ptr != '\0'; ptr++) {
- if (*ptr != tolower((u_char)*ptr)) {
- cis = 0;
- break;
- }
+ if (move) {
+ window_copy_move_coordinates(s, &fx, &fy, direction);
** }
- sgd = ss.grid;
- for (i = fy + 1; i < gd->hsize + gd->sy + 1; i++) {
- first = 0;
- if (i == fy + 1)
- first = fx;
- n = window_copy_search_lr(gd, sgd, &px, i - 1, first,
gd->sx,
- ** **cis);
- if (n) {
- window_copy_scroll_to(wp, px, i - 1);
- break;
- }
- }
- if (wrapflag && !n && !wrapped) {
- fx = 0;
- fy = 0;
- wrapped = 1;
- goto retry;
- }
+ cis = window_copy_is_lowercase(searchstr);
+ window_copy_clear_selection(wp);
+
+ window_copy_jump_to_searched_string(wp, gd, ss.grid, fx, fy,
+ direction ? gd->hsize + gd->sy - 1 : 0,
+ cis, wrapflag, direction);
** screen_free(&ss);
**}
**void
+window_copy_search_up(struct window_pane *wp, const char *searchstr,
+ const int move)
+{
+ window_copy_search(wp, searchstr, 0, move);
+}
+
+void
+window_copy_search_down(struct window_pane *wp, const char *searchstr,
+ const int move)
+{
+ window_copy_search(wp, searchstr, 1, move);
+}
+
+void
**window_copy_goto_line(struct window_pane *wp, const char *linestr)
**{
** struct window_copy_mode_data *data = wp->modedata;
Incremental search in window-copy mode
==============================
diff --git window-copy.c window-copy.c
index 1213380..243c755 100644
--- window-copy.c
+++ window-copy.c
@@ -53,6 +53,9 @@ int window_copy_is_lowercase(const char *);
**void window_copy_jump_to_searched_string(
** ** **struct window_pane *, struct grid *, struct grid *, u_int,
u_int,
** ** **u_int, int, int, const int);
+int window_copy_coord_from_hist(struct window_pane *wp,
+ ** **const size_t searchlen, u_int *fx, u_int *fy);
+void window_copy_clear_search_hist(struct window_pane *, u_int *, u_int
*);
**void window_copy_search(struct window_pane *, const char *,
** ** **const int, const int);
**void window_copy_search_up(struct window_pane *, const char *, const
int);
@@ -115,6 +118,22 @@ enum window_copy_input_type {
**};
**/*
+ * x, y - coordinates from which the search was made
+ * found - if the text was found
+ * searchlen - lenght of text that was searched
+ * prev - data of previous searches
+ */
+struct window_copy_search_hist {
+ u_int x;
+ u_int y;
+ int found;
+
+ size_t searchlen;
+
+ struct window_copy_search_hist ***prev;
+};
+
+/*
** * Copy-mode's visible screen (the "screen" field) is filled from one of
** * two sources: the original contents of the pane (used when we
** * actually enter via the "copy-mode" command, to copy the contents of
@@ -159,6 +178,7 @@ struct window_copy_mode_data {
** enum window_copy_input_type searchtype;
** char ** ** ** *searchstr;
+ struct window_copy_search_hist *searchhist;
** enum window_copy_input_type jumptype;
** char jumpchar;
@@ -190,6 +210,7 @@ window_copy_init(struct window_pane *wp)
** data->searchtype = WINDOW_COPY_OFF;
** data->searchstr = NULL;
+ data->searchhist = NULL;
** if (wp->fd != -1)
** bufferevent_disable(wp->event, EV_READ|EV_WRITE);
@@ -259,6 +280,7 @@ window_copy_free(struct window_pane *wp)
** free(data->searchstr);
** free(data->inputstr);
+ window_copy_clear_search_hist(wp, NULL, NULL);
** if (data->backing != &wp->base) {
** screen_free(data->backing);
@@ -672,10 +694,12 @@ window_copy_key(struct window_pane *wp, struct
session *sess, int key)
** data->inputtype = WINDOW_COPY_SEARCHUP;
** data->inputprompt = "Search Up";
+ *data->inputstr = '\0';
** goto input_on;
** data->inputtype = WINDOW_COPY_SEARCHDOWN;
** data->inputprompt = "Search Down";
+ *data->inputstr = '\0';
** goto input_on;
@@ -778,6 +802,7 @@ window_copy_key_input(struct window_pane *wp, int key)
** int np;
** struct paste_buffer *pb;
** u_char ch;
+ u_int fx, fy;
** switch (mode_key_lookup(&data->mdata, key, NULL)) {
@@ -787,9 +812,29 @@ window_copy_key_input(struct window_pane *wp, int key)
** inputlen = strlen(data->inputstr);
** if (inputlen > 0)
** data->inputstr[inputlen - 1] = '\0';
+ switch (data->inputtype) {
+ data->searchtype = data->inputtype;
+ free(data->searchstr);
+ data->searchstr = xstrdup(data->inputstr);
+ window_copy_search_up(wp, data->inputstr, 0);
+ break;
+ data->searchtype = data->inputtype;
+ free(data->searchstr);
+ data->searchstr = xstrdup(data->inputstr);
+ window_copy_search_down(wp, data->inputstr, 0);
+ break;
+ break;
+ }
** break;
** *data->inputstr = '\0';
+ fx = data->cx;
+ fy = screen_hsize(data->backing) - data->oy + data->cy;
+ window_copy_clear_search_hist(wp, &fx, &fy);
+ window_copy_scroll_to(wp, fx, fy);
** break;
** if ((pb = paste_get_top()) == NULL)
@@ -820,15 +865,17 @@ window_copy_key_input(struct window_pane *wp, int key)
** break;
** data->searchtype = data->inputtype;
+ free(data->searchstr);
** data->searchstr = xstrdup(data->inputstr);
- for (; np != 0; np--)
- window_copy_search_up(wp, data->inputstr,
0);
+ for (; np > 1; np--)
+ window_copy_search_up(wp, data->inputstr,
1);
** break;
** data->searchtype = data->inputtype;
+ free(data->searchstr);
** data->searchstr = xstrdup(data->inputstr);
- for (; np != 0; np--)
- window_copy_search_down(wp,
data->inputstr, 0);
+ for (; np > 1; np--)
+ window_copy_search_down(wp,
data->inputstr, 1);
** break;
** window_copy_copy_selection(wp, data->inputstr);
@@ -850,6 +897,22 @@ window_copy_key_input(struct window_pane *wp, int key)
** data->inputstr = xrealloc(data->inputstr, 1, inputlen);
** data->inputstr[inputlen - 2] = key;
** data->inputstr[inputlen - 1] = '\0';
+ switch (data->inputtype) {
+ data->searchtype = data->inputtype;
+ free(data->searchstr);
+ data->searchstr = xstrdup(data->inputstr);
+ window_copy_search_up(wp, data->inputstr, 0);
+ break;
+ data->searchtype = data->inputtype;
+ free(data->searchstr);
+ data->searchstr = xstrdup(data->inputstr);
+ window_copy_search_down(wp, data->inputstr, 0);
+ break;
+ break;
+ }
** break;
** break;
@@ -1082,6 +1145,8 @@ window_copy_jump_to_searched_string(struct
window_pane *wp,
** ** **struct grid *gd, struct grid *sgd, u_int fx, u_int fy,
** ** **u_int endline, int cis, int wrap, const int direction)
**{
+ struct window_copy_mode_data *data = wp->modedata;
+ struct window_copy_search_hist *searchhist = data->searchhist;
** u_int i, px;
** int firstIteration, found;
@@ -1112,6 +1177,60 @@ window_copy_jump_to_searched_string(struct
window_pane *wp,
** direction ? 0 : gd->sx - 1,
** direction ? 0 : gd->hsize + gd->sy - 1,
** fy, cis, 0, direction);
+ } else {
+ if (searchhist != NULL) {
+ searchhist->found = 0;
+ }
+ }
+}
+
+/* If it returns 0 then, according to search history, last time we searched
+ * a shorter string we haven't found anything, so there is no point in
+ * incremental-searching a longer string (just an optimization) */
+int
+window_copy_coord_from_hist(struct window_pane *wp,
+ ** **const size_t searchlen, u_int *fx, u_int *fy)
+{
+ struct window_copy_mode_data *data = wp->modedata;
+ struct window_copy_search_hist *searchhist = data->searchhist;
+
+ if (searchhist == NULL || searchhist->searchlen < searchlen) {
+ searchhist = xmalloc(sizeof (struct
window_copy_search_hist));
+ searchhist->x = data->cx;
+ searchhist->y =
+ screen_hsize(data->backing) - data->oy + data->cy;
+ searchhist->searchlen = searchlen;
+ searchhist->found = data->searchhist == NULL ?
+ 1 : data->searchhist->found;
+
+ searchhist->prev = data->searchhist;
+ data->searchhist = searchhist;
+
+ *fx = searchhist->x;
+ *fy = searchhist->y;
+ } else {
+ *fx = searchhist->x;
+ *fy = searchhist->y;
+ searchhist = data->searchhist->prev;
+ free(data->searchhist);
+ data->searchhist = searchhist;
+ }
+
+ return searchhist == NULL ? 1 : searchhist->found;
+}
+
+void
+window_copy_clear_search_hist(struct window_pane *wp, u_int *fx, u_int *fy)
+{
+ struct window_copy_mode_data *data = wp->modedata;
+ struct window_copy_search_hist *searchhist = data->searchhist;
+
+ while (searchhist != NULL) {
+ if (fx != NULL) *fx = searchhist->x;
+ if (fy != NULL) *fy = searchhist->y;
+ searchhist = searchhist->prev;
+ free(data->searchhist);
+ data->searchhist = searchhist;
** }
**}
@@ -1132,6 +1251,14 @@ window_copy_search(struct window_pane *wp,
** fx = data->cx;
** fy = screen_hsize(data->backing) - data->oy + data->cy;
+ /* User deleted all searched text, jump to the initial cursor
+ * position and delete the searchhistory */
+ if ((searchstr == NULL) || (*searchstr == '\0')) {
+ window_copy_clear_search_hist(wp, &fx, &fy);
+ window_copy_scroll_to(wp, fx, fy);
+ return;
+ }
+
** utf8flag = options_get_number(&wp->window->options, "utf8");
** wrapflag = options_get_number(&wp->window->options,
"wrap-search");
** searchlen = screen_write_strlen(utf8flag, "%s", searchstr);
@@ -1142,8 +1269,19 @@ window_copy_search(struct window_pane *wp,
** screen_write_nputs(&ctx, -1, &gc, utf8flag, "%s", searchstr);
** screen_write_stop(&ctx);
+ /*
+ * `move` is useful for incremental searching. When we do
incremental,
+ * **we don't want to jump to the next matching word if we already
stand
+ * **on one, so `move=0`.
+ * **But when user wants the next result, then we use `move=1`, so
+ * **we start searching from the place next to the current cursor
+ * **position */
** if (move) {
** window_copy_move_coordinates(s, &fx, &fy, direction);
+ } else {
+ if (!window_copy_coord_from_hist(wp, searchlen, &fx, &fy))
{
+ return;
+ }
** }
** cis = window_copy_is_lowercase(searchstr);
Highlight last search in window-copy mode
===============================
diff --git options-table.c options-table.c
index 8d680b3..79ecae3 100644
--- options-table.c
+++ options-table.c
@@ -619,6 +619,11 @@ const struct options_table_entry
window_options_table[] = {
** **.default_str = "bg=yellow,fg=black"
** },
+ { .name = "highlight-style",
+ **.type = OPTIONS_TABLE_STYLE,
+ **.default_str = "bg=green,fg=black"
+ },
+
** { .name = "monitor-activity",
** **.type = OPTIONS_TABLE_FLAG,
** **.default_num = 0
@@ -802,6 +807,11 @@ const struct options_table_entry
window_options_table[] = {
** **.default_num = 1
** },
+ { .name = "highlight-search",
+ **.type = OPTIONS_TABLE_FLAG,
+ **.default_num = 1
+ },
+
** { .name = "xterm-keys",
** **.type = OPTIONS_TABLE_FLAG,
** **.default_num = 0
diff --git screen-write.c screen-write.c
index 325fb9a..a36a1f2 100644
--- screen-write.c
+++ screen-write.c
@@ -902,7 +902,7 @@ screen_write_cell(struct screen_write_ctx *ctx, const
struct grid_cell *gc)
** struct grid *gd = s->grid;
** struct tty_ctx ttyctx;
** u_int width, xx, last;
- struct grid_cell tmp_gc, *tmp_gcp;
+ struct grid_cell tmp_gc, *tmp_gcp, *cell = NULL;
** struct utf8_data ud;
** int insert;
@@ -995,6 +995,15 @@ screen_write_cell(struct screen_write_ctx *ctx, const
struct grid_cell *gc)
** ** **(GRID_FLAG_FG256|GRID_FLAG_BG256);
** ttyctx.cell = &tmp_gc;
** tty_write(tty_cmd_cell, &ttyctx);
+ } else if (screen_check_highlight(s, s->cx - width, s->cy, &cell))
{
+ memcpy(&tmp_gc, cell, sizeof tmp_gc);
+ grid_cell_get(gc, &ud);
+ grid_cell_set(&tmp_gc, &ud);
+ tmp_gc.flags = gc->flags &
~(GRID_FLAG_FG256|GRID_FLAG_BG256);
+ tmp_gc.flags |= cell->flags &
+ ** **(GRID_FLAG_FG256|GRID_FLAG_BG256);
+ ttyctx.cell = &tmp_gc;
+ tty_write(tty_cmd_cell, &ttyctx);
** } else {
** ttyctx.cell = gc;
** tty_write(tty_cmd_cell, &ttyctx);
diff --git screen.c screen.c
index 7bfc015..734b38e 100644
--- screen.c
+++ screen.c
@@ -44,6 +44,7 @@ screen_init(struct screen *s, u_int sx, u_int sy, u_int
hlimit)
** s->cstyle = 0;
** s->ccolour = xstrdup("");
** s->tabs = NULL;
+ s->hls = NULL;
** screen_reinit(s);
**}
@@ -65,6 +66,7 @@ screen_reinit(struct screen *s)
** grid_clear_lines(s->grid, s->grid->hsize, s->grid->sy);
** screen_clear_selection(s);
+ screen_clear_highlight(s);
**}
**/* Destroy a screen. */
@@ -75,6 +77,7 @@ screen_free(struct screen *s)
** free(s->title);
** free(s->ccolour);
** grid_destroy(s->grid);
+ screen_clear_highlight(s);
**}
**/* Reset tabs to default, eight spaces apart. */
@@ -357,6 +360,56 @@ screen_check_selection(struct screen *s, u_int px,
u_int py)
** return (1);
**}
+/* Set highlight. */
+void
+screen_set_highlight(struct screen *s,
+ u_int sx, u_int ex, u_int y, struct grid_cell *gc)
+{
+ struct screen_hls *hls = xmalloc(sizeof (struct
screen_hls));
+
+ hls->sx = sx;
+ hls->ex = ex;
+ hls->y = y;
+ hls->next = s->hls;
+
+ memcpy(&hls->cell, gc, sizeof hls->cell);
+
+ s->hls = hls;
+}
+
+/* Clear highlights. */
+void
+screen_clear_highlight(struct screen *s)
+{
+ struct screen_hls *hls = s->hls, *hlsPrev;
+
+ while (hls != NULL) {
+ hlsPrev = hls;
+ hls = hls->next;
+ free(hlsPrev);
+ }
+
+ s->hls = NULL;
+}
+
+/* Check if cell in highlight. */
+int
+screen_check_highlight(struct screen *s, u_int px, u_int py,
+ struct grid_cell **cell)
+{
+ struct screen_hls *hls = s->hls;
+
+ while (hls != NULL) {
+ if (hls->sx <= px && px <= hls->ex && hls->y == py) {
+ *cell = &hls->cell;
+ return 1;
+ }
+ hls = hls->next;
+ }
+
+ return 0;
+}
+
**/* Reflow wrapped lines. */
**void
**screen_reflow(struct screen *s, u_int new_x)
diff --git tmux.h tmux.h
index c4c5236..6fc5fd0 100644
--- tmux.h
+++ tmux.h
@@ -766,6 +766,17 @@ struct screen_sel {
** struct grid_cell cell;
**};
+/* Screen highlights. */
+struct screen_hls {
+ u_int sx;
+ u_int ex;
+
+ u_int y;
+
+ struct grid_cell cell;
+ struct screen_hls *next;
+};
+
**/* Virtual screen. */
**struct screen {
** char *title;
@@ -786,6 +797,7 @@ struct screen {
** bitstr_t *tabs;
** struct screen_sel sel;
+ struct screen_hls *hls;
**};
**/* Screen write context. */
@@ -2118,6 +2130,11 @@ void screen_set_selection(struct screen *,
** ** ** u_int, u_int, u_int, u_int, u_int, struct grid_cell *);
**void screen_clear_selection(struct screen *);
**int screen_check_selection(struct screen *, u_int, u_int);
+void screen_set_highlight(struct screen *,
+ ** ** u_int, u_int, u_int, struct grid_cell *);
+void screen_clear_highlight(struct screen *);
+int screen_check_highlight(struct screen *, u_int, u_int,
+ ** ** struct grid_cell **);
**void screen_reflow(struct screen *, u_int);
**/* window.c */
diff --git tty.c tty.c
index 7688e90..4511533 100644
--- tty.c
+++ tty.c
@@ -614,7 +614,7 @@ tty_draw_line(struct tty *tty, struct screen *s, u_int
py, u_int ox, u_int oy)
**{
** const struct grid_cell *gc;
** struct grid_line *gl;
- struct grid_cell tmpgc;
+ struct grid_cell tmpgc, *cell = NULL;
** struct utf8_data ud;
** u_int i, sx;
@@ -649,6 +649,15 @@ tty_draw_line(struct tty *tty, struct screen *s,
u_int py, u_int ox, u_int oy)
** tmpgc.flags |= s->sel.cell.flags &
** ** **(GRID_FLAG_FG256|GRID_FLAG_BG256);
** tty_cell(tty, &tmpgc);
+ } else if (screen_check_highlight(s, i, py, &cell)) {
+ memcpy(&tmpgc, cell, sizeof tmpgc);
+ grid_cell_get(gc, &ud);
+ grid_cell_set(&tmpgc, &ud);
+ tmpgc.flags = gc->flags &
+ ** **~(GRID_FLAG_FG256|GRID_FLAG_BG256);
+ tmpgc.flags |= cell->flags &
+ ** **(GRID_FLAG_FG256|GRID_FLAG_BG256);
+ tty_cell(tty, &tmpgc);
** } else
** tty_cell(tty, gc);
** }
diff --git window-copy.c window-copy.c
index 243c755..00cdc3f 100644
--- window-copy.c
+++ window-copy.c
@@ -28,10 +28,13 @@ struct screen *window_copy_init(struct window_pane *);
**void window_copy_free(struct window_pane *);
**void window_copy_resize(struct window_pane *, u_int, u_int);
**void window_copy_key(struct window_pane *, struct session *, int);
+void window_copy_key_internal(struct window_pane *, struct session *,
int);
**int window_copy_key_input(struct window_pane *, int);
**int window_copy_key_numeric_prefix(struct window_pane *, int);
**void window_copy_mouse(
** ** **struct window_pane *, struct session *, struct mouse_event
*);
+void window_copy_mouse_internal(
+ ** **struct window_pane *, struct session *, struct mouse_event
*);
**void window_copy_redraw_lines(struct window_pane *, u_int, u_int);
**void window_copy_redraw_screen(struct window_pane *);
@@ -53,6 +56,7 @@ int window_copy_is_lowercase(const char *);
**void window_copy_jump_to_searched_string(
** ** **struct window_pane *, struct grid *, struct grid *, u_int,
u_int,
** ** **u_int, int, int, const int);
+void window_copy_highlight_search(struct window_pane *);
**int window_copy_coord_from_hist(struct window_pane *wp,
** ** **const size_t searchlen, u_int *fx, u_int *fy);
**void window_copy_clear_search_hist(struct window_pane *, u_int *, u_int
*);
@@ -397,6 +401,16 @@ window_copy_resize(struct window_pane *wp, u_int sx,
u_int sy)
**void
**window_copy_key(struct window_pane *wp, struct session *sess, int key)
**{
+ window_copy_key_internal(wp, sess, key);
+
+ if (wp->mode != NULL) {
+ window_copy_highlight_search(wp);
+ }
+}
+
+void
+window_copy_key_internal(struct window_pane *wp, struct session *sess,
int key)
+{
** const char *word_separators;
** struct window_copy_mode_data *data = wp->modedata;
** struct screen *s = &data->screen;
@@ -944,6 +958,17 @@ void
**window_copy_mouse(
** ** **struct window_pane *wp, struct session *sess, struct mouse_event
*m)
**{
+ window_copy_mouse_internal(wp, sess, m);
+
+ if (wp->mode != NULL) {
+ window_copy_highlight_search(wp);
+ }
+}
+
+void
+window_copy_mouse_internal(
+ ** **struct window_pane *wp, struct session *sess, struct mouse_event
*m)
+{
** struct window_copy_mode_data *data = wp->modedata;
** struct screen *s = &data->screen;
** u_int i;
@@ -1184,6 +1209,68 @@ window_copy_jump_to_searched_string(struct
window_pane *wp,
** }
**}
+void
+window_copy_highlight_search(struct window_pane *wp)
+{
+ struct window_copy_mode_data *data = wp->modedata;
+ struct screen *s = data->backing, ss;
+ struct screen_write_ctx ctx;
+ struct grid *gd = s->grid;
+ struct grid_cell gc;
+ struct options *oo = &wp->window->options;
+ const char *searchstr = data->searchstr;
+ size_t searchlen;
+ u_int i, px, last, beginline, endline;
+ int found, utf8flag, cis, highlight;
+
+ highlight = options_get_number(
+ &wp->window->options, "highlight-search");
+ if (!highlight) {
+ return;
+ }
+
+ screen_clear_highlight(&data->screen);
+
+ if ((searchstr != NULL) && (*searchstr != '\0')) {
+ utf8flag = options_get_number(&wp->window->options,
"utf8");
+ searchlen = screen_write_strlen(utf8flag, "%s",
searchstr);
+
+ screen_init(&ss, searchlen, 1, 0);
+ screen_write_start(&ctx, NULL, &ss);
+ memcpy(&gc, &grid_default_cell, sizeof gc);
+ screen_write_nputs(&ctx, -1, &gc, utf8flag, "%s",
searchstr);
+ screen_write_stop(&ctx);
+
+ cis = window_copy_is_lowercase(searchstr);
+
+ /* Set colours. */
+ style_apply(&gc, oo, "highlight-style");
+
+ beginline = screen_hsize(s) - data->oy;
+ endline = screen_hsize(s) - data->oy + screen_size_y(s) -
1;
+
+ for (i = beginline; i <= endline; ++i) {
+ last = 0;
+ do {
+ found = window_copy_search_lr(gd, ss.grid,
&px,
+ i, last, gd->sx, cis);
+ if (found) {
+ screen_set_highlight(
+ &data->screen,
+ px,
+ px + searchlen - 1,
+ i - (screen_hsize(s)
+ ** ** - data->oy),
+ &gc);
+ last += searchlen;
+ }
+ } while (found);
+ }
+ }
+
+ window_copy_redraw_screen(wp);
+}
+
**/* If it returns 0 then, according to search history, last time we
searched
** * a shorter string we haven't found anything, so there is no point in
** * incremental-searching a longer string (just an optimization) */
------------------------------------------------------------------------------
Want fast and easy access to all the code in your enterprise? Index and
search up to 200,000 lines of code with a free copy of Black Duck
Code Sight - the same software that powers the world's largest code
search on Ohloh, the Black Duck Open Hub! Try it now.
http://p.sf.net/sfu/bds
_______________________________________________
tmux-users mailing list
https://lists.sourceforge.net/lists/listinfo/tmux-users
Łukasz Piątkowski
2014-11-01 00:35:24 UTC
Permalink
Hi Felix,

I didn't have time to work on this, last few months were really busy. I
will try to rebase my changes on top of current revision and test them
before sending the code again. I hope I will find some time before the end
of year.

Cheers
Lukas
Was there any follow up to this thread? Incremental search would be a
great feature to have and is on the TODO list.
Thanks.
-FR
On Fri, Aug 8, 2014 at 11:21 AM, Nicholas Marriott <
Post by Nicholas Marriott
Hi
Your mailer has mangled the diffs, if you can't fix it so it works
inline please send them as attachments instead.
Post by Łukasz Piątkowski
I have split up my changes into 3 diffs, first is refactoring search
code
Post by Łukasz Piątkowski
in window-copy.c, second is adding incremental search and the last
one is
Post by Łukasz Piątkowski
adding search highlighting.
Cheers
Lukas
--
I**am**providing**code**in**this**repository**to**you**under**an**open**source**license.**Because**this**is**my**personal
repository,**the**license**you**receive**to**my**code**is**from**me**and**not**from**my**employer**(Facebook).
All contributions must be under the ISC license that is at the top of
each file you modify.
Thanks
Post by Łukasz Piątkowski
--
Refactor window-copy search functions
============================
diff --git window-copy.c window-copy.c
index 0775bcb..1213380 100644
--- window-copy.c
+++ window-copy.c
@@ -47,8 +47,16 @@ int window_copy_search_lr(
** ** **struct grid *, struct grid *, u_int *, u_int, u_int,
u_int,
Post by Łukasz Piątkowski
int);
**int window_copy_search_rl(
** ** **struct grid *, struct grid *, u_int *, u_int, u_int,
u_int,
Post by Łukasz Piątkowski
int);
-void window_copy_search_up(struct window_pane *, const char *);
-void window_copy_search_down(struct window_pane *, const char *);
+void window_copy_move_coordinates(
+ ** **struct screen *, u_int *, u_int *, const int);
+int window_copy_is_lowercase(const char *);
+void window_copy_jump_to_searched_string(
+ ** **struct window_pane *, struct grid *, struct grid *,
u_int,
Post by Łukasz Piątkowski
u_int,
+ ** **u_int, int, int, const int);
+void window_copy_search(struct window_pane *, const char *,
+ ** **const int, const int);
+void window_copy_search_up(struct window_pane *, const char *,
const
Post by Łukasz Piątkowski
int);
+void window_copy_search_down(struct window_pane *, const char *,
const
Post by Łukasz Piątkowski
int);
**void window_copy_goto_line(struct window_pane *, const char *);
**void window_copy_update_cursor(struct window_pane *, u_int,
u_int);
Post by Łukasz Piątkowski
**void window_copy_start_selection(struct window_pane *);
@@ -685,12 +693,12 @@ window_copy_key(struct window_pane *wp, struct
session *sess, int key)
** if (cmd == MODEKEYCOPY_SEARCHAGAIN) {
** for (; np != 0; np--) {
** window_copy_search_up(
- ** **wp, data->searchstr);
+ wp, data->searchstr,
1);
Post by Łukasz Piątkowski
** }
** } else {
** for (; np != 0; np--) {
** window_copy_search_down(
- ** **wp, data->searchstr);
+ wp, data->searchstr,
1);
Post by Łukasz Piątkowski
** }
** }
** break;
@@ -698,12 +706,12 @@ window_copy_key(struct window_pane *wp, struct
session *sess, int key)
** if (cmd == MODEKEYCOPY_SEARCHAGAIN) {
** for (; np != 0; np--) {
** window_copy_search_down(
- ** **wp, data->searchstr);
+ wp, data->searchstr,
1);
Post by Łukasz Piątkowski
** }
** } else {
** for (; np != 0; np--) {
** window_copy_search_up(
- ** **wp, data->searchstr);
+ wp, data->searchstr,
1);
Post by Łukasz Piątkowski
** }
** }
** break;
@@ -811,16 +819,16 @@ window_copy_key_input(struct window_pane *wp,
int
Post by Łukasz Piątkowski
key)
** break;
- for (; np != 0; np--)
- window_copy_search_up(wp,
data->inputstr);
Post by Łukasz Piątkowski
** data->searchtype = data->inputtype;
** data->searchstr = xstrdup(data->inputstr);
+ for (; np != 0; np--)
+ window_copy_search_up(wp,
data->inputstr,
Post by Łukasz Piątkowski
0);
** break;
- for (; np != 0; np--)
- window_copy_search_down(wp,
data->inputstr);
** data->searchtype = data->inputtype;
** data->searchstr = xstrdup(data->inputstr);
+ for (; np != 0; np--)
+ window_copy_search_down(wp,
data->inputstr, 0);
** break;
** window_copy_copy_selection(wp,
data->inputstr);
Post by Łukasz Piątkowski
@@ -1033,88 +1041,97 @@ window_copy_search_rl(struct grid *gd,
** return (0);
**}
+/* For direction == 0 move left, otherwise right; jump line if
needed */
Post by Łukasz Piątkowski
**void
-window_copy_search_up(struct window_pane *wp, const char *searchstr)
+window_copy_move_coordinates(struct screen *s,
+ u_int *fx, u_int *fy, const int direction)
**{
- struct window_copy_mode_data *data = wp->modedata;
- struct screen *s = data->backing, ss;
- struct screen_write_ctx ctx;
- struct grid *gd = s->grid, *sgd;
- struct grid_cell gc;
- size_t searchlen;
- u_int i, last, fx, fy, px;
- int utf8flag, n, wrapped,
wrapflag,
Post by Łukasz Piątkowski
cis;
- const char *ptr;
-
- if (*searchstr == '\0')
- return;
- utf8flag = options_get_number(&wp->window->options, "utf8");
- wrapflag = options_get_number(&wp->window->options,
"wrap-search");
- searchlen = screen_write_strlen(utf8flag, "%s", searchstr);
-
- screen_init(&ss, searchlen, 1, 0);
- screen_write_start(&ctx, NULL, &ss);
- memcpy(&gc, &grid_default_cell, sizeof gc);
- screen_write_nputs(&ctx, -1, &gc, utf8flag, "%s", searchstr);
- screen_write_stop(&ctx);
-
- fx = data->cx;
- fy = gd->hsize - data->oy + data->cy;
-
- if (fx == 0) {
- if (fy == 0)
+ /* If on left/right border */
+ if (*fx == (direction ? screen_size_x(s) - 1 : 0)) {
+ /* If on top/bottom border */
+ if (*fy == (direction ? screen_hsize(s) +
screen_size_y(s)
Post by Łukasz Piątkowski
: 0))
+ /* Nowhere to go */
** return;
- fx = gd->sx - 1;
- fy--;
- } else
- fx--;
- n = wrapped = 0;
+ /* Jump to beggin/end of lower/upper line */
+ *fx = direction ? 0 : screen_size_x(s) - 1;
+ *fy = direction ? *fy + 1 : *fy - 1;
+ } else {
+ *fx = direction ? *fx + 1 : *fx - 1;
+ }
+}
- cis = 1;
- for (ptr = searchstr; *ptr != '\0'; ptr++) {
+int
+window_copy_is_lowercase(const char *ptr)
+{
+ while (*ptr != '\0') {
** if (*ptr != tolower((u_char)*ptr)) {
- cis = 0;
- break;
+ return 0;
** }
+ ++ptr;
** }
+ return 1;
+}
- sgd = ss.grid;
- for (i = fy + 1; i > 0; i--) {
- last = screen_size_x(s);
- if (i == fy + 1)
- last = fx;
- n = window_copy_search_rl(gd, sgd, &px, i - 1, 0,
last,
Post by Łukasz Piątkowski
cis);
- if (n) {
- window_copy_scroll_to(wp, px, i - 1);
- break;
+/* Search in grid `gd` for text stored in grid `sgd` starting from position
+ * (`fx`, `fy`) up to line `endline` and if found then jump to it.
+ * If `cis` do it case-insensitive.
+ * `direction` 0 for searching up, down otherwise
+ * If `wrap` then go to begin/end of grid and try again up to line
`fy`
Post by Łukasz Piątkowski
*/
+void
+window_copy_jump_to_searched_string(struct window_pane *wp,
+ ** **struct grid *gd, struct grid *sgd, u_int fx, u_int fy,
+ ** **u_int endline, int cis, int wrap, const int direction)
+{
+ u_int i, px;
+ int firstIteration, found;
+
+ firstIteration = 1;
+ if (direction) {
+ for (i = fy; i <= endline; ++i) {
+ found = window_copy_search_lr(gd, sgd, &px,
i,
Post by Łukasz Piątkowski
+ firstIteration ? fx : 0, gd->sx,
cis);
Post by Łukasz Piątkowski
+ if (found) break;
+ firstIteration = 0;
+ }
+ } else {
+ for (i = fy + 1; endline < i; --i) {
+ found = window_copy_search_rl(gd, sgd, &px,
i - 1,
Post by Łukasz Piątkowski
+ 0, firstIteration ? fx : gd->sx,
cis);
Post by Łukasz Piątkowski
+ if (found) {
+ --i;
+ break;
+ }
+ firstIteration = 0;
** }
** }
- if (wrapflag && !n && !wrapped) {
- fx = gd->sx - 1;
- fy = gd->hsize + gd->sy - 1;
- wrapped = 1;
- goto retry;
+ if (found) {
+ window_copy_scroll_to(wp, px, i);
+ } else if (wrap) {
+ /* Start searching from begin/end of grid up to `fy`
line
Post by Łukasz Piątkowski
*/
+ window_copy_jump_to_searched_string(wp, gd, sgd,
+ direction ? 0 : gd->sx - 1,
+ direction ? 0 : gd->hsize + gd->sy - 1,
+ fy, cis, 0, direction);
** }
-
- screen_free(&ss);
**}
**void
-window_copy_search_down(struct window_pane *wp, const char
*searchstr)
Post by Łukasz Piątkowski
+window_copy_search(struct window_pane *wp,
+ ** **const char *searchstr, const int direction, const int move)
**{
** struct window_copy_mode_data *data = wp->modedata;
** struct screen *s = data->backing, ss;
** struct screen_write_ctx ctx;
- struct grid *gd = s->grid, *sgd;
- struct grid_cell gc;
+ struct grid *gd = s->grid;
+ struct grid_cell gc;
** size_t searchlen;
- u_int i, first, fx, fy, px;
- int utf8flag, n, wrapped,
wrapflag,
Post by Łukasz Piątkowski
cis;
- const char *ptr;
+ u_int fx, fy;
+ int utf8flag, wrapflag, cis;
+
+ /* current cursor coordinates */
+ fx = data->cx;
+ fy = screen_hsize(data->backing) - data->oy + data->cy;
- if (*searchstr == '\0')
- return;
** utf8flag = options_get_number(&wp->window->options, "utf8");
** wrapflag = options_get_number(&wp->window->options,
"wrap-search");
** searchlen = screen_write_strlen(utf8flag, "%s", searchstr);
@@ -1125,50 +1142,35 @@ window_copy_search_down(struct window_pane
*wp,
Post by Łukasz Piątkowski
const char *searchstr)
** screen_write_nputs(&ctx, -1, &gc, utf8flag, "%s", searchstr);
** screen_write_stop(&ctx);
- fx = data->cx;
- fy = gd->hsize - data->oy + data->cy;
-
- if (fx == gd->sx - 1) {
- if (fy == gd->hsize + gd->sy)
- return;
- fx = 0;
- fy++;
- } else
- fx++;
- n = wrapped = 0;
-
- cis = 1;
- for (ptr = searchstr; *ptr != '\0'; ptr++) {
- if (*ptr != tolower((u_char)*ptr)) {
- cis = 0;
- break;
- }
+ if (move) {
+ window_copy_move_coordinates(s, &fx, &fy, direction);
** }
- sgd = ss.grid;
- for (i = fy + 1; i < gd->hsize + gd->sy + 1; i++) {
- first = 0;
- if (i == fy + 1)
- first = fx;
- n = window_copy_search_lr(gd, sgd, &px, i - 1, first,
gd->sx,
- ** **cis);
- if (n) {
- window_copy_scroll_to(wp, px, i - 1);
- break;
- }
- }
- if (wrapflag && !n && !wrapped) {
- fx = 0;
- fy = 0;
- wrapped = 1;
- goto retry;
- }
+ cis = window_copy_is_lowercase(searchstr);
+ window_copy_clear_selection(wp);
+
+ window_copy_jump_to_searched_string(wp, gd, ss.grid, fx, fy,
+ direction ? gd->hsize + gd->sy - 1 : 0,
+ cis, wrapflag, direction);
** screen_free(&ss);
**}
**void
+window_copy_search_up(struct window_pane *wp, const char *searchstr,
+ const int move)
+{
+ window_copy_search(wp, searchstr, 0, move);
+}
+
+void
+window_copy_search_down(struct window_pane *wp, const char
*searchstr,
Post by Łukasz Piątkowski
+ const int move)
+{
+ window_copy_search(wp, searchstr, 1, move);
+}
+
+void
**window_copy_goto_line(struct window_pane *wp, const char *linestr)
**{
** struct window_copy_mode_data *data = wp->modedata;
Incremental search in window-copy mode
==============================
diff --git window-copy.c window-copy.c
index 1213380..243c755 100644
--- window-copy.c
+++ window-copy.c
@@ -53,6 +53,9 @@ int window_copy_is_lowercase(const char *);
**void window_copy_jump_to_searched_string(
** ** **struct window_pane *, struct grid *, struct grid *,
u_int,
Post by Łukasz Piątkowski
u_int,
** ** **u_int, int, int, const int);
+int window_copy_coord_from_hist(struct window_pane *wp,
+ ** **const size_t searchlen, u_int *fx, u_int *fy);
+void window_copy_clear_search_hist(struct window_pane *, u_int *,
u_int
Post by Łukasz Piątkowski
*);
**void window_copy_search(struct window_pane *, const char *,
** ** **const int, const int);
**void window_copy_search_up(struct window_pane *, const char *,
const
Post by Łukasz Piątkowski
int);
@@ -115,6 +118,22 @@ enum window_copy_input_type {
**};
**/*
+ * x, y - coordinates from which the search was made
+ * found - if the text was found
+ * searchlen - lenght of text that was searched
+ * prev - data of previous searches
+ */
+struct window_copy_search_hist {
+ u_int x;
+ u_int y;
+ int found;
+
+ size_t searchlen;
+
+ struct window_copy_search_hist ***prev;
+};
+
+/*
** * Copy-mode's visible screen (the "screen" field) is filled from
one of
Post by Łukasz Piątkowski
** * two sources: the original contents of the pane (used when we
** * actually enter via the "copy-mode" command, to copy the
contents of
Post by Łukasz Piątkowski
@@ -159,6 +178,7 @@ struct window_copy_mode_data {
** enum window_copy_input_type searchtype;
** char ** ** ** *searchstr;
+ struct window_copy_search_hist *searchhist;
** enum window_copy_input_type jumptype;
** char jumpchar;
@@ -190,6 +210,7 @@ window_copy_init(struct window_pane *wp)
** data->searchtype = WINDOW_COPY_OFF;
** data->searchstr = NULL;
+ data->searchhist = NULL;
** if (wp->fd != -1)
** bufferevent_disable(wp->event, EV_READ|EV_WRITE);
@@ -259,6 +280,7 @@ window_copy_free(struct window_pane *wp)
** free(data->searchstr);
** free(data->inputstr);
+ window_copy_clear_search_hist(wp, NULL, NULL);
** if (data->backing != &wp->base) {
** screen_free(data->backing);
@@ -672,10 +694,12 @@ window_copy_key(struct window_pane *wp, struct
session *sess, int key)
** data->inputtype = WINDOW_COPY_SEARCHUP;
** data->inputprompt = "Search Up";
+ *data->inputstr = '\0';
** goto input_on;
** data->inputtype = WINDOW_COPY_SEARCHDOWN;
** data->inputprompt = "Search Down";
+ *data->inputstr = '\0';
** goto input_on;
@@ -778,6 +802,7 @@ window_copy_key_input(struct window_pane *wp,
int key)
Post by Łukasz Piątkowski
** int np;
** struct paste_buffer *pb;
** u_char ch;
+ u_int fx, fy;
** switch (mode_key_lookup(&data->mdata, key, NULL)) {
@@ -787,9 +812,29 @@ window_copy_key_input(struct window_pane *wp,
int
Post by Łukasz Piątkowski
key)
** inputlen = strlen(data->inputstr);
** if (inputlen > 0)
** data->inputstr[inputlen - 1] = '\0';
+ switch (data->inputtype) {
+ data->searchtype = data->inputtype;
+ free(data->searchstr);
+ data->searchstr = xstrdup(data->inputstr);
+ window_copy_search_up(wp, data->inputstr, 0);
+ break;
+ data->searchtype = data->inputtype;
+ free(data->searchstr);
+ data->searchstr = xstrdup(data->inputstr);
+ window_copy_search_down(wp, data->inputstr,
0);
Post by Łukasz Piątkowski
+ break;
+ break;
+ }
** break;
** *data->inputstr = '\0';
+ fx = data->cx;
+ fy = screen_hsize(data->backing) - data->oy +
data->cy;
Post by Łukasz Piątkowski
+ window_copy_clear_search_hist(wp, &fx, &fy);
+ window_copy_scroll_to(wp, fx, fy);
** break;
** if ((pb = paste_get_top()) == NULL)
@@ -820,15 +865,17 @@ window_copy_key_input(struct window_pane *wp,
int
Post by Łukasz Piątkowski
key)
** break;
** data->searchtype = data->inputtype;
+ free(data->searchstr);
** data->searchstr = xstrdup(data->inputstr);
- for (; np != 0; np--)
- window_copy_search_up(wp,
data->inputstr,
Post by Łukasz Piątkowski
0);
+ for (; np > 1; np--)
+ window_copy_search_up(wp,
data->inputstr,
Post by Łukasz Piątkowski
1);
** break;
** data->searchtype = data->inputtype;
+ free(data->searchstr);
** data->searchstr = xstrdup(data->inputstr);
- for (; np != 0; np--)
- window_copy_search_down(wp,
data->inputstr, 0);
+ for (; np > 1; np--)
+ window_copy_search_down(wp,
data->inputstr, 1);
** break;
** window_copy_copy_selection(wp,
data->inputstr);
Post by Łukasz Piątkowski
@@ -850,6 +897,22 @@ window_copy_key_input(struct window_pane *wp,
int
Post by Łukasz Piątkowski
key)
** data->inputstr = xrealloc(data->inputstr, 1,
inputlen);
Post by Łukasz Piątkowski
** data->inputstr[inputlen - 2] = key;
** data->inputstr[inputlen - 1] = '\0';
+ switch (data->inputtype) {
+ data->searchtype = data->inputtype;
+ free(data->searchstr);
+ data->searchstr = xstrdup(data->inputstr);
+ window_copy_search_up(wp, data->inputstr, 0);
+ break;
+ data->searchtype = data->inputtype;
+ free(data->searchstr);
+ data->searchstr = xstrdup(data->inputstr);
+ window_copy_search_down(wp, data->inputstr,
0);
Post by Łukasz Piątkowski
+ break;
+ break;
+ }
** break;
** break;
@@ -1082,6 +1145,8 @@ window_copy_jump_to_searched_string(struct
window_pane *wp,
** ** **struct grid *gd, struct grid *sgd, u_int fx, u_int fy,
** ** **u_int endline, int cis, int wrap, const int direction)
**{
+ struct window_copy_mode_data *data = wp->modedata;
+ struct window_copy_search_hist *searchhist =
data->searchhist;
Post by Łukasz Piątkowski
** u_int i, px;
** int firstIteration, found;
@@ -1112,6 +1177,60 @@ window_copy_jump_to_searched_string(struct
window_pane *wp,
** direction ? 0 : gd->sx - 1,
** direction ? 0 : gd->hsize + gd->sy - 1,
** fy, cis, 0, direction);
+ } else {
+ if (searchhist != NULL) {
+ searchhist->found = 0;
+ }
+ }
+}
+
+/* If it returns 0 then, according to search history, last time we searched
+ * a shorter string we haven't found anything, so there is no point
in
Post by Łukasz Piątkowski
+ * incremental-searching a longer string (just an optimization) */
+int
+window_copy_coord_from_hist(struct window_pane *wp,
+ ** **const size_t searchlen, u_int *fx, u_int *fy)
+{
+ struct window_copy_mode_data *data = wp->modedata;
+ struct window_copy_search_hist *searchhist =
data->searchhist;
Post by Łukasz Piątkowski
+
+ if (searchhist == NULL || searchhist->searchlen < searchlen)
{
Post by Łukasz Piątkowski
+ searchhist = xmalloc(sizeof (struct
window_copy_search_hist));
+ searchhist->x = data->cx;
+ searchhist->y =
+ screen_hsize(data->backing) - data->oy +
data->cy;
Post by Łukasz Piątkowski
+ searchhist->searchlen = searchlen;
+ searchhist->found = data->searchhist == NULL ?
+ 1 : data->searchhist->found;
+
+ searchhist->prev = data->searchhist;
+ data->searchhist = searchhist;
+
+ *fx = searchhist->x;
+ *fy = searchhist->y;
+ } else {
+ *fx = searchhist->x;
+ *fy = searchhist->y;
+ searchhist = data->searchhist->prev;
+ free(data->searchhist);
+ data->searchhist = searchhist;
+ }
+
+ return searchhist == NULL ? 1 : searchhist->found;
+}
+
+void
+window_copy_clear_search_hist(struct window_pane *wp, u_int *fx,
u_int
Post by Łukasz Piątkowski
*fy)
+{
+ struct window_copy_mode_data *data = wp->modedata;
+ struct window_copy_search_hist *searchhist =
data->searchhist;
Post by Łukasz Piątkowski
+
+ while (searchhist != NULL) {
+ if (fx != NULL) *fx = searchhist->x;
+ if (fy != NULL) *fy = searchhist->y;
+ searchhist = searchhist->prev;
+ free(data->searchhist);
+ data->searchhist = searchhist;
** }
**}
@@ -1132,6 +1251,14 @@ window_copy_search(struct window_pane *wp,
** fx = data->cx;
** fy = screen_hsize(data->backing) - data->oy + data->cy;
+ /* User deleted all searched text, jump to the initial cursor
+ * position and delete the searchhistory */
+ if ((searchstr == NULL) || (*searchstr == '\0')) {
+ window_copy_clear_search_hist(wp, &fx, &fy);
+ window_copy_scroll_to(wp, fx, fy);
+ return;
+ }
+
** utf8flag = options_get_number(&wp->window->options, "utf8");
** wrapflag = options_get_number(&wp->window->options,
"wrap-search");
** searchlen = screen_write_strlen(utf8flag, "%s", searchstr);
@@ -1142,8 +1269,19 @@ window_copy_search(struct window_pane *wp,
** screen_write_nputs(&ctx, -1, &gc, utf8flag, "%s", searchstr);
** screen_write_stop(&ctx);
+ /*
+ * `move` is useful for incremental searching. When we do
incremental,
+ * **we don't want to jump to the next matching word if we
already
Post by Łukasz Piątkowski
stand
+ * **on one, so `move=0`.
+ * **But when user wants the next result, then we use
`move=1`, so
Post by Łukasz Piątkowski
+ * **we start searching from the place next to the current
cursor
Post by Łukasz Piątkowski
+ * **position */
** if (move) {
** window_copy_move_coordinates(s, &fx, &fy, direction);
+ } else {
+ if (!window_copy_coord_from_hist(wp, searchlen, &fx,
&fy))
Post by Łukasz Piątkowski
{
+ return;
+ }
** }
** cis = window_copy_is_lowercase(searchstr);
Highlight last search in window-copy mode
===============================
diff --git options-table.c options-table.c
index 8d680b3..79ecae3 100644
--- options-table.c
+++ options-table.c
@@ -619,6 +619,11 @@ const struct options_table_entry
window_options_table[] = {
** **.default_str = "bg=yellow,fg=black"
** },
+ { .name = "highlight-style",
+ **.type = OPTIONS_TABLE_STYLE,
+ **.default_str = "bg=green,fg=black"
+ },
+
** { .name = "monitor-activity",
** **.type = OPTIONS_TABLE_FLAG,
** **.default_num = 0
@@ -802,6 +807,11 @@ const struct options_table_entry
window_options_table[] = {
** **.default_num = 1
** },
+ { .name = "highlight-search",
+ **.type = OPTIONS_TABLE_FLAG,
+ **.default_num = 1
+ },
+
** { .name = "xterm-keys",
** **.type = OPTIONS_TABLE_FLAG,
** **.default_num = 0
diff --git screen-write.c screen-write.c
index 325fb9a..a36a1f2 100644
--- screen-write.c
+++ screen-write.c
@@ -902,7 +902,7 @@ screen_write_cell(struct screen_write_ctx *ctx,
const
Post by Łukasz Piątkowski
struct grid_cell *gc)
** struct grid *gd = s->grid;
** struct tty_ctx ttyctx;
** u_int width, xx, last;
- struct grid_cell tmp_gc, *tmp_gcp;
+ struct grid_cell tmp_gc, *tmp_gcp, *cell = NULL;
** struct utf8_data ud;
** int insert;
@@ -995,6 +995,15 @@ screen_write_cell(struct screen_write_ctx *ctx,
const
Post by Łukasz Piątkowski
struct grid_cell *gc)
** ** **(GRID_FLAG_FG256|GRID_FLAG_BG256);
** ttyctx.cell = &tmp_gc;
** tty_write(tty_cmd_cell, &ttyctx);
+ } else if (screen_check_highlight(s, s->cx - width, s->cy,
&cell))
Post by Łukasz Piątkowski
{
+ memcpy(&tmp_gc, cell, sizeof tmp_gc);
+ grid_cell_get(gc, &ud);
+ grid_cell_set(&tmp_gc, &ud);
+ tmp_gc.flags = gc->flags &
~(GRID_FLAG_FG256|GRID_FLAG_BG256);
+ tmp_gc.flags |= cell->flags &
+ ** **(GRID_FLAG_FG256|GRID_FLAG_BG256);
+ ttyctx.cell = &tmp_gc;
+ tty_write(tty_cmd_cell, &ttyctx);
** } else {
** ttyctx.cell = gc;
** tty_write(tty_cmd_cell, &ttyctx);
diff --git screen.c screen.c
index 7bfc015..734b38e 100644
--- screen.c
+++ screen.c
@@ -44,6 +44,7 @@ screen_init(struct screen *s, u_int sx, u_int sy,
u_int
Post by Łukasz Piątkowski
hlimit)
** s->cstyle = 0;
** s->ccolour = xstrdup("");
** s->tabs = NULL;
+ s->hls = NULL;
** screen_reinit(s);
**}
@@ -65,6 +66,7 @@ screen_reinit(struct screen *s)
** grid_clear_lines(s->grid, s->grid->hsize, s->grid->sy);
** screen_clear_selection(s);
+ screen_clear_highlight(s);
**}
**/* Destroy a screen. */
@@ -75,6 +77,7 @@ screen_free(struct screen *s)
** free(s->title);
** free(s->ccolour);
** grid_destroy(s->grid);
+ screen_clear_highlight(s);
**}
**/* Reset tabs to default, eight spaces apart. */
@@ -357,6 +360,56 @@ screen_check_selection(struct screen *s, u_int
px,
Post by Łukasz Piątkowski
u_int py)
** return (1);
**}
+/* Set highlight. */
+void
+screen_set_highlight(struct screen *s,
+ u_int sx, u_int ex, u_int y, struct grid_cell *gc)
+{
+ struct screen_hls *hls = xmalloc(sizeof (struct
screen_hls));
+
+ hls->sx = sx;
+ hls->ex = ex;
+ hls->y = y;
+ hls->next = s->hls;
+
+ memcpy(&hls->cell, gc, sizeof hls->cell);
+
+ s->hls = hls;
+}
+
+/* Clear highlights. */
+void
+screen_clear_highlight(struct screen *s)
+{
+ struct screen_hls *hls = s->hls, *hlsPrev;
+
+ while (hls != NULL) {
+ hlsPrev = hls;
+ hls = hls->next;
+ free(hlsPrev);
+ }
+
+ s->hls = NULL;
+}
+
+/* Check if cell in highlight. */
+int
+screen_check_highlight(struct screen *s, u_int px, u_int py,
+ struct grid_cell **cell)
+{
+ struct screen_hls *hls = s->hls;
+
+ while (hls != NULL) {
+ if (hls->sx <= px && px <= hls->ex && hls->y == py) {
+ *cell = &hls->cell;
+ return 1;
+ }
+ hls = hls->next;
+ }
+
+ return 0;
+}
+
**/* Reflow wrapped lines. */
**void
**screen_reflow(struct screen *s, u_int new_x)
diff --git tmux.h tmux.h
index c4c5236..6fc5fd0 100644
--- tmux.h
+++ tmux.h
@@ -766,6 +766,17 @@ struct screen_sel {
** struct grid_cell cell;
**};
+/* Screen highlights. */
+struct screen_hls {
+ u_int sx;
+ u_int ex;
+
+ u_int y;
+
+ struct grid_cell cell;
+ struct screen_hls *next;
+};
+
**/* Virtual screen. */
**struct screen {
** char *title;
@@ -786,6 +797,7 @@ struct screen {
** bitstr_t *tabs;
** struct screen_sel sel;
+ struct screen_hls *hls;
**};
**/* Screen write context. */
@@ -2118,6 +2130,11 @@ void screen_set_selection(struct screen
*,
Post by Łukasz Piątkowski
** ** ** u_int, u_int, u_int, u_int, u_int, struct grid_cell
*);
Post by Łukasz Piątkowski
**void screen_clear_selection(struct screen *);
**int screen_check_selection(struct screen *, u_int, u_int);
+void screen_set_highlight(struct screen *,
+ ** ** u_int, u_int, u_int, struct grid_cell *);
+void screen_clear_highlight(struct screen *);
+int screen_check_highlight(struct screen *, u_int, u_int,
+ ** ** struct grid_cell **);
**void screen_reflow(struct screen *, u_int);
**/* window.c */
diff --git tty.c tty.c
index 7688e90..4511533 100644
--- tty.c
+++ tty.c
@@ -614,7 +614,7 @@ tty_draw_line(struct tty *tty, struct screen *s,
u_int
Post by Łukasz Piątkowski
py, u_int ox, u_int oy)
**{
** const struct grid_cell *gc;
** struct grid_line *gl;
- struct grid_cell tmpgc;
+ struct grid_cell tmpgc, *cell = NULL;
** struct utf8_data ud;
** u_int i, sx;
@@ -649,6 +649,15 @@ tty_draw_line(struct tty *tty, struct screen *s,
u_int py, u_int ox, u_int oy)
** tmpgc.flags |= s->sel.cell.flags &
** ** **(GRID_FLAG_FG256|GRID_FLAG_BG256);
** tty_cell(tty, &tmpgc);
+ } else if (screen_check_highlight(s, i, py, &cell)) {
+ memcpy(&tmpgc, cell, sizeof tmpgc);
+ grid_cell_get(gc, &ud);
+ grid_cell_set(&tmpgc, &ud);
+ tmpgc.flags = gc->flags &
+ ** **~(GRID_FLAG_FG256|GRID_FLAG_BG256);
+ tmpgc.flags |= cell->flags &
+ ** **(GRID_FLAG_FG256|GRID_FLAG_BG256);
+ tty_cell(tty, &tmpgc);
** } else
** tty_cell(tty, gc);
** }
diff --git window-copy.c window-copy.c
index 243c755..00cdc3f 100644
--- window-copy.c
+++ window-copy.c
@@ -28,10 +28,13 @@ struct screen *window_copy_init(struct
window_pane *);
Post by Łukasz Piątkowski
**void window_copy_free(struct window_pane *);
**void window_copy_resize(struct window_pane *, u_int, u_int);
**void window_copy_key(struct window_pane *, struct session *, int);
+void window_copy_key_internal(struct window_pane *, struct
session *,
Post by Łukasz Piątkowski
int);
**int window_copy_key_input(struct window_pane *, int);
**int window_copy_key_numeric_prefix(struct window_pane *, int);
**void window_copy_mouse(
** ** **struct window_pane *, struct session *, struct
mouse_event
Post by Łukasz Piątkowski
*);
+void window_copy_mouse_internal(
+ ** **struct window_pane *, struct session *, struct
mouse_event
Post by Łukasz Piątkowski
*);
**void window_copy_redraw_lines(struct window_pane *, u_int, u_int);
**void window_copy_redraw_screen(struct window_pane *);
@@ -53,6 +56,7 @@ int window_copy_is_lowercase(const char *);
**void window_copy_jump_to_searched_string(
** ** **struct window_pane *, struct grid *, struct grid *,
u_int,
Post by Łukasz Piątkowski
u_int,
** ** **u_int, int, int, const int);
+void window_copy_highlight_search(struct window_pane *);
**int window_copy_coord_from_hist(struct window_pane *wp,
** ** **const size_t searchlen, u_int *fx, u_int *fy);
**void window_copy_clear_search_hist(struct window_pane *, u_int *,
u_int
Post by Łukasz Piątkowski
*);
@@ -397,6 +401,16 @@ window_copy_resize(struct window_pane *wp,
u_int sx,
Post by Łukasz Piątkowski
u_int sy)
**void
**window_copy_key(struct window_pane *wp, struct session *sess, int
key)
Post by Łukasz Piątkowski
**{
+ window_copy_key_internal(wp, sess, key);
+
+ if (wp->mode != NULL) {
+ window_copy_highlight_search(wp);
+ }
+}
+
+void
+window_copy_key_internal(struct window_pane *wp, struct session
*sess,
Post by Łukasz Piątkowski
int key)
+{
** const char *word_separators;
** struct window_copy_mode_data *data = wp->modedata;
** struct screen *s = &data->screen;
@@ -944,6 +958,17 @@ void
**window_copy_mouse(
** ** **struct window_pane *wp, struct session *sess, struct
mouse_event
Post by Łukasz Piątkowski
*m)
**{
+ window_copy_mouse_internal(wp, sess, m);
+
+ if (wp->mode != NULL) {
+ window_copy_highlight_search(wp);
+ }
+}
+
+void
+window_copy_mouse_internal(
+ ** **struct window_pane *wp, struct session *sess, struct
mouse_event
Post by Łukasz Piątkowski
*m)
+{
** struct window_copy_mode_data *data = wp->modedata;
** struct screen *s = &data->screen;
** u_int i;
@@ -1184,6 +1209,68 @@ window_copy_jump_to_searched_string(struct
window_pane *wp,
** }
**}
+void
+window_copy_highlight_search(struct window_pane *wp)
+{
+ struct window_copy_mode_data *data = wp->modedata;
+ struct screen *s = data->backing, ss;
+ struct screen_write_ctx ctx;
+ struct grid *gd = s->grid;
+ struct grid_cell gc;
+ struct options *oo = &wp->window->options;
+ const char *searchstr = data->searchstr;
+ size_t searchlen;
+ u_int i, px, last, beginline,
endline;
Post by Łukasz Piątkowski
+ int found, utf8flag, cis,
highlight;
Post by Łukasz Piątkowski
+
+ highlight = options_get_number(
+ &wp->window->options, "highlight-search");
+ if (!highlight) {
+ return;
+ }
+
+ screen_clear_highlight(&data->screen);
+
+ if ((searchstr != NULL) && (*searchstr != '\0')) {
+ utf8flag = options_get_number(&wp->window->options,
"utf8");
+ searchlen = screen_write_strlen(utf8flag, "%s",
searchstr);
+
+ screen_init(&ss, searchlen, 1, 0);
+ screen_write_start(&ctx, NULL, &ss);
+ memcpy(&gc, &grid_default_cell, sizeof gc);
+ screen_write_nputs(&ctx, -1, &gc, utf8flag, "%s",
searchstr);
+ screen_write_stop(&ctx);
+
+ cis = window_copy_is_lowercase(searchstr);
+
+ /* Set colours. */
+ style_apply(&gc, oo, "highlight-style");
+
+ beginline = screen_hsize(s) - data->oy;
+ endline = screen_hsize(s) - data->oy +
screen_size_y(s) -
Post by Łukasz Piątkowski
1;
+
+ for (i = beginline; i <= endline; ++i) {
+ last = 0;
+ do {
+ found = window_copy_search_lr(gd,
ss.grid,
Post by Łukasz Piątkowski
&px,
+ i, last, gd->sx, cis);
+ if (found) {
+ screen_set_highlight(
+ &data->screen,
+ px,
+ px + searchlen - 1,
+ i - (screen_hsize(s)
+ ** ** - data->oy),
+ &gc);
+ last += searchlen;
+ }
+ } while (found);
+ }
+ }
+
+ window_copy_redraw_screen(wp);
+}
+
**/* If it returns 0 then, according to search history, last time we
searched
** * a shorter string we haven't found anything, so there is no
point in
Post by Łukasz Piątkowski
** * incremental-searching a longer string (just an optimization) */
------------------------------------------------------------------------------
Post by Łukasz Piątkowski
Want fast and easy access to all the code in your enterprise? Index and
search up to 200,000 lines of code with a free copy of Black Duck
Code Sight - the same software that powers the world's largest code
search on Ohloh, the Black Duck Open Hub! Try it now.
http://p.sf.net/sfu/bds
_______________________________________________
tmux-users mailing list
https://lists.sourceforge.net/lists/listinfo/tmux-users
------------------------------------------------------------------------------
Want fast and easy access to all the code in your enterprise? Index and
search up to 200,000 lines of code with a free copy of Black Duck
Code Sight - the same software that powers the world's largest code
search on Ohloh, the Black Duck Open Hub! Try it now.
http://p.sf.net/sfu/bds
_______________________________________________
tmux-users mailing list
https://lists.sourceforge.net/lists/listinfo/tmux-users
Nicholas Marriott
2015-03-09 16:39:31 UTC
Permalink
I think you should highlight by default and use mode-style, so no need
for extra options. I'll look at this again when I'm back home the week
after next.
I finally got some time to sit down and test my changes again. It appears
that no one was touching the part of code that I have been working on, so
I am sending almost the same changes as last time. But this time I am
attaching them to the email instead of sending in the message.
Cheers
Lukas
2014-11-01 0:35 GMT+00:00 **ukasz Pi**tkowski
Hi Felix,
I didn't have time to work on this, last few months were really busy. I
will try to rebase my changes on top of current revision and test them
before sending the code again. I hope I will find some time before the
end of year.
Cheers
Lukas
Was there any follow up to this thread?** Incremental search would be
a great feature to have and is on the TODO list.
Thanks.
-FR
On Fri, Aug 8, 2014 at 11:21 AM, Nicholas Marriott
Hi
Your mailer has mangled the diffs, if you can't fix it so it works
inline please send them as attachments instead.
** ** I have split up my changes into 3 diffs, first is refactoring
search code
** ** in window-copy.c, second is adding incremental search and the
last one is
** ** adding search highlighting.
** ** Cheers
** ** Lukas
** ** --
** **
I**am**providing**code**in**this**repository**to**you**under**an**open**source**license.**Because**this**is**my**personal
** **
repository,**the**license**you**receive**to**my**code**is**from**me**and**not**from**my**employer**(Facebook).
All contributions must be under the ISC license that is at the top of
each file you modify.
Thanks
** ** --
** ** Refactor window-copy search functions
** ** ============================
** ** diff --git window-copy.c window-copy.c
** ** index 0775bcb..1213380 100644
** ** --- window-copy.c
** ** +++ window-copy.c
** ** **** ** ** **** **struct grid *, struct grid *, u_int *,
u_int, u_int, u_int,
** ** int);
** ** **int** **window_copy_search_rl(
** ** **** ** ** **** **struct grid *, struct grid *, u_int *,
u_int, u_int, u_int,
** ** int);
** ** -void** **window_copy_search_up(struct window_pane *, const
char *);
** ** -void** **window_copy_search_down(struct window_pane *, const
char *);
** ** +void** **window_copy_move_coordinates(
** ** +** ** ** ** ** **struct screen *, u_int *, u_int *, const
int);
** ** +int** ** window_copy_is_lowercase(const char *);
** ** +void** **window_copy_jump_to_searched_string(
** ** +** ** ** ** ** **struct window_pane *, struct grid *, struct
grid *, u_int,
** ** u_int,
** ** +** ** ** ** ** **u_int, int, int, const int);
** ** +void** **window_copy_search(struct window_pane *, const char
*,
** ** +** ** ** ** ** **const int, const int);
** ** +void** **window_copy_search_up(struct window_pane *, const
char *, const
** ** int);
** ** +void** **window_copy_search_down(struct window_pane *, const
char *, const
** ** int);
** ** **void** window_copy_goto_line(struct window_pane *, const
char *);
** ** **void** window_copy_update_cursor(struct window_pane *,
u_int, u_int);
** ** **void** window_copy_start_selection(struct window_pane *);
struct
** ** session *sess, int key)
** ** **** ** ** ** ** ** ** ** ** ** ** if (cmd ==
MODEKEYCOPY_SEARCHAGAIN) {
** ** **** ** ** ** ** ** ** ** ** ** ** ** ** ** ** for (; np !=
0; np--) {
** ** **** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** **
window_copy_search_up(
** ** -** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** **
** **wp, data->searchstr);
** ** +** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** **
** ** ** **wp, data->searchstr, 1);
** ** **** ** ** ** ** ** ** ** ** ** ** ** ** ** ** }
** ** **** ** ** ** ** ** ** ** ** ** ** } else {
** ** **** ** ** ** ** ** ** ** ** ** ** ** ** ** ** for (; np !=
0; np--) {
** ** **** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** **
window_copy_search_down(
** ** -** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** **
** **wp, data->searchstr);
** ** +** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** **
** ** ** **wp, data->searchstr, 1);
** ** **** ** ** ** ** ** ** ** ** ** ** ** ** ** ** }
** ** **** ** ** ** ** ** ** ** ** ** ** }
** ** **** ** ** ** ** ** ** ** ** ** ** break;
struct
** ** session *sess, int key)
** ** **** ** ** ** ** ** ** ** ** ** ** if (cmd ==
MODEKEYCOPY_SEARCHAGAIN) {
** ** **** ** ** ** ** ** ** ** ** ** ** ** ** ** ** for (; np !=
0; np--) {
** ** **** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** **
window_copy_search_down(
** ** -** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** **
** **wp, data->searchstr);
** ** +** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** **
** ** ** **wp, data->searchstr, 1);
** ** **** ** ** ** ** ** ** ** ** ** ** ** ** ** ** }
** ** **** ** ** ** ** ** ** ** ** ** ** } else {
** ** **** ** ** ** ** ** ** ** ** ** ** ** ** ** ** for (; np !=
0; np--) {
** ** **** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** **
window_copy_search_up(
** ** -** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** **
** **wp, data->searchstr);
** ** +** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** **
** ** ** **wp, data->searchstr, 1);
** ** **** ** ** ** ** ** ** ** ** ** ** ** ** ** ** }
** ** **** ** ** ** ** ** ** ** ** ** ** }
** ** **** ** ** ** ** ** ** ** ** ** ** break;
window_pane *wp, int
** ** key)
** ** **** ** ** ** ** ** ** ** ** ** ** break;
** ** -** ** ** ** ** ** ** ** ** ** ** **for (; np != 0; np--)
** ** -** ** ** ** ** ** ** ** ** ** ** ** ** ** **
**window_copy_search_up(wp, data->inputstr);
** ** **** ** ** ** ** ** ** ** ** ** ** data->searchtype =
data->inputtype;
** ** **** ** ** ** ** ** ** ** ** ** ** data->searchstr =
xstrdup(data->inputstr);
** ** +** ** ** ** ** ** ** ** ** ** ** **for (; np != 0; np--)
** ** +** ** ** ** ** ** ** ** ** ** ** ** ** ** **
**window_copy_search_up(wp, data->inputstr,
** ** 0);
** ** **** ** ** ** ** ** ** ** ** ** ** break;
** ** -** ** ** ** ** ** ** ** ** ** ** **for (; np != 0; np--)
** ** -** ** ** ** ** ** ** ** ** ** ** ** ** ** **
**window_copy_search_down(wp,
** ** data->inputstr);
** ** **** ** ** ** ** ** ** ** ** ** ** data->searchtype =
data->inputtype;
** ** **** ** ** ** ** ** ** ** ** ** ** data->searchstr =
xstrdup(data->inputstr);
** ** +** ** ** ** ** ** ** ** ** ** ** **for (; np != 0; np--)
** ** +** ** ** ** ** ** ** ** ** ** ** ** ** ** **
**window_copy_search_down(wp,
** ** data->inputstr, 0);
** ** **** ** ** ** ** ** ** ** ** ** ** break;
** ** **** ** ** ** ** ** ** ** ** ** **
window_copy_copy_selection(wp, data->inputstr);
*gd,
** ** **** ** ** return (0);
** ** **}
** ** +/* For direction == 0 move left, otherwise right; jump line
if needed */
** ** **void
** ** -window_copy_search_up(struct window_pane *wp, const char
*searchstr)
** ** +window_copy_move_coordinates(struct screen *s,
** ** +** ** ** **u_int *fx, u_int *fy, const int direction)
** ** **{
** ** -** ** ** **struct window_copy_mode_data** ** *data =
wp->modedata;
** ** -** ** ** **struct screen** ** ** ** ** ** ** ** ** ***s =
data->backing, ss;
** ** -** ** ** **struct screen_write_ctx** ** ** ** ** ** ** ** **
ctx;
** ** -** ** ** **struct grid** ** ** ** ** ** ** ** ** ** ***gd =
s->grid, *sgd;
** ** -** ** ** **struct grid_cell** ** ** ** ** ** ** ** **gc;
** ** -** ** ** **size_t** ** ** ** ** ** ** ** ** ** ** ** **
**searchlen;
** ** -** ** ** **u_int** ** ** ** ** ** ** ** ** ** ** ** ** ** i,
last, fx, fy, px;
** ** -** ** ** **int** ** ** ** ** ** ** ** ** ** ** ** ** ** **
utf8flag, n, wrapped, wrapflag,
** ** cis;
** ** -** ** ** **const char** ** ** ** ** ** ** ** ** ** ** *ptr;
** ** -
** ** -** ** ** **if (*searchstr == '\0')
** ** -** ** ** ** ** ** ** **return;
** ** -** ** ** **utf8flag =
options_get_number(&wp->window->options, "utf8");
** ** -** ** ** **wrapflag =
options_get_number(&wp->window->options,
** ** "wrap-search");
** ** -** ** ** **searchlen = screen_write_strlen(utf8flag, "%s",
searchstr);
** ** -
** ** -** ** ** **screen_init(&ss, searchlen, 1, 0);
** ** -** ** ** **screen_write_start(&ctx, NULL, &ss);
** ** -** ** ** **memcpy(&gc, &grid_default_cell, sizeof gc);
** ** -** ** ** **screen_write_nputs(&ctx, -1, &gc, utf8flag, "%s",
searchstr);
** ** -** ** ** **screen_write_stop(&ctx);
** ** -
** ** -** ** ** **fx = data->cx;
** ** -** ** ** **fy = gd->hsize - data->oy + data->cy;
** ** -
** ** -** ** ** **if (fx == 0) {
** ** -** ** ** ** ** ** ** **if (fy == 0)
** ** +** ** ** **/* If on left/right border */
0)) {
** ** +** ** ** ** ** ** ** **/* If on top/bottom border */
** ** +** ** ** ** ** ** ** **if (*fy == (direction ?
screen_hsize(s) + screen_size_y(s)
** ** : 0))
** ** +** ** ** ** ** ** ** ** ** ** ** **/* Nowhere to go */
** ** **** ** ** ** ** ** ** ** ** ** ** return;
** ** -** ** ** ** ** ** ** **fx = gd->sx - 1;
** ** -** ** ** ** ** ** ** **fy--;
** ** -** ** ** **} else
** ** -** ** ** ** ** ** ** **fx--;
** ** -** ** ** **n = wrapped = 0;
** ** +** ** ** ** ** ** ** **/* Jump to beggin/end of lower/upper
line */
screen_size_x(s) - 1;
** ** +** ** ** ** ** ** ** ***fy = direction ? *fy + 1 : *fy - 1;
** ** +** ** ** **} else {
** ** +** ** ** ** ** ** ** ***fx = direction ? *fx + 1 : *fx - 1;
** ** +** ** ** **}
** ** +}
** ** -** ** ** **cis = 1;
** ** -** ** ** **for (ptr = searchstr; *ptr != '\0'; ptr++) {
** ** +int
** ** +window_copy_is_lowercase(const char *ptr)
** ** +{
** ** +** ** ** **while (*ptr != '\0') {
** ** **** ** ** ** ** ** ** if (*ptr != tolower((u_char)*ptr)) {
** ** -** ** ** ** ** ** ** ** ** ** ** **cis = 0;
** ** -** ** ** ** ** ** ** ** ** ** ** **break;
** ** +** ** ** ** ** ** ** ** ** ** ** **return 0;
** ** **** ** ** ** ** ** ** }
** ** +** ** ** ** ** ** ** **++ptr;
** ** **** ** ** }
** ** +** ** ** **return 1;
** ** +}
** ** -** ** ** **sgd = ss.grid;
** ** -** ** ** **for (i = fy + 1; i > 0; i--) {
** ** -** ** ** ** ** ** ** **last = screen_size_x(s);
** ** -** ** ** ** ** ** ** **if (i == fy + 1)
** ** -** ** ** ** ** ** ** ** ** ** ** **last = fx;
** ** -** ** ** ** ** ** ** **n = window_copy_search_rl(gd, sgd,
&px, i - 1, 0, last,
** ** cis);
** ** -** ** ** ** ** ** ** **if (n) {
** ** -** ** ** ** ** ** ** ** ** ** ** **window_copy_scroll_to(wp,
px, i - 1);
** ** -** ** ** ** ** ** ** ** ** ** ** **break;
** ** +/* Search in grid `gd` for text stored in grid `sgd`
starting from
** ** position
** ** + * (`fx`, `fy`) up to line `endline` and if found then jump
to it.
** ** + * If `cis` do it case-insensitive.
** ** + * `direction` 0 for searching up, down otherwise
** ** + * If `wrap` then go to begin/end of grid and try again up
to line `fy`
** ** */
** ** +void
** ** +window_copy_jump_to_searched_string(struct window_pane *wp,
** ** + ** **struct grid *gd, struct grid *sgd, u_int fx, u_int fy,
** ** + ** **u_int endline, int cis, int wrap, const int direction)
** ** +{
** ** +** ** ** **u_int** ** ** ** ** ** ** ** ** ** ** ** ** ** i,
px;
** ** +** ** ** **int** ** ** ** ** ** ** ** ** ** ** ** ** ** **
firstIteration, found;
** ** +
** ** +** ** ** **firstIteration = 1;
** ** +** ** ** **if (direction) {
** ** +** ** ** ** ** ** ** **for (i = fy; i <= endline; ++i) {
** ** +** ** ** ** ** ** ** ** ** ** ** **found =
window_copy_search_lr(gd, sgd, &px, i,
** ** +** ** ** ** ** ** ** ** ** ** ** ** ** ** **
**firstIteration ? fx : 0, gd->sx, cis);
** ** +** ** ** ** ** ** ** ** ** ** ** **if (found) break;
** ** +** ** ** ** ** ** ** ** ** ** ** **firstIteration = 0;
** ** +** ** ** ** ** ** ** **}
** ** +** ** ** **} else {
** ** +** ** ** ** ** ** ** **for (i = fy + 1; endline < i; --i) {
** ** +** ** ** ** ** ** ** ** ** ** ** **found =
window_copy_search_rl(gd, sgd, &px, i - 1,
** ** +** ** ** ** ** ** ** ** ** ** ** ** ** ** ** **0,
firstIteration ? fx : gd->sx, cis);
** ** +** ** ** ** ** ** ** ** ** ** ** **if (found) {
** ** +** ** ** ** ** ** ** ** ** ** ** ** ** ** ** **--i;
** ** +** ** ** ** ** ** ** ** ** ** ** ** ** ** ** **break;
** ** +** ** ** ** ** ** ** ** ** ** ** **}
** ** +** ** ** ** ** ** ** ** ** ** ** **firstIteration = 0;
** ** **** ** ** ** ** ** ** }
** ** **** ** ** }
** ** -** ** ** **if (wrapflag && !n && !wrapped) {
** ** -** ** ** ** ** ** ** **fx = gd->sx - 1;
** ** -** ** ** ** ** ** ** **fy = gd->hsize + gd->sy - 1;
** ** -** ** ** ** ** ** ** **wrapped = 1;
** ** -** ** ** ** ** ** ** **goto retry;
** ** +** ** ** **if (found) {
** ** +** ** ** ** ** ** ** **window_copy_scroll_to(wp, px, i);
** ** +** ** ** **} else if (wrap) {
** ** +** ** ** ** ** ** ** **/* Start searching from begin/end of
grid up to `fy` line
** ** */
** ** +** ** ** ** ** ** **
**window_copy_jump_to_searched_string(wp, gd, sgd,
** ** +** ** ** ** ** ** ** ** ** ** ** **direction ? 0 : gd->sx -
1,
** ** +** ** ** ** ** ** ** ** ** ** ** **direction ? 0 : gd->hsize
+ gd->sy - 1,
** ** +** ** ** ** ** ** ** ** ** ** ** **fy, cis, 0, direction);
** ** **** ** ** }
** ** -
** ** -** ** ** **screen_free(&ss);
** ** **}
** ** **void
** ** -window_copy_search_down(struct window_pane *wp, const char
*searchstr)
** ** +window_copy_search(struct window_pane *wp,
** ** + ** **const char *searchstr, const int direction, const int
move)
** ** **{
** ** **** ** ** struct window_copy_mode_data** ** *data =
wp->modedata;
** ** **** ** ** struct screen** ** ** ** ** ** ** ** ** ***s =
data->backing, ss;
** ** **** ** ** struct screen_write_ctx** ** ** ** ** ** ** ** **
ctx;
** ** -** ** ** **struct grid** ** ** ** ** ** ** ** ** ** ***gd =
s->grid, *sgd;
** ** -** ** ** **struct grid_cell** ** ** ** ** ** ** ** **gc;
** ** +** ** ** **struct grid** ** ** ** ** ** ** ** ** ** ***gd =
s->grid;
** ** +** ** ** **struct grid_cell** ** ** ** ** ** ** ** **gc;
** ** **** ** ** size_t** ** ** ** ** ** ** ** ** ** ** ** **
**searchlen;
** ** -** ** ** **u_int** ** ** ** ** ** ** ** ** ** ** ** ** ** i,
first, fx, fy, px;
** ** -** ** ** **int** ** ** ** ** ** ** ** ** ** ** ** ** ** **
utf8flag, n, wrapped, wrapflag,
** ** cis;
** ** -** ** ** **const char** ** ** ** ** ** ** ** ** ** ** *ptr;
** ** +** ** ** **u_int** ** ** ** ** ** ** ** ** ** ** ** ** **
fx, fy;
** ** +** ** ** **int** ** ** ** ** ** ** ** ** ** ** ** ** ** **
utf8flag, wrapflag, cis;
** ** +
** ** +** ** ** **/* current cursor coordinates */
** ** +** ** ** **fx = data->cx;
** ** +** ** ** **fy = screen_hsize(data->backing) - data->oy +
data->cy;
** ** -** ** ** **if (*searchstr == '\0')
** ** -** ** ** ** ** ** ** **return;
** ** **** ** ** utf8flag =
options_get_number(&wp->window->options, "utf8");
** ** **** ** ** wrapflag =
options_get_number(&wp->window->options,
** ** "wrap-search");
** ** **** ** ** searchlen = screen_write_strlen(utf8flag, "%s",
searchstr);
window_pane *wp,
** ** const char *searchstr)
** ** **** ** ** screen_write_nputs(&ctx, -1, &gc, utf8flag, "%s",
searchstr);
** ** **** ** ** screen_write_stop(&ctx);
** ** -** ** ** **fx = data->cx;
** ** -** ** ** **fy = gd->hsize - data->oy + data->cy;
** ** -
** ** -** ** ** **if (fx == gd->sx - 1) {
** ** -** ** ** ** ** ** ** **if (fy == gd->hsize + gd->sy)
** ** -** ** ** ** ** ** ** ** ** ** ** **return;
** ** -** ** ** ** ** ** ** **fx = 0;
** ** -** ** ** ** ** ** ** **fy++;
** ** -** ** ** **} else
** ** -** ** ** ** ** ** ** **fx++;
** ** -** ** ** **n = wrapped = 0;
** ** -
** ** -** ** ** **cis = 1;
** ** -** ** ** **for (ptr = searchstr; *ptr != '\0'; ptr++) {
** ** -** ** ** ** ** ** ** **if (*ptr != tolower((u_char)*ptr)) {
** ** -** ** ** ** ** ** ** ** ** ** ** **cis = 0;
** ** -** ** ** ** ** ** ** ** ** ** ** **break;
** ** -** ** ** ** ** ** ** **}
** ** +** ** ** **if (move) {
** ** +** ** ** ** ** ** ** **window_copy_move_coordinates(s, &fx,
&fy, direction);
** ** **** ** ** }
** ** -** ** ** **sgd = ss.grid;
** ** -** ** ** **for (i = fy + 1; i < gd->hsize + gd->sy + 1; i++)
{
** ** -** ** ** ** ** ** ** **first = 0;
** ** -** ** ** ** ** ** ** **if (i == fy + 1)
** ** -** ** ** ** ** ** ** ** ** ** ** **first = fx;
** ** -** ** ** ** ** ** ** **n = window_copy_search_lr(gd, sgd,
&px, i - 1, first,
** ** gd->sx,
** ** -** ** ** ** ** ** ** ** ** **cis);
** ** -** ** ** ** ** ** ** **if (n) {
** ** -** ** ** ** ** ** ** ** ** ** ** **window_copy_scroll_to(wp,
px, i - 1);
** ** -** ** ** ** ** ** ** ** ** ** ** **break;
** ** -** ** ** ** ** ** ** **}
** ** -** ** ** **}
** ** -** ** ** **if (wrapflag && !n && !wrapped) {
** ** -** ** ** ** ** ** ** **fx = 0;
** ** -** ** ** ** ** ** ** **fy = 0;
** ** -** ** ** ** ** ** ** **wrapped = 1;
** ** -** ** ** ** ** ** ** **goto retry;
** ** -** ** ** **}
** ** +** ** ** **cis = window_copy_is_lowercase(searchstr);
** ** +** ** ** **window_copy_clear_selection(wp);
** ** +
** ** +** ** ** **window_copy_jump_to_searched_string(wp, gd,
ss.grid, fx, fy,
0,
** ** +** ** ** ** ** ** ** **cis, wrapflag, direction);
** ** **** ** ** screen_free(&ss);
** ** **}
** ** **void
** ** +window_copy_search_up(struct window_pane *wp, const char
*searchstr,
** ** +** ** ** **const int move)
** ** +{
** ** +** ** ** **window_copy_search(wp, searchstr, 0, move);
** ** +}
** ** +
** ** +void
** ** +window_copy_search_down(struct window_pane *wp, const char
*searchstr,
** ** +** ** ** **const int move)
** ** +{
** ** +** ** ** **window_copy_search(wp, searchstr, 1, move);
** ** +}
** ** +
** ** +void
** ** **window_copy_goto_line(struct window_pane *wp, const char
*linestr)
** ** **{
** ** **** ** ** struct window_copy_mode_data** ** *data =
wp->modedata;
** ** Incremental search in window-copy mode
** ** ==============================
** ** diff --git window-copy.c window-copy.c
** ** index 1213380..243c755 100644
** ** --- window-copy.c
** ** +++ window-copy.c
*);
** ** **void** window_copy_jump_to_searched_string(
** ** **** ** ** **** **struct window_pane *, struct grid *, struct
grid *, u_int,
** ** u_int,
** ** **** ** ** **** **u_int, int, int, const int);
** ** +int** ** window_copy_coord_from_hist(struct window_pane *wp,
** ** +** ** ** ** ** **const size_t searchlen, u_int *fx, u_int
*fy);
** ** +void** **window_copy_clear_search_hist(struct window_pane *,
u_int *, u_int
** ** *);
** ** **void** window_copy_search(struct window_pane *, const char
*,
** ** **** ** ** **** **const int, const int);
** ** **void** window_copy_search_up(struct window_pane *, const
char *, const
** ** int);
** ** **};
** ** **/*
** ** + * x, y - coordinates from which the search was made
** ** + * found - if the text was found
** ** + * searchlen - lenght of text that was searched
** ** + * prev - data of previous searches
** ** + */
** ** +struct window_copy_search_hist {
** ** +** ** ** **u_int** ** ** ** ** **x;
** ** +** ** ** **u_int** ** ** ** ** **y;
** ** +** ** ** **int** ** ** ** ** ** **found;
** ** +
** ** +** ** ** **size_t** ** ** ** ** searchlen;
** ** +
** ** +** ** ** **struct window_copy_search_hist ***prev;
** ** +};
** ** +
** ** +/*
** ** ** * Copy-mode's visible screen (the "screen" field) is
filled from one of
** ** ** * two sources: the original contents of the pane (used
when we
** ** ** * actually enter via the "copy-mode" command, to copy the
contents of
** ** **** ** ** enum window_copy_input_type searchtype;
** ** **** ** ** char** ** **** ** ** *searchstr;
** ** +** ** ** **struct window_copy_search_hist** *searchhist;
** ** **** ** ** enum window_copy_input_type jumptype;
** ** **** ** ** char** ** ** ** ** ** jumpchar;
** ** **** ** ** data->searchtype = WINDOW_COPY_OFF;
** ** **** ** ** data->searchstr = NULL;
** ** +** ** ** **data->searchhist = NULL;
** ** **** ** ** if (wp->fd != -1)
** ** **** ** ** ** ** ** ** bufferevent_disable(wp->event,
EV_READ|EV_WRITE);
** ** **** ** ** free(data->searchstr);
** ** **** ** ** free(data->inputstr);
** ** +** ** ** **window_copy_clear_search_hist(wp, NULL, NULL);
** ** **** ** ** if (data->backing != &wp->base) {
** ** **** ** ** ** ** ** ** screen_free(data->backing);
struct
** ** session *sess, int key)
** ** **** ** ** ** ** ** ** data->inputtype =
WINDOW_COPY_SEARCHUP;
** ** **** ** ** ** ** ** ** data->inputprompt = "Search Up";
** ** +** ** ** ** ** ** ** ***data->inputstr = '\0';
** ** **** ** ** ** ** ** ** goto input_on;
** ** **** ** ** ** ** ** ** data->inputtype =
WINDOW_COPY_SEARCHDOWN;
** ** **** ** ** ** ** ** ** data->inputprompt = "Search Down";
** ** +** ** ** ** ** ** ** ***data->inputstr = '\0';
** ** **** ** ** ** ** ** ** goto input_on;
*wp, int key)
** ** **** ** ** int** ** ** ** ** ** ** ** ** ** ** ** ** ** **
np;
** ** **** ** ** struct paste_buffer** ** ** ** ** ** ***pb;
** ** **** ** ** u_char** ** ** ** ** ** ** ** ** ** ** ** ** **ch;
** ** +** ** ** **u_int** ** ** ** ** ** ** ** ** ** ** ** ** **
fx, fy;
** ** **** ** ** switch (mode_key_lookup(&data->mdata, key, NULL))
{
*wp, int
** ** key)
** ** **** ** ** ** ** ** ** inputlen = strlen(data->inputstr);
** ** **** ** ** ** ** ** ** if (inputlen > 0)
** ** **** ** ** ** ** ** ** ** ** ** ** data->inputstr[inputlen -
1] = '\0';
** ** +** ** ** ** ** ** ** **switch (data->inputtype) {
** ** +** ** ** ** ** ** ** ** ** ** ** **data->searchtype =
data->inputtype;
** ** +** ** ** ** ** ** ** ** ** ** ** **free(data->searchstr);
** ** +** ** ** ** ** ** ** ** ** ** ** **data->searchstr =
xstrdup(data->inputstr);
** ** +** ** ** ** ** ** ** ** ** ** ** **window_copy_search_up(wp,
data->inputstr, 0);
** ** +** ** ** ** ** ** ** ** ** ** ** **break;
** ** +** ** ** ** ** ** ** ** ** ** ** **data->searchtype =
data->inputtype;
** ** +** ** ** ** ** ** ** ** ** ** ** **free(data->searchstr);
** ** +** ** ** ** ** ** ** ** ** ** ** **data->searchstr =
xstrdup(data->inputstr);
** ** +** ** ** ** ** ** ** ** ** ** **
**window_copy_search_down(wp, data->inputstr, 0);
** ** +** ** ** ** ** ** ** ** ** ** ** **break;
** ** +** ** ** ** ** ** ** ** ** ** ** **break;
** ** +** ** ** ** ** ** ** **}
** ** **** ** ** ** ** ** ** break;
** ** **** ** ** ** ** ** ** *data->inputstr = '\0';
** ** +** ** ** ** ** ** ** **fx = data->cx;
** ** +** ** ** ** ** ** ** **fy = screen_hsize(data->backing) -
data->oy + data->cy;
** ** +** ** ** ** ** ** ** **window_copy_clear_search_hist(wp,
&fx, &fy);
** ** +** ** ** ** ** ** ** **window_copy_scroll_to(wp, fx, fy);
** ** **** ** ** ** ** ** ** break;
** ** **** ** ** ** ** ** ** if ((pb = paste_get_top()) == NULL)
window_pane *wp, int
** ** key)
** ** **** ** ** ** ** ** ** ** ** ** ** break;
** ** **** ** ** ** ** ** ** ** ** ** ** data->searchtype =
data->inputtype;
** ** +** ** ** ** ** ** ** ** ** ** ** **free(data->searchstr);
** ** **** ** ** ** ** ** ** ** ** ** ** data->searchstr =
xstrdup(data->inputstr);
** ** -** ** ** ** ** ** ** ** ** ** ** **for (; np != 0; np--)
** ** -** ** ** ** ** ** ** ** ** ** ** ** ** ** **
**window_copy_search_up(wp, data->inputstr,
** ** 0);
** ** +** ** ** ** ** ** ** ** ** ** ** **for (; np > 1; np--)
** ** +** ** ** ** ** ** ** ** ** ** ** ** ** ** **
**window_copy_search_up(wp, data->inputstr,
** ** 1);
** ** **** ** ** ** ** ** ** ** ** ** ** break;
** ** **** ** ** ** ** ** ** ** ** ** ** data->searchtype =
data->inputtype;
** ** +** ** ** ** ** ** ** ** ** ** ** **free(data->searchstr);
** ** **** ** ** ** ** ** ** ** ** ** ** data->searchstr =
xstrdup(data->inputstr);
** ** -** ** ** ** ** ** ** ** ** ** ** **for (; np != 0; np--)
** ** -** ** ** ** ** ** ** ** ** ** ** ** ** ** **
**window_copy_search_down(wp,
** ** data->inputstr, 0);
** ** +** ** ** ** ** ** ** ** ** ** ** **for (; np > 1; np--)
** ** +** ** ** ** ** ** ** ** ** ** ** ** ** ** **
**window_copy_search_down(wp,
** ** data->inputstr, 1);
** ** **** ** ** ** ** ** ** ** ** ** ** break;
** ** **** ** ** ** ** ** ** ** ** ** **
window_copy_copy_selection(wp, data->inputstr);
*wp, int
** ** key)
** ** **** ** ** ** ** ** ** data->inputstr =
xrealloc(data->inputstr, 1, inputlen);
** ** **** ** ** ** ** ** ** data->inputstr[inputlen - 2] = key;
** ** **** ** ** ** ** ** ** data->inputstr[inputlen - 1] = '\0';
** ** +** ** ** ** ** ** ** **switch (data->inputtype) {
** ** +** ** ** ** ** ** ** ** ** ** ** **data->searchtype =
data->inputtype;
** ** +** ** ** ** ** ** ** ** ** ** ** **free(data->searchstr);
** ** +** ** ** ** ** ** ** ** ** ** ** **data->searchstr =
xstrdup(data->inputstr);
** ** +** ** ** ** ** ** ** ** ** ** ** **window_copy_search_up(wp,
data->inputstr, 0);
** ** +** ** ** ** ** ** ** ** ** ** ** **break;
** ** +** ** ** ** ** ** ** ** ** ** ** **data->searchtype =
data->inputtype;
** ** +** ** ** ** ** ** ** ** ** ** ** **free(data->searchstr);
** ** +** ** ** ** ** ** ** ** ** ** ** **data->searchstr =
xstrdup(data->inputstr);
** ** +** ** ** ** ** ** ** ** ** ** **
**window_copy_search_down(wp, data->inputstr, 0);
** ** +** ** ** ** ** ** ** ** ** ** ** **break;
** ** +** ** ** ** ** ** ** ** ** ** ** **break;
** ** +** ** ** ** ** ** ** **}
** ** **** ** ** ** ** ** ** break;
** ** **** ** ** ** ** ** ** break;
window_copy_jump_to_searched_string(struct
** ** window_pane *wp,
** ** ** ** **struct grid *gd, struct grid *sgd, u_int fx, u_int
fy,
** ** ** ** **u_int endline, int cis, int wrap, const int
direction)
** ** **{
** ** +** ** ** **struct window_copy_mode_data** ** *data =
wp->modedata;
** ** +** ** ** **struct window_copy_search_hist** *searchhist =
data->searchhist;
** ** **** ** ** u_int** ** ** ** ** ** ** ** ** ** ** ** ** ** i,
px;
** ** **** ** ** int** ** ** ** ** ** ** ** ** ** ** ** ** ** **
firstIteration, found;
window_copy_jump_to_searched_string(struct
** ** window_pane *wp,
** ** **** ** ** ** ** ** ** ** ** ** ** direction ? 0 : gd->sx -
1,
** ** **** ** ** ** ** ** ** ** ** ** ** direction ? 0 : gd->hsize
+ gd->sy - 1,
** ** **** ** ** ** ** ** ** ** ** ** ** fy, cis, 0, direction);
** ** +** ** ** **} else {
** ** +** ** ** ** ** ** ** **if (searchhist != NULL) {
** ** +** ** ** ** ** ** ** ** ** ** ** **searchhist->found = 0;
** ** +** ** ** ** ** ** ** **}
** ** +** ** ** **}
** ** +}
** ** +
** ** +/* If it returns 0 then, according to search history, last
time we
** ** searched
** ** + * a shorter string we haven't found anything, so there is
no point in
** ** + * incremental-searching a longer string (just an
optimization) */
** ** +int
** ** +window_copy_coord_from_hist(struct window_pane *wp,
** ** + ** **const size_t searchlen, u_int *fx, u_int *fy)
** ** +{
** ** +** ** ** **struct window_copy_mode_data** ** *data =
wp->modedata;
** ** +** ** ** **struct window_copy_search_hist** *searchhist =
data->searchhist;
** ** +
** ** +** ** ** **if (searchhist == NULL || searchhist->searchlen <
searchlen) {
** ** +** ** ** ** ** ** ** **searchhist = xmalloc(sizeof (struct
** ** window_copy_search_hist));
** ** +** ** ** ** ** ** ** **searchhist->x = data->cx;
** ** +** ** ** ** ** ** ** **searchhist->y =
** ** +** ** ** ** ** ** ** ** ** ** **
**screen_hsize(data->backing) - data->oy + data->cy;
** ** +** ** ** ** ** ** ** **searchhist->searchlen = searchlen;
** ** +** ** ** ** ** ** ** **searchhist->found = data->searchhist
== NULL ?
data->searchhist->found;
** ** +
** ** +** ** ** ** ** ** ** **searchhist->prev = data->searchhist;
** ** +** ** ** ** ** ** ** **data->searchhist = searchhist;
** ** +
** ** +** ** ** ** ** ** ** ***fx = searchhist->x;
** ** +** ** ** ** ** ** ** ***fy = searchhist->y;
** ** +** ** ** **} else {
** ** +** ** ** ** ** ** ** ***fx = searchhist->x;
** ** +** ** ** ** ** ** ** ***fy = searchhist->y;
** ** +** ** ** ** ** ** ** **searchhist = data->searchhist->prev;
** ** +** ** ** ** ** ** ** **free(data->searchhist);
** ** +** ** ** ** ** ** ** **data->searchhist = searchhist;
** ** +** ** ** **}
** ** +
searchhist->found;
** ** +}
** ** +
** ** +void
** ** +window_copy_clear_search_hist(struct window_pane *wp, u_int
*fx, u_int
** ** *fy)
** ** +{
** ** +** ** ** **struct window_copy_mode_data** ** *data =
wp->modedata;
** ** +** ** ** **struct window_copy_search_hist** *searchhist =
data->searchhist;
** ** +
** ** +** ** ** **while (searchhist != NULL) {
** ** +** ** ** ** ** ** ** **if (fx != NULL) *fx = searchhist->x;
** ** +** ** ** ** ** ** ** **if (fy != NULL) *fy = searchhist->y;
** ** +** ** ** ** ** ** ** **searchhist = searchhist->prev;
** ** +** ** ** ** ** ** ** **free(data->searchhist);
** ** +** ** ** ** ** ** ** **data->searchhist = searchhist;
** ** **** ** ** }
** ** **}
*wp,
** ** **** ** ** fx = data->cx;
** ** **** ** ** fy = screen_hsize(data->backing) - data->oy +
data->cy;
** ** +** ** ** **/* User deleted all searched text, jump to the
initial cursor
** ** +** ** ** ** * position and delete the searchhistory */
** ** +** ** ** **if ((searchstr == NULL) || (*searchstr == '\0'))
{
** ** +** ** ** ** ** ** ** **window_copy_clear_search_hist(wp,
&fx, &fy);
** ** +** ** ** ** ** ** ** **window_copy_scroll_to(wp, fx, fy);
** ** +** ** ** ** ** ** ** **return;
** ** +** ** ** **}
** ** +
** ** **** ** ** utf8flag =
options_get_number(&wp->window->options, "utf8");
** ** **** ** ** wrapflag =
options_get_number(&wp->window->options,
** ** "wrap-search");
** ** **** ** ** searchlen = screen_write_strlen(utf8flag, "%s",
searchstr);
*wp,
** ** **** ** ** screen_write_nputs(&ctx, -1, &gc, utf8flag, "%s",
searchstr);
** ** **** ** ** screen_write_stop(&ctx);
** ** +** ** ** **/*
** ** +** ** ** ** * `move` is useful for incremental searching.
When we do
** ** incremental,
** ** +** ** ** ** * **we don't want to jump to the next matching
word if we already
** ** stand
** ** +** ** ** ** * **on one, so `move=0`.
** ** +** ** ** ** * **But when user wants the next result, then we
use `move=1`, so
** ** +** ** ** ** * **we start searching from the place next to
the current cursor
** ** +** ** ** ** * **position */
** ** **** ** ** if (move) {
** ** **** ** ** ** ** ** ** window_copy_move_coordinates(s, &fx,
&fy, direction);
** ** +** ** ** **} else {
** ** +** ** ** ** ** ** ** **if (!window_copy_coord_from_hist(wp,
searchlen, &fx, &fy))
** ** {
** ** +** ** ** ** ** ** ** ** ** ** ** **return;
** ** +** ** ** ** ** ** ** **}
** ** **** ** ** }
** ** **** ** ** cis = window_copy_is_lowercase(searchstr);
** ** Highlight last search in window-copy mode
** ** ===============================
** ** diff --git options-table.c options-table.c
** ** index 8d680b3..79ecae3 100644
** ** --- options-table.c
** ** +++ options-table.c
** ** window_options_table[] = {
** ** **** ** ** ****.default_str = "bg=yellow,fg=black"
** ** **** ** ** },
** ** +** ** ** **{ .name = "highlight-style",
** ** +** ** ** ** **.type = OPTIONS_TABLE_STYLE,
** ** +** ** ** ** **.default_str = "bg=green,fg=black"
** ** +** ** ** **},
** ** +
** ** **** ** ** { .name = "monitor-activity",
** ** **** ** ** ****.type = OPTIONS_TABLE_FLAG,
** ** **** ** ** ****.default_num = 0
** ** window_options_table[] = {
** ** **** ** ** ****.default_num = 1
** ** **** ** ** },
** ** +** ** ** **{ .name = "highlight-search",
** ** +** ** ** ** **.type = OPTIONS_TABLE_FLAG,
** ** +** ** ** ** **.default_num = 1
** ** +** ** ** **},
** ** +
** ** **** ** ** { .name = "xterm-keys",
** ** **** ** ** ****.type = OPTIONS_TABLE_FLAG,
** ** **** ** ** ****.default_num = 0
** ** diff --git screen-write.c screen-write.c
** ** index 325fb9a..a36a1f2 100644
** ** --- screen-write.c
** ** +++ screen-write.c
*ctx, const
** ** struct grid_cell *gc)
** ** **** ** ** struct grid** ** ** ** ** ** ***gd = s->grid;
** ** **** ** ** struct tty_ctx** ** ** ** ** **ttyctx;
** ** **** ** ** u_int** ** ** ** ** ** ** ** ** ** width, xx,
last;
** ** -** ** ** **struct grid_cell** ** ** ** **tmp_gc, *tmp_gcp;
** ** +** ** ** **struct grid_cell** ** ** ** **tmp_gc, *tmp_gcp,
*cell = NULL;
** ** **** ** ** struct utf8_data** ** ** ** **ud;
** ** **** ** ** int** ** ** ** ** ** ** ** ** ** ** insert;
screen_write_ctx *ctx, const
** ** struct grid_cell *gc)
** ** **** ** ** ** ** ** ** ****
**(GRID_FLAG_FG256|GRID_FLAG_BG256);
** ** **** ** ** ** ** ** ** ttyctx.cell = &tmp_gc;
** ** **** ** ** ** ** ** ** tty_write(tty_cmd_cell, &ttyctx);
** ** +** ** ** **} else if (screen_check_highlight(s, s->cx -
width, s->cy, &cell))
** ** {
** ** +** ** ** ** ** ** ** **memcpy(&tmp_gc, cell, sizeof tmp_gc);
** ** +** ** ** ** ** ** ** **grid_cell_get(gc, &ud);
** ** +** ** ** ** ** ** ** **grid_cell_set(&tmp_gc, &ud);
** ** +** ** ** ** ** ** ** **tmp_gc.flags = gc->flags &
** ** ~(GRID_FLAG_FG256|GRID_FLAG_BG256);
** ** +** ** ** ** ** ** ** **tmp_gc.flags |= cell->flags &
** ** +** ** ** ** ** ** ** ** **
**(GRID_FLAG_FG256|GRID_FLAG_BG256);
** ** +** ** ** ** ** ** ** **ttyctx.cell = &tmp_gc;
** ** +** ** ** ** ** ** ** **tty_write(tty_cmd_cell, &ttyctx);
** ** **** ** ** } else {
** ** **** ** ** ** ** ** ** ttyctx.cell = gc;
** ** **** ** ** ** ** ** ** tty_write(tty_cmd_cell, &ttyctx);
** ** diff --git screen.c screen.c
** ** index 7bfc015..734b38e 100644
** ** --- screen.c
** ** +++ screen.c
u_int sy, u_int
** ** hlimit)
** ** **** ** ** s->cstyle = 0;
** ** **** ** ** s->ccolour = xstrdup("");
** ** **** ** ** s->tabs = NULL;
** ** +** ** ** **s->hls = NULL;
** ** **** ** ** screen_reinit(s);
** ** **}
** ** **** ** ** grid_clear_lines(s->grid, s->grid->hsize,
s->grid->sy);
** ** **** ** ** screen_clear_selection(s);
** ** +** ** ** **screen_clear_highlight(s);
** ** **}
** ** **/* Destroy a screen. */
** ** **** ** ** free(s->title);
** ** **** ** ** free(s->ccolour);
** ** **** ** ** grid_destroy(s->grid);
** ** +** ** ** **screen_clear_highlight(s);
** ** **}
** ** **/* Reset tabs to default, eight spaces apart. */
u_int px,
** ** u_int py)
** ** **** ** ** return (1);
** ** **}
** ** +/* Set highlight. */
** ** +void
** ** +screen_set_highlight(struct screen *s,
** ** +** ** ** **u_int sx, u_int ex, u_int y, struct grid_cell
*gc)
** ** +{
** ** +** ** ** **struct screen_hls** ** ** ***hls = xmalloc(sizeof
(struct
** ** screen_hls));
** ** +
** ** +** ** ** **hls->sx = sx;
** ** +** ** ** **hls->ex = ex;
** ** +** ** ** **hls->y = y;
** ** +** ** ** **hls->next = s->hls;
** ** +
** ** +** ** ** **memcpy(&hls->cell, gc, sizeof hls->cell);
** ** +
** ** +** ** ** **s->hls = hls;
** ** +}
** ** +
** ** +/* Clear highlights. */
** ** +void
** ** +screen_clear_highlight(struct screen *s)
** ** +{
** ** +** ** ** **struct screen_hls** ** ** ***hls = s->hls,
*hlsPrev;
** ** +
** ** +** ** ** **while (hls != NULL) {
** ** +** ** ** ** ** ** ** **hlsPrev = hls;
** ** +** ** ** ** ** ** ** **hls = hls->next;
** ** +** ** ** ** ** ** ** **free(hlsPrev);
** ** +** ** ** **}
** ** +
** ** +** ** ** **s->hls = NULL;
** ** +}
** ** +
** ** +/* Check if cell in highlight. */
** ** +int
** ** +screen_check_highlight(struct screen *s, u_int px, u_int py,
** ** +** ** ** **struct grid_cell **cell)
** ** +{
** ** +** ** ** **struct screen_hls** ** ** ***hls = s->hls;
** ** +
** ** +** ** ** **while (hls != NULL) {
** ** +** ** ** ** ** ** ** **if (hls->sx <= px && px <= hls->ex &&
hls->y == py) {
** ** +** ** ** ** ** ** ** ** ** ** ** ***cell = &hls->cell;
** ** +** ** ** ** ** ** ** ** ** ** ** **return 1;
** ** +** ** ** ** ** ** ** **}
** ** +** ** ** ** ** ** ** **hls = hls->next;
** ** +** ** ** **}
** ** +
** ** +** ** ** **return 0;
** ** +}
** ** +
** ** **/* Reflow wrapped lines. */
** ** **void
** ** **screen_reflow(struct screen *s, u_int new_x)
** ** diff --git tmux.h tmux.h
** ** index c4c5236..6fc5fd0 100644
** ** --- tmux.h
** ** +++ tmux.h
** ** **** ** ** struct grid_cell cell;
** ** **};
** ** +/* Screen highlights. */
** ** +struct screen_hls {
** ** +** ** ** **u_int** ** ** ** ** ** sx;
** ** +** ** ** **u_int** ** ** ** ** ** ex;
** ** +
** ** +** ** ** **u_int** ** ** ** ** ** y;
** ** +
** ** +** ** ** **struct grid_cell cell;
** ** +** ** ** **struct screen_hls *next;
** ** +};
** ** +
** ** **/* Virtual screen. */
** ** **struct screen {
** ** **** ** ** char** ** ** ** ** ** *title;
** ** **** ** ** bitstr_t** ** ** ** *tabs;
** ** **** ** ** struct screen_sel sel;
** ** +** ** ** **struct screen_hls *hls;
** ** **};
** ** **/* Screen write context. */
screen_set_selection(struct screen *,
** ** **** ** ** **** ** u_int, u_int, u_int, u_int, u_int, struct
grid_cell *);
** ** **void** **screen_clear_selection(struct screen *);
** ** **int** ** screen_check_selection(struct screen *, u_int,
u_int);
** ** +void** ** screen_set_highlight(struct screen *,
** ** +** ** ** ** ** ** u_int, u_int, u_int, struct grid_cell *);
** ** +void** ** screen_clear_highlight(struct screen *);
** ** +int** ** **screen_check_highlight(struct screen *, u_int,
u_int,
** ** +** ** ** ** ** ** struct grid_cell **);
** ** **void** **screen_reflow(struct screen *, u_int);
** ** **/* window.c */
** ** diff --git tty.c tty.c
** ** index 7688e90..4511533 100644
** ** --- tty.c
** ** +++ tty.c
screen *s, u_int
** ** py, u_int ox, u_int oy)
** ** **{
** ** **** ** ** const struct grid_cell** *gc;
** ** **** ** ** struct grid_line** ** ** ** *gl;
** ** -** ** ** **struct grid_cell** ** ** ** **tmpgc;
** ** +** ** ** **struct grid_cell** ** ** ** **tmpgc, *cell =
NULL;
** ** **** ** ** struct utf8_data** ** ** ** **ud;
** ** **** ** ** u_int** ** ** ** ** ** ** ** ** ** i, sx;
screen *s,
** ** u_int py, u_int ox, u_int oy)
** ** **** ** ** ** ** ** ** ** ** ** ** tmpgc.flags |=
s->sel.cell.flags &
** ** **** ** ** ** ** ** ** ** ** ** ** ****
**(GRID_FLAG_FG256|GRID_FLAG_BG256);
** ** **** ** ** ** ** ** ** ** ** ** ** tty_cell(tty, &tmpgc);
** ** +** ** ** ** ** ** ** **} else if (screen_check_highlight(s,
i, py, &cell)) {
** ** +** ** ** ** ** ** ** ** ** ** ** **memcpy(&tmpgc, cell,
sizeof tmpgc);
** ** +** ** ** ** ** ** ** ** ** ** ** **grid_cell_get(gc, &ud);
** ** +** ** ** ** ** ** ** ** ** ** ** **grid_cell_set(&tmpgc,
&ud);
** ** +** ** ** ** ** ** ** ** ** ** ** **tmpgc.flags = gc->flags &
** ** +** ** ** ** ** ** ** ** ** ** ** ** **
**~(GRID_FLAG_FG256|GRID_FLAG_BG256);
** ** +** ** ** ** ** ** ** ** ** ** ** **tmpgc.flags |=
cell->flags &
** ** +** ** ** ** ** ** ** ** ** ** ** ** **
**(GRID_FLAG_FG256|GRID_FLAG_BG256);
** ** +** ** ** ** ** ** ** ** ** ** ** **tty_cell(tty, &tmpgc);
** ** **** ** ** ** ** ** ** } else
** ** **** ** ** ** ** ** ** ** ** ** ** tty_cell(tty, gc);
** ** **** ** ** }
** ** diff --git window-copy.c window-copy.c
** ** index 243c755..00cdc3f 100644
** ** --- window-copy.c
** ** +++ window-copy.c
window_pane *);
** ** **void** window_copy_free(struct window_pane *);
** ** **void** window_copy_resize(struct window_pane *, u_int,
u_int);
** ** **void** window_copy_key(struct window_pane *, struct session
*, int);
** ** +void** **window_copy_key_internal(struct window_pane *,
struct session *,
** ** int);
** ** **int** **window_copy_key_input(struct window_pane *, int);
** ** **int** **window_copy_key_numeric_prefix(struct window_pane
*, int);
** ** **void** window_copy_mouse(
** ** **** ** ** **** **struct window_pane *, struct session *,
struct mouse_event
** ** *);
** ** +void** **window_copy_mouse_internal(
** ** +** ** ** ** ** **struct window_pane *, struct session *,
struct mouse_event
** ** *);
** ** **void** window_copy_redraw_lines(struct window_pane *,
u_int, u_int);
** ** **void** window_copy_redraw_screen(struct window_pane *);
*);
** ** **void** window_copy_jump_to_searched_string(
** ** **** ** ** **** **struct window_pane *, struct grid *, struct
grid *, u_int,
** ** u_int,
** ** **** ** ** **** **u_int, int, int, const int);
** ** +void** **window_copy_highlight_search(struct window_pane *);
** ** **int** **window_copy_coord_from_hist(struct window_pane *wp,
** ** **** ** ** **** **const size_t searchlen, u_int *fx, u_int
*fy);
** ** **void** window_copy_clear_search_hist(struct window_pane *,
u_int *, u_int
** ** *);
*wp, u_int sx,
** ** u_int sy)
** ** **void
** ** **window_copy_key(struct window_pane *wp, struct session
*sess, int key)
** ** **{
** ** +** ** ** **window_copy_key_internal(wp, sess, key);
** ** +
** ** +** ** ** **if (wp->mode != NULL) {
** ** +** ** ** ** ** ** ** **window_copy_highlight_search(wp);
** ** +** ** ** **}
** ** +}
** ** +
** ** +void
** ** +window_copy_key_internal(struct window_pane *wp, struct
session *sess,
** ** int key)
** ** +{
** ** **** ** ** const char** ** ** ** ** ** ** ** ** ** **
*word_separators;
** ** **** ** ** struct window_copy_mode_data** ** *data =
wp->modedata;
** ** **** ** ** struct screen** ** ** ** ** ** ** ** ** ***s =
&data->screen;
** ** **window_copy_mouse(
** ** ** ** **struct window_pane *wp, struct session *sess, struct
mouse_event
** ** *m)
** ** **{
** ** +** ** ** **window_copy_mouse_internal(wp, sess, m);
** ** +
** ** +** ** ** **if (wp->mode != NULL) {
** ** +** ** ** ** ** ** ** **window_copy_highlight_search(wp);
** ** +** ** ** **}
** ** +}
** ** +
** ** +void
** ** +window_copy_mouse_internal(
** ** + ** **struct window_pane *wp, struct session *sess, struct
mouse_event
** ** *m)
** ** +{
** ** **** ** ** struct window_copy_mode_data** ** *data =
wp->modedata;
** ** **** ** ** struct screen** ** ** ** ** ** ** ** ** ***s =
&data->screen;
** ** **** ** ** u_int** ** ** ** ** ** ** ** ** ** ** ** ** ** i;
window_copy_jump_to_searched_string(struct
** ** window_pane *wp,
** ** **** ** ** }
** ** **}
** ** +void
** ** +window_copy_highlight_search(struct window_pane *wp)
** ** +{
** ** +** ** ** **struct window_copy_mode_data** ** *data =
wp->modedata;
** ** +** ** ** **struct screen** ** ** ** ** ** ** ** ** ***s =
data->backing, ss;
** ** +** ** ** **struct screen_write_ctx** ** ** ** ** ** ** ** **
ctx;
** ** +** ** ** **struct grid** ** ** ** ** ** ** ** ** ** ***gd =
s->grid;
** ** +** ** ** **struct grid_cell** ** ** ** ** ** ** ** **gc;
** ** +** ** ** **struct options** ** ** ** ** ** ** ** ** *oo =
&wp->window->options;
** ** +** ** ** **const char** ** ** ** ** ** ** ** ** ** **
*searchstr = data->searchstr;
** ** +** ** ** **size_t** ** ** ** ** ** ** ** ** ** ** ** **
**searchlen;
** ** +** ** ** **u_int** ** ** ** ** ** ** ** ** ** ** ** ** ** i,
px, last, beginline, endline;
** ** +** ** ** **int** ** ** ** ** ** ** ** ** ** ** ** ** ** **
found, utf8flag, cis, highlight;
** ** +
** ** +** ** ** **highlight = options_get_number(
** ** +** ** ** ** ** ** ** **&wp->window->options,
"highlight-search");
** ** +** ** ** **if (!highlight) {
** ** +** ** ** ** ** ** ** **return;
** ** +** ** ** **}
** ** +
** ** +** ** ** **screen_clear_highlight(&data->screen);
** ** +
** ** +** ** ** **if ((searchstr != NULL) && (*searchstr != '\0'))
{
** ** +** ** ** ** ** ** ** **utf8flag =
options_get_number(&wp->window->options,
** ** "utf8");
** ** +** ** ** ** ** ** ** **searchlen =
screen_write_strlen(utf8flag, "%s",
** ** searchstr);
** ** +
** ** +** ** ** ** ** ** ** **screen_init(&ss, searchlen, 1, 0);
** ** +** ** ** ** ** ** ** **screen_write_start(&ctx, NULL, &ss);
** ** +** ** ** ** ** ** ** **memcpy(&gc, &grid_default_cell,
sizeof gc);
** ** +** ** ** ** ** ** ** **screen_write_nputs(&ctx, -1, &gc,
utf8flag, "%s",
** ** searchstr);
** ** +** ** ** ** ** ** ** **screen_write_stop(&ctx);
** ** +
** ** +** ** ** ** ** ** ** **cis =
window_copy_is_lowercase(searchstr);
** ** +
** ** +** ** ** ** ** ** ** **/* Set colours. */
** ** +** ** ** ** ** ** ** **style_apply(&gc, oo,
"highlight-style");
** ** +
** ** +** ** ** ** ** ** ** **beginline = screen_hsize(s) -
data->oy;
** ** +** ** ** ** ** ** ** **endline = screen_hsize(s) - data->oy
+ screen_size_y(s) -
** ** 1;
** ** +
** ** +** ** ** ** ** ** ** **for (i = beginline; i <= endline;
++i) {
** ** +** ** ** ** ** ** ** ** ** ** ** **last = 0;
** ** +** ** ** ** ** ** ** ** ** ** ** **do {
** ** +** ** ** ** ** ** ** ** ** ** ** ** ** ** ** **found =
window_copy_search_lr(gd, ss.grid,
** ** &px,
** ** +** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** **
**i, last, gd->sx, cis);
** ** +** ** ** ** ** ** ** ** ** ** ** ** ** ** ** **if (found) {
** ** +** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** **
**screen_set_highlight(
** ** +** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** **
** ** ** **&data->screen,
** ** +** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** **
** ** ** **px,
** ** +** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** **
** ** ** **px + searchlen - 1,
** ** +** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** **
** ** ** **i - (screen_hsize(s)
** ** +** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** **
** ** ** ** ** ** - data->oy),
** ** +** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** **
** ** ** **&gc);
** ** +** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** **
**last += searchlen;
** ** +** ** ** ** ** ** ** ** ** ** ** ** ** ** ** **}
** ** +** ** ** ** ** ** ** ** ** ** ** **} while (found);
** ** +** ** ** ** ** ** ** **}
** ** +** ** ** **}
** ** +
** ** +** ** ** **window_copy_redraw_screen(wp);
** ** +}
** ** +
** ** **/* If it returns 0 then, according to search history, last
time we
** ** searched
** ** ** * a shorter string we haven't found anything, so there is
no point in
** ** ** * incremental-searching a longer string (just an
optimization) */
------------------------------------------------------------------------------
Want fast and easy access to all the code in your enterprise?
Index and
search up to 200,000 lines of code with a free copy of Black Duck
Code Sight - the same software that powers the world's largest
code
search on Ohloh, the Black Duck Open Hub! Try it now.
[4]http://p.sf.net/sfu/bds
_______________________________________________
tmux-users mailing list
[6]https://lists.sourceforge.net/lists/listinfo/tmux-users
------------------------------------------------------------------------------
Want fast and easy access to all the code in your enterprise? Index and
search up to 200,000 lines of code with a free copy of Black Duck
Code Sight - the same software that powers the world's largest code
search on Ohloh, the Black Duck Open Hub! Try it now.
[7]http://p.sf.net/sfu/bds
_______________________________________________
tmux-users mailing list
[9]https://lists.sourceforge.net/lists/listinfo/tmux-users
References
Visible links
4. http://p.sf.net/sfu/bds
6. https://lists.sourceforge.net/lists/listinfo/tmux-users
7. http://p.sf.net/sfu/bds
9. https://lists.sourceforge.net/lists/listinfo/tmux-users
Nicholas Marriott
2015-04-21 23:36:14 UTC
Permalink
Hi

I made a few changes to your first diff, please take a look. Notably:

- update to latest git
- renamed some functions and variables to be shorter
- split window_copy_move_coordinates into two functions to avoid so much ?:
- passing const int into a function is useless, just use int
- don't use backticks for quotation marks, they look awful
- otherwise reformat some comments

Seems to work but please take a look, then I will apply it and we can
move from there with the next diff.


Index: window-copy.c
===================================================================
RCS file: /cvs/src/usr.bin/tmux/window-copy.c,v
retrieving revision 1.129
diff -u -p -r1.129 window-copy.c
--- window-copy.c 21 Apr 2015 15:16:06 -0000 1.129
+++ window-copy.c 21 Apr 2015 23:34:57 -0000
@@ -47,8 +47,14 @@ int window_copy_search_lr(struct grid *,
u_int, u_int, int);
int window_copy_search_rl(struct grid *, struct grid *, u_int *, u_int,
u_int, u_int, int);
-void window_copy_search_up(struct window_pane *, const char *);
-void window_copy_search_down(struct window_pane *, const char *);
+void window_copy_move_left(struct screen *, u_int *, u_int *);
+void window_copy_move_right(struct screen *, u_int *, u_int *);
+int window_copy_is_lowercase(const char *);
+void window_copy_search_jump(struct window_pane *, struct grid *,
+ struct grid *, u_int, u_int, u_int, int, int, int);
+void window_copy_search(struct window_pane *, const char *, int, int);
+void window_copy_search_up(struct window_pane *, const char *, int);
+void window_copy_search_down(struct window_pane *, const char *, int);
void window_copy_goto_line(struct window_pane *, const char *);
void window_copy_update_cursor(struct window_pane *, u_int, u_int);
void window_copy_start_selection(struct window_pane *);
@@ -706,20 +712,20 @@ window_copy_key(struct window_pane *wp,
ss = data->searchstr;
if (cmd == MODEKEYCOPY_SEARCHAGAIN) {
for (; np != 0; np--)
- window_copy_search_up(wp, ss);
+ window_copy_search_up(wp, ss, 1);
} else {
for (; np != 0; np--)
- window_copy_search_down(wp, ss);
+ window_copy_search_down(wp, ss, 1);
}
break;
case WINDOW_COPY_SEARCHDOWN:
ss = data->searchstr;
if (cmd == MODEKEYCOPY_SEARCHAGAIN) {
for (; np != 0; np--)
- window_copy_search_down(wp, ss);
+ window_copy_search_down(wp, ss, 1);
} else {
for (; np != 0; np--)
- window_copy_search_up(wp, ss);
+ window_copy_search_up(wp, ss, 1);
}
break;
}
@@ -828,16 +834,16 @@ window_copy_key_input(struct window_pane
case WINDOW_COPY_NUMERICPREFIX:
break;
case WINDOW_COPY_SEARCHUP:
- for (; np != 0; np--)
- window_copy_search_up(wp, data->inputstr);
data->searchtype = data->inputtype;
data->searchstr = xstrdup(data->inputstr);
+ for (; np != 0; np--)
+ window_copy_search_up(wp, data->inputstr, 0);
break;
case WINDOW_COPY_SEARCHDOWN:
- for (; np != 0; np--)
- window_copy_search_down(wp, data->inputstr);
data->searchtype = data->inputtype;
data->searchstr = xstrdup(data->inputstr);
+ for (; np != 0; np--)
+ window_copy_search_down(wp, data->inputstr, 0);
break;
case WINDOW_COPY_NAMEDBUFFER:
window_copy_copy_selection(wp, data->inputstr);
@@ -989,89 +995,103 @@ window_copy_search_rl(struct grid *gd,
}

void
-window_copy_search_up(struct window_pane *wp, const char *searchstr)
+window_copy_move_left(struct screen *s, u_int *fx, u_int *fy)
{
- struct window_copy_mode_data *data = wp->modedata;
- struct screen *s = data->backing, ss;
- struct screen_write_ctx ctx;
- struct grid *gd = s->grid, *sgd;
- struct grid_cell gc;
- size_t searchlen;
- u_int i, last, fx, fy, px;
- int utf8flag, n, wrapped, wrapflag, cis;
- const char *ptr;
-
- if (*searchstr == '\0')
- return;
- utf8flag = options_get_number(&wp->window->options, "utf8");
- wrapflag = options_get_number(&wp->window->options, "wrap-search");
- searchlen = screen_write_strlen(utf8flag, "%s", searchstr);
-
- screen_init(&ss, searchlen, 1, 0);
- screen_write_start(&ctx, NULL, &ss);
- memcpy(&gc, &grid_default_cell, sizeof gc);
- screen_write_nputs(&ctx, -1, &gc, utf8flag, "%s", searchstr);
- screen_write_stop(&ctx);
-
- fx = data->cx;
- fy = gd->hsize - data->oy + data->cy;
+ if (*fx == 0) { /* left */
+ if (*fy == 0) /* top */
+ return;
+ *fx = screen_size_x(s) - 1;
+ *fy = *fy - 1;
+ } else
+ *fx = *fx - 1;
+}

- if (fx == 0) {
- if (fy == 0)
+void
+window_copy_move_right(struct screen *s, u_int *fx, u_int *fy)
+{
+ if (*fx == screen_size_x(s) - 1) { /* right */
+ if (*fy == screen_hsize(s) + screen_size_y(s)) /* bottom */
return;
- fx = gd->sx - 1;
- fy--;
+ *fx = 0;
+ *fy = *fy + 1;
} else
- fx--;
- n = wrapped = 0;
+ *fx = *fx + 1;
+}

- cis = 1;
- for (ptr = searchstr; *ptr != '\0'; ptr++) {
+int
+window_copy_is_lowercase(const char *ptr)
+{
+ while (*ptr != '\0') {
if (*ptr != tolower((u_char)*ptr)) {
- cis = 0;
- break;
+ return 0;
}
+ ++ptr;
}
+ return 1;
+}

-retry:
- sgd = ss.grid;
- for (i = fy + 1; i > 0; i--) {
- last = screen_size_x(s);
- if (i == fy + 1)
- last = fx;
- n = window_copy_search_rl(gd, sgd, &px, i - 1, 0, last, cis);
- if (n) {
- window_copy_scroll_to(wp, px, i - 1);
- break;
+/*
+ * Search for text stored in sgd starting from position fx,fy up to endline. If
+ * found, jump to it. If cis then ignore case. The direction is 0 for searching
+ * up, down otherwise. If wrap then go to begin/end of grid and try again if
+ * not found.
+ */
+void
+window_copy_search_jump(struct window_pane *wp, struct grid *gd,
+ struct grid *sgd, u_int fx, u_int fy, u_int endline, int cis, int wrap,
+ int direction)
+{
+ u_int i, px;
+ int first = 1, found = 0;
+
+ if (direction) {
+ for (i = fy; i <= endline; ++i) {
+ found = window_copy_search_lr(gd, sgd, &px, i,
+ first ? fx : 0, gd->sx, cis);
+ if (found)
+ break;
+ first = 0;
+ }
+ } else {
+ for (i = fy + 1; endline < i; --i) {
+ found = window_copy_search_rl(gd, sgd, &px, i - 1, 0,
+ first ? fx : gd->sx, cis);
+ if (found) {
+ i--;
+ break;
+ }
+ first = 0;
}
}
- if (wrapflag && !n && !wrapped) {
- fx = gd->sx - 1;
- fy = gd->hsize + gd->sy - 1;
- wrapped = 1;
- goto retry;
+ if (found)
+ window_copy_scroll_to(wp, px, i);
+ else if (wrap) {
+ /* Start searching from begin/end of grid. */
+ window_copy_search_jump(wp, gd, sgd, direction ? 0 : gd->sx - 1,
+ direction ? 0 : gd->hsize + gd->sy - 1, fy, cis, 0,
+ direction);
}
-
- screen_free(&ss);
}

void
-window_copy_search_down(struct window_pane *wp, const char *searchstr)
+window_copy_search(struct window_pane *wp, const char *searchstr, int direction,
+ int moveflag)
{
struct window_copy_mode_data *data = wp->modedata;
struct screen *s = data->backing, ss;
struct screen_write_ctx ctx;
- struct grid *gd = s->grid, *sgd;
- struct grid_cell gc;
+ struct grid *gd = s->grid;
+ struct grid_cell gc;
size_t searchlen;
- u_int i, first, fx, fy, px;
- int utf8flag, n, wrapped, wrapflag, cis;
- const char *ptr;
+ u_int fx, fy;
+ int utf8flag, wrapflag, cis;
+
+ fx = data->cx;
+ fy = screen_hsize(data->backing) - data->oy + data->cy;

- if (*searchstr == '\0')
- return;
utf8flag = options_get_number(&wp->window->options, "utf8");
wrapflag = options_get_number(&wp->window->options, "wrap-search");
+
searchlen = screen_write_strlen(utf8flag, "%s", searchstr);

screen_init(&ss, searchlen, 1, 0);
@@ -1080,47 +1100,33 @@ window_copy_search_down(struct window_pa
screen_write_nputs(&ctx, -1, &gc, utf8flag, "%s", searchstr);
screen_write_stop(&ctx);

- fx = data->cx;
- fy = gd->hsize - data->oy + data->cy;
-
- if (fx == gd->sx - 1) {
- if (fy == gd->hsize + gd->sy)
- return;
- fx = 0;
- fy++;
- } else
- fx++;
- n = wrapped = 0;
-
- cis = 1;
- for (ptr = searchstr; *ptr != '\0'; ptr++) {
- if (*ptr != tolower((u_char)*ptr)) {
- cis = 0;
- break;
- }
+ if (moveflag) {
+ if (direction)
+ window_copy_move_right(s, &fx, &fy);
+ else
+ window_copy_move_left(s, &fx, &fy);
}
+ window_copy_clear_selection(wp);

-retry:
- sgd = ss.grid;
- for (i = fy + 1; i < gd->hsize + gd->sy + 1; i++) {
- first = 0;
- if (i == fy + 1)
- first = fx;
- n = window_copy_search_lr(gd, sgd, &px, i - 1, first, gd->sx,
- cis);
- if (n) {
- window_copy_scroll_to(wp, px, i - 1);
- break;
- }
- }
- if (wrapflag && !n && !wrapped) {
- fx = 0;
- fy = 0;
- wrapped = 1;
- goto retry;
- }
+ cis = window_copy_is_lowercase(searchstr);
+ window_copy_search_jump(wp, gd, ss.grid, fx, fy,
+ direction ? gd->hsize + gd->sy - 1 : 0, cis, wrapflag, direction);

screen_free(&ss);
+}
+
+void
+window_copy_search_up(struct window_pane *wp, const char *searchstr,
+ int moveflag)
+{
+ window_copy_search(wp, searchstr, 0, moveflag);
+}
+
+void
+window_copy_search_down(struct window_pane *wp, const char *searchstr,
+ int moveflag)
+{
+ window_copy_search(wp, searchstr, 1, moveflag);
}

void
I finally got some time to sit down and test my changes again. It appears
that no one was touching the part of code that I have been working on, so
I am sending almost the same changes as last time. But this time I am
attaching them to the email instead of sending in the message.
Cheers
Lukas
2014-11-01 0:35 GMT+00:00 **ukasz Pi**tkowski
Hi Felix,
I didn't have time to work on this, last few months were really busy. I
will try to rebase my changes on top of current revision and test them
before sending the code again. I hope I will find some time before the
end of year.
Cheers
Lukas
Was there any follow up to this thread?** Incremental search would be
a great feature to have and is on the TODO list.
Thanks.
-FR
On Fri, Aug 8, 2014 at 11:21 AM, Nicholas Marriott
Hi
Your mailer has mangled the diffs, if you can't fix it so it works
inline please send them as attachments instead.
** ** I have split up my changes into 3 diffs, first is refactoring
search code
** ** in window-copy.c, second is adding incremental search and the
last one is
** ** adding search highlighting.
** ** Cheers
** ** Lukas
** ** --
** **
I**am**providing**code**in**this**repository**to**you**under**an**open**source**license.**Because**this**is**my**personal
** **
repository,**the**license**you**receive**to**my**code**is**from**me**and**not**from**my**employer**(Facebook).
All contributions must be under the ISC license that is at the top of
each file you modify.
Thanks
** ** --
** ** Refactor window-copy search functions
** ** ============================
** ** diff --git window-copy.c window-copy.c
** ** index 0775bcb..1213380 100644
** ** --- window-copy.c
** ** +++ window-copy.c
** ** **** ** ** **** **struct grid *, struct grid *, u_int *,
u_int, u_int, u_int,
** ** int);
** ** **int** **window_copy_search_rl(
** ** **** ** ** **** **struct grid *, struct grid *, u_int *,
u_int, u_int, u_int,
** ** int);
** ** -void** **window_copy_search_up(struct window_pane *, const
char *);
** ** -void** **window_copy_search_down(struct window_pane *, const
char *);
** ** +void** **window_copy_move_coordinates(
** ** +** ** ** ** ** **struct screen *, u_int *, u_int *, const
int);
** ** +int** ** window_copy_is_lowercase(const char *);
** ** +void** **window_copy_jump_to_searched_string(
** ** +** ** ** ** ** **struct window_pane *, struct grid *, struct
grid *, u_int,
** ** u_int,
** ** +** ** ** ** ** **u_int, int, int, const int);
** ** +void** **window_copy_search(struct window_pane *, const char
*,
** ** +** ** ** ** ** **const int, const int);
** ** +void** **window_copy_search_up(struct window_pane *, const
char *, const
** ** int);
** ** +void** **window_copy_search_down(struct window_pane *, const
char *, const
** ** int);
** ** **void** window_copy_goto_line(struct window_pane *, const
char *);
** ** **void** window_copy_update_cursor(struct window_pane *,
u_int, u_int);
** ** **void** window_copy_start_selection(struct window_pane *);
struct
** ** session *sess, int key)
** ** **** ** ** ** ** ** ** ** ** ** ** if (cmd ==
MODEKEYCOPY_SEARCHAGAIN) {
** ** **** ** ** ** ** ** ** ** ** ** ** ** ** ** ** for (; np !=
0; np--) {
** ** **** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** **
window_copy_search_up(
** ** -** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** **
** **wp, data->searchstr);
** ** +** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** **
** ** ** **wp, data->searchstr, 1);
** ** **** ** ** ** ** ** ** ** ** ** ** ** ** ** ** }
** ** **** ** ** ** ** ** ** ** ** ** ** } else {
** ** **** ** ** ** ** ** ** ** ** ** ** ** ** ** ** for (; np !=
0; np--) {
** ** **** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** **
window_copy_search_down(
** ** -** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** **
** **wp, data->searchstr);
** ** +** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** **
** ** ** **wp, data->searchstr, 1);
** ** **** ** ** ** ** ** ** ** ** ** ** ** ** ** ** }
** ** **** ** ** ** ** ** ** ** ** ** ** }
** ** **** ** ** ** ** ** ** ** ** ** ** break;
struct
** ** session *sess, int key)
** ** **** ** ** ** ** ** ** ** ** ** ** if (cmd ==
MODEKEYCOPY_SEARCHAGAIN) {
** ** **** ** ** ** ** ** ** ** ** ** ** ** ** ** ** for (; np !=
0; np--) {
** ** **** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** **
window_copy_search_down(
** ** -** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** **
** **wp, data->searchstr);
** ** +** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** **
** ** ** **wp, data->searchstr, 1);
** ** **** ** ** ** ** ** ** ** ** ** ** ** ** ** ** }
** ** **** ** ** ** ** ** ** ** ** ** ** } else {
** ** **** ** ** ** ** ** ** ** ** ** ** ** ** ** ** for (; np !=
0; np--) {
** ** **** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** **
window_copy_search_up(
** ** -** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** **
** **wp, data->searchstr);
** ** +** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** **
** ** ** **wp, data->searchstr, 1);
** ** **** ** ** ** ** ** ** ** ** ** ** ** ** ** ** }
** ** **** ** ** ** ** ** ** ** ** ** ** }
** ** **** ** ** ** ** ** ** ** ** ** ** break;
window_pane *wp, int
** ** key)
** ** **** ** ** ** ** ** ** ** ** ** ** break;
** ** -** ** ** ** ** ** ** ** ** ** ** **for (; np != 0; np--)
** ** -** ** ** ** ** ** ** ** ** ** ** ** ** ** **
**window_copy_search_up(wp, data->inputstr);
** ** **** ** ** ** ** ** ** ** ** ** ** data->searchtype =
data->inputtype;
** ** **** ** ** ** ** ** ** ** ** ** ** data->searchstr =
xstrdup(data->inputstr);
** ** +** ** ** ** ** ** ** ** ** ** ** **for (; np != 0; np--)
** ** +** ** ** ** ** ** ** ** ** ** ** ** ** ** **
**window_copy_search_up(wp, data->inputstr,
** ** 0);
** ** **** ** ** ** ** ** ** ** ** ** ** break;
** ** -** ** ** ** ** ** ** ** ** ** ** **for (; np != 0; np--)
** ** -** ** ** ** ** ** ** ** ** ** ** ** ** ** **
**window_copy_search_down(wp,
** ** data->inputstr);
** ** **** ** ** ** ** ** ** ** ** ** ** data->searchtype =
data->inputtype;
** ** **** ** ** ** ** ** ** ** ** ** ** data->searchstr =
xstrdup(data->inputstr);
** ** +** ** ** ** ** ** ** ** ** ** ** **for (; np != 0; np--)
** ** +** ** ** ** ** ** ** ** ** ** ** ** ** ** **
**window_copy_search_down(wp,
** ** data->inputstr, 0);
** ** **** ** ** ** ** ** ** ** ** ** ** break;
** ** **** ** ** ** ** ** ** ** ** ** **
window_copy_copy_selection(wp, data->inputstr);
*gd,
** ** **** ** ** return (0);
** ** **}
** ** +/* For direction == 0 move left, otherwise right; jump line
if needed */
** ** **void
** ** -window_copy_search_up(struct window_pane *wp, const char
*searchstr)
** ** +window_copy_move_coordinates(struct screen *s,
** ** +** ** ** **u_int *fx, u_int *fy, const int direction)
** ** **{
** ** -** ** ** **struct window_copy_mode_data** ** *data =
wp->modedata;
** ** -** ** ** **struct screen** ** ** ** ** ** ** ** ** ***s =
data->backing, ss;
** ** -** ** ** **struct screen_write_ctx** ** ** ** ** ** ** ** **
ctx;
** ** -** ** ** **struct grid** ** ** ** ** ** ** ** ** ** ***gd =
s->grid, *sgd;
** ** -** ** ** **struct grid_cell** ** ** ** ** ** ** ** **gc;
** ** -** ** ** **size_t** ** ** ** ** ** ** ** ** ** ** ** **
**searchlen;
** ** -** ** ** **u_int** ** ** ** ** ** ** ** ** ** ** ** ** ** i,
last, fx, fy, px;
** ** -** ** ** **int** ** ** ** ** ** ** ** ** ** ** ** ** ** **
utf8flag, n, wrapped, wrapflag,
** ** cis;
** ** -** ** ** **const char** ** ** ** ** ** ** ** ** ** ** *ptr;
** ** -
** ** -** ** ** **if (*searchstr == '\0')
** ** -** ** ** ** ** ** ** **return;
** ** -** ** ** **utf8flag =
options_get_number(&wp->window->options, "utf8");
** ** -** ** ** **wrapflag =
options_get_number(&wp->window->options,
** ** "wrap-search");
** ** -** ** ** **searchlen = screen_write_strlen(utf8flag, "%s",
searchstr);
** ** -
** ** -** ** ** **screen_init(&ss, searchlen, 1, 0);
** ** -** ** ** **screen_write_start(&ctx, NULL, &ss);
** ** -** ** ** **memcpy(&gc, &grid_default_cell, sizeof gc);
** ** -** ** ** **screen_write_nputs(&ctx, -1, &gc, utf8flag, "%s",
searchstr);
** ** -** ** ** **screen_write_stop(&ctx);
** ** -
** ** -** ** ** **fx = data->cx;
** ** -** ** ** **fy = gd->hsize - data->oy + data->cy;
** ** -
** ** -** ** ** **if (fx == 0) {
** ** -** ** ** ** ** ** ** **if (fy == 0)
** ** +** ** ** **/* If on left/right border */
0)) {
** ** +** ** ** ** ** ** ** **/* If on top/bottom border */
** ** +** ** ** ** ** ** ** **if (*fy == (direction ?
screen_hsize(s) + screen_size_y(s)
** ** : 0))
** ** +** ** ** ** ** ** ** ** ** ** ** **/* Nowhere to go */
** ** **** ** ** ** ** ** ** ** ** ** ** return;
** ** -** ** ** ** ** ** ** **fx = gd->sx - 1;
** ** -** ** ** ** ** ** ** **fy--;
** ** -** ** ** **} else
** ** -** ** ** ** ** ** ** **fx--;
** ** -** ** ** **n = wrapped = 0;
** ** +** ** ** ** ** ** ** **/* Jump to beggin/end of lower/upper
line */
screen_size_x(s) - 1;
** ** +** ** ** ** ** ** ** ***fy = direction ? *fy + 1 : *fy - 1;
** ** +** ** ** **} else {
** ** +** ** ** ** ** ** ** ***fx = direction ? *fx + 1 : *fx - 1;
** ** +** ** ** **}
** ** +}
** ** -** ** ** **cis = 1;
** ** -** ** ** **for (ptr = searchstr; *ptr != '\0'; ptr++) {
** ** +int
** ** +window_copy_is_lowercase(const char *ptr)
** ** +{
** ** +** ** ** **while (*ptr != '\0') {
** ** **** ** ** ** ** ** ** if (*ptr != tolower((u_char)*ptr)) {
** ** -** ** ** ** ** ** ** ** ** ** ** **cis = 0;
** ** -** ** ** ** ** ** ** ** ** ** ** **break;
** ** +** ** ** ** ** ** ** ** ** ** ** **return 0;
** ** **** ** ** ** ** ** ** }
** ** +** ** ** ** ** ** ** **++ptr;
** ** **** ** ** }
** ** +** ** ** **return 1;
** ** +}
** ** -** ** ** **sgd = ss.grid;
** ** -** ** ** **for (i = fy + 1; i > 0; i--) {
** ** -** ** ** ** ** ** ** **last = screen_size_x(s);
** ** -** ** ** ** ** ** ** **if (i == fy + 1)
** ** -** ** ** ** ** ** ** ** ** ** ** **last = fx;
** ** -** ** ** ** ** ** ** **n = window_copy_search_rl(gd, sgd,
&px, i - 1, 0, last,
** ** cis);
** ** -** ** ** ** ** ** ** **if (n) {
** ** -** ** ** ** ** ** ** ** ** ** ** **window_copy_scroll_to(wp,
px, i - 1);
** ** -** ** ** ** ** ** ** ** ** ** ** **break;
** ** +/* Search in grid `gd` for text stored in grid `sgd`
starting from
** ** position
** ** + * (`fx`, `fy`) up to line `endline` and if found then jump
to it.
** ** + * If `cis` do it case-insensitive.
** ** + * `direction` 0 for searching up, down otherwise
** ** + * If `wrap` then go to begin/end of grid and try again up
to line `fy`
** ** */
** ** +void
** ** +window_copy_jump_to_searched_string(struct window_pane *wp,
** ** + ** **struct grid *gd, struct grid *sgd, u_int fx, u_int fy,
** ** + ** **u_int endline, int cis, int wrap, const int direction)
** ** +{
** ** +** ** ** **u_int** ** ** ** ** ** ** ** ** ** ** ** ** ** i,
px;
** ** +** ** ** **int** ** ** ** ** ** ** ** ** ** ** ** ** ** **
firstIteration, found;
** ** +
** ** +** ** ** **firstIteration = 1;
** ** +** ** ** **if (direction) {
** ** +** ** ** ** ** ** ** **for (i = fy; i <= endline; ++i) {
** ** +** ** ** ** ** ** ** ** ** ** ** **found =
window_copy_search_lr(gd, sgd, &px, i,
** ** +** ** ** ** ** ** ** ** ** ** ** ** ** ** **
**firstIteration ? fx : 0, gd->sx, cis);
** ** +** ** ** ** ** ** ** ** ** ** ** **if (found) break;
** ** +** ** ** ** ** ** ** ** ** ** ** **firstIteration = 0;
** ** +** ** ** ** ** ** ** **}
** ** +** ** ** **} else {
** ** +** ** ** ** ** ** ** **for (i = fy + 1; endline < i; --i) {
** ** +** ** ** ** ** ** ** ** ** ** ** **found =
window_copy_search_rl(gd, sgd, &px, i - 1,
** ** +** ** ** ** ** ** ** ** ** ** ** ** ** ** ** **0,
firstIteration ? fx : gd->sx, cis);
** ** +** ** ** ** ** ** ** ** ** ** ** **if (found) {
** ** +** ** ** ** ** ** ** ** ** ** ** ** ** ** ** **--i;
** ** +** ** ** ** ** ** ** ** ** ** ** ** ** ** ** **break;
** ** +** ** ** ** ** ** ** ** ** ** ** **}
** ** +** ** ** ** ** ** ** ** ** ** ** **firstIteration = 0;
** ** **** ** ** ** ** ** ** }
** ** **** ** ** }
** ** -** ** ** **if (wrapflag && !n && !wrapped) {
** ** -** ** ** ** ** ** ** **fx = gd->sx - 1;
** ** -** ** ** ** ** ** ** **fy = gd->hsize + gd->sy - 1;
** ** -** ** ** ** ** ** ** **wrapped = 1;
** ** -** ** ** ** ** ** ** **goto retry;
** ** +** ** ** **if (found) {
** ** +** ** ** ** ** ** ** **window_copy_scroll_to(wp, px, i);
** ** +** ** ** **} else if (wrap) {
** ** +** ** ** ** ** ** ** **/* Start searching from begin/end of
grid up to `fy` line
** ** */
** ** +** ** ** ** ** ** **
**window_copy_jump_to_searched_string(wp, gd, sgd,
** ** +** ** ** ** ** ** ** ** ** ** ** **direction ? 0 : gd->sx -
1,
** ** +** ** ** ** ** ** ** ** ** ** ** **direction ? 0 : gd->hsize
+ gd->sy - 1,
** ** +** ** ** ** ** ** ** ** ** ** ** **fy, cis, 0, direction);
** ** **** ** ** }
** ** -
** ** -** ** ** **screen_free(&ss);
** ** **}
** ** **void
** ** -window_copy_search_down(struct window_pane *wp, const char
*searchstr)
** ** +window_copy_search(struct window_pane *wp,
** ** + ** **const char *searchstr, const int direction, const int
move)
** ** **{
** ** **** ** ** struct window_copy_mode_data** ** *data =
wp->modedata;
** ** **** ** ** struct screen** ** ** ** ** ** ** ** ** ***s =
data->backing, ss;
** ** **** ** ** struct screen_write_ctx** ** ** ** ** ** ** ** **
ctx;
** ** -** ** ** **struct grid** ** ** ** ** ** ** ** ** ** ***gd =
s->grid, *sgd;
** ** -** ** ** **struct grid_cell** ** ** ** ** ** ** ** **gc;
** ** +** ** ** **struct grid** ** ** ** ** ** ** ** ** ** ***gd =
s->grid;
** ** +** ** ** **struct grid_cell** ** ** ** ** ** ** ** **gc;
** ** **** ** ** size_t** ** ** ** ** ** ** ** ** ** ** ** **
**searchlen;
** ** -** ** ** **u_int** ** ** ** ** ** ** ** ** ** ** ** ** ** i,
first, fx, fy, px;
** ** -** ** ** **int** ** ** ** ** ** ** ** ** ** ** ** ** ** **
utf8flag, n, wrapped, wrapflag,
** ** cis;
** ** -** ** ** **const char** ** ** ** ** ** ** ** ** ** ** *ptr;
** ** +** ** ** **u_int** ** ** ** ** ** ** ** ** ** ** ** ** **
fx, fy;
** ** +** ** ** **int** ** ** ** ** ** ** ** ** ** ** ** ** ** **
utf8flag, wrapflag, cis;
** ** +
** ** +** ** ** **/* current cursor coordinates */
** ** +** ** ** **fx = data->cx;
** ** +** ** ** **fy = screen_hsize(data->backing) - data->oy +
data->cy;
** ** -** ** ** **if (*searchstr == '\0')
** ** -** ** ** ** ** ** ** **return;
** ** **** ** ** utf8flag =
options_get_number(&wp->window->options, "utf8");
** ** **** ** ** wrapflag =
options_get_number(&wp->window->options,
** ** "wrap-search");
** ** **** ** ** searchlen = screen_write_strlen(utf8flag, "%s",
searchstr);
window_pane *wp,
** ** const char *searchstr)
** ** **** ** ** screen_write_nputs(&ctx, -1, &gc, utf8flag, "%s",
searchstr);
** ** **** ** ** screen_write_stop(&ctx);
** ** -** ** ** **fx = data->cx;
** ** -** ** ** **fy = gd->hsize - data->oy + data->cy;
** ** -
** ** -** ** ** **if (fx == gd->sx - 1) {
** ** -** ** ** ** ** ** ** **if (fy == gd->hsize + gd->sy)
** ** -** ** ** ** ** ** ** ** ** ** ** **return;
** ** -** ** ** ** ** ** ** **fx = 0;
** ** -** ** ** ** ** ** ** **fy++;
** ** -** ** ** **} else
** ** -** ** ** ** ** ** ** **fx++;
** ** -** ** ** **n = wrapped = 0;
** ** -
** ** -** ** ** **cis = 1;
** ** -** ** ** **for (ptr = searchstr; *ptr != '\0'; ptr++) {
** ** -** ** ** ** ** ** ** **if (*ptr != tolower((u_char)*ptr)) {
** ** -** ** ** ** ** ** ** ** ** ** ** **cis = 0;
** ** -** ** ** ** ** ** ** ** ** ** ** **break;
** ** -** ** ** ** ** ** ** **}
** ** +** ** ** **if (move) {
** ** +** ** ** ** ** ** ** **window_copy_move_coordinates(s, &fx,
&fy, direction);
** ** **** ** ** }
** ** -** ** ** **sgd = ss.grid;
** ** -** ** ** **for (i = fy + 1; i < gd->hsize + gd->sy + 1; i++)
{
** ** -** ** ** ** ** ** ** **first = 0;
** ** -** ** ** ** ** ** ** **if (i == fy + 1)
** ** -** ** ** ** ** ** ** ** ** ** ** **first = fx;
** ** -** ** ** ** ** ** ** **n = window_copy_search_lr(gd, sgd,
&px, i - 1, first,
** ** gd->sx,
** ** -** ** ** ** ** ** ** ** ** **cis);
** ** -** ** ** ** ** ** ** **if (n) {
** ** -** ** ** ** ** ** ** ** ** ** ** **window_copy_scroll_to(wp,
px, i - 1);
** ** -** ** ** ** ** ** ** ** ** ** ** **break;
** ** -** ** ** ** ** ** ** **}
** ** -** ** ** **}
** ** -** ** ** **if (wrapflag && !n && !wrapped) {
** ** -** ** ** ** ** ** ** **fx = 0;
** ** -** ** ** ** ** ** ** **fy = 0;
** ** -** ** ** ** ** ** ** **wrapped = 1;
** ** -** ** ** ** ** ** ** **goto retry;
** ** -** ** ** **}
** ** +** ** ** **cis = window_copy_is_lowercase(searchstr);
** ** +** ** ** **window_copy_clear_selection(wp);
** ** +
** ** +** ** ** **window_copy_jump_to_searched_string(wp, gd,
ss.grid, fx, fy,
0,
** ** +** ** ** ** ** ** ** **cis, wrapflag, direction);
** ** **** ** ** screen_free(&ss);
** ** **}
** ** **void
** ** +window_copy_search_up(struct window_pane *wp, const char
*searchstr,
** ** +** ** ** **const int move)
** ** +{
** ** +** ** ** **window_copy_search(wp, searchstr, 0, move);
** ** +}
** ** +
** ** +void
** ** +window_copy_search_down(struct window_pane *wp, const char
*searchstr,
** ** +** ** ** **const int move)
** ** +{
** ** +** ** ** **window_copy_search(wp, searchstr, 1, move);
** ** +}
** ** +
** ** +void
** ** **window_copy_goto_line(struct window_pane *wp, const char
*linestr)
** ** **{
** ** **** ** ** struct window_copy_mode_data** ** *data =
wp->modedata;
** ** Incremental search in window-copy mode
** ** ==============================
** ** diff --git window-copy.c window-copy.c
** ** index 1213380..243c755 100644
** ** --- window-copy.c
** ** +++ window-copy.c
*);
** ** **void** window_copy_jump_to_searched_string(
** ** **** ** ** **** **struct window_pane *, struct grid *, struct
grid *, u_int,
** ** u_int,
** ** **** ** ** **** **u_int, int, int, const int);
** ** +int** ** window_copy_coord_from_hist(struct window_pane *wp,
** ** +** ** ** ** ** **const size_t searchlen, u_int *fx, u_int
*fy);
** ** +void** **window_copy_clear_search_hist(struct window_pane *,
u_int *, u_int
** ** *);
** ** **void** window_copy_search(struct window_pane *, const char
*,
** ** **** ** ** **** **const int, const int);
** ** **void** window_copy_search_up(struct window_pane *, const
char *, const
** ** int);
** ** **};
** ** **/*
** ** + * x, y - coordinates from which the search was made
** ** + * found - if the text was found
** ** + * searchlen - lenght of text that was searched
** ** + * prev - data of previous searches
** ** + */
** ** +struct window_copy_search_hist {
** ** +** ** ** **u_int** ** ** ** ** **x;
** ** +** ** ** **u_int** ** ** ** ** **y;
** ** +** ** ** **int** ** ** ** ** ** **found;
** ** +
** ** +** ** ** **size_t** ** ** ** ** searchlen;
** ** +
** ** +** ** ** **struct window_copy_search_hist ***prev;
** ** +};
** ** +
** ** +/*
** ** ** * Copy-mode's visible screen (the "screen" field) is
filled from one of
** ** ** * two sources: the original contents of the pane (used
when we
** ** ** * actually enter via the "copy-mode" command, to copy the
contents of
** ** **** ** ** enum window_copy_input_type searchtype;
** ** **** ** ** char** ** **** ** ** *searchstr;
** ** +** ** ** **struct window_copy_search_hist** *searchhist;
** ** **** ** ** enum window_copy_input_type jumptype;
** ** **** ** ** char** ** ** ** ** ** jumpchar;
** ** **** ** ** data->searchtype = WINDOW_COPY_OFF;
** ** **** ** ** data->searchstr = NULL;
** ** +** ** ** **data->searchhist = NULL;
** ** **** ** ** if (wp->fd != -1)
** ** **** ** ** ** ** ** ** bufferevent_disable(wp->event,
EV_READ|EV_WRITE);
** ** **** ** ** free(data->searchstr);
** ** **** ** ** free(data->inputstr);
** ** +** ** ** **window_copy_clear_search_hist(wp, NULL, NULL);
** ** **** ** ** if (data->backing != &wp->base) {
** ** **** ** ** ** ** ** ** screen_free(data->backing);
struct
** ** session *sess, int key)
** ** **** ** ** ** ** ** ** data->inputtype =
WINDOW_COPY_SEARCHUP;
** ** **** ** ** ** ** ** ** data->inputprompt = "Search Up";
** ** +** ** ** ** ** ** ** ***data->inputstr = '\0';
** ** **** ** ** ** ** ** ** goto input_on;
** ** **** ** ** ** ** ** ** data->inputtype =
WINDOW_COPY_SEARCHDOWN;
** ** **** ** ** ** ** ** ** data->inputprompt = "Search Down";
** ** +** ** ** ** ** ** ** ***data->inputstr = '\0';
** ** **** ** ** ** ** ** ** goto input_on;
*wp, int key)
** ** **** ** ** int** ** ** ** ** ** ** ** ** ** ** ** ** ** **
np;
** ** **** ** ** struct paste_buffer** ** ** ** ** ** ***pb;
** ** **** ** ** u_char** ** ** ** ** ** ** ** ** ** ** ** ** **ch;
** ** +** ** ** **u_int** ** ** ** ** ** ** ** ** ** ** ** ** **
fx, fy;
** ** **** ** ** switch (mode_key_lookup(&data->mdata, key, NULL))
{
*wp, int
** ** key)
** ** **** ** ** ** ** ** ** inputlen = strlen(data->inputstr);
** ** **** ** ** ** ** ** ** if (inputlen > 0)
** ** **** ** ** ** ** ** ** ** ** ** ** data->inputstr[inputlen -
1] = '\0';
** ** +** ** ** ** ** ** ** **switch (data->inputtype) {
** ** +** ** ** ** ** ** ** ** ** ** ** **data->searchtype =
data->inputtype;
** ** +** ** ** ** ** ** ** ** ** ** ** **free(data->searchstr);
** ** +** ** ** ** ** ** ** ** ** ** ** **data->searchstr =
xstrdup(data->inputstr);
** ** +** ** ** ** ** ** ** ** ** ** ** **window_copy_search_up(wp,
data->inputstr, 0);
** ** +** ** ** ** ** ** ** ** ** ** ** **break;
** ** +** ** ** ** ** ** ** ** ** ** ** **data->searchtype =
data->inputtype;
** ** +** ** ** ** ** ** ** ** ** ** ** **free(data->searchstr);
** ** +** ** ** ** ** ** ** ** ** ** ** **data->searchstr =
xstrdup(data->inputstr);
** ** +** ** ** ** ** ** ** ** ** ** **
**window_copy_search_down(wp, data->inputstr, 0);
** ** +** ** ** ** ** ** ** ** ** ** ** **break;
** ** +** ** ** ** ** ** ** ** ** ** ** **break;
** ** +** ** ** ** ** ** ** **}
** ** **** ** ** ** ** ** ** break;
** ** **** ** ** ** ** ** ** *data->inputstr = '\0';
** ** +** ** ** ** ** ** ** **fx = data->cx;
** ** +** ** ** ** ** ** ** **fy = screen_hsize(data->backing) -
data->oy + data->cy;
** ** +** ** ** ** ** ** ** **window_copy_clear_search_hist(wp,
&fx, &fy);
** ** +** ** ** ** ** ** ** **window_copy_scroll_to(wp, fx, fy);
** ** **** ** ** ** ** ** ** break;
** ** **** ** ** ** ** ** ** if ((pb = paste_get_top()) == NULL)
window_pane *wp, int
** ** key)
** ** **** ** ** ** ** ** ** ** ** ** ** break;
** ** **** ** ** ** ** ** ** ** ** ** ** data->searchtype =
data->inputtype;
** ** +** ** ** ** ** ** ** ** ** ** ** **free(data->searchstr);
** ** **** ** ** ** ** ** ** ** ** ** ** data->searchstr =
xstrdup(data->inputstr);
** ** -** ** ** ** ** ** ** ** ** ** ** **for (; np != 0; np--)
** ** -** ** ** ** ** ** ** ** ** ** ** ** ** ** **
**window_copy_search_up(wp, data->inputstr,
** ** 0);
** ** +** ** ** ** ** ** ** ** ** ** ** **for (; np > 1; np--)
** ** +** ** ** ** ** ** ** ** ** ** ** ** ** ** **
**window_copy_search_up(wp, data->inputstr,
** ** 1);
** ** **** ** ** ** ** ** ** ** ** ** ** break;
** ** **** ** ** ** ** ** ** ** ** ** ** data->searchtype =
data->inputtype;
** ** +** ** ** ** ** ** ** ** ** ** ** **free(data->searchstr);
** ** **** ** ** ** ** ** ** ** ** ** ** data->searchstr =
xstrdup(data->inputstr);
** ** -** ** ** ** ** ** ** ** ** ** ** **for (; np != 0; np--)
** ** -** ** ** ** ** ** ** ** ** ** ** ** ** ** **
**window_copy_search_down(wp,
** ** data->inputstr, 0);
** ** +** ** ** ** ** ** ** ** ** ** ** **for (; np > 1; np--)
** ** +** ** ** ** ** ** ** ** ** ** ** ** ** ** **
**window_copy_search_down(wp,
** ** data->inputstr, 1);
** ** **** ** ** ** ** ** ** ** ** ** ** break;
** ** **** ** ** ** ** ** ** ** ** ** **
window_copy_copy_selection(wp, data->inputstr);
*wp, int
** ** key)
** ** **** ** ** ** ** ** ** data->inputstr =
xrealloc(data->inputstr, 1, inputlen);
** ** **** ** ** ** ** ** ** data->inputstr[inputlen - 2] = key;
** ** **** ** ** ** ** ** ** data->inputstr[inputlen - 1] = '\0';
** ** +** ** ** ** ** ** ** **switch (data->inputtype) {
** ** +** ** ** ** ** ** ** ** ** ** ** **data->searchtype =
data->inputtype;
** ** +** ** ** ** ** ** ** ** ** ** ** **free(data->searchstr);
** ** +** ** ** ** ** ** ** ** ** ** ** **data->searchstr =
xstrdup(data->inputstr);
** ** +** ** ** ** ** ** ** ** ** ** ** **window_copy_search_up(wp,
data->inputstr, 0);
** ** +** ** ** ** ** ** ** ** ** ** ** **break;
** ** +** ** ** ** ** ** ** ** ** ** ** **data->searchtype =
data->inputtype;
** ** +** ** ** ** ** ** ** ** ** ** ** **free(data->searchstr);
** ** +** ** ** ** ** ** ** ** ** ** ** **data->searchstr =
xstrdup(data->inputstr);
** ** +** ** ** ** ** ** ** ** ** ** **
**window_copy_search_down(wp, data->inputstr, 0);
** ** +** ** ** ** ** ** ** ** ** ** ** **break;
** ** +** ** ** ** ** ** ** ** ** ** ** **break;
** ** +** ** ** ** ** ** ** **}
** ** **** ** ** ** ** ** ** break;
** ** **** ** ** ** ** ** ** break;
window_copy_jump_to_searched_string(struct
** ** window_pane *wp,
** ** ** ** **struct grid *gd, struct grid *sgd, u_int fx, u_int
fy,
** ** ** ** **u_int endline, int cis, int wrap, const int
direction)
** ** **{
** ** +** ** ** **struct window_copy_mode_data** ** *data =
wp->modedata;
** ** +** ** ** **struct window_copy_search_hist** *searchhist =
data->searchhist;
** ** **** ** ** u_int** ** ** ** ** ** ** ** ** ** ** ** ** ** i,
px;
** ** **** ** ** int** ** ** ** ** ** ** ** ** ** ** ** ** ** **
firstIteration, found;
window_copy_jump_to_searched_string(struct
** ** window_pane *wp,
** ** **** ** ** ** ** ** ** ** ** ** ** direction ? 0 : gd->sx -
1,
** ** **** ** ** ** ** ** ** ** ** ** ** direction ? 0 : gd->hsize
+ gd->sy - 1,
** ** **** ** ** ** ** ** ** ** ** ** ** fy, cis, 0, direction);
** ** +** ** ** **} else {
** ** +** ** ** ** ** ** ** **if (searchhist != NULL) {
** ** +** ** ** ** ** ** ** ** ** ** ** **searchhist->found = 0;
** ** +** ** ** ** ** ** ** **}
** ** +** ** ** **}
** ** +}
** ** +
** ** +/* If it returns 0 then, according to search history, last
time we
** ** searched
** ** + * a shorter string we haven't found anything, so there is
no point in
** ** + * incremental-searching a longer string (just an
optimization) */
** ** +int
** ** +window_copy_coord_from_hist(struct window_pane *wp,
** ** + ** **const size_t searchlen, u_int *fx, u_int *fy)
** ** +{
** ** +** ** ** **struct window_copy_mode_data** ** *data =
wp->modedata;
** ** +** ** ** **struct window_copy_search_hist** *searchhist =
data->searchhist;
** ** +
** ** +** ** ** **if (searchhist == NULL || searchhist->searchlen <
searchlen) {
** ** +** ** ** ** ** ** ** **searchhist = xmalloc(sizeof (struct
** ** window_copy_search_hist));
** ** +** ** ** ** ** ** ** **searchhist->x = data->cx;
** ** +** ** ** ** ** ** ** **searchhist->y =
** ** +** ** ** ** ** ** ** ** ** ** **
**screen_hsize(data->backing) - data->oy + data->cy;
** ** +** ** ** ** ** ** ** **searchhist->searchlen = searchlen;
** ** +** ** ** ** ** ** ** **searchhist->found = data->searchhist
== NULL ?
data->searchhist->found;
** ** +
** ** +** ** ** ** ** ** ** **searchhist->prev = data->searchhist;
** ** +** ** ** ** ** ** ** **data->searchhist = searchhist;
** ** +
** ** +** ** ** ** ** ** ** ***fx = searchhist->x;
** ** +** ** ** ** ** ** ** ***fy = searchhist->y;
** ** +** ** ** **} else {
** ** +** ** ** ** ** ** ** ***fx = searchhist->x;
** ** +** ** ** ** ** ** ** ***fy = searchhist->y;
** ** +** ** ** ** ** ** ** **searchhist = data->searchhist->prev;
** ** +** ** ** ** ** ** ** **free(data->searchhist);
** ** +** ** ** ** ** ** ** **data->searchhist = searchhist;
** ** +** ** ** **}
** ** +
searchhist->found;
** ** +}
** ** +
** ** +void
** ** +window_copy_clear_search_hist(struct window_pane *wp, u_int
*fx, u_int
** ** *fy)
** ** +{
** ** +** ** ** **struct window_copy_mode_data** ** *data =
wp->modedata;
** ** +** ** ** **struct window_copy_search_hist** *searchhist =
data->searchhist;
** ** +
** ** +** ** ** **while (searchhist != NULL) {
** ** +** ** ** ** ** ** ** **if (fx != NULL) *fx = searchhist->x;
** ** +** ** ** ** ** ** ** **if (fy != NULL) *fy = searchhist->y;
** ** +** ** ** ** ** ** ** **searchhist = searchhist->prev;
** ** +** ** ** ** ** ** ** **free(data->searchhist);
** ** +** ** ** ** ** ** ** **data->searchhist = searchhist;
** ** **** ** ** }
** ** **}
*wp,
** ** **** ** ** fx = data->cx;
** ** **** ** ** fy = screen_hsize(data->backing) - data->oy +
data->cy;
** ** +** ** ** **/* User deleted all searched text, jump to the
initial cursor
** ** +** ** ** ** * position and delete the searchhistory */
** ** +** ** ** **if ((searchstr == NULL) || (*searchstr == '\0'))
{
** ** +** ** ** ** ** ** ** **window_copy_clear_search_hist(wp,
&fx, &fy);
** ** +** ** ** ** ** ** ** **window_copy_scroll_to(wp, fx, fy);
** ** +** ** ** ** ** ** ** **return;
** ** +** ** ** **}
** ** +
** ** **** ** ** utf8flag =
options_get_number(&wp->window->options, "utf8");
** ** **** ** ** wrapflag =
options_get_number(&wp->window->options,
** ** "wrap-search");
** ** **** ** ** searchlen = screen_write_strlen(utf8flag, "%s",
searchstr);
*wp,
** ** **** ** ** screen_write_nputs(&ctx, -1, &gc, utf8flag, "%s",
searchstr);
** ** **** ** ** screen_write_stop(&ctx);
** ** +** ** ** **/*
** ** +** ** ** ** * `move` is useful for incremental searching.
When we do
** ** incremental,
** ** +** ** ** ** * **we don't want to jump to the next matching
word if we already
** ** stand
** ** +** ** ** ** * **on one, so `move=0`.
** ** +** ** ** ** * **But when user wants the next result, then we
use `move=1`, so
** ** +** ** ** ** * **we start searching from the place next to
the current cursor
** ** +** ** ** ** * **position */
** ** **** ** ** if (move) {
** ** **** ** ** ** ** ** ** window_copy_move_coordinates(s, &fx,
&fy, direction);
** ** +** ** ** **} else {
** ** +** ** ** ** ** ** ** **if (!window_copy_coord_from_hist(wp,
searchlen, &fx, &fy))
** ** {
** ** +** ** ** ** ** ** ** ** ** ** ** **return;
** ** +** ** ** ** ** ** ** **}
** ** **** ** ** }
** ** **** ** ** cis = window_copy_is_lowercase(searchstr);
** ** Highlight last search in window-copy mode
** ** ===============================
** ** diff --git options-table.c options-table.c
** ** index 8d680b3..79ecae3 100644
** ** --- options-table.c
** ** +++ options-table.c
** ** window_options_table[] = {
** ** **** ** ** ****.default_str = "bg=yellow,fg=black"
** ** **** ** ** },
** ** +** ** ** **{ .name = "highlight-style",
** ** +** ** ** ** **.type = OPTIONS_TABLE_STYLE,
** ** +** ** ** ** **.default_str = "bg=green,fg=black"
** ** +** ** ** **},
** ** +
** ** **** ** ** { .name = "monitor-activity",
** ** **** ** ** ****.type = OPTIONS_TABLE_FLAG,
** ** **** ** ** ****.default_num = 0
** ** window_options_table[] = {
** ** **** ** ** ****.default_num = 1
** ** **** ** ** },
** ** +** ** ** **{ .name = "highlight-search",
** ** +** ** ** ** **.type = OPTIONS_TABLE_FLAG,
** ** +** ** ** ** **.default_num = 1
** ** +** ** ** **},
** ** +
** ** **** ** ** { .name = "xterm-keys",
** ** **** ** ** ****.type = OPTIONS_TABLE_FLAG,
** ** **** ** ** ****.default_num = 0
** ** diff --git screen-write.c screen-write.c
** ** index 325fb9a..a36a1f2 100644
** ** --- screen-write.c
** ** +++ screen-write.c
*ctx, const
** ** struct grid_cell *gc)
** ** **** ** ** struct grid** ** ** ** ** ** ***gd = s->grid;
** ** **** ** ** struct tty_ctx** ** ** ** ** **ttyctx;
** ** **** ** ** u_int** ** ** ** ** ** ** ** ** ** width, xx,
last;
** ** -** ** ** **struct grid_cell** ** ** ** **tmp_gc, *tmp_gcp;
** ** +** ** ** **struct grid_cell** ** ** ** **tmp_gc, *tmp_gcp,
*cell = NULL;
** ** **** ** ** struct utf8_data** ** ** ** **ud;
** ** **** ** ** int** ** ** ** ** ** ** ** ** ** ** insert;
screen_write_ctx *ctx, const
** ** struct grid_cell *gc)
** ** **** ** ** ** ** ** ** ****
**(GRID_FLAG_FG256|GRID_FLAG_BG256);
** ** **** ** ** ** ** ** ** ttyctx.cell = &tmp_gc;
** ** **** ** ** ** ** ** ** tty_write(tty_cmd_cell, &ttyctx);
** ** +** ** ** **} else if (screen_check_highlight(s, s->cx -
width, s->cy, &cell))
** ** {
** ** +** ** ** ** ** ** ** **memcpy(&tmp_gc, cell, sizeof tmp_gc);
** ** +** ** ** ** ** ** ** **grid_cell_get(gc, &ud);
** ** +** ** ** ** ** ** ** **grid_cell_set(&tmp_gc, &ud);
** ** +** ** ** ** ** ** ** **tmp_gc.flags = gc->flags &
** ** ~(GRID_FLAG_FG256|GRID_FLAG_BG256);
** ** +** ** ** ** ** ** ** **tmp_gc.flags |= cell->flags &
** ** +** ** ** ** ** ** ** ** **
**(GRID_FLAG_FG256|GRID_FLAG_BG256);
** ** +** ** ** ** ** ** ** **ttyctx.cell = &tmp_gc;
** ** +** ** ** ** ** ** ** **tty_write(tty_cmd_cell, &ttyctx);
** ** **** ** ** } else {
** ** **** ** ** ** ** ** ** ttyctx.cell = gc;
** ** **** ** ** ** ** ** ** tty_write(tty_cmd_cell, &ttyctx);
** ** diff --git screen.c screen.c
** ** index 7bfc015..734b38e 100644
** ** --- screen.c
** ** +++ screen.c
u_int sy, u_int
** ** hlimit)
** ** **** ** ** s->cstyle = 0;
** ** **** ** ** s->ccolour = xstrdup("");
** ** **** ** ** s->tabs = NULL;
** ** +** ** ** **s->hls = NULL;
** ** **** ** ** screen_reinit(s);
** ** **}
** ** **** ** ** grid_clear_lines(s->grid, s->grid->hsize,
s->grid->sy);
** ** **** ** ** screen_clear_selection(s);
** ** +** ** ** **screen_clear_highlight(s);
** ** **}
** ** **/* Destroy a screen. */
** ** **** ** ** free(s->title);
** ** **** ** ** free(s->ccolour);
** ** **** ** ** grid_destroy(s->grid);
** ** +** ** ** **screen_clear_highlight(s);
** ** **}
** ** **/* Reset tabs to default, eight spaces apart. */
u_int px,
** ** u_int py)
** ** **** ** ** return (1);
** ** **}
** ** +/* Set highlight. */
** ** +void
** ** +screen_set_highlight(struct screen *s,
** ** +** ** ** **u_int sx, u_int ex, u_int y, struct grid_cell
*gc)
** ** +{
** ** +** ** ** **struct screen_hls** ** ** ***hls = xmalloc(sizeof
(struct
** ** screen_hls));
** ** +
** ** +** ** ** **hls->sx = sx;
** ** +** ** ** **hls->ex = ex;
** ** +** ** ** **hls->y = y;
** ** +** ** ** **hls->next = s->hls;
** ** +
** ** +** ** ** **memcpy(&hls->cell, gc, sizeof hls->cell);
** ** +
** ** +** ** ** **s->hls = hls;
** ** +}
** ** +
** ** +/* Clear highlights. */
** ** +void
** ** +screen_clear_highlight(struct screen *s)
** ** +{
** ** +** ** ** **struct screen_hls** ** ** ***hls = s->hls,
*hlsPrev;
** ** +
** ** +** ** ** **while (hls != NULL) {
** ** +** ** ** ** ** ** ** **hlsPrev = hls;
** ** +** ** ** ** ** ** ** **hls = hls->next;
** ** +** ** ** ** ** ** ** **free(hlsPrev);
** ** +** ** ** **}
** ** +
** ** +** ** ** **s->hls = NULL;
** ** +}
** ** +
** ** +/* Check if cell in highlight. */
** ** +int
** ** +screen_check_highlight(struct screen *s, u_int px, u_int py,
** ** +** ** ** **struct grid_cell **cell)
** ** +{
** ** +** ** ** **struct screen_hls** ** ** ***hls = s->hls;
** ** +
** ** +** ** ** **while (hls != NULL) {
** ** +** ** ** ** ** ** ** **if (hls->sx <= px && px <= hls->ex &&
hls->y == py) {
** ** +** ** ** ** ** ** ** ** ** ** ** ***cell = &hls->cell;
** ** +** ** ** ** ** ** ** ** ** ** ** **return 1;
** ** +** ** ** ** ** ** ** **}
** ** +** ** ** ** ** ** ** **hls = hls->next;
** ** +** ** ** **}
** ** +
** ** +** ** ** **return 0;
** ** +}
** ** +
** ** **/* Reflow wrapped lines. */
** ** **void
** ** **screen_reflow(struct screen *s, u_int new_x)
** ** diff --git tmux.h tmux.h
** ** index c4c5236..6fc5fd0 100644
** ** --- tmux.h
** ** +++ tmux.h
** ** **** ** ** struct grid_cell cell;
** ** **};
** ** +/* Screen highlights. */
** ** +struct screen_hls {
** ** +** ** ** **u_int** ** ** ** ** ** sx;
** ** +** ** ** **u_int** ** ** ** ** ** ex;
** ** +
** ** +** ** ** **u_int** ** ** ** ** ** y;
** ** +
** ** +** ** ** **struct grid_cell cell;
** ** +** ** ** **struct screen_hls *next;
** ** +};
** ** +
** ** **/* Virtual screen. */
** ** **struct screen {
** ** **** ** ** char** ** ** ** ** ** *title;
** ** **** ** ** bitstr_t** ** ** ** *tabs;
** ** **** ** ** struct screen_sel sel;
** ** +** ** ** **struct screen_hls *hls;
** ** **};
** ** **/* Screen write context. */
screen_set_selection(struct screen *,
** ** **** ** ** **** ** u_int, u_int, u_int, u_int, u_int, struct
grid_cell *);
** ** **void** **screen_clear_selection(struct screen *);
** ** **int** ** screen_check_selection(struct screen *, u_int,
u_int);
** ** +void** ** screen_set_highlight(struct screen *,
** ** +** ** ** ** ** ** u_int, u_int, u_int, struct grid_cell *);
** ** +void** ** screen_clear_highlight(struct screen *);
** ** +int** ** **screen_check_highlight(struct screen *, u_int,
u_int,
** ** +** ** ** ** ** ** struct grid_cell **);
** ** **void** **screen_reflow(struct screen *, u_int);
** ** **/* window.c */
** ** diff --git tty.c tty.c
** ** index 7688e90..4511533 100644
** ** --- tty.c
** ** +++ tty.c
screen *s, u_int
** ** py, u_int ox, u_int oy)
** ** **{
** ** **** ** ** const struct grid_cell** *gc;
** ** **** ** ** struct grid_line** ** ** ** *gl;
** ** -** ** ** **struct grid_cell** ** ** ** **tmpgc;
** ** +** ** ** **struct grid_cell** ** ** ** **tmpgc, *cell =
NULL;
** ** **** ** ** struct utf8_data** ** ** ** **ud;
** ** **** ** ** u_int** ** ** ** ** ** ** ** ** ** i, sx;
screen *s,
** ** u_int py, u_int ox, u_int oy)
** ** **** ** ** ** ** ** ** ** ** ** ** tmpgc.flags |=
s->sel.cell.flags &
** ** **** ** ** ** ** ** ** ** ** ** ** ****
**(GRID_FLAG_FG256|GRID_FLAG_BG256);
** ** **** ** ** ** ** ** ** ** ** ** ** tty_cell(tty, &tmpgc);
** ** +** ** ** ** ** ** ** **} else if (screen_check_highlight(s,
i, py, &cell)) {
** ** +** ** ** ** ** ** ** ** ** ** ** **memcpy(&tmpgc, cell,
sizeof tmpgc);
** ** +** ** ** ** ** ** ** ** ** ** ** **grid_cell_get(gc, &ud);
** ** +** ** ** ** ** ** ** ** ** ** ** **grid_cell_set(&tmpgc,
&ud);
** ** +** ** ** ** ** ** ** ** ** ** ** **tmpgc.flags = gc->flags &
** ** +** ** ** ** ** ** ** ** ** ** ** ** **
**~(GRID_FLAG_FG256|GRID_FLAG_BG256);
** ** +** ** ** ** ** ** ** ** ** ** ** **tmpgc.flags |=
cell->flags &
** ** +** ** ** ** ** ** ** ** ** ** ** ** **
**(GRID_FLAG_FG256|GRID_FLAG_BG256);
** ** +** ** ** ** ** ** ** ** ** ** ** **tty_cell(tty, &tmpgc);
** ** **** ** ** ** ** ** ** } else
** ** **** ** ** ** ** ** ** ** ** ** ** tty_cell(tty, gc);
** ** **** ** ** }
** ** diff --git window-copy.c window-copy.c
** ** index 243c755..00cdc3f 100644
** ** --- window-copy.c
** ** +++ window-copy.c
window_pane *);
** ** **void** window_copy_free(struct window_pane *);
** ** **void** window_copy_resize(struct window_pane *, u_int,
u_int);
** ** **void** window_copy_key(struct window_pane *, struct session
*, int);
** ** +void** **window_copy_key_internal(struct window_pane *,
struct session *,
** ** int);
** ** **int** **window_copy_key_input(struct window_pane *, int);
** ** **int** **window_copy_key_numeric_prefix(struct window_pane
*, int);
** ** **void** window_copy_mouse(
** ** **** ** ** **** **struct window_pane *, struct session *,
struct mouse_event
** ** *);
** ** +void** **window_copy_mouse_internal(
** ** +** ** ** ** ** **struct window_pane *, struct session *,
struct mouse_event
** ** *);
** ** **void** window_copy_redraw_lines(struct window_pane *,
u_int, u_int);
** ** **void** window_copy_redraw_screen(struct window_pane *);
*);
** ** **void** window_copy_jump_to_searched_string(
** ** **** ** ** **** **struct window_pane *, struct grid *, struct
grid *, u_int,
** ** u_int,
** ** **** ** ** **** **u_int, int, int, const int);
** ** +void** **window_copy_highlight_search(struct window_pane *);
** ** **int** **window_copy_coord_from_hist(struct window_pane *wp,
** ** **** ** ** **** **const size_t searchlen, u_int *fx, u_int
*fy);
** ** **void** window_copy_clear_search_hist(struct window_pane *,
u_int *, u_int
** ** *);
*wp, u_int sx,
** ** u_int sy)
** ** **void
** ** **window_copy_key(struct window_pane *wp, struct session
*sess, int key)
** ** **{
** ** +** ** ** **window_copy_key_internal(wp, sess, key);
** ** +
** ** +** ** ** **if (wp->mode != NULL) {
** ** +** ** ** ** ** ** ** **window_copy_highlight_search(wp);
** ** +** ** ** **}
** ** +}
** ** +
** ** +void
** ** +window_copy_key_internal(struct window_pane *wp, struct
session *sess,
** ** int key)
** ** +{
** ** **** ** ** const char** ** ** ** ** ** ** ** ** ** **
*word_separators;
** ** **** ** ** struct window_copy_mode_data** ** *data =
wp->modedata;
** ** **** ** ** struct screen** ** ** ** ** ** ** ** ** ***s =
&data->screen;
** ** **window_copy_mouse(
** ** ** ** **struct window_pane *wp, struct session *sess, struct
mouse_event
** ** *m)
** ** **{
** ** +** ** ** **window_copy_mouse_internal(wp, sess, m);
** ** +
** ** +** ** ** **if (wp->mode != NULL) {
** ** +** ** ** ** ** ** ** **window_copy_highlight_search(wp);
** ** +** ** ** **}
** ** +}
** ** +
** ** +void
** ** +window_copy_mouse_internal(
** ** + ** **struct window_pane *wp, struct session *sess, struct
mouse_event
** ** *m)
** ** +{
** ** **** ** ** struct window_copy_mode_data** ** *data =
wp->modedata;
** ** **** ** ** struct screen** ** ** ** ** ** ** ** ** ***s =
&data->screen;
** ** **** ** ** u_int** ** ** ** ** ** ** ** ** ** ** ** ** ** i;
window_copy_jump_to_searched_string(struct
** ** window_pane *wp,
** ** **** ** ** }
** ** **}
** ** +void
** ** +window_copy_highlight_search(struct window_pane *wp)
** ** +{
** ** +** ** ** **struct window_copy_mode_data** ** *data =
wp->modedata;
** ** +** ** ** **struct screen** ** ** ** ** ** ** ** ** ***s =
data->backing, ss;
** ** +** ** ** **struct screen_write_ctx** ** ** ** ** ** ** ** **
ctx;
** ** +** ** ** **struct grid** ** ** ** ** ** ** ** ** ** ***gd =
s->grid;
** ** +** ** ** **struct grid_cell** ** ** ** ** ** ** ** **gc;
** ** +** ** ** **struct options** ** ** ** ** ** ** ** ** *oo =
&wp->window->options;
** ** +** ** ** **const char** ** ** ** ** ** ** ** ** ** **
*searchstr = data->searchstr;
** ** +** ** ** **size_t** ** ** ** ** ** ** ** ** ** ** ** **
**searchlen;
** ** +** ** ** **u_int** ** ** ** ** ** ** ** ** ** ** ** ** ** i,
px, last, beginline, endline;
** ** +** ** ** **int** ** ** ** ** ** ** ** ** ** ** ** ** ** **
found, utf8flag, cis, highlight;
** ** +
** ** +** ** ** **highlight = options_get_number(
** ** +** ** ** ** ** ** ** **&wp->window->options,
"highlight-search");
** ** +** ** ** **if (!highlight) {
** ** +** ** ** ** ** ** ** **return;
** ** +** ** ** **}
** ** +
** ** +** ** ** **screen_clear_highlight(&data->screen);
** ** +
** ** +** ** ** **if ((searchstr != NULL) && (*searchstr != '\0'))
{
** ** +** ** ** ** ** ** ** **utf8flag =
options_get_number(&wp->window->options,
** ** "utf8");
** ** +** ** ** ** ** ** ** **searchlen =
screen_write_strlen(utf8flag, "%s",
** ** searchstr);
** ** +
** ** +** ** ** ** ** ** ** **screen_init(&ss, searchlen, 1, 0);
** ** +** ** ** ** ** ** ** **screen_write_start(&ctx, NULL, &ss);
** ** +** ** ** ** ** ** ** **memcpy(&gc, &grid_default_cell,
sizeof gc);
** ** +** ** ** ** ** ** ** **screen_write_nputs(&ctx, -1, &gc,
utf8flag, "%s",
** ** searchstr);
** ** +** ** ** ** ** ** ** **screen_write_stop(&ctx);
** ** +
** ** +** ** ** ** ** ** ** **cis =
window_copy_is_lowercase(searchstr);
** ** +
** ** +** ** ** ** ** ** ** **/* Set colours. */
** ** +** ** ** ** ** ** ** **style_apply(&gc, oo,
"highlight-style");
** ** +
** ** +** ** ** ** ** ** ** **beginline = screen_hsize(s) -
data->oy;
** ** +** ** ** ** ** ** ** **endline = screen_hsize(s) - data->oy
+ screen_size_y(s) -
** ** 1;
** ** +
** ** +** ** ** ** ** ** ** **for (i = beginline; i <= endline;
++i) {
** ** +** ** ** ** ** ** ** ** ** ** ** **last = 0;
** ** +** ** ** ** ** ** ** ** ** ** ** **do {
** ** +** ** ** ** ** ** ** ** ** ** ** ** ** ** ** **found =
window_copy_search_lr(gd, ss.grid,
** ** &px,
** ** +** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** **
**i, last, gd->sx, cis);
** ** +** ** ** ** ** ** ** ** ** ** ** ** ** ** ** **if (found) {
** ** +** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** **
**screen_set_highlight(
** ** +** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** **
** ** ** **&data->screen,
** ** +** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** **
** ** ** **px,
** ** +** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** **
** ** ** **px + searchlen - 1,
** ** +** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** **
** ** ** **i - (screen_hsize(s)
** ** +** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** **
** ** ** ** ** ** - data->oy),
** ** +** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** **
** ** ** **&gc);
** ** +** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** **
**last += searchlen;
** ** +** ** ** ** ** ** ** ** ** ** ** ** ** ** ** **}
** ** +** ** ** ** ** ** ** ** ** ** ** **} while (found);
** ** +** ** ** ** ** ** ** **}
** ** +** ** ** **}
** ** +
** ** +** ** ** **window_copy_redraw_screen(wp);
** ** +}
** ** +
** ** **/* If it returns 0 then, according to search history, last
time we
** ** searched
** ** ** * a shorter string we haven't found anything, so there is
no point in
** ** ** * incremental-searching a longer string (just an
optimization) */
------------------------------------------------------------------------------
Want fast and easy access to all the code in your enterprise?
Index and
search up to 200,000 lines of code with a free copy of Black Duck
Code Sight - the same software that powers the world's largest
code
search on Ohloh, the Black Duck Open Hub! Try it now.
[4]http://p.sf.net/sfu/bds
_______________________________________________
tmux-users mailing list
[6]https://lists.sourceforge.net/lists/listinfo/tmux-users
------------------------------------------------------------------------------
Want fast and easy access to all the code in your enterprise? Index and
search up to 200,000 lines of code with a free copy of Black Duck
Code Sight - the same software that powers the world's largest code
search on Ohloh, the Black Duck Open Hub! Try it now.
[7]http://p.sf.net/sfu/bds
_______________________________________________
tmux-users mailing list
[9]https://lists.sourceforge.net/lists/listinfo/tmux-users
References
Visible links
4. http://p.sf.net/sfu/bds
6. https://lists.sourceforge.net/lists/listinfo/tmux-users
7. http://p.sf.net/sfu/bds
9. https://lists.sourceforge.net/lists/listinfo/tmux-users
Suraj N. Kurapati
2015-04-22 00:45:49 UTC
Permalink
Post by Nicholas Marriott
I made a few changes to your first diff, please take a look.
I tried this but I can't seem to trigger the new functionality:

1. Run "tmux copy-mode"
2. Press "?"
3. Start typing some text that is already shown on the screen
4. tmux doesn't automatically move cursor to the first match :(

What am I doing wrong here? Thanks for your consideration.
Łukasz Piątkowski
2015-04-22 00:57:10 UTC
Permalink
Hi Suraj,

I believe that Nicholas only send the first diff which is refactoring.
We just need to make sure that nothing is broken/changed with this diff.

Cheers,
Lukas
Post by Suraj N. Kurapati
Post by Nicholas Marriott
I made a few changes to your first diff, please take a look.
1. Run "tmux copy-mode"
2. Press "?"
3. Start typing some text that is already shown on the screen
4. tmux doesn't automatically move cursor to the first match :(
What am I doing wrong here? Thanks for your consideration.
Suraj N. Kurapati
2015-04-23 04:12:58 UTC
Permalink
Post by Łukasz Piątkowski
I believe that Nicholas only send the first diff which is refactoring.
We just need to make sure that nothing is broken/changed with this diff.
Ah, that makes sense now. I'll report any issues with the patch. Thanks!
Nicholas Marriott
2015-04-29 22:14:53 UTC
Permalink
Ok, is this good to go?
Post by Nicholas Marriott
Hi
- update to latest git
- renamed some functions and variables to be shorter
- passing const int into a function is useless, just use int
- don't use backticks for quotation marks, they look awful
- otherwise reformat some comments
Seems to work but please take a look, then I will apply it and we can
move from there with the next diff.
Index: window-copy.c
===================================================================
RCS file: /cvs/src/usr.bin/tmux/window-copy.c,v
retrieving revision 1.129
diff -u -p -r1.129 window-copy.c
--- window-copy.c 21 Apr 2015 15:16:06 -0000 1.129
+++ window-copy.c 21 Apr 2015 23:34:57 -0000
@@ -47,8 +47,14 @@ int window_copy_search_lr(struct grid *,
u_int, u_int, int);
int window_copy_search_rl(struct grid *, struct grid *, u_int *, u_int,
u_int, u_int, int);
-void window_copy_search_up(struct window_pane *, const char *);
-void window_copy_search_down(struct window_pane *, const char *);
+void window_copy_move_left(struct screen *, u_int *, u_int *);
+void window_copy_move_right(struct screen *, u_int *, u_int *);
+int window_copy_is_lowercase(const char *);
+void window_copy_search_jump(struct window_pane *, struct grid *,
+ struct grid *, u_int, u_int, u_int, int, int, int);
+void window_copy_search(struct window_pane *, const char *, int, int);
+void window_copy_search_up(struct window_pane *, const char *, int);
+void window_copy_search_down(struct window_pane *, const char *, int);
void window_copy_goto_line(struct window_pane *, const char *);
void window_copy_update_cursor(struct window_pane *, u_int, u_int);
void window_copy_start_selection(struct window_pane *);
@@ -706,20 +712,20 @@ window_copy_key(struct window_pane *wp,
ss = data->searchstr;
if (cmd == MODEKEYCOPY_SEARCHAGAIN) {
for (; np != 0; np--)
- window_copy_search_up(wp, ss);
+ window_copy_search_up(wp, ss, 1);
} else {
for (; np != 0; np--)
- window_copy_search_down(wp, ss);
+ window_copy_search_down(wp, ss, 1);
}
break;
ss = data->searchstr;
if (cmd == MODEKEYCOPY_SEARCHAGAIN) {
for (; np != 0; np--)
- window_copy_search_down(wp, ss);
+ window_copy_search_down(wp, ss, 1);
} else {
for (; np != 0; np--)
- window_copy_search_up(wp, ss);
+ window_copy_search_up(wp, ss, 1);
}
break;
}
@@ -828,16 +834,16 @@ window_copy_key_input(struct window_pane
break;
- for (; np != 0; np--)
- window_copy_search_up(wp, data->inputstr);
data->searchtype = data->inputtype;
data->searchstr = xstrdup(data->inputstr);
+ for (; np != 0; np--)
+ window_copy_search_up(wp, data->inputstr, 0);
break;
- for (; np != 0; np--)
- window_copy_search_down(wp, data->inputstr);
data->searchtype = data->inputtype;
data->searchstr = xstrdup(data->inputstr);
+ for (; np != 0; np--)
+ window_copy_search_down(wp, data->inputstr, 0);
break;
window_copy_copy_selection(wp, data->inputstr);
@@ -989,89 +995,103 @@ window_copy_search_rl(struct grid *gd,
}
void
-window_copy_search_up(struct window_pane *wp, const char *searchstr)
+window_copy_move_left(struct screen *s, u_int *fx, u_int *fy)
{
- struct window_copy_mode_data *data = wp->modedata;
- struct screen *s = data->backing, ss;
- struct screen_write_ctx ctx;
- struct grid *gd = s->grid, *sgd;
- struct grid_cell gc;
- size_t searchlen;
- u_int i, last, fx, fy, px;
- int utf8flag, n, wrapped, wrapflag, cis;
- const char *ptr;
-
- if (*searchstr == '\0')
- return;
- utf8flag = options_get_number(&wp->window->options, "utf8");
- wrapflag = options_get_number(&wp->window->options, "wrap-search");
- searchlen = screen_write_strlen(utf8flag, "%s", searchstr);
-
- screen_init(&ss, searchlen, 1, 0);
- screen_write_start(&ctx, NULL, &ss);
- memcpy(&gc, &grid_default_cell, sizeof gc);
- screen_write_nputs(&ctx, -1, &gc, utf8flag, "%s", searchstr);
- screen_write_stop(&ctx);
-
- fx = data->cx;
- fy = gd->hsize - data->oy + data->cy;
+ if (*fx == 0) { /* left */
+ if (*fy == 0) /* top */
+ return;
+ *fx = screen_size_x(s) - 1;
+ *fy = *fy - 1;
+ } else
+ *fx = *fx - 1;
+}
- if (fx == 0) {
- if (fy == 0)
+void
+window_copy_move_right(struct screen *s, u_int *fx, u_int *fy)
+{
+ if (*fx == screen_size_x(s) - 1) { /* right */
+ if (*fy == screen_hsize(s) + screen_size_y(s)) /* bottom */
return;
- fx = gd->sx - 1;
- fy--;
+ *fx = 0;
+ *fy = *fy + 1;
} else
- fx--;
- n = wrapped = 0;
+ *fx = *fx + 1;
+}
- cis = 1;
- for (ptr = searchstr; *ptr != '\0'; ptr++) {
+int
+window_copy_is_lowercase(const char *ptr)
+{
+ while (*ptr != '\0') {
if (*ptr != tolower((u_char)*ptr)) {
- cis = 0;
- break;
+ return 0;
}
+ ++ptr;
}
+ return 1;
+}
- sgd = ss.grid;
- for (i = fy + 1; i > 0; i--) {
- last = screen_size_x(s);
- if (i == fy + 1)
- last = fx;
- n = window_copy_search_rl(gd, sgd, &px, i - 1, 0, last, cis);
- if (n) {
- window_copy_scroll_to(wp, px, i - 1);
- break;
+/*
+ * Search for text stored in sgd starting from position fx,fy up to endline. If
+ * found, jump to it. If cis then ignore case. The direction is 0 for searching
+ * up, down otherwise. If wrap then go to begin/end of grid and try again if
+ * not found.
+ */
+void
+window_copy_search_jump(struct window_pane *wp, struct grid *gd,
+ struct grid *sgd, u_int fx, u_int fy, u_int endline, int cis, int wrap,
+ int direction)
+{
+ u_int i, px;
+ int first = 1, found = 0;
+
+ if (direction) {
+ for (i = fy; i <= endline; ++i) {
+ found = window_copy_search_lr(gd, sgd, &px, i,
+ first ? fx : 0, gd->sx, cis);
+ if (found)
+ break;
+ first = 0;
+ }
+ } else {
+ for (i = fy + 1; endline < i; --i) {
+ found = window_copy_search_rl(gd, sgd, &px, i - 1, 0,
+ first ? fx : gd->sx, cis);
+ if (found) {
+ i--;
+ break;
+ }
+ first = 0;
}
}
- if (wrapflag && !n && !wrapped) {
- fx = gd->sx - 1;
- fy = gd->hsize + gd->sy - 1;
- wrapped = 1;
- goto retry;
+ if (found)
+ window_copy_scroll_to(wp, px, i);
+ else if (wrap) {
+ /* Start searching from begin/end of grid. */
+ window_copy_search_jump(wp, gd, sgd, direction ? 0 : gd->sx - 1,
+ direction ? 0 : gd->hsize + gd->sy - 1, fy, cis, 0,
+ direction);
}
-
- screen_free(&ss);
}
void
-window_copy_search_down(struct window_pane *wp, const char *searchstr)
+window_copy_search(struct window_pane *wp, const char *searchstr, int direction,
+ int moveflag)
{
struct window_copy_mode_data *data = wp->modedata;
struct screen *s = data->backing, ss;
struct screen_write_ctx ctx;
- struct grid *gd = s->grid, *sgd;
- struct grid_cell gc;
+ struct grid *gd = s->grid;
+ struct grid_cell gc;
size_t searchlen;
- u_int i, first, fx, fy, px;
- int utf8flag, n, wrapped, wrapflag, cis;
- const char *ptr;
+ u_int fx, fy;
+ int utf8flag, wrapflag, cis;
+
+ fx = data->cx;
+ fy = screen_hsize(data->backing) - data->oy + data->cy;
- if (*searchstr == '\0')
- return;
utf8flag = options_get_number(&wp->window->options, "utf8");
wrapflag = options_get_number(&wp->window->options, "wrap-search");
+
searchlen = screen_write_strlen(utf8flag, "%s", searchstr);
screen_init(&ss, searchlen, 1, 0);
@@ -1080,47 +1100,33 @@ window_copy_search_down(struct window_pa
screen_write_nputs(&ctx, -1, &gc, utf8flag, "%s", searchstr);
screen_write_stop(&ctx);
- fx = data->cx;
- fy = gd->hsize - data->oy + data->cy;
-
- if (fx == gd->sx - 1) {
- if (fy == gd->hsize + gd->sy)
- return;
- fx = 0;
- fy++;
- } else
- fx++;
- n = wrapped = 0;
-
- cis = 1;
- for (ptr = searchstr; *ptr != '\0'; ptr++) {
- if (*ptr != tolower((u_char)*ptr)) {
- cis = 0;
- break;
- }
+ if (moveflag) {
+ if (direction)
+ window_copy_move_right(s, &fx, &fy);
+ else
+ window_copy_move_left(s, &fx, &fy);
}
+ window_copy_clear_selection(wp);
- sgd = ss.grid;
- for (i = fy + 1; i < gd->hsize + gd->sy + 1; i++) {
- first = 0;
- if (i == fy + 1)
- first = fx;
- n = window_copy_search_lr(gd, sgd, &px, i - 1, first, gd->sx,
- cis);
- if (n) {
- window_copy_scroll_to(wp, px, i - 1);
- break;
- }
- }
- if (wrapflag && !n && !wrapped) {
- fx = 0;
- fy = 0;
- wrapped = 1;
- goto retry;
- }
+ cis = window_copy_is_lowercase(searchstr);
+ window_copy_search_jump(wp, gd, ss.grid, fx, fy,
+ direction ? gd->hsize + gd->sy - 1 : 0, cis, wrapflag, direction);
screen_free(&ss);
+}
+
+void
+window_copy_search_up(struct window_pane *wp, const char *searchstr,
+ int moveflag)
+{
+ window_copy_search(wp, searchstr, 0, moveflag);
+}
+
+void
+window_copy_search_down(struct window_pane *wp, const char *searchstr,
+ int moveflag)
+{
+ window_copy_search(wp, searchstr, 1, moveflag);
}
void
I finally got some time to sit down and test my changes again. It appears
that no one was touching the part of code that I have been working on, so
I am sending almost the same changes as last time. But this time I am
attaching them to the email instead of sending in the message.
Cheers
Lukas
2014-11-01 0:35 GMT+00:00 **ukasz Pi**tkowski
Hi Felix,
I didn't have time to work on this, last few months were really busy. I
will try to rebase my changes on top of current revision and test them
before sending the code again. I hope I will find some time before the
end of year.
Cheers
Lukas
Was there any follow up to this thread?** Incremental search would be
a great feature to have and is on the TODO list.
Thanks.
-FR
On Fri, Aug 8, 2014 at 11:21 AM, Nicholas Marriott
Hi
Your mailer has mangled the diffs, if you can't fix it so it works
inline please send them as attachments instead.
** ** I have split up my changes into 3 diffs, first is refactoring
search code
** ** in window-copy.c, second is adding incremental search and the
last one is
** ** adding search highlighting.
** ** Cheers
** ** Lukas
** ** --
** **
I**am**providing**code**in**this**repository**to**you**under**an**open**source**license.**Because**this**is**my**personal
** **
repository,**the**license**you**receive**to**my**code**is**from**me**and**not**from**my**employer**(Facebook).
All contributions must be under the ISC license that is at the top of
each file you modify.
Thanks
** ** --
** ** Refactor window-copy search functions
** ** ============================
** ** diff --git window-copy.c window-copy.c
** ** index 0775bcb..1213380 100644
** ** --- window-copy.c
** ** +++ window-copy.c
** ** **** ** ** **** **struct grid *, struct grid *, u_int *,
u_int, u_int, u_int,
** ** int);
** ** **int** **window_copy_search_rl(
** ** **** ** ** **** **struct grid *, struct grid *, u_int *,
u_int, u_int, u_int,
** ** int);
** ** -void** **window_copy_search_up(struct window_pane *, const
char *);
** ** -void** **window_copy_search_down(struct window_pane *, const
char *);
** ** +void** **window_copy_move_coordinates(
** ** +** ** ** ** ** **struct screen *, u_int *, u_int *, const
int);
** ** +int** ** window_copy_is_lowercase(const char *);
** ** +void** **window_copy_jump_to_searched_string(
** ** +** ** ** ** ** **struct window_pane *, struct grid *, struct
grid *, u_int,
** ** u_int,
** ** +** ** ** ** ** **u_int, int, int, const int);
** ** +void** **window_copy_search(struct window_pane *, const char
*,
** ** +** ** ** ** ** **const int, const int);
** ** +void** **window_copy_search_up(struct window_pane *, const
char *, const
** ** int);
** ** +void** **window_copy_search_down(struct window_pane *, const
char *, const
** ** int);
** ** **void** window_copy_goto_line(struct window_pane *, const
char *);
** ** **void** window_copy_update_cursor(struct window_pane *,
u_int, u_int);
** ** **void** window_copy_start_selection(struct window_pane *);
struct
** ** session *sess, int key)
** ** **** ** ** ** ** ** ** ** ** ** ** if (cmd ==
MODEKEYCOPY_SEARCHAGAIN) {
** ** **** ** ** ** ** ** ** ** ** ** ** ** ** ** ** for (; np !=
0; np--) {
** ** **** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** **
window_copy_search_up(
** ** -** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** **
** **wp, data->searchstr);
** ** +** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** **
** ** ** **wp, data->searchstr, 1);
** ** **** ** ** ** ** ** ** ** ** ** ** ** ** ** ** }
** ** **** ** ** ** ** ** ** ** ** ** ** } else {
** ** **** ** ** ** ** ** ** ** ** ** ** ** ** ** ** for (; np !=
0; np--) {
** ** **** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** **
window_copy_search_down(
** ** -** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** **
** **wp, data->searchstr);
** ** +** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** **
** ** ** **wp, data->searchstr, 1);
** ** **** ** ** ** ** ** ** ** ** ** ** ** ** ** ** }
** ** **** ** ** ** ** ** ** ** ** ** ** }
** ** **** ** ** ** ** ** ** ** ** ** ** break;
struct
** ** session *sess, int key)
** ** **** ** ** ** ** ** ** ** ** ** ** if (cmd ==
MODEKEYCOPY_SEARCHAGAIN) {
** ** **** ** ** ** ** ** ** ** ** ** ** ** ** ** ** for (; np !=
0; np--) {
** ** **** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** **
window_copy_search_down(
** ** -** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** **
** **wp, data->searchstr);
** ** +** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** **
** ** ** **wp, data->searchstr, 1);
** ** **** ** ** ** ** ** ** ** ** ** ** ** ** ** ** }
** ** **** ** ** ** ** ** ** ** ** ** ** } else {
** ** **** ** ** ** ** ** ** ** ** ** ** ** ** ** ** for (; np !=
0; np--) {
** ** **** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** **
window_copy_search_up(
** ** -** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** **
** **wp, data->searchstr);
** ** +** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** **
** ** ** **wp, data->searchstr, 1);
** ** **** ** ** ** ** ** ** ** ** ** ** ** ** ** ** }
** ** **** ** ** ** ** ** ** ** ** ** ** }
** ** **** ** ** ** ** ** ** ** ** ** ** break;
window_pane *wp, int
** ** key)
** ** **** ** ** ** ** ** ** ** ** ** ** break;
** ** -** ** ** ** ** ** ** ** ** ** ** **for (; np != 0; np--)
** ** -** ** ** ** ** ** ** ** ** ** ** ** ** ** **
**window_copy_search_up(wp, data->inputstr);
** ** **** ** ** ** ** ** ** ** ** ** ** data->searchtype =
data->inputtype;
** ** **** ** ** ** ** ** ** ** ** ** ** data->searchstr =
xstrdup(data->inputstr);
** ** +** ** ** ** ** ** ** ** ** ** ** **for (; np != 0; np--)
** ** +** ** ** ** ** ** ** ** ** ** ** ** ** ** **
**window_copy_search_up(wp, data->inputstr,
** ** 0);
** ** **** ** ** ** ** ** ** ** ** ** ** break;
** ** -** ** ** ** ** ** ** ** ** ** ** **for (; np != 0; np--)
** ** -** ** ** ** ** ** ** ** ** ** ** ** ** ** **
**window_copy_search_down(wp,
** ** data->inputstr);
** ** **** ** ** ** ** ** ** ** ** ** ** data->searchtype =
data->inputtype;
** ** **** ** ** ** ** ** ** ** ** ** ** data->searchstr =
xstrdup(data->inputstr);
** ** +** ** ** ** ** ** ** ** ** ** ** **for (; np != 0; np--)
** ** +** ** ** ** ** ** ** ** ** ** ** ** ** ** **
**window_copy_search_down(wp,
** ** data->inputstr, 0);
** ** **** ** ** ** ** ** ** ** ** ** ** break;
** ** **** ** ** ** ** ** ** ** ** ** **
window_copy_copy_selection(wp, data->inputstr);
*gd,
** ** **** ** ** return (0);
** ** **}
** ** +/* For direction == 0 move left, otherwise right; jump line
if needed */
** ** **void
** ** -window_copy_search_up(struct window_pane *wp, const char
*searchstr)
** ** +window_copy_move_coordinates(struct screen *s,
** ** +** ** ** **u_int *fx, u_int *fy, const int direction)
** ** **{
** ** -** ** ** **struct window_copy_mode_data** ** *data =
wp->modedata;
** ** -** ** ** **struct screen** ** ** ** ** ** ** ** ** ***s =
data->backing, ss;
** ** -** ** ** **struct screen_write_ctx** ** ** ** ** ** ** ** **
ctx;
** ** -** ** ** **struct grid** ** ** ** ** ** ** ** ** ** ***gd =
s->grid, *sgd;
** ** -** ** ** **struct grid_cell** ** ** ** ** ** ** ** **gc;
** ** -** ** ** **size_t** ** ** ** ** ** ** ** ** ** ** ** **
**searchlen;
** ** -** ** ** **u_int** ** ** ** ** ** ** ** ** ** ** ** ** ** i,
last, fx, fy, px;
** ** -** ** ** **int** ** ** ** ** ** ** ** ** ** ** ** ** ** **
utf8flag, n, wrapped, wrapflag,
** ** cis;
** ** -** ** ** **const char** ** ** ** ** ** ** ** ** ** ** *ptr;
** ** -
** ** -** ** ** **if (*searchstr == '\0')
** ** -** ** ** ** ** ** ** **return;
** ** -** ** ** **utf8flag =
options_get_number(&wp->window->options, "utf8");
** ** -** ** ** **wrapflag =
options_get_number(&wp->window->options,
** ** "wrap-search");
** ** -** ** ** **searchlen = screen_write_strlen(utf8flag, "%s",
searchstr);
** ** -
** ** -** ** ** **screen_init(&ss, searchlen, 1, 0);
** ** -** ** ** **screen_write_start(&ctx, NULL, &ss);
** ** -** ** ** **memcpy(&gc, &grid_default_cell, sizeof gc);
** ** -** ** ** **screen_write_nputs(&ctx, -1, &gc, utf8flag, "%s",
searchstr);
** ** -** ** ** **screen_write_stop(&ctx);
** ** -
** ** -** ** ** **fx = data->cx;
** ** -** ** ** **fy = gd->hsize - data->oy + data->cy;
** ** -
** ** -** ** ** **if (fx == 0) {
** ** -** ** ** ** ** ** ** **if (fy == 0)
** ** +** ** ** **/* If on left/right border */
0)) {
** ** +** ** ** ** ** ** ** **/* If on top/bottom border */
** ** +** ** ** ** ** ** ** **if (*fy == (direction ?
screen_hsize(s) + screen_size_y(s)
** ** : 0))
** ** +** ** ** ** ** ** ** ** ** ** ** **/* Nowhere to go */
** ** **** ** ** ** ** ** ** ** ** ** ** return;
** ** -** ** ** ** ** ** ** **fx = gd->sx - 1;
** ** -** ** ** ** ** ** ** **fy--;
** ** -** ** ** **} else
** ** -** ** ** ** ** ** ** **fx--;
** ** -** ** ** **n = wrapped = 0;
** ** +** ** ** ** ** ** ** **/* Jump to beggin/end of lower/upper
line */
screen_size_x(s) - 1;
** ** +** ** ** ** ** ** ** ***fy = direction ? *fy + 1 : *fy - 1;
** ** +** ** ** **} else {
** ** +** ** ** ** ** ** ** ***fx = direction ? *fx + 1 : *fx - 1;
** ** +** ** ** **}
** ** +}
** ** -** ** ** **cis = 1;
** ** -** ** ** **for (ptr = searchstr; *ptr != '\0'; ptr++) {
** ** +int
** ** +window_copy_is_lowercase(const char *ptr)
** ** +{
** ** +** ** ** **while (*ptr != '\0') {
** ** **** ** ** ** ** ** ** if (*ptr != tolower((u_char)*ptr)) {
** ** -** ** ** ** ** ** ** ** ** ** ** **cis = 0;
** ** -** ** ** ** ** ** ** ** ** ** ** **break;
** ** +** ** ** ** ** ** ** ** ** ** ** **return 0;
** ** **** ** ** ** ** ** ** }
** ** +** ** ** ** ** ** ** **++ptr;
** ** **** ** ** }
** ** +** ** ** **return 1;
** ** +}
** ** -** ** ** **sgd = ss.grid;
** ** -** ** ** **for (i = fy + 1; i > 0; i--) {
** ** -** ** ** ** ** ** ** **last = screen_size_x(s);
** ** -** ** ** ** ** ** ** **if (i == fy + 1)
** ** -** ** ** ** ** ** ** ** ** ** ** **last = fx;
** ** -** ** ** ** ** ** ** **n = window_copy_search_rl(gd, sgd,
&px, i - 1, 0, last,
** ** cis);
** ** -** ** ** ** ** ** ** **if (n) {
** ** -** ** ** ** ** ** ** ** ** ** ** **window_copy_scroll_to(wp,
px, i - 1);
** ** -** ** ** ** ** ** ** ** ** ** ** **break;
** ** +/* Search in grid `gd` for text stored in grid `sgd`
starting from
** ** position
** ** + * (`fx`, `fy`) up to line `endline` and if found then jump
to it.
** ** + * If `cis` do it case-insensitive.
** ** + * `direction` 0 for searching up, down otherwise
** ** + * If `wrap` then go to begin/end of grid and try again up
to line `fy`
** ** */
** ** +void
** ** +window_copy_jump_to_searched_string(struct window_pane *wp,
** ** + ** **struct grid *gd, struct grid *sgd, u_int fx, u_int fy,
** ** + ** **u_int endline, int cis, int wrap, const int direction)
** ** +{
** ** +** ** ** **u_int** ** ** ** ** ** ** ** ** ** ** ** ** ** i,
px;
** ** +** ** ** **int** ** ** ** ** ** ** ** ** ** ** ** ** ** **
firstIteration, found;
** ** +
** ** +** ** ** **firstIteration = 1;
** ** +** ** ** **if (direction) {
** ** +** ** ** ** ** ** ** **for (i = fy; i <= endline; ++i) {
** ** +** ** ** ** ** ** ** ** ** ** ** **found =
window_copy_search_lr(gd, sgd, &px, i,
** ** +** ** ** ** ** ** ** ** ** ** ** ** ** ** **
**firstIteration ? fx : 0, gd->sx, cis);
** ** +** ** ** ** ** ** ** ** ** ** ** **if (found) break;
** ** +** ** ** ** ** ** ** ** ** ** ** **firstIteration = 0;
** ** +** ** ** ** ** ** ** **}
** ** +** ** ** **} else {
** ** +** ** ** ** ** ** ** **for (i = fy + 1; endline < i; --i) {
** ** +** ** ** ** ** ** ** ** ** ** ** **found =
window_copy_search_rl(gd, sgd, &px, i - 1,
** ** +** ** ** ** ** ** ** ** ** ** ** ** ** ** ** **0,
firstIteration ? fx : gd->sx, cis);
** ** +** ** ** ** ** ** ** ** ** ** ** **if (found) {
** ** +** ** ** ** ** ** ** ** ** ** ** ** ** ** ** **--i;
** ** +** ** ** ** ** ** ** ** ** ** ** ** ** ** ** **break;
** ** +** ** ** ** ** ** ** ** ** ** ** **}
** ** +** ** ** ** ** ** ** ** ** ** ** **firstIteration = 0;
** ** **** ** ** ** ** ** ** }
** ** **** ** ** }
** ** -** ** ** **if (wrapflag && !n && !wrapped) {
** ** -** ** ** ** ** ** ** **fx = gd->sx - 1;
** ** -** ** ** ** ** ** ** **fy = gd->hsize + gd->sy - 1;
** ** -** ** ** ** ** ** ** **wrapped = 1;
** ** -** ** ** ** ** ** ** **goto retry;
** ** +** ** ** **if (found) {
** ** +** ** ** ** ** ** ** **window_copy_scroll_to(wp, px, i);
** ** +** ** ** **} else if (wrap) {
** ** +** ** ** ** ** ** ** **/* Start searching from begin/end of
grid up to `fy` line
** ** */
** ** +** ** ** ** ** ** **
**window_copy_jump_to_searched_string(wp, gd, sgd,
** ** +** ** ** ** ** ** ** ** ** ** ** **direction ? 0 : gd->sx -
1,
** ** +** ** ** ** ** ** ** ** ** ** ** **direction ? 0 : gd->hsize
+ gd->sy - 1,
** ** +** ** ** ** ** ** ** ** ** ** ** **fy, cis, 0, direction);
** ** **** ** ** }
** ** -
** ** -** ** ** **screen_free(&ss);
** ** **}
** ** **void
** ** -window_copy_search_down(struct window_pane *wp, const char
*searchstr)
** ** +window_copy_search(struct window_pane *wp,
** ** + ** **const char *searchstr, const int direction, const int
move)
** ** **{
** ** **** ** ** struct window_copy_mode_data** ** *data =
wp->modedata;
** ** **** ** ** struct screen** ** ** ** ** ** ** ** ** ***s =
data->backing, ss;
** ** **** ** ** struct screen_write_ctx** ** ** ** ** ** ** ** **
ctx;
** ** -** ** ** **struct grid** ** ** ** ** ** ** ** ** ** ***gd =
s->grid, *sgd;
** ** -** ** ** **struct grid_cell** ** ** ** ** ** ** ** **gc;
** ** +** ** ** **struct grid** ** ** ** ** ** ** ** ** ** ***gd =
s->grid;
** ** +** ** ** **struct grid_cell** ** ** ** ** ** ** ** **gc;
** ** **** ** ** size_t** ** ** ** ** ** ** ** ** ** ** ** **
**searchlen;
** ** -** ** ** **u_int** ** ** ** ** ** ** ** ** ** ** ** ** ** i,
first, fx, fy, px;
** ** -** ** ** **int** ** ** ** ** ** ** ** ** ** ** ** ** ** **
utf8flag, n, wrapped, wrapflag,
** ** cis;
** ** -** ** ** **const char** ** ** ** ** ** ** ** ** ** ** *ptr;
** ** +** ** ** **u_int** ** ** ** ** ** ** ** ** ** ** ** ** **
fx, fy;
** ** +** ** ** **int** ** ** ** ** ** ** ** ** ** ** ** ** ** **
utf8flag, wrapflag, cis;
** ** +
** ** +** ** ** **/* current cursor coordinates */
** ** +** ** ** **fx = data->cx;
** ** +** ** ** **fy = screen_hsize(data->backing) - data->oy +
data->cy;
** ** -** ** ** **if (*searchstr == '\0')
** ** -** ** ** ** ** ** ** **return;
** ** **** ** ** utf8flag =
options_get_number(&wp->window->options, "utf8");
** ** **** ** ** wrapflag =
options_get_number(&wp->window->options,
** ** "wrap-search");
** ** **** ** ** searchlen = screen_write_strlen(utf8flag, "%s",
searchstr);
window_pane *wp,
** ** const char *searchstr)
** ** **** ** ** screen_write_nputs(&ctx, -1, &gc, utf8flag, "%s",
searchstr);
** ** **** ** ** screen_write_stop(&ctx);
** ** -** ** ** **fx = data->cx;
** ** -** ** ** **fy = gd->hsize - data->oy + data->cy;
** ** -
** ** -** ** ** **if (fx == gd->sx - 1) {
** ** -** ** ** ** ** ** ** **if (fy == gd->hsize + gd->sy)
** ** -** ** ** ** ** ** ** ** ** ** ** **return;
** ** -** ** ** ** ** ** ** **fx = 0;
** ** -** ** ** ** ** ** ** **fy++;
** ** -** ** ** **} else
** ** -** ** ** ** ** ** ** **fx++;
** ** -** ** ** **n = wrapped = 0;
** ** -
** ** -** ** ** **cis = 1;
** ** -** ** ** **for (ptr = searchstr; *ptr != '\0'; ptr++) {
** ** -** ** ** ** ** ** ** **if (*ptr != tolower((u_char)*ptr)) {
** ** -** ** ** ** ** ** ** ** ** ** ** **cis = 0;
** ** -** ** ** ** ** ** ** ** ** ** ** **break;
** ** -** ** ** ** ** ** ** **}
** ** +** ** ** **if (move) {
** ** +** ** ** ** ** ** ** **window_copy_move_coordinates(s, &fx,
&fy, direction);
** ** **** ** ** }
** ** -** ** ** **sgd = ss.grid;
** ** -** ** ** **for (i = fy + 1; i < gd->hsize + gd->sy + 1; i++)
{
** ** -** ** ** ** ** ** ** **first = 0;
** ** -** ** ** ** ** ** ** **if (i == fy + 1)
** ** -** ** ** ** ** ** ** ** ** ** ** **first = fx;
** ** -** ** ** ** ** ** ** **n = window_copy_search_lr(gd, sgd,
&px, i - 1, first,
** ** gd->sx,
** ** -** ** ** ** ** ** ** ** ** **cis);
** ** -** ** ** ** ** ** ** **if (n) {
** ** -** ** ** ** ** ** ** ** ** ** ** **window_copy_scroll_to(wp,
px, i - 1);
** ** -** ** ** ** ** ** ** ** ** ** ** **break;
** ** -** ** ** ** ** ** ** **}
** ** -** ** ** **}
** ** -** ** ** **if (wrapflag && !n && !wrapped) {
** ** -** ** ** ** ** ** ** **fx = 0;
** ** -** ** ** ** ** ** ** **fy = 0;
** ** -** ** ** ** ** ** ** **wrapped = 1;
** ** -** ** ** ** ** ** ** **goto retry;
** ** -** ** ** **}
** ** +** ** ** **cis = window_copy_is_lowercase(searchstr);
** ** +** ** ** **window_copy_clear_selection(wp);
** ** +
** ** +** ** ** **window_copy_jump_to_searched_string(wp, gd,
ss.grid, fx, fy,
0,
** ** +** ** ** ** ** ** ** **cis, wrapflag, direction);
** ** **** ** ** screen_free(&ss);
** ** **}
** ** **void
** ** +window_copy_search_up(struct window_pane *wp, const char
*searchstr,
** ** +** ** ** **const int move)
** ** +{
** ** +** ** ** **window_copy_search(wp, searchstr, 0, move);
** ** +}
** ** +
** ** +void
** ** +window_copy_search_down(struct window_pane *wp, const char
*searchstr,
** ** +** ** ** **const int move)
** ** +{
** ** +** ** ** **window_copy_search(wp, searchstr, 1, move);
** ** +}
** ** +
** ** +void
** ** **window_copy_goto_line(struct window_pane *wp, const char
*linestr)
** ** **{
** ** **** ** ** struct window_copy_mode_data** ** *data =
wp->modedata;
** ** Incremental search in window-copy mode
** ** ==============================
** ** diff --git window-copy.c window-copy.c
** ** index 1213380..243c755 100644
** ** --- window-copy.c
** ** +++ window-copy.c
*);
** ** **void** window_copy_jump_to_searched_string(
** ** **** ** ** **** **struct window_pane *, struct grid *, struct
grid *, u_int,
** ** u_int,
** ** **** ** ** **** **u_int, int, int, const int);
** ** +int** ** window_copy_coord_from_hist(struct window_pane *wp,
** ** +** ** ** ** ** **const size_t searchlen, u_int *fx, u_int
*fy);
** ** +void** **window_copy_clear_search_hist(struct window_pane *,
u_int *, u_int
** ** *);
** ** **void** window_copy_search(struct window_pane *, const char
*,
** ** **** ** ** **** **const int, const int);
** ** **void** window_copy_search_up(struct window_pane *, const
char *, const
** ** int);
** ** **};
** ** **/*
** ** + * x, y - coordinates from which the search was made
** ** + * found - if the text was found
** ** + * searchlen - lenght of text that was searched
** ** + * prev - data of previous searches
** ** + */
** ** +struct window_copy_search_hist {
** ** +** ** ** **u_int** ** ** ** ** **x;
** ** +** ** ** **u_int** ** ** ** ** **y;
** ** +** ** ** **int** ** ** ** ** ** **found;
** ** +
** ** +** ** ** **size_t** ** ** ** ** searchlen;
** ** +
** ** +** ** ** **struct window_copy_search_hist ***prev;
** ** +};
** ** +
** ** +/*
** ** ** * Copy-mode's visible screen (the "screen" field) is
filled from one of
** ** ** * two sources: the original contents of the pane (used
when we
** ** ** * actually enter via the "copy-mode" command, to copy the
contents of
** ** **** ** ** enum window_copy_input_type searchtype;
** ** **** ** ** char** ** **** ** ** *searchstr;
** ** +** ** ** **struct window_copy_search_hist** *searchhist;
** ** **** ** ** enum window_copy_input_type jumptype;
** ** **** ** ** char** ** ** ** ** ** jumpchar;
** ** **** ** ** data->searchtype = WINDOW_COPY_OFF;
** ** **** ** ** data->searchstr = NULL;
** ** +** ** ** **data->searchhist = NULL;
** ** **** ** ** if (wp->fd != -1)
** ** **** ** ** ** ** ** ** bufferevent_disable(wp->event,
EV_READ|EV_WRITE);
** ** **** ** ** free(data->searchstr);
** ** **** ** ** free(data->inputstr);
** ** +** ** ** **window_copy_clear_search_hist(wp, NULL, NULL);
** ** **** ** ** if (data->backing != &wp->base) {
** ** **** ** ** ** ** ** ** screen_free(data->backing);
struct
** ** session *sess, int key)
** ** **** ** ** ** ** ** ** data->inputtype =
WINDOW_COPY_SEARCHUP;
** ** **** ** ** ** ** ** ** data->inputprompt = "Search Up";
** ** +** ** ** ** ** ** ** ***data->inputstr = '\0';
** ** **** ** ** ** ** ** ** goto input_on;
** ** **** ** ** ** ** ** ** data->inputtype =
WINDOW_COPY_SEARCHDOWN;
** ** **** ** ** ** ** ** ** data->inputprompt = "Search Down";
** ** +** ** ** ** ** ** ** ***data->inputstr = '\0';
** ** **** ** ** ** ** ** ** goto input_on;
*wp, int key)
** ** **** ** ** int** ** ** ** ** ** ** ** ** ** ** ** ** ** **
np;
** ** **** ** ** struct paste_buffer** ** ** ** ** ** ***pb;
** ** **** ** ** u_char** ** ** ** ** ** ** ** ** ** ** ** ** **ch;
** ** +** ** ** **u_int** ** ** ** ** ** ** ** ** ** ** ** ** **
fx, fy;
** ** **** ** ** switch (mode_key_lookup(&data->mdata, key, NULL))
{
*wp, int
** ** key)
** ** **** ** ** ** ** ** ** inputlen = strlen(data->inputstr);
** ** **** ** ** ** ** ** ** if (inputlen > 0)
** ** **** ** ** ** ** ** ** ** ** ** ** data->inputstr[inputlen -
1] = '\0';
** ** +** ** ** ** ** ** ** **switch (data->inputtype) {
** ** +** ** ** ** ** ** ** ** ** ** ** **data->searchtype =
data->inputtype;
** ** +** ** ** ** ** ** ** ** ** ** ** **free(data->searchstr);
** ** +** ** ** ** ** ** ** ** ** ** ** **data->searchstr =
xstrdup(data->inputstr);
** ** +** ** ** ** ** ** ** ** ** ** ** **window_copy_search_up(wp,
data->inputstr, 0);
** ** +** ** ** ** ** ** ** ** ** ** ** **break;
** ** +** ** ** ** ** ** ** ** ** ** ** **data->searchtype =
data->inputtype;
** ** +** ** ** ** ** ** ** ** ** ** ** **free(data->searchstr);
** ** +** ** ** ** ** ** ** ** ** ** ** **data->searchstr =
xstrdup(data->inputstr);
** ** +** ** ** ** ** ** ** ** ** ** **
**window_copy_search_down(wp, data->inputstr, 0);
** ** +** ** ** ** ** ** ** ** ** ** ** **break;
** ** +** ** ** ** ** ** ** ** ** ** ** **break;
** ** +** ** ** ** ** ** ** **}
** ** **** ** ** ** ** ** ** break;
** ** **** ** ** ** ** ** ** *data->inputstr = '\0';
** ** +** ** ** ** ** ** ** **fx = data->cx;
** ** +** ** ** ** ** ** ** **fy = screen_hsize(data->backing) -
data->oy + data->cy;
** ** +** ** ** ** ** ** ** **window_copy_clear_search_hist(wp,
&fx, &fy);
** ** +** ** ** ** ** ** ** **window_copy_scroll_to(wp, fx, fy);
** ** **** ** ** ** ** ** ** break;
** ** **** ** ** ** ** ** ** if ((pb = paste_get_top()) == NULL)
window_pane *wp, int
** ** key)
** ** **** ** ** ** ** ** ** ** ** ** ** break;
** ** **** ** ** ** ** ** ** ** ** ** ** data->searchtype =
data->inputtype;
** ** +** ** ** ** ** ** ** ** ** ** ** **free(data->searchstr);
** ** **** ** ** ** ** ** ** ** ** ** ** data->searchstr =
xstrdup(data->inputstr);
** ** -** ** ** ** ** ** ** ** ** ** ** **for (; np != 0; np--)
** ** -** ** ** ** ** ** ** ** ** ** ** ** ** ** **
**window_copy_search_up(wp, data->inputstr,
** ** 0);
** ** +** ** ** ** ** ** ** ** ** ** ** **for (; np > 1; np--)
** ** +** ** ** ** ** ** ** ** ** ** ** ** ** ** **
**window_copy_search_up(wp, data->inputstr,
** ** 1);
** ** **** ** ** ** ** ** ** ** ** ** ** break;
** ** **** ** ** ** ** ** ** ** ** ** ** data->searchtype =
data->inputtype;
** ** +** ** ** ** ** ** ** ** ** ** ** **free(data->searchstr);
** ** **** ** ** ** ** ** ** ** ** ** ** data->searchstr =
xstrdup(data->inputstr);
** ** -** ** ** ** ** ** ** ** ** ** ** **for (; np != 0; np--)
** ** -** ** ** ** ** ** ** ** ** ** ** ** ** ** **
**window_copy_search_down(wp,
** ** data->inputstr, 0);
** ** +** ** ** ** ** ** ** ** ** ** ** **for (; np > 1; np--)
** ** +** ** ** ** ** ** ** ** ** ** ** ** ** ** **
**window_copy_search_down(wp,
** ** data->inputstr, 1);
** ** **** ** ** ** ** ** ** ** ** ** ** break;
** ** **** ** ** ** ** ** ** ** ** ** **
window_copy_copy_selection(wp, data->inputstr);
*wp, int
** ** key)
** ** **** ** ** ** ** ** ** data->inputstr =
xrealloc(data->inputstr, 1, inputlen);
** ** **** ** ** ** ** ** ** data->inputstr[inputlen - 2] = key;
** ** **** ** ** ** ** ** ** data->inputstr[inputlen - 1] = '\0';
** ** +** ** ** ** ** ** ** **switch (data->inputtype) {
** ** +** ** ** ** ** ** ** ** ** ** ** **data->searchtype =
data->inputtype;
** ** +** ** ** ** ** ** ** ** ** ** ** **free(data->searchstr);
** ** +** ** ** ** ** ** ** ** ** ** ** **data->searchstr =
xstrdup(data->inputstr);
** ** +** ** ** ** ** ** ** ** ** ** ** **window_copy_search_up(wp,
data->inputstr, 0);
** ** +** ** ** ** ** ** ** ** ** ** ** **break;
** ** +** ** ** ** ** ** ** ** ** ** ** **data->searchtype =
data->inputtype;
** ** +** ** ** ** ** ** ** ** ** ** ** **free(data->searchstr);
** ** +** ** ** ** ** ** ** ** ** ** ** **data->searchstr =
xstrdup(data->inputstr);
** ** +** ** ** ** ** ** ** ** ** ** **
**window_copy_search_down(wp, data->inputstr, 0);
** ** +** ** ** ** ** ** ** ** ** ** ** **break;
** ** +** ** ** ** ** ** ** ** ** ** ** **break;
** ** +** ** ** ** ** ** ** **}
** ** **** ** ** ** ** ** ** break;
** ** **** ** ** ** ** ** ** break;
window_copy_jump_to_searched_string(struct
** ** window_pane *wp,
** ** ** ** **struct grid *gd, struct grid *sgd, u_int fx, u_int
fy,
** ** ** ** **u_int endline, int cis, int wrap, const int
direction)
** ** **{
** ** +** ** ** **struct window_copy_mode_data** ** *data =
wp->modedata;
** ** +** ** ** **struct window_copy_search_hist** *searchhist =
data->searchhist;
** ** **** ** ** u_int** ** ** ** ** ** ** ** ** ** ** ** ** ** i,
px;
** ** **** ** ** int** ** ** ** ** ** ** ** ** ** ** ** ** ** **
firstIteration, found;
window_copy_jump_to_searched_string(struct
** ** window_pane *wp,
** ** **** ** ** ** ** ** ** ** ** ** ** direction ? 0 : gd->sx -
1,
** ** **** ** ** ** ** ** ** ** ** ** ** direction ? 0 : gd->hsize
+ gd->sy - 1,
** ** **** ** ** ** ** ** ** ** ** ** ** fy, cis, 0, direction);
** ** +** ** ** **} else {
** ** +** ** ** ** ** ** ** **if (searchhist != NULL) {
** ** +** ** ** ** ** ** ** ** ** ** ** **searchhist->found = 0;
** ** +** ** ** ** ** ** ** **}
** ** +** ** ** **}
** ** +}
** ** +
** ** +/* If it returns 0 then, according to search history, last
time we
** ** searched
** ** + * a shorter string we haven't found anything, so there is
no point in
** ** + * incremental-searching a longer string (just an
optimization) */
** ** +int
** ** +window_copy_coord_from_hist(struct window_pane *wp,
** ** + ** **const size_t searchlen, u_int *fx, u_int *fy)
** ** +{
** ** +** ** ** **struct window_copy_mode_data** ** *data =
wp->modedata;
** ** +** ** ** **struct window_copy_search_hist** *searchhist =
data->searchhist;
** ** +
** ** +** ** ** **if (searchhist == NULL || searchhist->searchlen <
searchlen) {
** ** +** ** ** ** ** ** ** **searchhist = xmalloc(sizeof (struct
** ** window_copy_search_hist));
** ** +** ** ** ** ** ** ** **searchhist->x = data->cx;
** ** +** ** ** ** ** ** ** **searchhist->y =
** ** +** ** ** ** ** ** ** ** ** ** **
**screen_hsize(data->backing) - data->oy + data->cy;
** ** +** ** ** ** ** ** ** **searchhist->searchlen = searchlen;
** ** +** ** ** ** ** ** ** **searchhist->found = data->searchhist
== NULL ?
data->searchhist->found;
** ** +
** ** +** ** ** ** ** ** ** **searchhist->prev = data->searchhist;
** ** +** ** ** ** ** ** ** **data->searchhist = searchhist;
** ** +
** ** +** ** ** ** ** ** ** ***fx = searchhist->x;
** ** +** ** ** ** ** ** ** ***fy = searchhist->y;
** ** +** ** ** **} else {
** ** +** ** ** ** ** ** ** ***fx = searchhist->x;
** ** +** ** ** ** ** ** ** ***fy = searchhist->y;
** ** +** ** ** ** ** ** ** **searchhist = data->searchhist->prev;
** ** +** ** ** ** ** ** ** **free(data->searchhist);
** ** +** ** ** ** ** ** ** **data->searchhist = searchhist;
** ** +** ** ** **}
** ** +
searchhist->found;
** ** +}
** ** +
** ** +void
** ** +window_copy_clear_search_hist(struct window_pane *wp, u_int
*fx, u_int
** ** *fy)
** ** +{
** ** +** ** ** **struct window_copy_mode_data** ** *data =
wp->modedata;
** ** +** ** ** **struct window_copy_search_hist** *searchhist =
data->searchhist;
** ** +
** ** +** ** ** **while (searchhist != NULL) {
** ** +** ** ** ** ** ** ** **if (fx != NULL) *fx = searchhist->x;
** ** +** ** ** ** ** ** ** **if (fy != NULL) *fy = searchhist->y;
** ** +** ** ** ** ** ** ** **searchhist = searchhist->prev;
** ** +** ** ** ** ** ** ** **free(data->searchhist);
** ** +** ** ** ** ** ** ** **data->searchhist = searchhist;
** ** **** ** ** }
** ** **}
*wp,
** ** **** ** ** fx = data->cx;
** ** **** ** ** fy = screen_hsize(data->backing) - data->oy +
data->cy;
** ** +** ** ** **/* User deleted all searched text, jump to the
initial cursor
** ** +** ** ** ** * position and delete the searchhistory */
** ** +** ** ** **if ((searchstr == NULL) || (*searchstr == '\0'))
{
** ** +** ** ** ** ** ** ** **window_copy_clear_search_hist(wp,
&fx, &fy);
** ** +** ** ** ** ** ** ** **window_copy_scroll_to(wp, fx, fy);
** ** +** ** ** ** ** ** ** **return;
** ** +** ** ** **}
** ** +
** ** **** ** ** utf8flag =
options_get_number(&wp->window->options, "utf8");
** ** **** ** ** wrapflag =
options_get_number(&wp->window->options,
** ** "wrap-search");
** ** **** ** ** searchlen = screen_write_strlen(utf8flag, "%s",
searchstr);
*wp,
** ** **** ** ** screen_write_nputs(&ctx, -1, &gc, utf8flag, "%s",
searchstr);
** ** **** ** ** screen_write_stop(&ctx);
** ** +** ** ** **/*
** ** +** ** ** ** * `move` is useful for incremental searching.
When we do
** ** incremental,
** ** +** ** ** ** * **we don't want to jump to the next matching
word if we already
** ** stand
** ** +** ** ** ** * **on one, so `move=0`.
** ** +** ** ** ** * **But when user wants the next result, then we
use `move=1`, so
** ** +** ** ** ** * **we start searching from the place next to
the current cursor
** ** +** ** ** ** * **position */
** ** **** ** ** if (move) {
** ** **** ** ** ** ** ** ** window_copy_move_coordinates(s, &fx,
&fy, direction);
** ** +** ** ** **} else {
** ** +** ** ** ** ** ** ** **if (!window_copy_coord_from_hist(wp,
searchlen, &fx, &fy))
** ** {
** ** +** ** ** ** ** ** ** ** ** ** ** **return;
** ** +** ** ** ** ** ** ** **}
** ** **** ** ** }
** ** **** ** ** cis = window_copy_is_lowercase(searchstr);
** ** Highlight last search in window-copy mode
** ** ===============================
** ** diff --git options-table.c options-table.c
** ** index 8d680b3..79ecae3 100644
** ** --- options-table.c
** ** +++ options-table.c
** ** window_options_table[] = {
** ** **** ** ** ****.default_str = "bg=yellow,fg=black"
** ** **** ** ** },
** ** +** ** ** **{ .name = "highlight-style",
** ** +** ** ** ** **.type = OPTIONS_TABLE_STYLE,
** ** +** ** ** ** **.default_str = "bg=green,fg=black"
** ** +** ** ** **},
** ** +
** ** **** ** ** { .name = "monitor-activity",
** ** **** ** ** ****.type = OPTIONS_TABLE_FLAG,
** ** **** ** ** ****.default_num = 0
** ** window_options_table[] = {
** ** **** ** ** ****.default_num = 1
** ** **** ** ** },
** ** +** ** ** **{ .name = "highlight-search",
** ** +** ** ** ** **.type = OPTIONS_TABLE_FLAG,
** ** +** ** ** ** **.default_num = 1
** ** +** ** ** **},
** ** +
** ** **** ** ** { .name = "xterm-keys",
** ** **** ** ** ****.type = OPTIONS_TABLE_FLAG,
** ** **** ** ** ****.default_num = 0
** ** diff --git screen-write.c screen-write.c
** ** index 325fb9a..a36a1f2 100644
** ** --- screen-write.c
** ** +++ screen-write.c
*ctx, const
** ** struct grid_cell *gc)
** ** **** ** ** struct grid** ** ** ** ** ** ***gd = s->grid;
** ** **** ** ** struct tty_ctx** ** ** ** ** **ttyctx;
** ** **** ** ** u_int** ** ** ** ** ** ** ** ** ** width, xx,
last;
** ** -** ** ** **struct grid_cell** ** ** ** **tmp_gc, *tmp_gcp;
** ** +** ** ** **struct grid_cell** ** ** ** **tmp_gc, *tmp_gcp,
*cell = NULL;
** ** **** ** ** struct utf8_data** ** ** ** **ud;
** ** **** ** ** int** ** ** ** ** ** ** ** ** ** ** insert;
screen_write_ctx *ctx, const
** ** struct grid_cell *gc)
** ** **** ** ** ** ** ** ** ****
**(GRID_FLAG_FG256|GRID_FLAG_BG256);
** ** **** ** ** ** ** ** ** ttyctx.cell = &tmp_gc;
** ** **** ** ** ** ** ** ** tty_write(tty_cmd_cell, &ttyctx);
** ** +** ** ** **} else if (screen_check_highlight(s, s->cx -
width, s->cy, &cell))
** ** {
** ** +** ** ** ** ** ** ** **memcpy(&tmp_gc, cell, sizeof tmp_gc);
** ** +** ** ** ** ** ** ** **grid_cell_get(gc, &ud);
** ** +** ** ** ** ** ** ** **grid_cell_set(&tmp_gc, &ud);
** ** +** ** ** ** ** ** ** **tmp_gc.flags = gc->flags &
** ** ~(GRID_FLAG_FG256|GRID_FLAG_BG256);
** ** +** ** ** ** ** ** ** **tmp_gc.flags |= cell->flags &
** ** +** ** ** ** ** ** ** ** **
**(GRID_FLAG_FG256|GRID_FLAG_BG256);
** ** +** ** ** ** ** ** ** **ttyctx.cell = &tmp_gc;
** ** +** ** ** ** ** ** ** **tty_write(tty_cmd_cell, &ttyctx);
** ** **** ** ** } else {
** ** **** ** ** ** ** ** ** ttyctx.cell = gc;
** ** **** ** ** ** ** ** ** tty_write(tty_cmd_cell, &ttyctx);
** ** diff --git screen.c screen.c
** ** index 7bfc015..734b38e 100644
** ** --- screen.c
** ** +++ screen.c
u_int sy, u_int
** ** hlimit)
** ** **** ** ** s->cstyle = 0;
** ** **** ** ** s->ccolour = xstrdup("");
** ** **** ** ** s->tabs = NULL;
** ** +** ** ** **s->hls = NULL;
** ** **** ** ** screen_reinit(s);
** ** **}
** ** **** ** ** grid_clear_lines(s->grid, s->grid->hsize,
s->grid->sy);
** ** **** ** ** screen_clear_selection(s);
** ** +** ** ** **screen_clear_highlight(s);
** ** **}
** ** **/* Destroy a screen. */
** ** **** ** ** free(s->title);
** ** **** ** ** free(s->ccolour);
** ** **** ** ** grid_destroy(s->grid);
** ** +** ** ** **screen_clear_highlight(s);
** ** **}
** ** **/* Reset tabs to default, eight spaces apart. */
u_int px,
** ** u_int py)
** ** **** ** ** return (1);
** ** **}
** ** +/* Set highlight. */
** ** +void
** ** +screen_set_highlight(struct screen *s,
** ** +** ** ** **u_int sx, u_int ex, u_int y, struct grid_cell
*gc)
** ** +{
** ** +** ** ** **struct screen_hls** ** ** ***hls = xmalloc(sizeof
(struct
** ** screen_hls));
** ** +
** ** +** ** ** **hls->sx = sx;
** ** +** ** ** **hls->ex = ex;
** ** +** ** ** **hls->y = y;
** ** +** ** ** **hls->next = s->hls;
** ** +
** ** +** ** ** **memcpy(&hls->cell, gc, sizeof hls->cell);
** ** +
** ** +** ** ** **s->hls = hls;
** ** +}
** ** +
** ** +/* Clear highlights. */
** ** +void
** ** +screen_clear_highlight(struct screen *s)
** ** +{
** ** +** ** ** **struct screen_hls** ** ** ***hls = s->hls,
*hlsPrev;
** ** +
** ** +** ** ** **while (hls != NULL) {
** ** +** ** ** ** ** ** ** **hlsPrev = hls;
** ** +** ** ** ** ** ** ** **hls = hls->next;
** ** +** ** ** ** ** ** ** **free(hlsPrev);
** ** +** ** ** **}
** ** +
** ** +** ** ** **s->hls = NULL;
** ** +}
** ** +
** ** +/* Check if cell in highlight. */
** ** +int
** ** +screen_check_highlight(struct screen *s, u_int px, u_int py,
** ** +** ** ** **struct grid_cell **cell)
** ** +{
** ** +** ** ** **struct screen_hls** ** ** ***hls = s->hls;
** ** +
** ** +** ** ** **while (hls != NULL) {
** ** +** ** ** ** ** ** ** **if (hls->sx <= px && px <= hls->ex &&
hls->y == py) {
** ** +** ** ** ** ** ** ** ** ** ** ** ***cell = &hls->cell;
** ** +** ** ** ** ** ** ** ** ** ** ** **return 1;
** ** +** ** ** ** ** ** ** **}
** ** +** ** ** ** ** ** ** **hls = hls->next;
** ** +** ** ** **}
** ** +
** ** +** ** ** **return 0;
** ** +}
** ** +
** ** **/* Reflow wrapped lines. */
** ** **void
** ** **screen_reflow(struct screen *s, u_int new_x)
** ** diff --git tmux.h tmux.h
** ** index c4c5236..6fc5fd0 100644
** ** --- tmux.h
** ** +++ tmux.h
** ** **** ** ** struct grid_cell cell;
** ** **};
** ** +/* Screen highlights. */
** ** +struct screen_hls {
** ** +** ** ** **u_int** ** ** ** ** ** sx;
** ** +** ** ** **u_int** ** ** ** ** ** ex;
** ** +
** ** +** ** ** **u_int** ** ** ** ** ** y;
** ** +
** ** +** ** ** **struct grid_cell cell;
** ** +** ** ** **struct screen_hls *next;
** ** +};
** ** +
** ** **/* Virtual screen. */
** ** **struct screen {
** ** **** ** ** char** ** ** ** ** ** *title;
** ** **** ** ** bitstr_t** ** ** ** *tabs;
** ** **** ** ** struct screen_sel sel;
** ** +** ** ** **struct screen_hls *hls;
** ** **};
** ** **/* Screen write context. */
screen_set_selection(struct screen *,
** ** **** ** ** **** ** u_int, u_int, u_int, u_int, u_int, struct
grid_cell *);
** ** **void** **screen_clear_selection(struct screen *);
** ** **int** ** screen_check_selection(struct screen *, u_int,
u_int);
** ** +void** ** screen_set_highlight(struct screen *,
** ** +** ** ** ** ** ** u_int, u_int, u_int, struct grid_cell *);
** ** +void** ** screen_clear_highlight(struct screen *);
** ** +int** ** **screen_check_highlight(struct screen *, u_int,
u_int,
** ** +** ** ** ** ** ** struct grid_cell **);
** ** **void** **screen_reflow(struct screen *, u_int);
** ** **/* window.c */
** ** diff --git tty.c tty.c
** ** index 7688e90..4511533 100644
** ** --- tty.c
** ** +++ tty.c
screen *s, u_int
** ** py, u_int ox, u_int oy)
** ** **{
** ** **** ** ** const struct grid_cell** *gc;
** ** **** ** ** struct grid_line** ** ** ** *gl;
** ** -** ** ** **struct grid_cell** ** ** ** **tmpgc;
** ** +** ** ** **struct grid_cell** ** ** ** **tmpgc, *cell =
NULL;
** ** **** ** ** struct utf8_data** ** ** ** **ud;
** ** **** ** ** u_int** ** ** ** ** ** ** ** ** ** i, sx;
screen *s,
** ** u_int py, u_int ox, u_int oy)
** ** **** ** ** ** ** ** ** ** ** ** ** tmpgc.flags |=
s->sel.cell.flags &
** ** **** ** ** ** ** ** ** ** ** ** ** ****
**(GRID_FLAG_FG256|GRID_FLAG_BG256);
** ** **** ** ** ** ** ** ** ** ** ** ** tty_cell(tty, &tmpgc);
** ** +** ** ** ** ** ** ** **} else if (screen_check_highlight(s,
i, py, &cell)) {
** ** +** ** ** ** ** ** ** ** ** ** ** **memcpy(&tmpgc, cell,
sizeof tmpgc);
** ** +** ** ** ** ** ** ** ** ** ** ** **grid_cell_get(gc, &ud);
** ** +** ** ** ** ** ** ** ** ** ** ** **grid_cell_set(&tmpgc,
&ud);
** ** +** ** ** ** ** ** ** ** ** ** ** **tmpgc.flags = gc->flags &
** ** +** ** ** ** ** ** ** ** ** ** ** ** **
**~(GRID_FLAG_FG256|GRID_FLAG_BG256);
** ** +** ** ** ** ** ** ** ** ** ** ** **tmpgc.flags |=
cell->flags &
** ** +** ** ** ** ** ** ** ** ** ** ** ** **
**(GRID_FLAG_FG256|GRID_FLAG_BG256);
** ** +** ** ** ** ** ** ** ** ** ** ** **tty_cell(tty, &tmpgc);
** ** **** ** ** ** ** ** ** } else
** ** **** ** ** ** ** ** ** ** ** ** ** tty_cell(tty, gc);
** ** **** ** ** }
** ** diff --git window-copy.c window-copy.c
** ** index 243c755..00cdc3f 100644
** ** --- window-copy.c
** ** +++ window-copy.c
window_pane *);
** ** **void** window_copy_free(struct window_pane *);
** ** **void** window_copy_resize(struct window_pane *, u_int,
u_int);
** ** **void** window_copy_key(struct window_pane *, struct session
*, int);
** ** +void** **window_copy_key_internal(struct window_pane *,
struct session *,
** ** int);
** ** **int** **window_copy_key_input(struct window_pane *, int);
** ** **int** **window_copy_key_numeric_prefix(struct window_pane
*, int);
** ** **void** window_copy_mouse(
** ** **** ** ** **** **struct window_pane *, struct session *,
struct mouse_event
** ** *);
** ** +void** **window_copy_mouse_internal(
** ** +** ** ** ** ** **struct window_pane *, struct session *,
struct mouse_event
** ** *);
** ** **void** window_copy_redraw_lines(struct window_pane *,
u_int, u_int);
** ** **void** window_copy_redraw_screen(struct window_pane *);
*);
** ** **void** window_copy_jump_to_searched_string(
** ** **** ** ** **** **struct window_pane *, struct grid *, struct
grid *, u_int,
** ** u_int,
** ** **** ** ** **** **u_int, int, int, const int);
** ** +void** **window_copy_highlight_search(struct window_pane *);
** ** **int** **window_copy_coord_from_hist(struct window_pane *wp,
** ** **** ** ** **** **const size_t searchlen, u_int *fx, u_int
*fy);
** ** **void** window_copy_clear_search_hist(struct window_pane *,
u_int *, u_int
** ** *);
*wp, u_int sx,
** ** u_int sy)
** ** **void
** ** **window_copy_key(struct window_pane *wp, struct session
*sess, int key)
** ** **{
** ** +** ** ** **window_copy_key_internal(wp, sess, key);
** ** +
** ** +** ** ** **if (wp->mode != NULL) {
** ** +** ** ** ** ** ** ** **window_copy_highlight_search(wp);
** ** +** ** ** **}
** ** +}
** ** +
** ** +void
** ** +window_copy_key_internal(struct window_pane *wp, struct
session *sess,
** ** int key)
** ** +{
** ** **** ** ** const char** ** ** ** ** ** ** ** ** ** **
*word_separators;
** ** **** ** ** struct window_copy_mode_data** ** *data =
wp->modedata;
** ** **** ** ** struct screen** ** ** ** ** ** ** ** ** ***s =
&data->screen;
** ** **window_copy_mouse(
** ** ** ** **struct window_pane *wp, struct session *sess, struct
mouse_event
** ** *m)
** ** **{
** ** +** ** ** **window_copy_mouse_internal(wp, sess, m);
** ** +
** ** +** ** ** **if (wp->mode != NULL) {
** ** +** ** ** ** ** ** ** **window_copy_highlight_search(wp);
** ** +** ** ** **}
** ** +}
** ** +
** ** +void
** ** +window_copy_mouse_internal(
** ** + ** **struct window_pane *wp, struct session *sess, struct
mouse_event
** ** *m)
** ** +{
** ** **** ** ** struct window_copy_mode_data** ** *data =
wp->modedata;
** ** **** ** ** struct screen** ** ** ** ** ** ** ** ** ***s =
&data->screen;
** ** **** ** ** u_int** ** ** ** ** ** ** ** ** ** ** ** ** ** i;
window_copy_jump_to_searched_string(struct
** ** window_pane *wp,
** ** **** ** ** }
** ** **}
** ** +void
** ** +window_copy_highlight_search(struct window_pane *wp)
** ** +{
** ** +** ** ** **struct window_copy_mode_data** ** *data =
wp->modedata;
** ** +** ** ** **struct screen** ** ** ** ** ** ** ** ** ***s =
data->backing, ss;
** ** +** ** ** **struct screen_write_ctx** ** ** ** ** ** ** ** **
ctx;
** ** +** ** ** **struct grid** ** ** ** ** ** ** ** ** ** ***gd =
s->grid;
** ** +** ** ** **struct grid_cell** ** ** ** ** ** ** ** **gc;
** ** +** ** ** **struct options** ** ** ** ** ** ** ** ** *oo =
&wp->window->options;
** ** +** ** ** **const char** ** ** ** ** ** ** ** ** ** **
*searchstr = data->searchstr;
** ** +** ** ** **size_t** ** ** ** ** ** ** ** ** ** ** ** **
**searchlen;
** ** +** ** ** **u_int** ** ** ** ** ** ** ** ** ** ** ** ** ** i,
px, last, beginline, endline;
** ** +** ** ** **int** ** ** ** ** ** ** ** ** ** ** ** ** ** **
found, utf8flag, cis, highlight;
** ** +
** ** +** ** ** **highlight = options_get_number(
** ** +** ** ** ** ** ** ** **&wp->window->options,
"highlight-search");
** ** +** ** ** **if (!highlight) {
** ** +** ** ** ** ** ** ** **return;
** ** +** ** ** **}
** ** +
** ** +** ** ** **screen_clear_highlight(&data->screen);
** ** +
** ** +** ** ** **if ((searchstr != NULL) && (*searchstr != '\0'))
{
** ** +** ** ** ** ** ** ** **utf8flag =
options_get_number(&wp->window->options,
** ** "utf8");
** ** +** ** ** ** ** ** ** **searchlen =
screen_write_strlen(utf8flag, "%s",
** ** searchstr);
** ** +
** ** +** ** ** ** ** ** ** **screen_init(&ss, searchlen, 1, 0);
** ** +** ** ** ** ** ** ** **screen_write_start(&ctx, NULL, &ss);
** ** +** ** ** ** ** ** ** **memcpy(&gc, &grid_default_cell,
sizeof gc);
** ** +** ** ** ** ** ** ** **screen_write_nputs(&ctx, -1, &gc,
utf8flag, "%s",
** ** searchstr);
** ** +** ** ** ** ** ** ** **screen_write_stop(&ctx);
** ** +
** ** +** ** ** ** ** ** ** **cis =
window_copy_is_lowercase(searchstr);
** ** +
** ** +** ** ** ** ** ** ** **/* Set colours. */
** ** +** ** ** ** ** ** ** **style_apply(&gc, oo,
"highlight-style");
** ** +
** ** +** ** ** ** ** ** ** **beginline = screen_hsize(s) -
data->oy;
** ** +** ** ** ** ** ** ** **endline = screen_hsize(s) - data->oy
+ screen_size_y(s) -
** ** 1;
** ** +
** ** +** ** ** ** ** ** ** **for (i = beginline; i <= endline;
++i) {
** ** +** ** ** ** ** ** ** ** ** ** ** **last = 0;
** ** +** ** ** ** ** ** ** ** ** ** ** **do {
** ** +** ** ** ** ** ** ** ** ** ** ** ** ** ** ** **found =
window_copy_search_lr(gd, ss.grid,
** ** &px,
** ** +** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** **
**i, last, gd->sx, cis);
** ** +** ** ** ** ** ** ** ** ** ** ** ** ** ** ** **if (found) {
** ** +** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** **
**screen_set_highlight(
** ** +** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** **
** ** ** **&data->screen,
** ** +** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** **
** ** ** **px,
** ** +** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** **
** ** ** **px + searchlen - 1,
** ** +** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** **
** ** ** **i - (screen_hsize(s)
** ** +** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** **
** ** ** ** ** ** - data->oy),
** ** +** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** **
** ** ** **&gc);
** ** +** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** **
**last += searchlen;
** ** +** ** ** ** ** ** ** ** ** ** ** ** ** ** ** **}
** ** +** ** ** ** ** ** ** ** ** ** ** **} while (found);
** ** +** ** ** ** ** ** ** **}
** ** +** ** ** **}
** ** +
** ** +** ** ** **window_copy_redraw_screen(wp);
** ** +}
** ** +
** ** **/* If it returns 0 then, according to search history, last
time we
** ** searched
** ** ** * a shorter string we haven't found anything, so there is
no point in
** ** ** * incremental-searching a longer string (just an
optimization) */
------------------------------------------------------------------------------
Want fast and easy access to all the code in your enterprise?
Index and
search up to 200,000 lines of code with a free copy of Black Duck
Code Sight - the same software that powers the world's largest
code
search on Ohloh, the Black Duck Open Hub! Try it now.
[4]http://p.sf.net/sfu/bds
_______________________________________________
tmux-users mailing list
[6]https://lists.sourceforge.net/lists/listinfo/tmux-users
------------------------------------------------------------------------------
Want fast and easy access to all the code in your enterprise? Index
and
search up to 200,000 lines of code with a free copy of Black Duck
Code Sight - the same software that powers the world's largest code
search on Ohloh, the Black Duck Open Hub! Try it now.
[7]http://p.sf.net/sfu/bds
_______________________________________________
tmux-users mailing list
[9]https://lists.sourceforge.net/lists/listinfo/tmux-users
References
Visible links
4. http://p.sf.net/sfu/bds
6. https://lists.sourceforge.net/lists/listinfo/tmux-users
7. http://p.sf.net/sfu/bds
9. https://lists.sourceforge.net/lists/listinfo/tmux-users
Loading...