summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNicholas Marriott <nicm@cvs.openbsd.org>2024-11-08 08:51:37 +0000
committerNicholas Marriott <nicm@cvs.openbsd.org>2024-11-08 08:51:37 +0000
commit80a557e14f0fc4aac1a920de028e43fb4b6259dd (patch)
tree2401027291852bdb46c87ba62edf2ed1d11bcd64
parent5f64f3553ccef70f3e4561f07ea7a0cc75632238 (diff)
Some fixes for searching for tabs, from Alexander Arch.
-rw-r--r--usr.bin/tmux/grid.c12
-rw-r--r--usr.bin/tmux/screen-write.c18
-rw-r--r--usr.bin/tmux/window-copy.c63
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 <nicholas.marriott@gmail.com>
@@ -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 <nicholas.marriott@gmail.com>
@@ -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 <nicholas.marriott@gmail.com>
@@ -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, &reg);
+ &px, &width, py, px, sx, &reg);
+ 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();