The branch, master has been updated
       via  4d1d4d6e8eb40f21eea851461ea2166242b3409f (commit)
      from  a96dd1932ad43457e710d154edccbfb08c1c2520 (commit)

- Log -----------------------------------------------------------------
commit 4d1d4d6e8eb40f21eea851461ea2166242b3409f
Author: Nicholas Marriott <nicholas.marri...@gmail.com>
Commit: Nicholas Marriott <nicholas.marri...@gmail.com>

    Add -e flag to capture-pane to include embedded ANSI SGR escape sequences, 
from
    George Nachman.
---
 cmd-capture-pane.c |   28 +++++---
 grid-view.c        |    2 +-
 grid.c             |  191 ++++++++++++++++++++++++++++++++++++++++++++++++++-
 tmux.1             |    4 +
 tmux.h             |    3 +-
 5 files changed, 210 insertions(+), 18 deletions(-)

diff --git a/cmd-capture-pane.c b/cmd-capture-pane.c
index 3c09d1c..80be016 100644
--- a/cmd-capture-pane.c
+++ b/cmd-capture-pane.c
@@ -31,8 +31,8 @@ enum cmd_retval        cmd_capture_pane_exec(struct cmd *, 
struct cmd_ctx *);
 
 const struct cmd_entry cmd_capture_pane_entry = {
        "capture-pane", "capturep",
-       "b:E:pS:t:", 0, 0,
-       "[-p] [-b buffer-index] [-E end-line] [-S start-line]"
+       "eb:E:pS:t:", 0, 0,
+       "[-ep] [-b buffer-index] [-E end-line] [-S start-line]"
        CMD_TARGET_PANE_USAGE,
        0,
        NULL,
@@ -46,12 +46,13 @@ cmd_capture_pane_exec(struct cmd *self, struct cmd_ctx *ctx)
        struct args             *args = self->args;
        struct client           *c = ctx->cmdclient;
        struct window_pane      *wp;
-       char                    *buf, *line, *cause;
+       char                    *buf, *line, *cause;
        struct screen           *s;
        struct grid             *gd;
-       int                      buffer, n;
+       int                      buffer, n, with_codes;
        u_int                    i, limit, top, bottom, tmp;
-       size_t                   len, linelen;
+       size_t                   len, linelen;
+       struct grid_cell        *gc;
 
        if (cmd_find_pane(ctx, args_get(args, 't'), NULL, &wp) == NULL)
                return (CMD_RETURN_ERROR);
@@ -89,16 +90,19 @@ cmd_capture_pane_exec(struct cmd *self, struct cmd_ctx *ctx)
                top = tmp;
        }
 
+       gc = NULL;
+       with_codes = args_has(args, 'e');
        for (i = top; i <= bottom; i++) {
-              line = grid_string_cells(s->grid, 0, i, screen_size_x(s));
-              linelen = strlen(line);
+               line = grid_string_cells(s->grid, 0, i, screen_size_x(s),
+                   &gc, with_codes);
+               linelen = strlen(line);
 
-              buf = xrealloc(buf, 1, len + linelen + 1);
-              memcpy(buf + len, line, linelen);
-              len += linelen;
-              buf[len++] = '\n';
+               buf = xrealloc(buf, 1, len + linelen + 1);
+               memcpy(buf + len, line, linelen);
+               len += linelen;
+               buf[len++] = '\n';
 
-              free(line);
+               free(line);
        }
 
        if (args_has(args, 'p')) {
diff --git a/grid-view.c b/grid-view.c
index b435541..baaddbe 100644
--- a/grid-view.c
+++ b/grid-view.c
@@ -234,5 +234,5 @@ grid_view_string_cells(struct grid *gd, u_int px, u_int py, 
u_int nx)
        px = grid_view_x(gd, px);
        py = grid_view_y(gd, py);
 
-       return (grid_string_cells(gd, px, py, nx));
+       return (grid_string_cells(gd, px, py, nx, NULL, 0));
 }
diff --git a/grid.c b/grid.c
index 3bf02ae..3c32f22 100644
--- a/grid.c
+++ b/grid.c
@@ -74,6 +74,10 @@ void grid_reflow_join(struct grid *, u_int *, struct 
grid_line *, u_int);
 void   grid_reflow_split(struct grid *, u_int *, struct grid_line *, u_int,
            u_int);
 void   grid_reflow_move(struct grid *, u_int *, struct grid_line *);
+size_t grid_string_cells_fg(const struct grid_cell *, int *);
+size_t grid_string_cells_bg(const struct grid_cell *, int *);
+void   grid_string_cells_code(const struct grid_cell *,
+           const struct grid_cell *, char *, size_t);
 
 /* Create a new grid. */
 struct grid *
