[BACK]Return to window-copy.c CVS log [TXT][DIR] Up to [local] / src / usr.bin / tmux

Diff for /src/usr.bin/tmux/window-copy.c between version 1.243 and 1.244

version 1.243, 2019/12/11 18:30:29 version 1.244, 2019/12/27 18:42:49
Line 19 
Line 19 
 #include <sys/types.h>  #include <sys/types.h>
   
 #include <ctype.h>  #include <ctype.h>
   #include <regex.h>
 #include <stdlib.h>  #include <stdlib.h>
 #include <string.h>  #include <string.h>
   
Line 57 
Line 58 
                     u_int, u_int, u_int, int);                      u_int, u_int, u_int, int);
 static int      window_copy_search_rl(struct grid *, struct grid *, u_int *,  static int      window_copy_search_rl(struct grid *, struct grid *, u_int *,
                     u_int, u_int, u_int, int);                      u_int, u_int, u_int, int);
   static int      window_copy_search_lr_regex(struct grid *, struct grid *,
                       u_int *, u_int *, u_int, u_int, u_int, int);
   static int      window_copy_search_rl_regex(struct grid *, struct grid *,
                       u_int *, u_int *, u_int, u_int, u_int, int);
   static int      window_copy_last_regex(struct grid *gd, u_int py, u_int first,
                       u_int last, u_int len, u_int *ppx, u_int *psx,
                       const char *buf, const regex_t *preg, int eflags);
   static char    *window_copy_stringify(struct grid *, u_int, u_int, u_int,
                       char *, u_int *);
   static void     window_copy_cstrtocellpos(struct grid *, u_int, u_int *, u_int *,
                       const char *str);
 static int      window_copy_search_marks(struct window_mode_entry *,  static int      window_copy_search_marks(struct window_mode_entry *,
                     struct screen *);                      struct screen *, int);
 static void     window_copy_clear_marks(struct window_mode_entry *);  static void     window_copy_clear_marks(struct window_mode_entry *);
 static void     window_copy_move_left(struct screen *, u_int *, u_int *, int);  static void     window_copy_move_left(struct screen *, u_int *, u_int *, int);
 static void     window_copy_move_right(struct screen *, u_int *, u_int *, int);  static void     window_copy_move_right(struct screen *, u_int *, u_int *, int);
 static int      window_copy_is_lowercase(const char *);  static int      window_copy_is_lowercase(const char *);
 static int      window_copy_search_jump(struct window_mode_entry *,  static int      window_copy_search_jump(struct window_mode_entry *,
                     struct grid *, struct grid *, u_int, u_int, u_int, int, int,                      struct grid *, struct grid *, u_int, u_int, u_int, int, int,
                     int);                      int, int);
 static int      window_copy_search(struct window_mode_entry *, int);  static int      window_copy_search(struct window_mode_entry *, int, int);
 static int      window_copy_search_up(struct window_mode_entry *);  static int      window_copy_search_up(struct window_mode_entry *, int);
 static int      window_copy_search_down(struct window_mode_entry *);  static int      window_copy_search_down(struct window_mode_entry *, int);
 static void     window_copy_goto_line(struct window_mode_entry *, const char *);  static void     window_copy_goto_line(struct window_mode_entry *, const char *);
 static void     window_copy_update_cursor(struct window_mode_entry *, u_int,  static void     window_copy_update_cursor(struct window_mode_entry *, u_int,
                     u_int);                      u_int);
Line 622 
Line 634 
         screen_write_stop(&ctx);          screen_write_stop(&ctx);
   
         if (search)          if (search)
                 window_copy_search_marks(wme, NULL);                  window_copy_search_marks(wme, NULL, 1);
         data->searchx = data->cx;          data->searchx = data->cx;
         data->searchy = data->cy;          data->searchy = data->cy;
         data->searcho = data->oy;          data->searcho = data->oy;
