diff --git a/cmd-capture-pane.c b/cmd-capture-pane.c index 83ec303c..fd65e093 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", - "eb:E:pS:t:", 0, 0, - "[-ep] [-b buffer-index] [-E end-line] [-S start-line]" + "b:CeE:JpS:t:", 0, 0, + "[-CeJp] [-b buffer-index] [-E end-line] [-S start-line]" CMD_TARGET_PANE_USAGE, 0, NULL, @@ -49,10 +49,11 @@ cmd_capture_pane_exec(struct cmd *self, struct cmd_ctx *ctx) char *buf, *line, *cause; struct screen *s; struct grid *gd; - int buffer, n, with_codes; + int buffer, n, with_codes, escape_c0, join_lines; u_int i, limit, top, bottom, tmp; size_t len, linelen; struct grid_cell *gc; + const struct grid_line *gl; if (cmd_find_pane(ctx, args_get(args, 't'), NULL, &wp) == NULL) return (CMD_RETURN_ERROR); @@ -90,17 +91,23 @@ cmd_capture_pane_exec(struct cmd *self, struct cmd_ctx *ctx) top = tmp; } - gc = NULL; with_codes = args_has(args, 'e'); + escape_c0 = args_has(args, 'C'); + join_lines = args_has(args, 'J'); + + gc = NULL; for (i = top; i <= bottom; i++) { line = grid_string_cells(s->grid, 0, i, screen_size_x(s), - &gc, with_codes); + &gc, with_codes, escape_c0); linelen = strlen(line); buf = xrealloc(buf, 1, len + linelen + 1); memcpy(buf + len, line, linelen); len += linelen; - buf[len++] = '\n'; + + gl = grid_peek_line(s->grid, i); + if (!join_lines || !(gl->flags & GRID_LINE_WRAPPED)) + buf[len++] = '\n'; free(line); } diff --git a/grid-view.c b/grid-view.c index baaddbe0..3c5a8728 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, NULL, 0)); + return (grid_string_cells(gd, px, py, nx, NULL, 0, 0)); } diff --git a/grid.c b/grid.c index 71778224..d4164142 100644 --- a/grid.c +++ b/grid.c @@ -77,7 +77,7 @@ 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); + const struct grid_cell *, char *, size_t, int); /* Create a new grid. */ struct grid * @@ -234,6 +234,15 @@ grid_expand_line(struct grid *gd, u_int py, u_int sx) gl->cellsize = sx; } +/* Peek at grid line. */ +const struct grid_line * +grid_peek_line(struct grid *gd, u_int py) +{ + if (grid_check_y(gd, py) != 0) + return (NULL); + return (&gd->linedata[py]); +} + /* Get cell for reading. */ const struct grid_cell * grid_peek_cell(struct grid *gd, u_int px, u_int py) @@ -485,7 +494,7 @@ grid_string_cells_bg(const struct grid_cell *gc, int *values) */ void grid_string_cells_code(const struct grid_cell *lastgc, - const struct grid_cell *gc, char *buf, size_t len) + const struct grid_cell *gc, char *buf, size_t len, int escape_c0) { int oldc[16], newc[16], s[32]; size_t noldc, nnewc, n, i; @@ -542,7 +551,10 @@ grid_string_cells_code(const struct grid_cell *lastgc, /* If there are any parameters, append an SGR code. */ *buf = '\0'; if (n > 0) { - strlcat(buf, "\033[", len); + if (escape_c0) + strlcat(buf, "\\033[", len); + else + strlcat(buf, "\033[", len); for (i = 0; i < n; i++) { if (i + 1 < n) xsnprintf(tmp, sizeof tmp, "%d;", s[i]); @@ -554,22 +566,31 @@ grid_string_cells_code(const struct grid_cell *lastgc, } /* 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 */ + if ((attr & GRID_ATTR_CHARSET) && !(lastattr & GRID_ATTR_CHARSET)) { + if (escape_c0) + strlcat(buf, "\\016", len); /* SO */ + else + strlcat(buf, "\016", len); /* SO */ + } + if (!(attr & GRID_ATTR_CHARSET) && (lastattr & GRID_ATTR_CHARSET)) { + if (escape_c0) + strlcat(buf, "\\017", len); /* SI */ + else + 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, - struct grid_cell **lastgc, int with_codes) + struct grid_cell **lastgc, int with_codes, int escape_c0) { const struct grid_cell *gc; static struct grid_cell lastgc1; struct utf8_data ud; + const char* data; char *buf, code[128]; - size_t len, off, codelen; + size_t len, off, size, codelen; u_int xx; GRID_DEBUG(gd, "px=%u, py=%u, nx=%u", px, py, nx); @@ -590,13 +611,21 @@ grid_string_cells(struct grid *gd, u_int px, u_int py, u_int nx, grid_cell_get(gc, &ud); if (with_codes) { - grid_string_cells_code(*lastgc, gc, code, sizeof code); + grid_string_cells_code(*lastgc, gc, code, sizeof code, + escape_c0); codelen = strlen(code); memcpy(*lastgc, gc, sizeof *gc); } else codelen = 0; - while (len < off + ud.size + codelen + 1) { + data = ud.data; + size = ud.size; + if (escape_c0 && size == 1 && *data == '\\') { + data = "\\"; + size = 2; + } + + while (len < off + size + codelen + 1) { buf = xrealloc(buf, 2, len); len *= 2; } @@ -605,13 +634,14 @@ grid_string_cells(struct grid *gd, u_int px, u_int py, u_int nx, memcpy(buf + off, code, codelen); off += codelen; } - memcpy(buf + off, ud.data, ud.size); - off += ud.size; + memcpy(buf + off, data, size); + off += size; } while (off > 0 && buf[off - 1] == ' ') off--; buf[off] = '\0'; + return (buf); } diff --git a/tmux.1 b/tmux.1 index fcca0924..7d5eb5a8 100644 --- a/tmux.1 +++ b/tmux.1 @@ -1067,7 +1067,12 @@ is given, the output goes to stdout, otherwise to the buffer specified with or a new buffer if omitted. If .Fl e -is given, the output includes escape sequences for text and background attributes. +is given, the output includes escape sequences for text and background +attributes. +.Fl C +also escapes non-printable characters as octal \\xxx. +.Fl J +joins wrapped lines. .Pp .Fl S and diff --git a/tmux.h b/tmux.h index 8772175a..4fd62d30 100644 --- a/tmux.h +++ b/tmux.h @@ -1969,6 +1969,7 @@ void grid_scroll_history(struct grid *); void grid_scroll_history_region(struct grid *, u_int, u_int); void grid_expand_line(struct grid *, u_int, u_int); const struct grid_cell *grid_peek_cell(struct grid *, u_int, u_int); +const struct grid_line *grid_peek_line(struct grid *, u_int); struct grid_cell *grid_get_cell(struct grid *, u_int, u_int); void grid_set_cell(struct grid *, u_int, u_int, const struct grid_cell *); void grid_clear(struct grid *, u_int, u_int, u_int, u_int); @@ -1976,7 +1977,7 @@ 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, - struct grid_cell **, int); + struct grid_cell **, int, 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);