From 9a569e26b820026b63a93d354730bfbb40076eed Mon Sep 17 00:00:00 2001 From: nicm Date: Fri, 5 Feb 2021 12:29:18 +0000 Subject: [PATCH] Send Unicode directional isolate characters around horizontal pane borders if the terminal support UTF-8 and an extension terminfo(5) capability "Bidi" is present. On terminals with BiDi support (ie, VTE) this seems to be enough to display right-to-left text acceptably enough to be usable (with some caveats about the mouse position). Requested by and with help from Mahmoud Elagdar in GitHub issue 2425. --- usr.bin/tmux/grid.c | 6 +++--- usr.bin/tmux/screen-redraw.c | 26 ++++++++++++++++++++------ usr.bin/tmux/tmux.1 | 6 +++++- usr.bin/tmux/tmux.h | 3 ++- usr.bin/tmux/tty-term.c | 3 ++- 5 files changed, 32 insertions(+), 12 deletions(-) diff --git a/usr.bin/tmux/grid.c b/usr.bin/tmux/grid.c index 6f4013abd8e..29f7d194b8b 100644 --- a/usr.bin/tmux/grid.c +++ b/usr.bin/tmux/grid.c @@ -1,4 +1,4 @@ -/* $OpenBSD: grid.c,v 1.120 2021/01/18 10:27:54 nicm Exp $ */ +/* $OpenBSD: grid.c,v 1.121 2021/02/05 12:29:18 nicm Exp $ */ /* * Copyright (c) 2008 Nicholas Marriott @@ -1045,14 +1045,14 @@ grid_duplicate_lines(struct grid *dst, u_int dy, struct grid *src, u_int sy, srcl->cellsize * sizeof *dstl->celldata); } else dstl->celldata = NULL; - if (srcl->extdsize != 0) { dstl->extdsize = srcl->extdsize; dstl->extddata = xreallocarray(NULL, dstl->extdsize, sizeof *dstl->extddata); memcpy(dstl->extddata, srcl->extddata, dstl->extdsize * sizeof *dstl->extddata); - } + } else + dstl->extddata = NULL; sy++; dy++; diff --git a/usr.bin/tmux/screen-redraw.c b/usr.bin/tmux/screen-redraw.c index 542b9b58cd7..38ecd2c4f9a 100644 --- a/usr.bin/tmux/screen-redraw.c +++ b/usr.bin/tmux/screen-redraw.c @@ -1,4 +1,4 @@ -/* $OpenBSD: screen-redraw.c,v 1.82 2020/12/07 09:46:58 nicm Exp $ */ +/* $OpenBSD: screen-redraw.c,v 1.83 2021/02/05 12:29:18 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott @@ -32,8 +32,8 @@ static void screen_redraw_set_context(struct client *, struct screen_redraw_ctx *); #define CELL_INSIDE 0 -#define CELL_LEFTRIGHT 1 -#define CELL_TOPBOTTOM 2 +#define CELL_TOPBOTTOM 1 +#define CELL_LEFTRIGHT 2 #define CELL_TOPLEFT 3 #define CELL_TOPRIGHT 4 #define CELL_BOTTOMLEFT 5 @@ -47,6 +47,9 @@ static void screen_redraw_set_context(struct client *, #define CELL_BORDERS " xqlkmjwvtun~" +#define START_ISOLATE "\342\201\246" +#define END_ISOLATE "\342\201\251" + static const struct utf8_data screen_redraw_double_borders[] = { { "", 0, 0, 0 }, { "\342\225\221", 0, 3, 1 }, /* U+2551 */ @@ -299,7 +302,7 @@ screen_redraw_type_of_cell(struct client *c, u_int px, u_int py, case 13: /* 1101, left right bottom */ return (CELL_TOPJOIN); case 12: /* 1100, left right */ - return (CELL_TOPBOTTOM); + return (CELL_LEFTRIGHT); case 11: /* 1011, left top bottom */ return (CELL_RIGHTJOIN); case 10: /* 1010, left top */ @@ -313,7 +316,7 @@ screen_redraw_type_of_cell(struct client *c, u_int px, u_int py, case 5: /* 0101, right bottom */ return (CELL_TOPLEFT); case 3: /* 0011, top bottom */ - return (CELL_LEFTRIGHT); + return (CELL_TOPBOTTOM); } return (CELL_OUTSIDE); } @@ -680,7 +683,7 @@ screen_redraw_draw_borders_cell(struct screen_redraw_ctx *ctx, u_int i, u_int j) struct tty *tty = &c->tty; struct window_pane *wp; u_int cell_type, x = ctx->ox + i, y = ctx->oy + j; - int pane_status = ctx->pane_status; + int pane_status = ctx->pane_status, isolates; struct grid_cell gc; const struct grid_cell *tmp; @@ -705,11 +708,22 @@ screen_redraw_draw_borders_cell(struct screen_redraw_ctx *ctx, u_int i, u_int j) } screen_redraw_border_set(wp, ctx->pane_lines, cell_type, &gc); + if (cell_type == CELL_TOPBOTTOM && + (c->flags & CLIENT_UTF8) && + tty_term_has(tty->term, TTYC_BIDI)) + isolates = 1; + else + isolates = 0; + if (ctx->statustop) tty_cursor(tty, i, ctx->statuslines + j); else tty_cursor(tty, i, j); + if (isolates) + tty_puts(tty, END_ISOLATE); tty_cell(tty, &gc, &grid_default_cell, NULL); + if (isolates) + tty_puts(tty, START_ISOLATE); } /* Draw the borders. */ diff --git a/usr.bin/tmux/tmux.1 b/usr.bin/tmux/tmux.1 index 831005bc7d4..2816e084004 100644 --- a/usr.bin/tmux/tmux.1 +++ b/usr.bin/tmux/tmux.1 @@ -1,4 +1,4 @@ -.\" $OpenBSD: tmux.1,v 1.817 2021/02/05 12:23:49 nicm Exp $ +.\" $OpenBSD: tmux.1,v 1.818 2021/02/05 12:29:18 nicm Exp $ .\" .\" Copyright (c) 2007 Nicholas Marriott .\" @@ -5953,6 +5953,10 @@ option should be used. An existing extension that tells .Nm the terminal supports default colours. +.It Em \&Bidi +Tell +.Nm +that the terminal supports the VTE bidirectional text extensions. .It Em \&Cs , Cr Set the cursor colour. The first takes a single string argument and is used to set the colour; diff --git a/usr.bin/tmux/tmux.h b/usr.bin/tmux/tmux.h index 77d20a0106f..3ad7d9d4f80 100644 --- a/usr.bin/tmux/tmux.h +++ b/usr.bin/tmux/tmux.h @@ -1,4 +1,4 @@ -/* $OpenBSD: tmux.h,v 1.1087 2021/01/29 09:48:43 nicm Exp $ */ +/* $OpenBSD: tmux.h,v 1.1088 2021/02/05 12:29:19 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott @@ -261,6 +261,7 @@ enum tty_code_code { TTYC_AX, TTYC_BCE, TTYC_BEL, + TTYC_BIDI, TTYC_BLINK, TTYC_BOLD, TTYC_CIVIS, diff --git a/usr.bin/tmux/tty-term.c b/usr.bin/tmux/tty-term.c index 09c907d3c66..2f4722b19f6 100644 --- a/usr.bin/tmux/tty-term.c +++ b/usr.bin/tmux/tty-term.c @@ -1,4 +1,4 @@ -/* $OpenBSD: tty-term.c,v 1.85 2020/10/13 07:29:24 nicm Exp $ */ +/* $OpenBSD: tty-term.c,v 1.86 2021/02/05 12:29:19 nicm Exp $ */ /* * Copyright (c) 2008 Nicholas Marriott @@ -58,6 +58,7 @@ static const struct tty_term_code_entry tty_term_codes[] = { [TTYC_AX] = { TTYCODE_FLAG, "AX" }, [TTYC_BCE] = { TTYCODE_FLAG, "bce" }, [TTYC_BEL] = { TTYCODE_STRING, "bel" }, + [TTYC_BIDI] = { TTYCODE_STRING, "Bidi" }, [TTYC_BLINK] = { TTYCODE_STRING, "blink" }, [TTYC_BOLD] = { TTYCODE_STRING, "bold" }, [TTYC_CIVIS] = { TTYCODE_STRING, "civis" }, -- 2.20.1