Merge branch 'obsd-master'

This commit is contained in:
Thomas Adam
2026-07-02 10:15:06 +01:00
5 changed files with 197 additions and 5 deletions

View File

@@ -45,7 +45,7 @@ attributes_tostring(int attr)
(attr & GRID_ATTR_UNDERSCORE_3) ? "curly-underscore," : "", (attr & GRID_ATTR_UNDERSCORE_3) ? "curly-underscore," : "",
(attr & GRID_ATTR_UNDERSCORE_4) ? "dotted-underscore," : "", (attr & GRID_ATTR_UNDERSCORE_4) ? "dotted-underscore," : "",
(attr & GRID_ATTR_UNDERSCORE_5) ? "dashed-underscore," : "", (attr & GRID_ATTR_UNDERSCORE_5) ? "dashed-underscore," : "",
(attr & GRID_ATTR_OVERLINE) ? "overline," : "", (attr & GRID_ATTR_OVERLINE) ? "overline," : "",
(attr & GRID_ATTR_NOATTR) ? "noattr," : ""); (attr & GRID_ATTR_NOATTR) ? "noattr," : "");
if (len > 0) if (len > 0)
buf[len - 1] = '\0'; buf[len - 1] = '\0';

View File

@@ -20,6 +20,7 @@
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <vis.h>
#include "tmux.h" #include "tmux.h"
@@ -42,8 +43,8 @@ const struct cmd_entry cmd_capture_pane_entry = {
.name = "capture-pane", .name = "capture-pane",
.alias = "capturep", .alias = "capturep",
.args = { "ab:CeE:FHJLMNpPqS:Tt:", 0, 0, NULL }, .args = { "ab:CeE:FHJLMNpPqRS:Tt:", 0, 0, NULL },
.usage = "[-aCeFHJLMNpPqT] " CMD_BUFFER_USAGE " [-E end-line] " .usage = "[-aCeFHJLMNpPqRT] " CMD_BUFFER_USAGE " [-E end-line] "
"[-S start-line] " CMD_TARGET_PANE_USAGE, "[-S start-line] " CMD_TARGET_PANE_USAGE,
.target = { 't', CMD_FIND_PANE, 0 }, .target = { 't', CMD_FIND_PANE, 0 },
@@ -75,6 +76,95 @@ cmd_capture_pane_append(char *buf, size_t *len, const char *line,
return (buf); return (buf);
} }
static char *
cmd_capture_pane_cell(struct screen *s, u_int xx, u_int yy)
{
struct grid *gd = s->grid;
struct hyperlinks *hl = s->hyperlinks;
struct grid_cell gc;
char *line, *data, *tmp, *link, *linkid, *f, *b, *u;
const char *uri, *iid;
u_int flags;
grid_get_cell(gd, xx, yy, &gc);
tmp = utf8_tocstr(&gc.data);
utf8_stravis(&data, tmp, VIS_OCTAL|VIS_CSTYLE|VIS_TAB|VIS_NL);
free(tmp);
if (gc.link != 0 && hyperlinks_get(hl, gc.link, &uri, &iid, NULL)) {
xasprintf(&link, "%s", uri);
if (iid != NULL && *iid != '\0')
xasprintf(&linkid, "%s", iid);
else
xasprintf(&linkid, "NONE");
} else {
xasprintf(&link, "NONE");
xasprintf(&linkid, "NONE");
}
flags = gc.flags;
if (gc.fg & COLOUR_FLAG_256)
flags |= GRID_FLAG_FG256;
if (gc.bg & COLOUR_FLAG_256)
flags |= GRID_FLAG_BG256;
xasprintf(&f, "%s[%x]", colour_tostring(gc.fg), gc.fg);
xasprintf(&b, "%s[%x]", colour_tostring(gc.bg), gc.bg);
xasprintf(&u, "%s[%x]", colour_tostring(gc.us), gc.us);
xasprintf(&line, "\t\tC %u,%u data=(%u,%u,%s) flags=%s[%x] "
"attr=%s[%x] fg=%s bg=%s us=%s link=%s linkid=%s\n",
yy, xx, gc.data.width, gc.data.size, data,
grid_cell_flags_string(flags), flags,
grid_cell_attr_string(gc.attr), gc.attr, f, b, u, link, linkid);
free(f);
free(b);
free(u);
free(link);
free(linkid);
free(data);
return (line);
}
static char *
cmd_capture_pane_grid(struct window_pane *wp, size_t *len)
{
struct screen *s = &wp->base;
struct grid *gd = s->grid;
struct grid_line *gl;
char *buf = xstrdup(""), *line;
char p[11];
u_int yy, xx, total = gd->hsize + gd->sy;
xasprintf(&line, "G %ux%u (%u/%u)\n", gd->sx, gd->sy, gd->hsize,
gd->hlimit);
buf = cmd_capture_pane_append(buf, len, line, strlen(line));
free(line);
for (yy = 0; yy < total; yy++) {
gl = grid_get_line(gd, yy);
if (yy < gd->hsize)
snprintf(p, sizeof p, "-");
else
snprintf(p, sizeof p, "%u", yy - gd->hsize);
xasprintf(&line, "\tL %u (%s) flags=%s[%x] %u/%u\n", yy,
p, grid_line_flags_string(gl->flags), gl->flags,
gl->cellused, gl->cellsize);
buf = cmd_capture_pane_append(buf, len, line, strlen(line));
free(line);
for (xx = 0; xx < gd->sx; xx++) {
line = cmd_capture_pane_cell(s, xx, yy);
buf = cmd_capture_pane_append(buf, len, line,
strlen(line));
free(line);
}
}
return (buf);
}
static char * static char *
cmd_capture_pane_pending(struct args *args, struct window_pane *wp, cmd_capture_pane_pending(struct args *args, struct window_pane *wp,
size_t *len) size_t *len)
@@ -323,7 +413,9 @@ cmd_capture_pane_exec(struct cmd *self, struct cmdq_item *item)
} }
len = 0; len = 0;
if (args_has(args, 'P') && !args_has(args, 'H')) if (args_has(args, 'R'))
buf = cmd_capture_pane_grid(wp, &len);
else if (args_has(args, 'P') && !args_has(args, 'H'))
buf = cmd_capture_pane_pending(args, wp, &len); buf = cmd_capture_pane_pending(args, wp, &len);
else else
buf = cmd_capture_pane_history(args, item, wp, &len); buf = cmd_capture_pane_history(args, item, wp, &len);

