Send Unicode directional isolate characters around horizontal pane
authornicm <nicm@openbsd.org>
Fri, 5 Feb 2021 12:29:18 +0000 (12:29 +0000)
committernicm <nicm@openbsd.org>
Fri, 5 Feb 2021 12:29:18 +0000 (12:29 +0000)
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
usr.bin/tmux/screen-redraw.c
usr.bin/tmux/tmux.1
usr.bin/tmux/tmux.h
usr.bin/tmux/tty-term.c

index 6f4013a..29f7d19 100644 (file)
@@ -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 <nicholas.marriott@gmail.com>
@@ -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++;
index 542b9b5..38ecd2c 100644 (file)
@@ -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 <nicholas.marriott@gmail.com>
@@ -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. */
index 831005b..2816e08 100644 (file)
@@ -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 <nicholas.marriott@gmail.com>
 .\"
@@ -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;
index 77d20a0..3ad7d9d 100644 (file)
@@ -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 <nicholas.marriott@gmail.com>
@@ -261,6 +261,7 @@ enum tty_code_code {
        TTYC_AX,
        TTYC_BCE,
        TTYC_BEL,
+       TTYC_BIDI,
        TTYC_BLINK,
        TTYC_BOLD,
        TTYC_CIVIS,
index 09c907d..2f4722b 100644 (file)
@@ -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 <nicholas.marriott@gmail.com>
@@ -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" },