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