95
grid.c
View File

@@ -1712,3 +1712,98 @@ grid_in_set(struct grid *gd, u_int px, u_int py, const char *set)
return (0); return (0);
return (utf8_cstrhas(set, &gc.data)); return (utf8_cstrhas(set, &gc.data));
} }
/* Line flags to string. */
const char *
grid_line_flags_string(int flags)
{
static char s[128];
*s = '\0';
if (flags & GRID_LINE_WRAPPED)
strlcat(s, "WRAPPED,", sizeof s);
if (flags & GRID_LINE_EXTENDED)
strlcat(s, "EXTENDED,", sizeof s);
if (flags & GRID_LINE_DEAD)
strlcat(s, "DEAD,", sizeof s);
if (flags & GRID_LINE_START_PROMPT)
strlcat(s, "START_PROMPT,", sizeof s);
if (flags & GRID_LINE_START_OUTPUT)
strlcat(s, "START_OUTPUT,", sizeof s);
if (flags & GRID_LINE_HYPERLINK)
strlcat(s, "HYPERLINK,", sizeof s);
if (*s == '\0')
return ("NONE");
s[strlen(s) - 1] = '\0';
return (s);
}
/* Cell flags to string. */
const char *
grid_cell_flags_string(int flags)
{
static char s[128];
*s = '\0';
if (flags & GRID_FLAG_FG256)
strlcat(s, "FG256,", sizeof s);
if (flags & GRID_FLAG_BG256)
strlcat(s, "BG256,", sizeof s);
if (flags & GRID_FLAG_PADDING)
strlcat(s, "PADDING,", sizeof s);
if (flags & GRID_FLAG_EXTENDED)
strlcat(s, "EXTENDED,", sizeof s);
if (flags & GRID_FLAG_SELECTED)
strlcat(s, "SELECTED,", sizeof s);
if (flags & GRID_FLAG_CLEARED)
strlcat(s, "CLEARED,", sizeof s);
if (flags & GRID_FLAG_TAB)
strlcat(s, "TAB,", sizeof s);
if (flags & GRID_FLAG_NOPALETTE)
strlcat(s, "NOPALETTE,", sizeof s);
if (*s == '\0')
return ("NONE");
s[strlen(s) - 1] = '\0';
return (s);
}
/* Cell attributes to string. */
const char *
grid_cell_attr_string(int attr)
{
static char s[256];
*s = '\0';
if (attr & GRID_ATTR_CHARSET)
strlcat(s, "CHARSET,", sizeof s);
if (attr & GRID_ATTR_BRIGHT)
strlcat(s, "BRIGHT,", sizeof s);
if (attr & GRID_ATTR_DIM)
strlcat(s, "DIM,", sizeof s);
if (attr & GRID_ATTR_UNDERSCORE)
strlcat(s, "UNDERSCORE,", sizeof s);
if (attr & GRID_ATTR_BLINK)
strlcat(s, "BLINK,", sizeof s);
if (attr & GRID_ATTR_REVERSE)
strlcat(s, "REVERSE,", sizeof s);
if (attr & GRID_ATTR_HIDDEN)
strlcat(s, "HIDDEN,", sizeof s);
if (attr & GRID_ATTR_ITALICS)
strlcat(s, "ITALICS,", sizeof s);
if (attr & GRID_ATTR_STRIKETHROUGH)
strlcat(s, "STRIKETHROUGH,", sizeof s);
if (attr & GRID_ATTR_UNDERSCORE_2)
strlcat(s, "UNDERSCORE_2,", sizeof s);
if (attr & GRID_ATTR_UNDERSCORE_3)
strlcat(s, "UNDERSCORE_3,", sizeof s);
if (attr & GRID_ATTR_UNDERSCORE_4)
strlcat(s, "UNDERSCORE_4,", sizeof s);
if (attr & GRID_ATTR_UNDERSCORE_5)
strlcat(s, "UNDERSCORE_5,", sizeof s);
if (attr & GRID_ATTR_OVERLINE)
strlcat(s, "OVERLINE,", sizeof s);
if (*s == '\0')
return ("NONE");
s[strlen(s) - 1] = '\0';
return (s);
}

