From 80a557e14f0fc4aac1a920de028e43fb4b6259dd Mon Sep 17 00:00:00 2001 From: Nicholas Marriott Date: Fri, 8 Nov 2024 08:51:37 +0000 Subject: Some fixes for searching for tabs, from Alexander Arch. --- usr.bin/tmux/grid.c | 12 ++++++--- usr.bin/tmux/screen-write.c | 18 ++++++++++--- usr.bin/tmux/window-copy.c | 63 +++++++++++++++++++++++++++++++++------------ 3 files changed, 68 insertions(+), 25 deletions(-) diff --git a/usr.bin/tmux/grid.c b/usr.bin/tmux/grid.c index a11c96f0455..9dfab95a165 100644 --- a/usr.bin/tmux/grid.c +++ b/usr.bin/tmux/grid.c @@ -1,4 +1,4 @@ -/* $OpenBSD: grid.c,v 1.133 2024/11/04 08:52:13 nicm Exp $ */ +/* $OpenBSD: grid.c,v 1.134 2024/11/08 08:51:36 nicm Exp $ */ /* * Copyright (c) 2008 Nicholas Marriott @@ -235,9 +235,13 @@ grid_check_y(struct grid *gd, const char *from, u_int py) int grid_cells_look_equal(const struct grid_cell *gc1, const struct grid_cell *gc2) { + int flags1 = gc1->flags, flags2 = gc2->flags;; + if (gc1->fg != gc2->fg || gc1->bg != gc2->bg) return (0); - if (gc1->attr != gc2->attr || gc1->flags != gc2->flags) + if (gc1->attr != gc2->attr) + return (0); + if ((flags1 & ~GRID_FLAG_CLEARED) != (flags2 & ~GRID_FLAG_CLEARED)) return (0); if (gc1->link != gc2->link) return (0); @@ -261,10 +265,10 @@ grid_cells_equal(const struct grid_cell *gc1, const struct grid_cell *gc2) void grid_set_tab(struct grid_cell *gc, u_int width) { - memset(&gc->data, 0, sizeof gc->data); + memset(gc->data.data, 0, sizeof gc->data.data); gc->flags |= GRID_FLAG_TAB; gc->data.width = gc->data.size = gc->data.have = width; - memset(&gc->data, ' ', gc->data.size); + memset(gc->data.data, ' ', gc->data.size); } /* Free one line. */ diff --git a/usr.bin/tmux/screen-write.c b/usr.bin/tmux/screen-write.c index 039cab62dd8..38d118ed9f3 100644 --- a/usr.bin/tmux/screen-write.c +++ b/usr.bin/tmux/screen-write.c @@ -1,4 +1,4 @@ -/* $OpenBSD: screen-write.c,v 1.229 2024/11/05 09:41:17 nicm Exp $ */ +/* $OpenBSD: screen-write.c,v 1.230 2024/11/08 08:51:36 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott @@ -377,7 +377,7 @@ screen_write_strlen(const char *fmt, ...) if (more == UTF8_DONE) size += ud.width; } else { - if (*ptr > 0x1f && *ptr < 0x7f) + if (*ptr == '\t' || (*ptr > 0x1f && *ptr < 0x7f)) size++; ptr++; } @@ -547,7 +547,7 @@ screen_write_vnputs(struct screen_write_ctx *ctx, ssize_t maxlen, else if (*ptr == '\n') { screen_write_linefeed(ctx, 0, 8); screen_write_carriagereturn(ctx); - } else if (*ptr > 0x1f && *ptr < 0x7f) { + } else if (*ptr == '\t' || (*ptr > 0x1f && *ptr < 0x7f)) { size++; screen_write_putc(ctx, &gc, *ptr); } @@ -2143,7 +2143,17 @@ screen_write_overwrite(struct screen_write_ctx *ctx, struct grid_cell *gc, break; log_debug("%s: overwrite at %u,%u", __func__, xx, s->cy); - grid_view_set_cell(gd, xx, s->cy, &grid_default_cell); + if (gc->flags & GRID_FLAG_TAB) { + memcpy(&tmp_gc, gc, sizeof tmp_gc); + memset(tmp_gc.data.data, 0, + sizeof tmp_gc.data.data); + *tmp_gc.data.data = ' '; + tmp_gc.data.width = tmp_gc.data.size = + tmp_gc.data.have = 1; + grid_view_set_cell(gd, xx, s->cy, &tmp_gc); + } else + grid_view_set_cell(gd, xx, s->cy, + &grid_default_cell); done = 1; } } diff --git a/usr.bin/tmux/window-copy.c b/usr.bin/tmux/window-copy.c index 148b32f5189..1a6c6690705 100644 --- a/usr.bin/tmux/window-copy.c +++ b/usr.bin/tmux/window-copy.c @@ -1,4 +1,4 @@ -/* $OpenBSD: window-copy.c,v 1.363 2024/11/05 09:41:17 nicm Exp $ */ +/* $OpenBSD: window-copy.c,v 1.364 2024/11/08 08:51:36 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott @@ -3098,14 +3098,16 @@ static int window_copy_search_lr(struct grid *gd, struct grid *sgd, u_int *ppx, u_int py, u_int first, u_int last, int cis) { - u_int ax, bx, px, pywrap, endline; + u_int ax, bx, px, pywrap, endline, padding; int matched; struct grid_line *gl; + struct grid_cell gc; endline = gd->hsize + gd->sy - 1; for (ax = first; ax < last; ax++) { + padding = 0; for (bx = 0; bx < sgd->sx; bx++) { - px = ax + bx; + px = ax + bx + padding; pywrap = py; /* Wrap line. */ while (px >= gd->sx && pywrap < endline) { @@ -3116,8 +3118,13 @@ window_copy_search_lr(struct grid *gd, struct grid *sgd, u_int *ppx, u_int py, pywrap++; } /* We have run off the end of the grid. */ - if (px >= gd->sx) + if (px - padding >= gd->sx) break; + + grid_get_cell(gd, px, pywrap, &gc); + if (gc.flags & GRID_FLAG_TAB) + padding += gc.data.width - 1; + matched = window_copy_search_compare(gd, px, pywrap, sgd, bx, cis); if (!matched) @@ -3135,14 +3142,16 @@ static int window_copy_search_rl(struct grid *gd, struct grid *sgd, u_int *ppx, u_int py, u_int first, u_int last, int cis) { - u_int ax, bx, px, pywrap, endline; + u_int ax, bx, px, pywrap, endline, padding; int matched; struct grid_line *gl; + struct grid_cell gc; endline = gd->hsize + gd->sy - 1; for (ax = last; ax > first; ax--) { + padding = 0; for (bx = 0; bx < sgd->sx; bx++) { - px = ax - 1 + bx; + px = ax - 1 + bx + padding; pywrap = py; /* Wrap line. */ while (px >= gd->sx && pywrap < endline) { @@ -3153,8 +3162,13 @@ window_copy_search_rl(struct grid *gd, pywrap++; } /* We have run off the end of the grid. */ - if (px >= gd->sx) + if (px - padding >= gd->sx) break; + + grid_get_cell(gd, px, pywrap, &gc); + if (gc.flags & GRID_FLAG_TAB) + padding += gc.data.width - 1; + matched = window_copy_search_compare(gd, px, pywrap, sgd, bx, cis); if (!matched) @@ -3875,10 +3889,12 @@ window_copy_search_marks(struct window_mode_entry *wme, struct screen *ssp, struct screen *s = data->backing, ss; struct screen_write_ctx ctx; struct grid *gd = s->grid; + struct grid_cell gc; int found, cis, stopped = 0; int cflags = REG_EXTENDED; - u_int px, py, i, b, nfound = 0, width; - u_int ssize = 1, start, end; + u_int px, py, i, b, nfound = 0, width, tw; + u_int ssize = 1, start, end, sx = gd->sx; + u_int sy = gd->sy; char *sbuf; regex_t reg; uint64_t stop = 0, tstart, t; @@ -3915,13 +3931,13 @@ window_copy_search_marks(struct window_mode_entry *wme, struct screen *ssp, window_copy_visible_lines(data, &start, &end); else { start = 0; - end = gd->hsize + gd->sy; + end = gd->hsize + sy; stop = get_timer() + WINDOW_COPY_SEARCH_ALL_TIMEOUT; } again: free(data->searchmark); - data->searchmark = xcalloc(gd->sx, gd->sy); + data->searchmark = xcalloc(sx, sy); data->searchgen = 1; for (py = start; py < end; py++) { @@ -3929,21 +3945,34 @@ again: for (;;) { if (regex) { found = window_copy_search_lr_regex(gd, - &px, &width, py, px, gd->sx, ®); + &px, &width, py, px, sx, ®); + grid_get_cell(gd, px + width - 1, py, &gc); + if (gc.data.width > 2) + width += gc.data.width - 1; if (!found) break; } else { found = window_copy_search_lr(gd, ssp->grid, - &px, py, px, gd->sx, cis); + &px, py, px, sx, cis); if (!found) break; } nfound++; + tw = width; if (window_copy_search_mark_at(data, px, py, &b) == 0) { - if (b + width > gd->sx * gd->sy) - width = (gd->sx * gd->sy) - b; - for (i = b; i < b + width; i++) { + if (b + width > sx * sy) + width = (sx * sy) - b; + tw = width; + for (i = b; i < b + tw; i++) { + if (!regex) { + grid_get_cell(gd, px + (i - b), + py, &gc); + if (gc.flags & GRID_FLAG_TAB) + tw += gc.data.width - 1; + if (b + tw > sx * sy) + tw = (sx * sy) - b; + } if (data->searchmark[i] != 0) continue; data->searchmark[i] = data->searchgen; @@ -3953,7 +3982,7 @@ again: else data->searchgen++; } - px += width; + px += tw; } t = get_timer(); -- cgit v1.2.3