@@ -392,18 +396,186 @@ grid_move_cells(struct grid *gd, u_int dx, u_int px, 
u_int py, u_int nx)
        }
 }
 
+/* Get ANSI foreground sequence. */
+size_t
+grid_string_cells_fg(const struct grid_cell *gc, int *values)
+{
+       size_t  n;
+
+       n = 0;
+       if (gc->flags & GRID_FLAG_FG256) {
+               values[n++] = 38;
+               values[n++] = 5;
+               values[n++] = gc->fg;
+       } else {
+               switch (gc->fg) {
+                       case 0:
+                       case 1:
+                       case 2:
+                       case 3:
+                       case 4:
+                       case 5:
+                       case 6:
+                       case 7:
+                               values[n++] = gc->fg + 30;
+                               break;
+                       case 8:
+                               values[n++] = 39;
+                               break;
+                       case 90:
+                       case 91:
+                       case 92:
+                       case 93:
+                       case 94:
+                       case 95:
+                       case 96:
+                       case 97:
+                               values[n++] = gc->fg;
+                               break;
+               }
+       }
+       return (n);
+}
+
+/* Get ANSI background sequence. */
+size_t
+grid_string_cells_bg(const struct grid_cell *gc, int *values)
+{
+       size_t  n;
+
+       n = 0;
+       if (gc->flags & GRID_FLAG_BG256) {
+               values[n++] = 48;
+               values[n++] = 5;
+               values[n++] = gc->bg;
+       } else {
+               switch (gc->bg) {
+               case 0:
+               case 1:
+               case 2:
+               case 3:
+               case 4:
+               case 5:
+               case 6:
+               case 7:
+                       values[n++] = gc->bg + 40;
+                       break;
+               case 8:
+                       values[n++] = 49;
+                       break;
+               case 100:
+               case 101:
+               case 102:
+               case 103:
+               case 104:
+                       case 105:
+               case 106:
+               case 107:
+                       values[n++] = gc->bg - 10;
+                       break;
+               }
+       }
+       return (n);
+}
+
+/*
+ * Returns ANSI code to set particular attributes (colour, bold and so on)
+ * given a current state. The output buffer must be able to hold at least 57
+ * bytes.
+ */
+void
+grid_string_cells_code(const struct grid_cell *lastgc,
+    const struct grid_cell *gc, char *buf, size_t len)
+{
+       int     oldc[16], newc[16], s[32];
+       size_t  noldc, nnewc, n, i;
+       u_int   attr = gc->attr;
+       u_int   lastattr = lastgc->attr;
+       char    tmp[64];
+
+       struct {
+               u_int   mask;
+               u_int   code;
+       } attrs[] = {
+               { GRID_ATTR_BRIGHT, 1 },
+               { GRID_ATTR_DIM, 2 },
+               { GRID_ATTR_ITALICS, 3 },
+               { GRID_ATTR_UNDERSCORE, 4 },
+               { GRID_ATTR_BLINK, 5 },
+               { GRID_ATTR_REVERSE, 7 },
+               { GRID_ATTR_HIDDEN, 8 }
+       };
+       n = 0;
+
+       /* If any attribute is removed, begin with 0. */
+       for (i = 0; i < nitems(attrs); i++) {
+               if (!(attr & attrs[i].mask) && (lastattr & attrs[i].mask)) {
+                       s[n++] = 0;
+                       break;
+               }
+       }
+       /* For each attribute that is newly set, add its code. */
+       for (i = 0; i < nitems(attrs); i++) {
+               if ((attr & attrs[i].mask) && !(lastattr & attrs[i].mask))
+                       s[n++] = attrs[i].code;
+       }
+
+       /* If the foreground c changed, append its parameters. */
+       nnewc = grid_string_cells_fg(gc, newc);
+       noldc = grid_string_cells_fg(lastgc, oldc);
+       if (nnewc != noldc || memcmp(newc, oldc, nnewc * sizeof newc[0]) != 0) {
+               for (i = 0; i < nnewc; i++)
+                       s[n++] = newc[i];
+       }
+
+       /* If the background c changed, append its parameters. */
+       nnewc = grid_string_cells_bg(gc, newc);
+       noldc = grid_string_cells_bg(lastgc, oldc);
+       if (nnewc != noldc || memcmp(newc, oldc, nnewc * sizeof newc[0]) != 0) {
+               for (i = 0; i < nnewc; i++)
+                       s[n++] = newc[i];
+       }
+
+       /* If there are any parameters, append an SGR code. */
+       *buf = '\0';
+       if (n > 0) {
+               strlcat(buf, "\033[", len);
+               for (i = 0; i < n; i++) {
+                       if (i + 1 < n)
+                               xsnprintf(tmp, sizeof tmp, "%d;", s[i]);
+                       else
+                               xsnprintf(tmp, sizeof tmp, "%d", s[i]);
+                       strlcat(buf, tmp, len);
+               }
+               strlcat(buf, "m", len);
+       }
+
+       /* Append shift in/shift out if needed. */
+       if ((attr & GRID_ATTR_CHARSET) && !(lastattr & GRID_ATTR_CHARSET))
+               strlcat(buf, "\016", len);  /* SO */
+       if (!(attr & GRID_ATTR_CHARSET) && (lastattr & GRID_ATTR_CHARSET))
+               strlcat(buf, "\017", len);  /* SI */
+}
+
 /* Convert cells into a string. */
 char *