4
tmux.1
View File

@@ -2770,7 +2770,7 @@ The pane must not already be floating or hidden, and the window must not
be zoomed. be zoomed.
.Tg capturep .Tg capturep
.It Xo Ic capture\-pane .It Xo Ic capture\-pane
.Op Fl aeFHLpPqCJMN .Op Fl aeFHLpPRqCJMN
.Op Fl b Ar buffer\-name .Op Fl b Ar buffer\-name
.Op Fl E Ar end\-line .Op Fl E Ar end\-line
.Op Fl S Ar start\-line .Op Fl S Ar start\-line
@@ -2830,6 +2830,8 @@ With
.Fl H , .Fl H ,
only hyperlinks in the specified lines are captured. only hyperlinks in the specified lines are captured.
Multiple hyperlinks on the same line are separated by spaces. Multiple hyperlinks on the same line are separated by spaces.
.Fl R
dumps the internal grid data for diagnostics.
.Pp .Pp
.Fl S .Fl S
and and

3
tmux.h
View File

@@ -3337,6 +3337,9 @@ struct grid *grid_create(u_int, u_int, u_int);
void grid_destroy(struct grid *); void grid_destroy(struct grid *);
void grid_free_lines(struct grid *, u_int, u_int); void grid_free_lines(struct grid *, u_int, u_int);
int grid_compare(struct grid *, struct grid *); int grid_compare(struct grid *, struct grid *);
const char *grid_line_flags_string(int);
const char *grid_cell_flags_string(int);
const char *grid_cell_attr_string(int);
void grid_collect_history(struct grid *, int); void grid_collect_history(struct grid *, int);
void grid_remove_history(struct grid *, u_int ); void grid_remove_history(struct grid *, u_int );
void grid_scroll_history(struct grid *, u_int); void grid_scroll_history(struct grid *, u_int);