mirror of
https://github.com/tmux/tmux.git
synced 2026-10-06 17:49:52 +00:00
More cleanup.
This commit is contained in:
30
input.c
30
input.c
@@ -3199,6 +3199,7 @@ input_osc_133_save_marker(struct window_pane *wp, struct screen *s)
|
||||
{
|
||||
struct grid *gd = s->grid;
|
||||
struct grid_line *gl;
|
||||
struct osc133_data *od;
|
||||
struct input_osc_133_ctx ctx = {0};
|
||||
u_int y;
|
||||
|
||||
@@ -3210,16 +3211,21 @@ input_osc_133_save_marker(struct window_pane *wp, struct screen *s)
|
||||
ctx.collected = gd->scroll_collected;
|
||||
for (y = gd->hsize + gd->sy; y > 0; y--) {
|
||||
gl = grid_get_line(gd, y - 1);
|
||||
if ((gl->flags & GRID_LINE_START_OUTPUT) &&
|
||||
(~gl->flags & GRID_LINE_END_OUTPUT ||
|
||||
gl->osc133_data.out_end_col < gl->osc133_data.out_start_col) &&
|
||||
(~gl->flags & GRID_LINE_START_PROMPT ||
|
||||
gl->osc133_data.prompt_col <= gl->osc133_data.out_start_col)) {
|
||||
ctx.start = y - 1;
|
||||
ctx.col = gl->osc133_data.out_start_col;
|
||||
if (~gl->flags & GRID_LINE_START_OUTPUT) {
|
||||
if (gl->flags &
|
||||
(GRID_LINE_START_PROMPT|GRID_LINE_END_OUTPUT))
|
||||
break;
|
||||
continue;
|
||||
}
|
||||
if (gl->flags & (GRID_LINE_START_PROMPT|GRID_LINE_END_OUTPUT))
|
||||
od = &gl->osc133_data;
|
||||
if ((gl->flags & GRID_LINE_END_OUTPUT) &&
|
||||
od->out_end_col >= od->out_start_col)
|
||||
break;
|
||||
if ((gl->flags & GRID_LINE_START_PROMPT) &&
|
||||
od->prompt_col > od->out_start_col)
|
||||
break;
|
||||
ctx.start = y - 1;
|
||||
ctx.col = od->out_start_col;
|
||||
break;
|
||||
}
|
||||
return (ctx);
|
||||
@@ -3252,9 +3258,8 @@ input_osc_133_restore_marker(struct screen *s,
|
||||
static int
|
||||
input_osc_133_exit_status(const char *p, int *present)
|
||||
{
|
||||
const char *end;
|
||||
const char *end, *errstr;
|
||||
char *copy;
|
||||
char *endptr;
|
||||
long long status;
|
||||
|
||||
*present = 0;
|
||||
@@ -3272,10 +3277,9 @@ input_osc_133_exit_status(const char *p, int *present)
|
||||
return (0);
|
||||
}
|
||||
*present = 1;
|
||||
errno = 0;
|
||||
status = (int)strtol(copy, &endptr, 10);
|
||||
status = strtonum(copy, 0, 255, &errstr);
|
||||
free(copy);
|
||||
if (errno != 0 || endptr == copy || status < 0 || status > 255)
|
||||
if (errstr != NULL)
|
||||
return (255);
|
||||
return (status);
|
||||
}
|
||||
|
||||
@@ -115,6 +115,7 @@ static const char *options_table_theme_list[] = {
|
||||
static const char *options_table_copy_mode_line_numbers_list[] = {
|
||||
"off", "default", "absolute", "relative", "hybrid", NULL
|
||||
};
|
||||
|
||||
/* Status line format. */
|
||||
#define OPTIONS_TABLE_STATUS_FORMAT1 \
|
||||
"#[align=left range=left #{E:status-left-style}]" \
|
||||
|
||||
@@ -84,7 +84,7 @@ check_grep " 3 !- p\$ two"
|
||||
|
||||
# A format wider than the standard three-column gutter is not truncated.
|
||||
$TMUX2 send -X cancel || exit 1
|
||||
$TMUX2 set -g copy-mode-exit-status-format \
|
||||
$TMUX2 set -p copy-mode-exit-status-format \
|
||||
'#[align=right]#{?exit_status,!#{exit_status}, }' || exit 1
|
||||
$TMUX2 copy-mode -c || exit 1
|
||||
$TMUX2 send -X history-top || exit 1
|
||||
|
||||
@@ -26,5 +26,16 @@ check_raw_matches osc133 \
|
||||
'L 7 \(7\) flags=START_OUTPUT,END_OUTPUT,END_OUTPUT_STATUS\[[0-9a-f]+\].* osc133=0,0,2,5,255' \
|
||||
'L 8 \(8\) flags=START_OUTPUT,END_OUTPUT\[[0-9a-f]+\].* osc133=0,0,3,5,0'
|
||||
|
||||
# Reject malformed statuses and distinguish zero from a missing status.
|
||||
start_pane osc133-status 20 8 \
|
||||
'\033]133;C\007a\033]133;D;1junk\007\n\033]133;C\007b\033]133;D;4294967296\007\n\033]133;C\007c\033]133;D;255\007\n\033]133;C\007d\033]133;D;0;foo=bar\007\n\033]133;C\007e\033]133;D;foo=bar\007\n\033]133;C\007f\033]133;D;\007\n'
|
||||
check_raw_matches osc133-status \
|
||||
'L 0 \(0\) flags=START_OUTPUT,END_OUTPUT,END_OUTPUT_STATUS\[[0-9a-f]+\].* osc133=0,0,0,1,255' \
|
||||
'L 1 \(1\) flags=START_OUTPUT,END_OUTPUT,END_OUTPUT_STATUS\[[0-9a-f]+\].* osc133=0,0,0,1,255' \
|
||||
'L 2 \(2\) flags=START_OUTPUT,END_OUTPUT,END_OUTPUT_STATUS\[[0-9a-f]+\].* osc133=0,0,0,1,255' \
|
||||
'L 3 \(3\) flags=START_OUTPUT,END_OUTPUT,END_OUTPUT_STATUS\[[0-9a-f]+\].* osc133=0,0,0,1,0' \
|
||||
'L 4 \(4\) flags=START_OUTPUT,END_OUTPUT\[[0-9a-f]+\].* osc133=0,0,0,1,0' \
|
||||
'L 5 \(5\) flags=START_OUTPUT,END_OUTPUT\[[0-9a-f]+\].* osc133=0,0,0,1,0'
|
||||
|
||||
$TMUX kill-server 2>/dev/null
|
||||
exit $exit_status
|
||||
|
||||
@@ -288,4 +288,18 @@ $TMUX show-buffer >$OUT
|
||||
grep -q seq "$OUT" && exit 1
|
||||
$TMUX send-keys -t :hist.0 -X cancel || exit 1
|
||||
|
||||
# View mode has no pane source snapshot.
|
||||
$TMUX new-window -d -n view 'exec sleep 100' || exit 1
|
||||
$TMUX run-shell -t :view.0 "printf 'view one\nview two\n'" || exit 1
|
||||
[ "$($TMUX display-message -p -t :view.0 '#{pane_mode}')" = view-mode ] || exit 1
|
||||
$TMUX set-buffer sentinel || exit 1
|
||||
$TMUX send-keys -t :view.0 -X copy-output -a || exit 1
|
||||
[ "$($TMUX show-buffer)" = "$(printf 'view one\nview two')" ] || exit 1
|
||||
$TMUX send-keys -t :view.0 -X select-output -a || exit 1
|
||||
[ "$($TMUX display-message -p -t :view.0 '#{selection_present}')" = 1 ] || exit 1
|
||||
$TMUX set-buffer sentinel || exit 1
|
||||
$TMUX send-keys -t :view.0 -X copy-selection || exit 1
|
||||
[ "$($TMUX show-buffer)" = "$(printf 'view one\nview two')" ] || exit 1
|
||||
$TMUX send-keys -t :view.0 -X cancel || exit 1
|
||||
|
||||
exit 0
|
||||
|
||||
16
tmux.1
16
tmux.1
@@ -2213,10 +2213,23 @@ Expand the output for the command on the cursor line.
|
||||
With
|
||||
.Fl a ,
|
||||
expand all command output in the copy-mode buffer.
|
||||
.Pp
|
||||
.It Xo
|
||||
.Ic toggle\-output
|
||||
.Op Fl a
|
||||
.Xc
|
||||
Toggle whether output for the command on the cursor line is collapsed.
|
||||
With
|
||||
.Fl a ,
|
||||
toggle all command output in the copy-mode buffer.
|
||||
The Tab key toggles output for the command on the cursor line and S-Tab
|
||||
toggles all command output.
|
||||
.It Xo
|
||||
.Ic fold\-view\-toggle
|
||||
(vi: O)
|
||||
(emacs: O)
|
||||
.Xc
|
||||
Toggle OSC 133 output controls in copy mode and expand all command output.
|
||||
.It Xo
|
||||
.Ic middle\-line
|
||||
(vi: M)
|
||||
(emacs: M\-r)
|
||||
@@ -7434,6 +7447,7 @@ The following variables are available, where appropriate:
|
||||
.It Li "copy_cursor_word" Ta "" Ta "Word under cursor in copy mode"
|
||||
.It Li "copy_cursor_x" Ta "" Ta "Cursor X position in copy mode"
|
||||
.It Li "copy_cursor_y" Ta "" Ta "Cursor Y position in copy mode"
|
||||
.It Li "copy_fold_view" Ta "" Ta "1 if OSC 133 output controls are shown"
|
||||
.It Li "copy_line_numbers" Ta "" Ta "1 if line numbers are shown in copy mode"
|
||||
.It Li "copy_position" Ta "" Ta "Position shown in the copy mode indicator"
|
||||
.It Li "copy_position_limit" Ta "" Ta "Limit shown in the copy mode indicator"
|
||||
|
||||
463
window-copy.c
463
window-copy.c
@@ -82,6 +82,9 @@ static void window_copy_write_line(struct window_mode_entry *,
|
||||
struct screen_write_ctx *, u_int);
|
||||
static void window_copy_write_lines(struct window_mode_entry *,
|
||||
struct screen_write_ctx *, u_int, u_int);
|
||||
static void window_copy_write_gutter(struct window_mode_entry *,
|
||||
struct screen_write_ctx *, u_int, u_int,
|
||||
const struct grid_cell *);
|
||||
static void window_copy_rebuild_backing(struct window_mode_entry *);
|
||||
static int window_copy_set_fold(struct window_mode_entry *,
|
||||
const struct window_copy_fold_request *);
|
||||
@@ -339,7 +342,7 @@ struct window_copy_mode_data {
|
||||
|
||||
struct screen *backing;
|
||||
struct screen *source;
|
||||
u_char *source_flags; /* Flags per source line */
|
||||
u_char *source_flags; /* flags per source line */
|
||||
u_int source_line_count;
|
||||
struct window_copy_line *lines;
|
||||
u_int line_count;
|
||||
@@ -560,6 +563,8 @@ window_copy_set_control(struct window_copy_mode_data *data, u_int y,
|
||||
line->flags |= WINDOW_COPY_LINE_CONTROL;
|
||||
if (expandable)
|
||||
line->flags |= WINDOW_COPY_LINE_EXPANDABLE;
|
||||
else
|
||||
line->flags &= ~WINDOW_COPY_LINE_EXPANDABLE;
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -583,10 +588,7 @@ window_copy_expand_exit_status(struct window_mode_entry *wme,
|
||||
const char *value;
|
||||
char *expanded;
|
||||
|
||||
/*
|
||||
* This is called while rebuilding the backing grid, before the copy
|
||||
* cursor and viewport have been restored for the new grid.
|
||||
*/
|
||||
/* The copy cursor and viewport have not been restored yet. */
|
||||
ft = format_create(NULL, NULL, 0, 0);
|
||||
format_add(ft, "exit_status", "0");
|
||||
format_add(ft, "exit_status_present", "0");
|
||||
@@ -594,7 +596,7 @@ window_copy_expand_exit_status(struct window_mode_entry *wme,
|
||||
format_add(ft, "exit_status", "%hhu", line->exit_status);
|
||||
format_add(ft, "exit_status_present", "1");
|
||||
}
|
||||
value = options_get_string(wme->wp->window->options,
|
||||
value = options_get_string(wme->wp->options,
|
||||
"copy-mode-exit-status-format");
|
||||
expanded = format_expand(ft, value);
|
||||
format_free(ft);
|
||||
@@ -607,7 +609,7 @@ window_copy_update_exit_status_width(struct window_mode_entry *wme)
|
||||
struct window_copy_mode_data *data = wme->data;
|
||||
struct window_copy_line *line;
|
||||
char *expanded;
|
||||
u_int width, y;
|
||||
u_int width, length, y;
|
||||
|
||||
data->output_status_width = 0;
|
||||
if (!data->fold_view || data->lines == NULL)
|
||||
@@ -618,8 +620,9 @@ window_copy_update_exit_status_width(struct window_mode_entry *wme)
|
||||
if (~line->flags & WINDOW_COPY_LINE_CONTROL)
|
||||
continue;
|
||||
expanded = window_copy_expand_exit_status(wme, line);
|
||||
if (format_width(expanded) > width)
|
||||
width = format_width(expanded);
|
||||
length = format_width(expanded);
|
||||
if (length > width)
|
||||
width = length;
|
||||
free(expanded);
|
||||
}
|
||||
data->output_status_width = width;
|
||||
@@ -638,6 +641,19 @@ window_copy_set_source_folded(struct window_copy_mode_data *data, u_int y,
|
||||
return (1);
|
||||
}
|
||||
|
||||
/* Find the first primary prompt, if any. */
|
||||
static u_int
|
||||
window_copy_first_prompt(struct grid *gd)
|
||||
{
|
||||
u_int y, total = gd->hsize + gd->sy;
|
||||
|
||||
for (y = 0; y < total; y++) {
|
||||
if (grid_get_line(gd, y)->flags & GRID_LINE_START_PROMPT)
|
||||
return (y);
|
||||
}
|
||||
return (UINT_MAX);
|
||||
}
|
||||
|
||||
static int
|
||||
window_copy_any_fold_collapsed(struct window_copy_mode_data *data)
|
||||
{
|
||||
@@ -646,14 +662,10 @@ window_copy_any_fold_collapsed(struct window_copy_mode_data *data)
|
||||
u_int y;
|
||||
int command = 0, output = 0;
|
||||
|
||||
for (y = 0; y < gd->hsize + gd->sy; y++) {
|
||||
gl = grid_get_line(gd, y);
|
||||
if (gl->flags & GRID_LINE_START_PROMPT)
|
||||
break;
|
||||
}
|
||||
if (y != 0 && y != gd->hsize + gd->sy &&
|
||||
y = window_copy_first_prompt(gd);
|
||||
if (y != 0 && y != UINT_MAX &&
|
||||
(data->source_flags[0] & WINDOW_COPY_FOLD_COLLAPSED))
|
||||
/* Output which has scrolled off top of buffer is collapsed. */
|
||||
/* The initial output region is collapsed. */
|
||||
return (1);
|
||||
|
||||
for (y = 0; y < gd->hsize + gd->sy; y++) {
|
||||
@@ -671,7 +683,8 @@ window_copy_any_fold_collapsed(struct window_copy_mode_data *data)
|
||||
}
|
||||
if (gl->flags & GRID_LINE_END_OUTPUT) {
|
||||
if (!output && command &&
|
||||
(data->source_flags[y] & WINDOW_COPY_FOLD_COLLAPSED))
|
||||
(data->source_flags[y] &
|
||||
WINDOW_COPY_FOLD_COLLAPSED))
|
||||
return (1);
|
||||
command = output = 0;
|
||||
}
|
||||
@@ -687,15 +700,10 @@ window_copy_set_all_folds(struct window_copy_mode_data *data, int collapse)
|
||||
u_int y;
|
||||
int changed = 0, command = 0, output = 0;
|
||||
|
||||
for (y = 0; y < gd->hsize + gd->sy; y++) {
|
||||
gl = grid_get_line(gd, y);
|
||||
if (gl->flags & GRID_LINE_START_PROMPT)
|
||||
break;
|
||||
}
|
||||
if (y != 0 && y != gd->hsize + gd->sy &&
|
||||
window_copy_set_source_folded(data, 0, collapse)) {
|
||||
y = window_copy_first_prompt(gd);
|
||||
if (y != 0 && y != UINT_MAX &&
|
||||
window_copy_set_source_folded(data, 0, collapse))
|
||||
changed = 1;
|
||||
}
|
||||
|
||||
for (y = 0; y < gd->hsize + gd->sy; y++) {
|
||||
gl = grid_get_line(gd, y);
|
||||
@@ -706,16 +714,14 @@ window_copy_set_all_folds(struct window_copy_mode_data *data, int collapse)
|
||||
if (gl->flags & GRID_LINE_START_COMMAND)
|
||||
command = 1;
|
||||
if (gl->flags & GRID_LINE_START_OUTPUT) {
|
||||
if (window_copy_set_source_folded(data, y, collapse)) {
|
||||
if (window_copy_set_source_folded(data, y, collapse))
|
||||
changed = 1;
|
||||
}
|
||||
output = 1;
|
||||
}
|
||||
if (gl->flags & GRID_LINE_END_OUTPUT) {
|
||||
if (!output && command &&
|
||||
window_copy_set_source_folded(data, y, collapse)) {
|
||||
window_copy_set_source_folded(data, y, collapse))
|
||||
changed = 1;
|
||||
}
|
||||
command = output = 0;
|
||||
}
|
||||
}
|
||||
@@ -730,7 +736,6 @@ window_copy_rebuild_backing(struct window_mode_entry *wme)
|
||||
struct screen *src = data->source, *dst;
|
||||
struct grid *sgd;
|
||||
struct grid_line *sgl, *dgl;
|
||||
struct window_copy_line *line;
|
||||
struct screen_write_ctx ctx;
|
||||
struct grid_cell gc;
|
||||
struct osc133_data *osc133;
|
||||
@@ -744,7 +749,8 @@ window_copy_rebuild_backing(struct window_mode_entry *wme)
|
||||
if (src == NULL)
|
||||
return;
|
||||
if (!data->fold_view) {
|
||||
dst = window_copy_clone_screen(src, &data->screen, NULL, NULL, 0);
|
||||
dst = window_copy_clone_screen(src, &data->screen, NULL, NULL,
|
||||
0);
|
||||
if (data->backing != NULL) {
|
||||
screen_free(data->backing);
|
||||
free(data->backing);
|
||||
@@ -759,8 +765,8 @@ window_copy_rebuild_backing(struct window_mode_entry *wme)
|
||||
sgd = src->grid;
|
||||
total = sgd->hsize + sgd->sy;
|
||||
dst = xcalloc(1, sizeof *dst);
|
||||
screen_init(dst, screen_size_x(&data->screen), screen_size_y(&data->screen),
|
||||
screen_hlimit(src));
|
||||
screen_init(dst, screen_size_x(&data->screen),
|
||||
screen_size_y(&data->screen), screen_hlimit(src));
|
||||
dst->grid->flags |= GRID_HISTORY;
|
||||
free(data->lines);
|
||||
data->lines = xcalloc(total, sizeof *data->lines);
|
||||
@@ -769,24 +775,12 @@ window_copy_rebuild_backing(struct window_mode_entry *wme)
|
||||
data->lines[y].source_line = UINT_MAX;
|
||||
data->lines[y].output_line = UINT_MAX;
|
||||
}
|
||||
for (y = 0; y < total; y++) {
|
||||
sgl = grid_get_line(sgd, y);
|
||||
if (sgl->flags & GRID_LINE_START_PROMPT)
|
||||
break;
|
||||
}
|
||||
if (y != 0 && y != total)
|
||||
/*
|
||||
* The source begins in an existing command or its output. Treat its
|
||||
* first line as a synthetic command for the region before the first A.
|
||||
*/
|
||||
fold.initial = 1;
|
||||
y = window_copy_first_prompt(sgd);
|
||||
/* Keep the first line as the control for any initial output. */
|
||||
fold.initial = (y != 0 && y != UINT_MAX);
|
||||
|
||||
screen_write_start(&ctx, dst);
|
||||
/*
|
||||
* Markers may occur at any column, so copy the source one cell boundary at
|
||||
* a time. The final boundary (cellused) is included to handle a marker
|
||||
* immediately after the last cell on a line.
|
||||
*/
|
||||
/* Include the final cell boundary for markers after the last cell. */
|
||||
for (y = 0; y < total; y++) {
|
||||
sgl = grid_get_line(sgd, y);
|
||||
osc133 = &sgl->osc133_data;
|
||||
@@ -794,124 +788,81 @@ window_copy_rebuild_backing(struct window_mode_entry *wme)
|
||||
dy = dst->grid->hsize + dst->cy;
|
||||
was_hiding = fold.hiding;
|
||||
if (!fold.hiding)
|
||||
/*
|
||||
* Row is visible. Records the source
|
||||
* row and current output-block identity
|
||||
* for cursor restoration, selection,
|
||||
* gutter drawing, and line numbers.
|
||||
*/
|
||||
/* Map visible rows to their source. */
|
||||
window_copy_set_line(data, dy, y,
|
||||
fold.output_line, 0);
|
||||
/*
|
||||
* Continue even if row is folded because
|
||||
* there may be markers to process.
|
||||
*/
|
||||
/* Process markers on hidden rows too. */
|
||||
dgl = grid_get_line(dst->grid, dy);
|
||||
if (fold.initial && y == 0 && x == 0)
|
||||
/* Top line of buffer, no osc133 marker yet.
|
||||
* Attach controls to top line, make it a
|
||||
* "synthetic command" so top lines can fold.
|
||||
*/
|
||||
/* Attach initial output controls. */
|
||||
window_copy_set_line(data, dy, y, UINT_MAX,
|
||||
WINDOW_COPY_LINE_CONTROL | WINDOW_COPY_LINE_INITIAL);
|
||||
WINDOW_COPY_LINE_CONTROL|
|
||||
WINDOW_COPY_LINE_INITIAL);
|
||||
if ((sgl->flags & GRID_LINE_START_OUTPUT) &&
|
||||
x == osc133->out_start_col) {
|
||||
/*
|
||||
* osc133 C starts the collapsible region
|
||||
* controlled by this source line.
|
||||
*/
|
||||
/* C starts the collapsible output region. */
|
||||
dgl->flags |= GRID_LINE_START_OUTPUT;
|
||||
dgl->osc133_data.out_start_col = dst->cx;
|
||||
fold.output_line = y;
|
||||
/* used to draw the | or L in gutter */
|
||||
fold.tree = 1;
|
||||
fold.in_output = 1;
|
||||
fold.output_empty = 1;
|
||||
fold.collapsed = data->source_flags[y] &
|
||||
WINDOW_COPY_FOLD_COLLAPSED;
|
||||
/* Start/stop hiding cells */
|
||||
fold.hiding = fold.collapsed;
|
||||
if (fold.prompt_dy != UINT_MAX)
|
||||
/* Attach +/- controls to the prompt. */
|
||||
window_copy_set_control(data,
|
||||
fold.prompt_dy, fold.output_line, 1);
|
||||
fold.prompt_dy,
|
||||
fold.output_line, 1);
|
||||
}
|
||||
if ((sgl->flags & GRID_LINE_END_OUTPUT) &&
|
||||
x == osc133->out_end_col) {
|
||||
/*
|
||||
* Command output ends at the osc133 D
|
||||
* marker. There may be more lines
|
||||
* (like pre-prompt output) before next A
|
||||
* marker. Fold these with previous output
|
||||
* until the following A marker.
|
||||
*/
|
||||
/* Fold text after D until the next A. */
|
||||
dgl->flags |= GRID_LINE_END_OUTPUT;
|
||||
if (sgl->flags & GRID_LINE_END_OUTPUT_STATUS)
|
||||
dgl->flags |= GRID_LINE_END_OUTPUT_STATUS;
|
||||
dgl->flags |=
|
||||
GRID_LINE_END_OUTPUT_STATUS;
|
||||
dgl->osc133_data.out_end_col = dst->cx;
|
||||
dgl->osc133_data.exit_status = osc133->exit_status;
|
||||
dgl->osc133_data.exit_status =
|
||||
osc133->exit_status;
|
||||
if (fold.in_output && fold.output_empty &&
|
||||
fold.prompt_dy != UINT_MAX) {
|
||||
line = window_copy_get_line_info(data,
|
||||
fold.prompt_dy);
|
||||
if (line != NULL)
|
||||
fold.prompt_dy != UINT_MAX)
|
||||
/* No output to hide, no +/-. */
|
||||
line->flags &= ~WINDOW_COPY_LINE_EXPANDABLE;
|
||||
}
|
||||
window_copy_set_control(data,
|
||||
fold.prompt_dy,
|
||||
fold.output_line, 0);
|
||||
fold.in_output = 0;
|
||||
if (fold.output_line == UINT_MAX &&
|
||||
fold.command) {
|
||||
/*
|
||||
* Saw osc133 B but not C marker.
|
||||
* This could be user pressed enter
|
||||
* or command like 'true' with no
|
||||
* output.
|
||||
*/
|
||||
/* B without C has no output. */
|
||||
fold.output_line = y;
|
||||
fold.tree = 1;
|
||||
/* Block is collapsed? */
|
||||
fold.collapsed = data->source_flags[y] &
|
||||
WINDOW_COPY_FOLD_COLLAPSED;
|
||||
if (fold.prompt_dy != UINT_MAX)
|
||||
/*
|
||||
* Make this a +/- control row
|
||||
* but without the +/- for now
|
||||
* since we don't know what
|
||||
* comes below.
|
||||
*/
|
||||
/* Show output controls. */
|
||||
window_copy_set_control(data,
|
||||
fold.prompt_dy,
|
||||
fold.output_line, 0);
|
||||
}
|
||||
if (fold.prompt_dy != UINT_MAX &&
|
||||
sgl->flags & GRID_LINE_END_OUTPUT_STATUS)
|
||||
/*
|
||||
* osc133 D, record exit status on the
|
||||
* command's prompt row.
|
||||
*/
|
||||
window_copy_set_exit_status(data,
|
||||
fold.prompt_dy, osc133->exit_status);
|
||||
fold.prompt_dy,
|
||||
osc133->exit_status);
|
||||
if (fold.initial && fold.prompt_dy == UINT_MAX)
|
||||
/* At top of buffer before first osc A
|
||||
* marker use first line's fold state.
|
||||
*/
|
||||
/* Keep the initial fold state. */
|
||||
fold.hiding = data->source_flags[0] &
|
||||
WINDOW_COPY_FOLD_COLLAPSED;
|
||||
else
|
||||
/*
|
||||
* Otherwise, use the current block's
|
||||
* fold state.
|
||||
*/
|
||||
fold.hiding = fold.collapsed;
|
||||
fold.command = 0;
|
||||
}
|
||||
/*
|
||||
* Process osc133 C and D before a following prompt
|
||||
* at the same column.
|
||||
*/
|
||||
/* Process C and D before A at the same column. */
|
||||
if ((sgl->flags & GRID_LINE_START_PROMPT) &&
|
||||
x == osc133->prompt_col) {
|
||||
/* osc133 A ends region, starts new prompt. */
|
||||
/* A starts a new prompt. */
|
||||
dgl->flags |= GRID_LINE_START_PROMPT;
|
||||
dgl->osc133_data.prompt_col = dst->cx;
|
||||
fold.prompt_dy = dy;
|
||||
@@ -922,21 +873,16 @@ window_copy_rebuild_backing(struct window_mode_entry *wme)
|
||||
}
|
||||
if ((sgl->flags & GRID_LINE_SECOND_PROMPT) &&
|
||||
x == osc133->prompt_col) {
|
||||
/* osc133 A;k=s, marks secondary prompt. */
|
||||
dgl->flags |= GRID_LINE_SECOND_PROMPT;
|
||||
dgl->osc133_data.prompt_col = dst->cx;
|
||||
}
|
||||
if ((sgl->flags & GRID_LINE_START_COMMAND) &&
|
||||
x == osc133->cmd_col) {
|
||||
/* osc133 B marks start/continue of command. */
|
||||
dgl->flags |= GRID_LINE_START_COMMAND;
|
||||
dgl->osc133_data.cmd_col = dst->cx;
|
||||
fold.command = 1;
|
||||
}
|
||||
/*
|
||||
* An osc133 A may expose the remainder of this source
|
||||
* line after a folded region.
|
||||
*/
|
||||
/* A may expose cells after a folded region. */
|
||||
if (was_hiding && !fold.hiding)
|
||||
window_copy_set_line(data, dy, y,
|
||||
fold.output_line, 0);
|
||||
@@ -952,40 +898,31 @@ window_copy_rebuild_backing(struct window_mode_entry *wme)
|
||||
fold.prompt_dy != UINT_MAX)
|
||||
window_copy_set_control(data, fold.prompt_dy,
|
||||
fold.output_line, 1);
|
||||
/*
|
||||
* osc133 marker processing continues while folded, but
|
||||
* cell output does not.
|
||||
*/
|
||||
/* Skip hidden cells after processing their markers. */
|
||||
if (fold.hiding)
|
||||
continue;
|
||||
if (!(gc.flags & GRID_FLAG_PADDING)) {
|
||||
screen_write_cell(&ctx, &gc);
|
||||
if (fold.tree)
|
||||
window_copy_set_line(data, dy, y,
|
||||
fold.output_line, WINDOW_COPY_LINE_MEMBER);
|
||||
fold.output_line,
|
||||
WINDOW_COPY_LINE_MEMBER);
|
||||
}
|
||||
}
|
||||
if (!fold.hiding && fold.tree && sgl->cellused == 0 &&
|
||||
~(sgl->flags) & (GRID_LINE_START_PROMPT |
|
||||
GRID_LINE_START_OUTPUT | GRID_LINE_END_OUTPUT))
|
||||
/* Mark empty visible lines so gutter tree continues */
|
||||
/* Continue the gutter tree on empty lines. */
|
||||
window_copy_set_line(data, dy, y, fold.output_line,
|
||||
WINDOW_COPY_LINE_MEMBER);
|
||||
if (y + 1 != total && !(sgl->flags & GRID_LINE_WRAPPED) &&
|
||||
(!fold.hiding || (fold.initial && y == 0))) {
|
||||
/*
|
||||
* Hide folded line breaks, except after the initial
|
||||
* synthetic command line (top line of copy buffer).
|
||||
*/
|
||||
/* Keep the initial region's control line visible. */
|
||||
screen_write_carriagereturn(&ctx);
|
||||
screen_write_linefeed(&ctx, 0, 8);
|
||||
}
|
||||
if (fold.initial && y == 0) {
|
||||
/*
|
||||
* Top line of buffer (which may not be a command)
|
||||
* becomes our "synthisied" commmand to anchor lines
|
||||
* folded below it up to first osc133 A.
|
||||
*/
|
||||
/* Fold initial output below its control line. */
|
||||
fold.tree = 1;
|
||||
fold.hiding = data->source_flags[0] &
|
||||
WINDOW_COPY_FOLD_COLLAPSED;
|
||||
@@ -1029,11 +966,10 @@ window_copy_sync_backing(struct window_mode_entry *wme)
|
||||
struct screen *src = &wp->base;
|
||||
struct screen *dst = data->source;
|
||||
struct grid *sg = src->grid;
|
||||
struct grid *dg = dst->grid;
|
||||
u_int sy = sg->sy;
|
||||
u_int old_hsize = dg->hsize;
|
||||
u_int new_hsize = sg->hsize;
|
||||
u_int added, collected, kept, old_count, new_count;
|
||||
struct grid *dg;
|
||||
u_int sy, old_hsize, new_hsize;
|
||||
u_int added, collected, kept;
|
||||
u_int old_count, new_count;
|
||||
|
||||
/*
|
||||
* Only a pane's own live grid is tracked incrementally. A different
|
||||
@@ -1042,6 +978,10 @@ window_copy_sync_backing(struct window_mode_entry *wme)
|
||||
*/
|
||||
if (data->source == NULL || data->viewmode || wme->swp != wme->wp)
|
||||
return (0);
|
||||
dg = dst->grid;
|
||||
sy = sg->sy;
|
||||
old_hsize = dg->hsize;
|
||||
new_hsize = sg->hsize;
|
||||
|
||||
/* Indices only line up at the same size and generation. */
|
||||
if (sg->sx != dg->sx || sg->sy != dg->sy ||
|
||||
@@ -1064,17 +1004,15 @@ window_copy_sync_backing(struct window_mode_entry *wme)
|
||||
kept = old_hsize - collected;
|
||||
old_count = old_hsize + sy;
|
||||
new_count = new_hsize + sy;
|
||||
if (collected != 0) {
|
||||
if (collected != 0)
|
||||
memmove(data->source_flags, data->source_flags + collected,
|
||||
(old_count - collected) * sizeof *data->source_flags);
|
||||
}
|
||||
data->source_flags = xreallocarray(data->source_flags, new_count,
|
||||
sizeof *data->source_flags);
|
||||
if (new_count > old_count - collected) {
|
||||
if (new_count > old_count - collected)
|
||||
memset(data->source_flags + old_count - collected, 0,
|
||||
(new_count - (old_count - collected)) *
|
||||
sizeof *data->source_flags);
|
||||
}
|
||||
data->source_line_count = new_count;
|
||||
|
||||
if (added == 0 && collected == 0) {
|
||||
@@ -1194,7 +1132,8 @@ window_copy_init(struct window_mode_entry *wme,
|
||||
window_copy_find_fold(wme, cy, &prompt, &chosen)) {
|
||||
restored = window_copy_restore_cursor(wme, cx, cy);
|
||||
if (!restored)
|
||||
restored = window_copy_restore_command_end(wme, prompt, chosen);
|
||||
restored = window_copy_restore_command_end(wme, prompt,
|
||||
chosen);
|
||||
} else if (data->fold_view)
|
||||
restored = window_copy_restore_cursor(wme, cx, cy);
|
||||
if (!restored && cy < screen_hsize(data->backing)) {
|
||||
@@ -2187,6 +2126,7 @@ window_copy_cmd_select_output(struct window_copy_cmd_state *cs)
|
||||
.action = WINDOW_COPY_FOLD_EXPAND
|
||||
};
|
||||
struct grid_reader gr;
|
||||
struct grid *gd;
|
||||
void *buf;
|
||||
size_t len;
|
||||
u_int sx, sy, ex, ey, bsx, bsy, bex, bey;
|
||||
@@ -2194,10 +2134,13 @@ window_copy_cmd_select_output(struct window_copy_cmd_state *cs)
|
||||
int all = args_has(cs->wargs, 'a');
|
||||
|
||||
if (all) {
|
||||
gd = data->backing->grid;
|
||||
if (data->source != NULL)
|
||||
gd = data->source->grid;
|
||||
sx = sy = 0;
|
||||
total = data->source->grid->hsize + data->source->grid->sy;
|
||||
total = gd->hsize + gd->sy;
|
||||
ey = total - 1;
|
||||
ex = grid_get_line(data->source->grid, ey)->cellused;
|
||||
ex = grid_get_line(gd, ey)->cellused;
|
||||
} else if (!window_copy_find_output_range(wme, &sx, &sy, &ex, &ey))
|
||||
return (WINDOW_COPY_CMD_NOTHING);
|
||||
buf = window_copy_get_output(wme, &len, all);
|
||||
@@ -4145,8 +4088,8 @@ window_copy_find_fold(struct window_mode_entry *wme, u_int target,
|
||||
for (y = 0; y < gd->hsize + gd->sy; y++) {
|
||||
gl = grid_get_line(gd, y);
|
||||
if (gl->flags & GRID_LINE_START_PROMPT) {
|
||||
if (have_prompt && target >= last_prompt && target < y &&
|
||||
candidate != UINT_MAX) {
|
||||
if (have_prompt && candidate != UINT_MAX &&
|
||||
target >= last_prompt && target < y) {
|
||||
*prompt = last_prompt;
|
||||
*chosen = candidate;
|
||||
return (1);
|
||||
@@ -4194,8 +4137,7 @@ window_copy_cursor_source(struct window_mode_entry *wme, u_int *source_x,
|
||||
else if (line->source_line == UINT_MAX) {
|
||||
*source_x = UINT_MAX;
|
||||
*source_y = data->source_line_count - 1;
|
||||
}
|
||||
else
|
||||
} else
|
||||
*source_y = line->source_line;
|
||||
}
|
||||
|
||||
@@ -4263,7 +4205,8 @@ window_copy_restore_command_end(struct window_mode_entry *wme, u_int prompt,
|
||||
struct grid *gd = data->backing->grid;
|
||||
struct grid_line *gl;
|
||||
struct window_copy_line *line;
|
||||
u_int command_start = UINT_MAX, marker = UINT_MAX;
|
||||
u_int command_start = UINT_MAX;
|
||||
u_int marker = UINT_MAX;
|
||||
u_int marker_x = 0, length, y;
|
||||
int previous = 0;
|
||||
|
||||
@@ -4354,9 +4297,10 @@ window_copy_set_fold(struct window_mode_entry *wme,
|
||||
{
|
||||
struct window_copy_mode_data *data = wme->data;
|
||||
u_int prompt = 0, source_x, source_y;
|
||||
u_int chosen = UINT_MAX, first_prompt, y;
|
||||
u_int chosen = UINT_MAX, first_prompt;
|
||||
u_int target = request->target;
|
||||
int changed = 0, enabled = 0, found, initial;
|
||||
int changed = 0, enabled = 0;
|
||||
int found, initial;
|
||||
int wanted;
|
||||
|
||||
if (data->source == NULL)
|
||||
@@ -4364,44 +4308,30 @@ window_copy_set_fold(struct window_mode_entry *wme,
|
||||
window_copy_cursor_source(wme, &source_x, &source_y);
|
||||
if (target == UINT_MAX)
|
||||
target = source_y;
|
||||
first_prompt = screen_hsize(data->source) + screen_size_y(data->source);
|
||||
for (y = 0; y < first_prompt; y++) {
|
||||
if (grid_get_line(data->source->grid, y)->flags &
|
||||
GRID_LINE_START_PROMPT) {
|
||||
first_prompt = y;
|
||||
break;
|
||||
}
|
||||
}
|
||||
initial = first_prompt != 0 &&
|
||||
first_prompt != screen_hsize(data->source) +
|
||||
screen_size_y(data->source) && target < first_prompt;
|
||||
first_prompt = window_copy_first_prompt(data->source->grid);
|
||||
initial = (first_prompt != 0 && first_prompt != UINT_MAX &&
|
||||
target < first_prompt);
|
||||
if (!data->fold_view) {
|
||||
data->fold_view = 1;
|
||||
window_copy_rebuild_backing(wme);
|
||||
enabled = 1;
|
||||
}
|
||||
found = window_copy_find_fold(wme, target, &prompt, &chosen);
|
||||
if (request->all) {
|
||||
wanted = (request->action == WINDOW_COPY_FOLD_COLLAPSE);
|
||||
if (request->all) {
|
||||
if (request->action == WINDOW_COPY_FOLD_TOGGLE)
|
||||
wanted = !window_copy_any_fold_collapsed(data);
|
||||
changed = window_copy_set_all_folds(data, wanted);
|
||||
} else if (initial) {
|
||||
wanted = (request->action == WINDOW_COPY_FOLD_COLLAPSE);
|
||||
if (request->action == WINDOW_COPY_FOLD_TOGGLE)
|
||||
wanted = !(data->source_flags[0] &
|
||||
WINDOW_COPY_FOLD_COLLAPSED);
|
||||
if (window_copy_set_source_folded(data, 0, wanted)) {
|
||||
changed = 1;
|
||||
}
|
||||
changed = window_copy_set_source_folded(data, 0, wanted);
|
||||
} else if (found && chosen != UINT_MAX) {
|
||||
wanted = (request->action == WINDOW_COPY_FOLD_COLLAPSE);
|
||||
if (request->action == WINDOW_COPY_FOLD_TOGGLE)
|
||||
wanted = !(data->source_flags[chosen] &
|
||||
WINDOW_COPY_FOLD_COLLAPSED);
|
||||
if (window_copy_set_source_folded(data, chosen, wanted)) {
|
||||
changed = 1;
|
||||
}
|
||||
changed = window_copy_set_source_folded(data, chosen, wanted);
|
||||
}
|
||||
if (!changed) {
|
||||
if (enabled) {
|
||||
@@ -4469,26 +4399,31 @@ window_copy_cmd_toggle_output(struct window_copy_cmd_state *cs)
|
||||
u_int current, current_prompt, target;
|
||||
u_int target_prompt, chosen, x, y;
|
||||
int current_found;
|
||||
int initial, target_found;
|
||||
int initial;
|
||||
|
||||
if (args_has(cs->wargs, 'm')) {
|
||||
if (cs->m == NULL || cmd_mouse_at(cs->wme->wp, cs->m, &x, &y,
|
||||
0) != 0 || x >= window_copy_left_margin(cs->wme))
|
||||
if (cs->m == NULL)
|
||||
return (WINDOW_COPY_CMD_NOTHING);
|
||||
if (cmd_mouse_at(cs->wme->wp, cs->m, &x, &y, 0) != 0)
|
||||
return (WINDOW_COPY_CMD_NOTHING);
|
||||
if (x >= window_copy_left_margin(cs->wme))
|
||||
return (WINDOW_COPY_CMD_NOTHING);
|
||||
target = screen_hsize(data->backing) + y - data->oy;
|
||||
line = window_copy_get_line_info(data, target);
|
||||
if (line == NULL || line->source_line == UINT_MAX)
|
||||
return (WINDOW_COPY_CMD_NOTHING);
|
||||
initial = line->flags & WINDOW_COPY_LINE_INITIAL;
|
||||
request.command_end = 1;
|
||||
if (!initial) {
|
||||
if (!window_copy_find_fold(cs->wme, line->source_line,
|
||||
&target_prompt, &chosen))
|
||||
return (WINDOW_COPY_CMD_NOTHING);
|
||||
window_copy_cursor_source(cs->wme, &x, ¤t);
|
||||
current_found = window_copy_find_fold(cs->wme, current,
|
||||
¤t_prompt, &chosen);
|
||||
target_found = initial || window_copy_find_fold(cs->wme,
|
||||
line->source_line, &target_prompt, &chosen);
|
||||
if (!target_found)
|
||||
return (WINDOW_COPY_CMD_NOTHING);
|
||||
request.command_end = initial || !current_found ||
|
||||
request.command_end = !current_found ||
|
||||
current_prompt != target_prompt;
|
||||
}
|
||||
request.target = line->source_line;
|
||||
}
|
||||
if (window_copy_set_fold(cs->wme, &request))
|
||||
@@ -5178,7 +5113,8 @@ window_copy_command(struct window_mode_entry *wme, struct client *c,
|
||||
enum window_copy_cmd_action action;
|
||||
enum window_copy_cmd_clear clear = WINDOW_COPY_CMD_CLEAR_NEVER;
|
||||
const char *command;
|
||||
u_int i, count = args_count(args), mouse_x, mouse_y;
|
||||
u_int i, count = args_count(args);
|
||||
u_int mouse_x, mouse_y;
|
||||
int keys, flags, mouse_control = 0;
|
||||
char *error = NULL;
|
||||
|
||||
@@ -6606,12 +6542,12 @@ static u_int
|
||||
window_copy_left_margin(struct window_mode_entry *wme)
|
||||
{
|
||||
struct window_copy_mode_data *data = wme->data;
|
||||
u_int width = 0;
|
||||
u_int width;
|
||||
|
||||
width = window_copy_line_number_width(wme);
|
||||
if (data->fold_view)
|
||||
width = data->output_status_width + 2;
|
||||
|
||||
return (window_copy_line_number_width(wme) + width);
|
||||
width += data->output_status_width + 2;
|
||||
return (width);
|
||||
}
|
||||
|
||||
static u_int
|
||||
@@ -6702,6 +6638,61 @@ window_copy_get_current_offset(struct window_pane *wp, u_int *offset,
|
||||
return (1);
|
||||
}
|
||||
|
||||
static void
|
||||
window_copy_write_gutter(struct window_mode_entry *wme,
|
||||
struct screen_write_ctx *ctx, u_int py, u_int line_width,
|
||||
const struct grid_cell *gc)
|
||||
{
|
||||
struct window_copy_mode_data *data = wme->data;
|
||||
struct window_copy_line *line, *next;
|
||||
struct grid_cell control_gc;
|
||||
u_int backing_y, output_line = UINT_MAX, i;
|
||||
u_int width = data->output_status_width + 2;
|
||||
char control = ' ', *status;
|
||||
|
||||
backing_y = screen_hsize(data->backing) - data->oy + py;
|
||||
line = window_copy_get_line_info(data, backing_y);
|
||||
if (line != NULL && line->flags & WINDOW_COPY_LINE_CONTROL) {
|
||||
if (line->flags & WINDOW_COPY_LINE_INITIAL)
|
||||
output_line = 0;
|
||||
else if (line->flags & WINDOW_COPY_LINE_EXPANDABLE &&
|
||||
line->output_line < data->source_line_count)
|
||||
output_line = line->output_line;
|
||||
if (output_line != UINT_MAX) {
|
||||
if (data->source_flags[output_line] &
|
||||
WINDOW_COPY_FOLD_COLLAPSED)
|
||||
control = '+';
|
||||
else
|
||||
control = '-';
|
||||
}
|
||||
} else if (line != NULL && line->flags & WINDOW_COPY_LINE_MEMBER) {
|
||||
next = window_copy_get_line_info(data, backing_y + 1);
|
||||
if (next == NULL || ~next->flags & WINDOW_COPY_LINE_MEMBER ||
|
||||
next->output_line != line->output_line)
|
||||
control = 'm'; /* ACS L character */
|
||||
else
|
||||
control = 'x'; /* ACS | character */
|
||||
}
|
||||
screen_write_cursormove(ctx, line_width, py, 0);
|
||||
for (i = 0; i < width; i++)
|
||||
screen_write_putc(ctx, gc, ' ');
|
||||
if (control != ' ') {
|
||||
screen_write_cursormove(ctx,
|
||||
line_width + data->output_status_width, py, 0);
|
||||
memcpy(&control_gc, gc, sizeof control_gc);
|
||||
if (control == 'x' || control == 'm')
|
||||
control_gc.attr |= GRID_ATTR_CHARSET;
|
||||
screen_write_putc(ctx, &control_gc, control);
|
||||
}
|
||||
if (line != NULL && line->flags & WINDOW_COPY_LINE_CONTROL) {
|
||||
status = window_copy_expand_exit_status(wme, line);
|
||||
screen_write_cursormove(ctx, line_width, py, 0);
|
||||
format_draw(ctx, gc, data->output_status_width, status, NULL,
|
||||
0);
|
||||
free(status);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
window_copy_write_line(struct window_mode_entry *wme,
|
||||
struct screen_write_ctx *ctx, u_int py)
|
||||
@@ -6712,22 +6703,18 @@ window_copy_write_line(struct window_mode_entry *wme,
|
||||
struct options *oo = wp->window->options;
|
||||
struct grid_cell gc, mgc, cgc, mkgc, clgc, ln_gc;
|
||||
struct grid_cell cur_ln_gc;
|
||||
struct grid_cell control_gc;
|
||||
struct window_copy_line *line, *next;
|
||||
const struct grid_cell *line_gc;
|
||||
u_int sx = screen_size_x(s);
|
||||
u_int hsize = screen_hsize(data->backing);
|
||||
u_int width, line_width, gutter_width, backing_y;
|
||||
u_int width, line_width, backing_y;
|
||||
u_int absolute, line_number, content_sx;
|
||||
u_int i;
|
||||
const char *value;
|
||||
char *expanded, *status;
|
||||
char *expanded;
|
||||
struct format_tree *ft;
|
||||
char control;
|
||||
int current, mode;
|
||||
|
||||
line_width = window_copy_line_number_width(wme);
|
||||
gutter_width = data->fold_view ? data->output_status_width + 2 : 0;
|
||||
width = line_width + gutter_width;
|
||||
width = window_copy_left_margin(wme);
|
||||
if (width >= sx)
|
||||
content_sx = 1;
|
||||
else if (width != 0)
|
||||
@@ -6755,6 +6742,7 @@ window_copy_write_line(struct window_mode_entry *wme,
|
||||
"copy-mode-current-line-number-style", ft);
|
||||
cur_ln_gc.flags |= GRID_FLAG_NOPALETTE;
|
||||
current = (py == data->cy);
|
||||
line_gc = current ? &cur_ln_gc : &ln_gc;
|
||||
backing_y = hsize - data->oy + py;
|
||||
absolute = backing_y + 1;
|
||||
if (data->lines != NULL && backing_y < data->line_count &&
|
||||
@@ -6780,62 +6768,12 @@ window_copy_write_line(struct window_mode_entry *wme,
|
||||
line_number = data->cy - py;
|
||||
if (line_width != 0) {
|
||||
screen_write_cursormove(ctx, 0, py, 0);
|
||||
screen_write_nputs(ctx, line_width,
|
||||
current ? &cur_ln_gc : &ln_gc, "%*u ",
|
||||
screen_write_nputs(ctx, line_width, line_gc, "%*u ",
|
||||
(int)line_width - 1, line_number);
|
||||
}
|
||||
if (gutter_width != 0) {
|
||||
line = NULL;
|
||||
control = ' ';
|
||||
if (data->lines != NULL && backing_y < data->line_count)
|
||||
line = &data->lines[backing_y];
|
||||
if (line != NULL &&
|
||||
line->flags & WINDOW_COPY_LINE_CONTROL) {
|
||||
if (line->flags &
|
||||
WINDOW_COPY_LINE_INITIAL) {
|
||||
control = data->source_flags[0] &
|
||||
WINDOW_COPY_FOLD_COLLAPSED ? '+' : '-';
|
||||
} else if (line->flags & WINDOW_COPY_LINE_EXPANDABLE &&
|
||||
line->output_line < data->source_line_count) {
|
||||
if (data->source_flags[line->output_line] &
|
||||
WINDOW_COPY_FOLD_COLLAPSED)
|
||||
control = '+';
|
||||
else
|
||||
control = '-';
|
||||
}
|
||||
} else if (line != NULL &&
|
||||
line->flags & WINDOW_COPY_LINE_MEMBER) {
|
||||
next = NULL;
|
||||
if (backing_y + 1 < data->line_count)
|
||||
next = &data->lines[backing_y + 1];
|
||||
if (next == NULL ||
|
||||
~(next->flags) & WINDOW_COPY_LINE_MEMBER ||
|
||||
next->output_line != line->output_line)
|
||||
control = 'm'; /* ACS L character */
|
||||
else
|
||||
control = 'x'; /* ACS | character */
|
||||
}
|
||||
screen_write_cursormove(ctx, line_width, py, 0);
|
||||
for (i = 0; i < gutter_width; i++)
|
||||
screen_write_putc(ctx, current ? &cur_ln_gc : &ln_gc, ' ');
|
||||
if (control != ' ') {
|
||||
screen_write_cursormove(ctx,
|
||||
line_width + data->output_status_width, py, 0);
|
||||
memcpy(&control_gc, current ? &cur_ln_gc : &ln_gc,
|
||||
sizeof control_gc);
|
||||
if (control == 'x' || control == 'm')
|
||||
control_gc.attr |= GRID_ATTR_CHARSET;
|
||||
screen_write_putc(ctx, &control_gc, control);
|
||||
}
|
||||
if (line != NULL &&
|
||||
line->flags & WINDOW_COPY_LINE_CONTROL) {
|
||||
status = window_copy_expand_exit_status(wme, line);
|
||||
screen_write_cursormove(ctx, line_width, py, 0);
|
||||
format_draw(ctx, current ? &cur_ln_gc : &ln_gc,
|
||||
data->output_status_width, status, NULL, 0);
|
||||
free(status);
|
||||
}
|
||||
}
|
||||
if (data->fold_view)
|
||||
window_copy_write_gutter(wme, ctx, py, line_width,
|
||||
line_gc);
|
||||
}
|
||||
|
||||
window_copy_write_one(wme, ctx, width, py, hsize - data->oy + py,
|
||||
@@ -6847,7 +6785,8 @@ window_copy_write_line(struct window_mode_entry *wme,
|
||||
expanded = format_expand(ft, value);
|
||||
if (*expanded != '\0') {
|
||||
screen_write_cursormove(ctx, width, 0, 0);
|
||||
format_draw(ctx, &gc, content_sx, expanded, NULL, 0);
|
||||
format_draw(ctx, &gc, content_sx, expanded,
|
||||
NULL, 0);
|
||||
}
|
||||
free(expanded);
|
||||
}
|
||||
@@ -7456,7 +7395,8 @@ window_copy_find_previous_output_range(struct screen *s, u_int cursor_x,
|
||||
struct osc133_data *od;
|
||||
u_int start_x, start_y, end_x, end_y;
|
||||
u_int y, total;
|
||||
int found = 0, found_empty = 0, have_prompt = 0;
|
||||
int found = 0, found_empty = 0;
|
||||
int have_prompt = 0;
|
||||
int pending = 0, started_here;
|
||||
int has_start, has_end, end_first;
|
||||
|
||||
@@ -7491,12 +7431,7 @@ window_copy_find_previous_output_range(struct screen *s, u_int cursor_x,
|
||||
end_x = od->out_end_col;
|
||||
end_y = y;
|
||||
|
||||
/*
|
||||
* Prefer a previously found non-empty output over a
|
||||
* later one that turns out to be empty (for example a
|
||||
* command with no output immediately followed by the
|
||||
* cursor's prompt).
|
||||
*/
|
||||
/* Prefer earlier output to a later empty command. */
|
||||
if (!found || found_empty ||
|
||||
start_x != end_x || start_y != end_y) {
|
||||
*sx = start_x;
|
||||
@@ -7538,12 +7473,11 @@ window_copy_get_output(struct window_mode_entry *wme, size_t *len, int all)
|
||||
{
|
||||
struct window_copy_mode_data *data = wme->data;
|
||||
struct grid *gd;
|
||||
void *buf;
|
||||
u_int sx, sy, ex, ey, total;
|
||||
|
||||
if (data->source == NULL) {
|
||||
*len = 0;
|
||||
return (NULL);
|
||||
}
|
||||
gd = data->backing->grid;
|
||||
if (data->source != NULL)
|
||||
gd = data->source->grid;
|
||||
total = gd->hsize + gd->sy;
|
||||
if (all) {
|
||||
@@ -7554,7 +7488,8 @@ window_copy_get_output(struct window_mode_entry *wme, size_t *len, int all)
|
||||
*len = 0;
|
||||
return (NULL);
|
||||
}
|
||||
return (window_copy_get_grid_range(gd, sx, sy, ex, ey, len));
|
||||
buf = window_copy_get_grid_range(gd, sx, sy, ex, ey, len);
|
||||
return (buf);
|
||||
}
|
||||
|
||||
static void *
|
||||
|
||||
Reference in New Issue
Block a user