Merge remote-tracking branch 'refs/remotes/tmux-openbsd/master'

* refs/remotes/tmux-openbsd/master:
  Add commands to copy mode to select, pipe and open OSC 133 command output, from Michael Grant.
  Fix bugs with empty panes and load-buffer -w, GitHub issue 5701 from Alexandre Fiori.
  Track allocations in yacc to avoid leaking when parsing commands, GitHub issue 5632 from Jeong, Heon.
  Fix commands being lost when chained with assignment, GitHub issue 5702 from Jeong, Heon
This commit is contained in:
Nicholas Marriott
2026-10-08 16:36:34 +01:00
13 changed files with 980 additions and 159 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>
@@ -1347,12 +1347,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;
@@ -1383,13 +1431,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;
}
@@ -1416,6 +1471,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++;
/*
@@ -1486,6 +1543,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;
@@ -1493,6 +1558,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;
@@ -1504,11 +1571,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. */