Line 1458 
Line 1470 
   
         if (data->searchtype == WINDOW_COPY_SEARCHUP) {          if (data->searchtype == WINDOW_COPY_SEARCHUP) {
                 for (; np != 0; np--)                  for (; np != 0; np--)
                         window_copy_search_up(wme);                          window_copy_search_up(wme, 1);
         } else if (data->searchtype == WINDOW_COPY_SEARCHDOWN) {          } else if (data->searchtype == WINDOW_COPY_SEARCHDOWN) {
                 for (; np != 0; np--)                  for (; np != 0; np--)
                         window_copy_search_down(wme);                          window_copy_search_down(wme, 1);
         }          }
         return (WINDOW_COPY_CMD_NOTHING);          return (WINDOW_COPY_CMD_NOTHING);
 }  }
Line 1475 
Line 1487 
   
         if (data->searchtype == WINDOW_COPY_SEARCHUP) {          if (data->searchtype == WINDOW_COPY_SEARCHUP) {
                 for (; np != 0; np--)                  for (; np != 0; np--)
                         window_copy_search_down(wme);                          window_copy_search_down(wme, 1);
         } else if (data->searchtype == WINDOW_COPY_SEARCHDOWN) {          } else if (data->searchtype == WINDOW_COPY_SEARCHDOWN) {
                 for (; np != 0; np--)                  for (; np != 0; np--)
                         window_copy_search_up(wme);                          window_copy_search_up(wme, 1);
         }          }
         return (WINDOW_COPY_CMD_NOTHING);          return (WINDOW_COPY_CMD_NOTHING);
 }  }
Line 1696 
Line 1708 
         if (data->searchstr != NULL) {          if (data->searchstr != NULL) {
                 data->searchtype = WINDOW_COPY_SEARCHUP;                  data->searchtype = WINDOW_COPY_SEARCHUP;
                 for (; np != 0; np--)                  for (; np != 0; np--)
                         window_copy_search_up(wme);                          window_copy_search_up(wme, 1);
         }          }
         return (WINDOW_COPY_CMD_NOTHING);          return (WINDOW_COPY_CMD_NOTHING);
 }  }
Line 1731 
Line 1743 
         if (data->searchstr != NULL) {          if (data->searchstr != NULL) {
                 data->searchtype = WINDOW_COPY_SEARCHDOWN;                  data->searchtype = WINDOW_COPY_SEARCHDOWN;
                 for (; np != 0; np--)                  for (; np != 0; np--)
                         window_copy_search_down(wme);                          window_copy_search_down(wme, 1);
         }          }
         return (WINDOW_COPY_CMD_NOTHING);          return (WINDOW_COPY_CMD_NOTHING);
 }  }
Line 1767 
Line 1779 
                 data->searchtype = WINDOW_COPY_SEARCHUP;                  data->searchtype = WINDOW_COPY_SEARCHUP;
                 free(data->searchstr);                  free(data->searchstr);
                 data->searchstr = xstrdup(argument);                  data->searchstr = xstrdup(argument);
                 if (!window_copy_search_up(wme)) {                  if (!window_copy_search_up(wme, 0)) {
                         window_copy_clear_marks(wme);                          window_copy_clear_marks(wme);
                         return (WINDOW_COPY_CMD_REDRAW);                          return (WINDOW_COPY_CMD_REDRAW);
                 }                  }
Line 1776 
Line 1788 
                 data->searchtype = WINDOW_COPY_SEARCHDOWN;                  data->searchtype = WINDOW_COPY_SEARCHDOWN;
                 free(data->searchstr);                  free(data->searchstr);
                 data->searchstr = xstrdup(argument);                  data->searchstr = xstrdup(argument);
                 if (!window_copy_search_down(wme)) {                  if (!window_copy_search_down(wme, 0)) {
                         window_copy_clear_marks(wme);                          window_copy_clear_marks(wme);
                         return (WINDOW_COPY_CMD_REDRAW);                          return (WINDOW_COPY_CMD_REDRAW);
                 }                  }
