Add commands to copy mode to select, pipe and open OSC 133 command

output, from Michael Grant.
This commit is contained in:
nicm
2026-10-08 07:50:05 +00:00
committed by tmux update bot
parent cb44afd415
commit a0a0e12234
10 changed files with 744 additions and 54 deletions

81
grid.c
View File

@@ -1,4 +1,4 @@
/* $OpenBSD: grid.c,v 1.158 2026/09/01 12:49:49 nicm Exp $ */
/* $OpenBSD: grid.c,v 1.159 2026/10/08 07:50:05 nicm Exp $ */
/*
* Copyright (c) 2008 Nicholas Marriott <nicholas.marriott@gmail.com>
@@ -1296,12 +1296,60 @@ grid_reflow_move(struct grid *gd, struct grid_line *from)
return (to);
}
/* Move the OSC 133 markers from one line to another. */
static void
grid_reflow_move_osc133(struct grid_line *to, struct grid_line *from,
u_int to_col, u_int count, int last)
{
struct osc133_data *src = &from->osc133_data;
struct osc133_data *dst = &to->osc133_data;
u_short *src_col[] = {
&src->prompt_col,
&src->cmd_col,
&src->out_start_col,
&src->out_end_col
};
u_short *dst_col[] = {
&dst->prompt_col,
&dst->cmd_col,
&dst->out_start_col,
&dst->out_end_col
};
u_int flags[] = {
GRID_LINE_START_PROMPT|GRID_LINE_SECOND_PROMPT,
GRID_LINE_START_COMMAND,
GRID_LINE_START_OUTPUT,
GRID_LINE_END_OUTPUT
};
u_int i, flag;
if ((from->flags & GRID_LINE_OSC133_FLAGS) == 0)
return;
for (i = 0; i < nitems(flags); i++) {
flag = from->flags & flags[i];
if (flag == 0)
continue;
if (!last && *src_col[i] >= count) {
*src_col[i] -= count;
continue;
}
*dst_col[i] = to_col + *src_col[i];
to->flags |= flag;
from->flags &= ~flag;
*src_col[i] = 0;
if (flag == GRID_LINE_END_OUTPUT) {
dst->exit_status = src->exit_status;
src->exit_status = 0;
}
}
}
/* Join line below onto this one. */
static void
grid_reflow_join(struct grid *target, struct grid *gd, u_int sx, u_int yy,
u_int width, int already)
{
struct grid_line *gl, *from = NULL;
struct grid_line *gl, *from = NULL, *next;
struct grid_cell gc;
u_int lines, left, i, to, line, want = 0;
u_int at;
@@ -1332,13 +1380,20 @@ grid_reflow_join(struct grid *target, struct grid *gd, u_int sx, u_int yy,
break;
line = yy + 1 + lines;
/* If the next line is empty, skip it. */
/* Consume empty lines, including any markers. */
if (~gd->linedata[line].flags & GRID_LINE_WRAPPED)
wrapped = 0;
if (gd->linedata[line].cellused == 0) {
next = &gd->linedata[line];
if (!wrapped &&
(next->flags & GRID_LINE_OSC133_FLAGS) == 0)
break;
from = next;
want = 0;
grid_reflow_move_osc133(gl, from, at, 0, 1);
lines++;
if (!wrapped)
break;
lines++;
continue;
}
@@ -1365,6 +1420,8 @@ grid_reflow_join(struct grid *target, struct grid *gd, u_int sx, u_int yy,
grid_set_cell(target, at, to, &gc);
at++;
}
grid_reflow_move_osc133(gl, from, at - want, want,
want == from->cellused);
lines++;
/*
@@ -1435,6 +1492,14 @@ grid_reflow_split(struct grid *target, struct grid *gd, u_int sx, u_int yy,
line = target->sy + 1;
first = grid_reflow_add(target, lines);
/* The first line keeps only the markers within its first at cells. */
memcpy(first, gl, sizeof *first);
first->cellsize = first->cellused = at;
first->flags &= ~GRID_LINE_OSC133_FLAGS;
first->flags |= GRID_LINE_WRAPPED;
memset(&first->osc133_data, 0, sizeof first->osc133_data);
grid_reflow_move_osc133(first, gl, 0, at, 0);
/* Copy sections from the original line. */
width = 0;
xx = 0;
@@ -1442,6 +1507,8 @@ grid_reflow_split(struct grid *target, struct grid *gd, u_int sx, u_int yy,
grid_get_cell1(gl, i, &gc);
if (width + gc.data.width > sx) {
target->linedata[line].flags |= GRID_LINE_WRAPPED;
grid_reflow_move_osc133(&target->linedata[line], gl, 0,
xx, 0);
line++;
width = 0;
@@ -1453,11 +1520,7 @@ grid_reflow_split(struct grid *target, struct grid *gd, u_int sx, u_int yy,
}
if (flags & GRID_LINE_WRAPPED)
target->linedata[line].flags |= GRID_LINE_WRAPPED;
/* Move the remainder of the original line. */
gl->cellsize = gl->cellused = at;
gl->flags |= GRID_LINE_WRAPPED;
memcpy(first, gl, sizeof *first);
grid_reflow_move_osc133(&target->linedata[line], gl, 0, xx, 1);
grid_reflow_dead(gl);
/* Adjust the scroll position. */