Hi
Your mailer has mangled the diffs, if you can't fix it so it works
inline please send them as attachments instead.
On Mon, Aug 04, 2014 at 07:47:28PM -0700, ??ukasz Pi??tkowski wrote:
> 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
> @@ -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) */
> ------------------------------------------------------------------------------
> 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
> [email protected]
> 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
[email protected]
https://lists.sourceforge.net/lists/listinfo/tmux-users