Line 1816 
Line 1828 
                 data->searchtype = WINDOW_COPY_SEARCHDOWN;                  data->searchtype = WINDOW_COPY_SEARCHDOWN;
                 free(data->searchstr);                  free(data->searchstr);
                 data->searchstr = xstrdup(argument);                  data->searchstr = xstrdup(argument);
                 if (!window_copy_search_down(wme)) {                  if (!window_copy_search_down(wme, 0)) {
                         window_copy_clear_marks(wme);                          window_copy_clear_marks(wme);
                         return (WINDOW_COPY_CMD_REDRAW);                          return (WINDOW_COPY_CMD_REDRAW);
                 }                  }
Line 1825 
Line 1837 
                 data->searchtype = WINDOW_COPY_SEARCHUP;                  data->searchtype = WINDOW_COPY_SEARCHUP;
                 free(data->searchstr);                  free(data->searchstr);
                 data->searchstr = xstrdup(argument);                  data->searchstr = xstrdup(argument);
                 if (!window_copy_search_up(wme)) {                  if (!window_copy_search_up(wme, 0)) {
                         window_copy_clear_marks(wme);                          window_copy_clear_marks(wme);
                         return (WINDOW_COPY_CMD_REDRAW);                          return (WINDOW_COPY_CMD_REDRAW);
                 }                  }
