diff --git a/usr.bin/tmux/screen-write.c b/usr.bin/tmux/screen-write.c index e51c088e9e2..b7ad250482a 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.268 2026/06/11 19:50:23 nicm Exp $ */ +/* $OpenBSD: screen-write.c,v 1.269 2026/06/15 07:40:45 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott @@ -1127,6 +1127,25 @@ screen_write_backspace(struct screen_write_ctx *ctx) screen_write_set_cursor(ctx, cx, cy); } +/* Is this cell a single ASCII character? */ +static int +screen_write_cell_is_single(const struct grid_cell *gc) +{ + if (gc->data.width != 1) + return (0); + if (gc->data.size != 1) + return (0); + if (*gc->data.data < 0x20 || *gc->data.data == 0x7f) + return (0); + if (gc->flags & GRID_FLAG_CLEARED) + return (0); + if (gc->flags & GRID_FLAG_PADDING) + return (0); + if (gc->flags & GRID_FLAG_TAB) + return (0); + return (1); +} + /* Redraw all visible cells on a line. */ static void screen_write_redraw_line(struct screen_write_ctx *ctx, struct tty_ctx *ttyctx, @@ -1135,11 +1154,14 @@ screen_write_redraw_line(struct screen_write_ctx *ctx, struct tty_ctx *ttyctx, struct window_pane *wp = ctx->wp; struct screen *s = ctx->s; struct grid_cell gc, ngc; - u_int sx = screen_size_x(s), cx, i, n; + u_int sx = screen_size_x(s), cx, i; int xoff = wp->xoff, yoff = wp->yoff; struct visible_ranges *r; struct visible_range *ri; + if (s->mode & MODE_SYNC) + return; + r = screen_redraw_get_visible_ranges(wp, xoff, yoff + yy, sx, NULL); for (i = 0; i < r->used; i++) { ri = &r->ranges[i]; @@ -1147,20 +1169,34 @@ screen_write_redraw_line(struct screen_write_ctx *ctx, struct tty_ctx *ttyctx, continue; cx = ri->px - xoff; - for (n = 0; n < ri->nx && cx < sx; n++, cx++) { - grid_view_get_cell(s->grid, cx, yy, &gc); - if (~gc.flags & GRID_FLAG_SELECTED) - ttyctx->cell = &gc; - else { - screen_select_cell(s, &ngc, &gc); - ttyctx->cell = &ngc; - } + if (cx >= sx) + continue; + if (cx + ri->nx > sx) + ttyctx->n = sx - cx; + else + ttyctx->n = ri->nx; + if (ttyctx->n == 0) + continue; + ttyctx->ocx = cx; + ttyctx->ocy = yy; - ttyctx->ocx = cx; - ttyctx->ocy = yy; - if (~s->mode & MODE_SYNC) - tty_write(tty_cmd_cell, ttyctx); + if (ttyctx->n != 1) { + tty_write(tty_cmd_redrawline, ttyctx); + continue; } + + grid_view_get_cell(s->grid, cx, yy, &gc); + if (!screen_write_cell_is_single(&gc)) { + tty_write(tty_cmd_redrawline, ttyctx); + continue; + } + if (~gc.flags & GRID_FLAG_SELECTED) + ttyctx->cell = &gc; + else { + screen_select_cell(s, &ngc, &gc); + ttyctx->cell = &ngc; + } + tty_write(tty_cmd_cell, ttyctx); } } diff --git a/usr.bin/tmux/tmux.h b/usr.bin/tmux/tmux.h index 73bfcc9cff1..8875d3564c0 100644 --- a/usr.bin/tmux/tmux.h +++ b/usr.bin/tmux/tmux.h @@ -1,4 +1,4 @@ -/* $OpenBSD: tmux.h,v 1.1349 2026/06/14 19:31:37 nicm Exp $ */ +/* $OpenBSD: tmux.h,v 1.1350 2026/06/15 07:40:45 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott @@ -2697,6 +2697,7 @@ void tty_write(void (*)(struct tty *, const struct tty_ctx *), void tty_cmd_alignmenttest(struct tty *, const struct tty_ctx *); void tty_cmd_cell(struct tty *, const struct tty_ctx *); void tty_cmd_cells(struct tty *, const struct tty_ctx *); +void tty_cmd_redrawline(struct tty *, const struct tty_ctx *); void tty_cmd_clearendofline(struct tty *, const struct tty_ctx *); void tty_cmd_clearendofscreen(struct tty *, const struct tty_ctx *); void tty_cmd_clearline(struct tty *, const struct tty_ctx *); diff --git a/usr.bin/tmux/tty.c b/usr.bin/tmux/tty.c index 55224a511dc..b68e7eb7adb 100644 --- a/usr.bin/tmux/tty.c +++ b/usr.bin/tmux/tty.c @@ -1,4 +1,4 @@ -/* $OpenBSD: tty.c,v 1.471 2026/06/09 21:22:22 nicm Exp $ */ +/* $OpenBSD: tty.c,v 1.472 2026/06/15 07:40:45 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott @@ -1430,6 +1430,26 @@ tty_draw_pane(struct tty *tty, const struct tty_ctx *ctx, u_int py) } } +void +tty_cmd_redrawline(struct tty *tty, const struct tty_ctx *ctx) +{ + u_int i, x, rx, ry, j; + struct visible_ranges *r; + struct visible_range *rr; + + if (tty_clamp_line(tty, ctx, ctx->ocx, ctx->ocy, ctx->n, + &i, &x, &rx, &ry)) { + r = tty_check_overlay_range(tty, x, ry, rx); + for (j = 0; j < r->used; j++) { + rr = &r->ranges[j]; + if (rr->nx == 0) + continue; + tty_draw_line(tty, ctx->s, i + rr->px - x, + ctx->ocy, rr->nx, rr->px, ry, &ctx->style_ctx); + } + } +} + /* Check if character needs to be mapped for codeset. */ const struct grid_cell * tty_check_codeset(struct tty *tty, const struct grid_cell *gc)