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
On 1 Nov 2014 00:42, "Felix Rosencrantz" <f.rosencra...@gmail.com> wrote:

> 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 <
> nicholas.marri...@gmail.com> wrote:
>
>> 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
>> > tmux-users@lists.sourceforge.net
>> > 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
>> tmux-users@lists.sourceforge.net
>> https://lists.sourceforge.net/lists/listinfo/tmux-users
>>
>
>
------------------------------------------------------------------------------
_______________________________________________
tmux-users mailing list
tmux-users@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/tmux-users

Reply via email to