Line 2152 
Line 2164 
         return (0);          return (0);
 }  }
   
   static int
   window_copy_search_lr_regex(struct grid *gd, struct grid *sgd,
       u_int *ppx, u_int *psx, u_int py, u_int first, u_int last, int cis)
   {
           int                     cflags = REG_EXTENDED, eflags = 0;
           u_int                   endline, foundx, foundy, len, pywrap, size = 1;
           u_int                   ssize = 1;
           char                   *buf, *sbuf;
           regex_t                 reg;
           regmatch_t              regmatch;
           struct grid_line       *gl;
   
           /*
            * This can happen during search if the last match was the last
            * character on a line.
            */
           if (first >= last)
                   return (0);
   
           sbuf = xmalloc(ssize);
           sbuf[0] = '\0';
           sbuf = window_copy_stringify(sgd, 0, 0, sgd->sx, sbuf, &ssize);
           if (sbuf == NULL)
                   return (0);
   
           /* Set flags for regex search. */
           if (cis)
                   cflags |= REG_ICASE;
           if (regcomp(&reg, sbuf, cflags) != 0) {
                   free(sbuf);
                   return (0);
           }
           if (first != 0)
                   eflags |= REG_NOTBOL;
   
           /* Need to look at the entire string. */
           buf = xmalloc(size);
           buf[0] = '\0';
           buf = window_copy_stringify(gd, py, first, gd->sx, buf, &size);
           len = gd->sx - first;
           endline = gd->hsize + gd->sy - 1;
           pywrap = py;
           while (buf != NULL && pywrap <= endline) {
                   gl = grid_get_line(gd, pywrap);
                   if (~gl->flags & GRID_LINE_WRAPPED)
                           break;
                   pywrap++;
                   buf = window_copy_stringify(gd, pywrap, 0, gd->sx, buf, &size);
                   len += gd->sx;
           }
   
           if (regexec(&reg, buf, 1, &regmatch, eflags) == 0) {
                   foundx = first;
                   foundy = py;
                   window_copy_cstrtocellpos(gd, len, &foundx, &foundy,
                       buf + regmatch.rm_so);
                   if (foundy == py && foundx < last) {
                           *ppx = foundx;
                           len -= foundx - first;
                           window_copy_cstrtocellpos(gd, len, &foundx, &foundy,
                               buf + regmatch.rm_eo);
                           *psx = foundx;
                           while (foundy > py) {
                                   *psx += gd->sx;
                                   foundy--;
                           }
                           *psx -= *ppx;
                           regfree(&reg);
                           free(sbuf);
                           free(buf);
                           return (1);
                   }
           }
   
           regfree(&reg);
           free(sbuf);
           free(buf);
           *ppx = 0;
           *psx = 0;
           return (0);
   }
   
   static int
   window_copy_search_rl_regex(struct grid *gd, struct grid *sgd,
       u_int *ppx, u_int *psx, u_int py, u_int first, u_int last, int cis)
   {
           int                     cflags = REG_EXTENDED, eflags = 0;
           u_int                   endline, len, pywrap, size = 1, ssize = 1;
           char                   *buf, *sbuf;
           regex_t                 reg;
           struct grid_line       *gl;
   
           sbuf = xmalloc(ssize);
           sbuf[0] = '\0';
           sbuf = window_copy_stringify(sgd, 0, 0, sgd->sx, sbuf, &ssize);
           if (sbuf == NULL)
                   return (0);
   
           /* Set flags for regex search. */
           if (cis)
                   cflags |= REG_ICASE;
           if (regcomp(&reg, sbuf, cflags) != 0) {
                   free(sbuf);
                   return (0);
           }
           if (first != 0)
                   eflags |= REG_NOTBOL;
   
           /* Need to look at the entire string. */
           buf = xmalloc(size);
           buf[0] = '\0';
           buf = window_copy_stringify(gd, py, first, gd->sx, buf, &size);
           len = gd->sx - first;
           endline = gd->hsize + gd->sy - 1;
           pywrap = py;
           while (buf != NULL && (pywrap <= endline)) {
                   gl = grid_get_line(gd, pywrap);
                   if (~gl->flags & GRID_LINE_WRAPPED)
                           break;
                   pywrap++;
                   buf = window_copy_stringify(gd, pywrap, 0, gd->sx, buf, &size);
                   len += gd->sx;
           }
   
           if (window_copy_last_regex(gd, py, first, last, len, ppx, psx, buf,
               &reg, eflags))
           {
                   regfree(&reg);
                   free(sbuf);
                   free(buf);
                   return (1);
           }
   
           regfree(&reg);
           free(sbuf);
           free(buf);
           *ppx = 0;
           *psx = 0;
           return (0);
   }
   
   /* Find last match in given range. */
   static int
   window_copy_last_regex(struct grid *gd, u_int py, u_int first, u_int last,
       u_int len, u_int *ppx, u_int *psx, const char *buf, const regex_t *preg,
       int eflags)
   {
           u_int           foundx, foundy, oldx, px = 0, savepx, savesx = 0;
           regmatch_t      regmatch;
   
           foundx = first;
           foundy = py;
           oldx = first;
           while (regexec(preg, buf + px, 1, &regmatch, eflags) == 0) {
                   window_copy_cstrtocellpos(gd, len, &foundx, &foundy,
                       buf + px + regmatch.rm_so);
                   if (foundy > py || foundx >= last)
                           break;
                   len -= foundx - oldx;
                   savepx = foundx;
                   window_copy_cstrtocellpos(gd, len, &foundx, &foundy,
                       buf + px + regmatch.rm_eo);
                   if (foundy > py || foundx >= last) {
                           *ppx = savepx;
                           *psx = foundx;
                           while (foundy > py) {
                                   *psx += gd->sx;
                                   foundy--;
                           }
                           *psx -= *ppx;
                           return (1);
                   } else {
                           savesx = foundx - savepx;
                           len -= savesx;
                           oldx = foundx;
                   }
                   px += regmatch.rm_eo;
           }
   
           if (savesx > 0) {
                   *ppx = savepx;
                   *psx = savesx;
                   return (1);
           } else {
                   *ppx = 0;
                   *psx = 0;
                   return (0);
           }
   }
   
   /* Stringify line and append to input buffer. Caller frees. */
   static char *
   window_copy_stringify(struct grid *gd, u_int py, u_int first, u_int last,
       char *buf, u_int *size)
   {
           u_int                   ax, bx, newsize;
           struct grid_cell        gc;
   
           bx = *size - 1;
           newsize = *size;
           for (ax = first; ax < last; ax++) {
                   grid_get_cell(gd, ax, py, &gc);
                   newsize += gc.data.size;
                   buf = xrealloc(buf, newsize);
                   memcpy(buf + bx, gc.data.data, gc.data.size);
                   bx += gc.data.size;
           }
   
           buf[newsize - 1] = '\0';
           *size = newsize;
           return (buf);
   }
   
   /* Map start of C string containing UTF-8 data to grid cell position. */
 static void  static void
   window_copy_cstrtocellpos(struct grid *gd, u_int ncells, u_int *ppx, u_int *ppy,
       const char *str)
   {
           u_int                   cell, ccell, px, pywrap;
           int                     match;
           const char             *cstr;
           char                   *celldata, **cells;
           struct grid_cell        gc;
   
           /* Set up staggered array of cell contents. This speeds up search. */
           cells = xreallocarray(NULL, ncells, sizeof cells[0]);
   
           /* Populate the array of cell data. */
           cell = 0;
           px = *ppx;
           pywrap = *ppy;
           while (cell < ncells) {
                   grid_get_cell(gd, px, pywrap, &gc);
                   celldata = xmalloc(gc.data.size + 1);
                   memcpy(celldata, gc.data.data, gc.data.size);
                   celldata[gc.data.size] = '\0';
                   cells[cell] = celldata;
                   cell++;
                   px = (px + 1) % gd->sx;
                   if (px == 0)
                           pywrap++;
           }
   
           /* Locate starting cell. */
           cell = 0;
           while (cell < ncells) {
                   ccell = cell;
                   cstr = str;
                   match = 1;
                   while (ccell < ncells) {
                           /* Anchor found to the end. */
                           if (*cstr == '\0') {
                                   match = 0;
                                   break;
                           }
   
                           celldata = cells[ccell];
                           while (*celldata != '\0' && *cstr != '\0') {
                                   if (*celldata++ != *cstr++) {
                                           match = 0;
                                           break;
                                   }
                           }
   
                           if (!match)
                                   break;
                           ccell++;
                   }
   
                   if (match)
                           break;
                   cell++;
           }
   
           /* If not found this will be one past the end. */
           px = *ppx + cell;
           pywrap = *ppy;
           while (px >= gd->sx) {
                   px -= gd->sx;
                   pywrap++;
           }
   
           *ppx = px;
           *ppy = pywrap;
   
           /* Free cell data. */
           for (cell = 0; cell < ncells; cell++)
                   free(cells[cell]);
           free(cells);
   }
   
   static void
 window_copy_move_left(struct screen *s, u_int *fx, u_int *fy, int wrapflag)  window_copy_move_left(struct screen *s, u_int *fx, u_int *fy, int wrapflag)
 {  {
         if (*fx == 0) { /* left */          if (*fx == 0) { /* left */
Line 2206 
Line 2509 
 static int  static int
 window_copy_search_jump(struct window_mode_entry *wme, struct grid *gd,  window_copy_search_jump(struct window_mode_entry *wme, struct grid *gd,
     struct grid *sgd, u_int fx, u_int fy, u_int endline, int cis, int wrap,      struct grid *sgd, u_int fx, u_int fy, u_int endline, int cis, int wrap,
     int direction)      int direction, int regex)
 {  {
         u_int   i, px;          u_int   i, px, sx;
         int     found;          int     found = 0;
   
         found = 0;  
         if (direction) {          if (direction) {
                 for (i = fy; i <= endline; i++) {                  for (i = fy; i <= endline; i++) {
                         found = window_copy_search_lr(gd, sgd, &px, i, fx,                          if (regex)
                             gd->sx, cis);                                  found = window_copy_search_lr_regex(gd, sgd,
                                       &px, &sx, i, fx, gd->sx, cis);
                           else
                                   found = window_copy_search_lr(gd, sgd,
                                       &px, i, fx, gd->sx, cis);
                         if (found)                          if (found)
                                 break;                                  break;
                         fx = 0;                          fx = 0;
                 }                  }
         } else {          } else {
                 for (i = fy + 1; endline < i; i--) {                  for (i = fy + 1; endline < i; i--) {
                         found = window_copy_search_rl(gd, sgd, &px, i - 1, 0,                          if (regex)
                             fx + 1, cis);                                  found = window_copy_search_rl_regex(gd, sgd,
                                       &px, &sx, i - 1, 0, fx + 1, cis);
                           else
                                   found = window_copy_search_rl(gd, sgd,
                                       &px, i - 1, 0, fx + 1, cis);
                         if (found) {                          if (found) {
                                 i--;                                  i--;
                                 break;                                  break;
Line 2240 
Line 2550 
                 return (window_copy_search_jump(wme, gd, sgd,                  return (window_copy_search_jump(wme, gd, sgd,
                     direction ? 0 : gd->sx - 1,                      direction ? 0 : gd->sx - 1,
                     direction ? 0 : gd->hsize + gd->sy - 1, fy, cis, 0,                      direction ? 0 : gd->hsize + gd->sy - 1, fy, cis, 0,
                     direction));                      direction, regex));
         }          }
         return (0);          return (0);
 }  }
Line 2250 
Line 2560 
  * down.   * down.
  */   */
 static int  static int
 window_copy_search(struct window_mode_entry *wme, int direction)  window_copy_search(struct window_mode_entry *wme, int direction, int regex)
 {  {
         struct window_pane              *wp = wme->wp;          struct window_pane              *wp = wme->wp;
         struct window_copy_mode_data    *data = wme->data;          struct window_copy_mode_data    *data = wme->data;
Line 2281 
Line 2591 
                 window_copy_move_left(s, &fx, &fy, wrapflag);                  window_copy_move_left(s, &fx, &fy, wrapflag);
                 endline = 0;                  endline = 0;
         }          }
   
         found = window_copy_search_jump(wme, gd, ss.grid, fx, fy, endline, cis,          found = window_copy_search_jump(wme, gd, ss.grid, fx, fy, endline, cis,
             wrapflag, direction);              wrapflag, direction, regex);
   
         if (window_copy_search_marks(wme, &ss))          if (window_copy_search_marks(wme, &ss, regex))
                 window_copy_redraw_screen(wme);                  window_copy_redraw_screen(wme);
   
         screen_free(&ss);          screen_free(&ss);
Line 2292 
Line 2603 
 }  }
   
 static int  static int
 window_copy_search_marks(struct window_mode_entry *wme, struct screen *ssp)  window_copy_search_marks(struct window_mode_entry *wme, struct screen *ssp,
       int regex)
 {  {
         struct window_copy_mode_data    *data = wme->data;          struct window_copy_mode_data    *data = wme->data;
         struct screen                   *s = data->backing, ss;          struct screen                   *s = data->backing, ss;
Line 2320 
Line 2632 
         for (py = 0; py < gd->hsize + gd->sy; py++) {          for (py = 0; py < gd->hsize + gd->sy; py++) {
                 px = 0;                  px = 0;
                 for (;;) {                  for (;;) {
                         found = window_copy_search_lr(gd, ssp->grid, &px, py,                          if (regex) {
                             px, gd->sx, cis);                                  found = window_copy_search_lr_regex(gd,
                         if (!found)                                              ssp->grid, &px, &width, py, px,
                                 break;                                              gd->sx, cis);
                                   if (!found)
                                           break;
                           }
                           else {
                                   found = window_copy_search_lr(gd, ssp->grid,
                                                   &px, py, px, gd->sx, cis);
                                   if (!found)
                                           break;
                           }
   
                         nfound++;                          nfound++;
                         if (px == data->cx && py == gd->hsize + data->cy - data->oy)                          if (px == data->cx && py == gd->hsize + data->cy - data->oy)
Line 2357 
Line 2678 
 }  }
   
 static int  static int
 window_copy_search_up(struct window_mode_entry *wme)  window_copy_search_up(struct window_mode_entry *wme, int regex)
 {  {
         return (window_copy_search(wme, 0));          return (window_copy_search(wme, 0, regex));
 }  }
   
 static int  static int
 window_copy_search_down(struct window_mode_entry *wme)  window_copy_search_down(struct window_mode_entry *wme, int regex)
 {  {
         return (window_copy_search(wme, 1));          return (window_copy_search(wme, 1, regex));
 }  }
   
 static void  static void

Legend:
Removed from v.1.243  
changed lines
  Added in v.1.244