-grid_string_cells(struct grid *gd, u_int px, u_int py, u_int nx)
+grid_string_cells(struct grid *gd, u_int px, u_int py, u_int nx,
+    struct grid_cell **lastgc, int with_codes)
 {
        const struct grid_cell  *gc;
+       static struct grid_cell  lastgc1;
        struct utf8_data         ud;
-       char                    *buf;
-       size_t                   len, off;
+       char                    *buf, code[128];
+       size_t                   len, off, codelen;
        u_int                    xx;
 
        GRID_DEBUG(gd, "px=%u, py=%u, nx=%u", px, py, nx);
 
+       if (*lastgc == NULL) {
+               memcpy(&lastgc1, &grid_default_cell, sizeof lastgc1);
+               *lastgc = &lastgc1;
+       }
+
        len = 128;
        buf = xmalloc(len);
        off = 0;
@@ -414,11 +586,22 @@ grid_string_cells(struct grid *gd, u_int px, u_int py, 
u_int nx)
                        continue;
                grid_cell_get(gc, &ud);
 
-               while (len < off + ud.size + 1) {
+               if (with_codes) {
+                       grid_string_cells_code(*lastgc, gc, code, sizeof code);
+                       codelen = strlen(code);
+                       memcpy(*lastgc, gc, sizeof *gc);
+               } else
+                       codelen = 0;
+
+               while (len < off + ud.size + codelen + 1) {
                        buf = xrealloc(buf, 2, len);
                        len *= 2;
                }
 
+               if (codelen != 0) {
+                       memcpy(buf + off, code, codelen);
+                       off += codelen;
+               }
                memcpy(buf + off, ud.data, ud.size);
                off += ud.size;
        }
diff --git a/tmux.1 b/tmux.1
index 98561f9..c1380ff 100644
--- a/tmux.1
+++ b/tmux.1
@@ -1040,6 +1040,7 @@ By default, it uses the format
 but a different format may be specified with
 .Fl F .
 .It Xo Ic capture-pane
+.Op Fl e
 .Op Fl p
 .Op Fl b Ar buffer-index
 .Op Fl E Ar end-line
@@ -1053,6 +1054,9 @@ If
 is given, the output goes to stdout, otherwise to the buffer specified with
 .Fl b
 or a new buffer if omitted.
+If
+.Fl e
+is given, the output includes escape sequences for text and background 
attributes.
 .Pp
 .Fl S
 and
diff --git a/tmux.h b/tmux.h
index df47cdb..8b3d4e1 100644
--- a/tmux.h
+++ b/tmux.h
@@ -1973,7 +1973,8 @@ void       grid_clear(struct grid *, u_int, u_int, u_int, 
u_int);
 void    grid_clear_lines(struct grid *, u_int, u_int);
 void    grid_move_lines(struct grid *, u_int, u_int, u_int);
 void    grid_move_cells(struct grid *, u_int, u_int, u_int, u_int);
-char   *grid_string_cells(struct grid *, u_int, u_int, u_int);
+char   *grid_string_cells(struct grid *, u_int, u_int, u_int,
+            struct grid_cell **, int);
 void    grid_duplicate_lines(
             struct grid *, u_int, struct grid *, u_int, u_int);
 u_int   grid_reflow(struct grid *, struct grid *, u_int);


-----------------------------------------------------------------------

Summary of changes:
 cmd-capture-pane.c |   28 +++++---
 grid-view.c        |    2 +-
 grid.c             |  191 ++++++++++++++++++++++++++++++++++++++++++++++++++-
 tmux.1             |    4 +
 tmux.h             |    3 +-
 5 files changed, 210 insertions(+), 18 deletions(-)


hooks/post-receive
-- 
tmux

------------------------------------------------------------------------------
Everyone hates slow websites. So do we.
Make your web apps faster with AppDynamics
Download AppDynamics Lite for free today:
http://p.sf.net/sfu/appdyn_d2d_feb
_______________________________________________
tmux-cvs mailing list
tmux-cvs@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/tmux-cvs

Reply via email to