Add option to show arrows for active pane indicator, GitHub issue 3022
authornicm <nicm@openbsd.org>
Tue, 1 Feb 2022 14:46:41 +0000 (14:46 +0000)
committernicm <nicm@openbsd.org>
Tue, 1 Feb 2022 14:46:41 +0000 (14:46 +0000)
from Marcel Partap.

usr.bin/tmux/options-table.c
usr.bin/tmux/screen-redraw.c
usr.bin/tmux/tmux.1
usr.bin/tmux/tmux.h

index 01b7c44..a355164 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: options-table.c,v 1.155 2021/12/13 09:42:20 nicm Exp $ */
+/* $OpenBSD: options-table.c,v 1.156 2022/02/01 14:46:41 nicm Exp $ */
 
 /*
  * Copyright (c) 2011 Nicholas Marriott <nicholas.marriott@gmail.com>
@@ -64,6 +64,9 @@ static const char *options_table_cursor_style_list[] = {
 static const char *options_table_pane_status_list[] = {
        "off", "top", "bottom", NULL
 };
+static const char *options_table_pane_border_indicators_list[] = {
+       "off", "colour", "arrows", "both", NULL
+};
 static const char *options_table_pane_border_lines_list[] = {
        "single", "double", "heavy", "simple", "number", NULL
 };
@@ -971,6 +974,15 @@ const struct options_table_entry options_table[] = {
          .text = "Format of text in the pane status lines."
        },
 
+       { .name = "pane-border-indicators",
+         .type = OPTIONS_TABLE_CHOICE,
+         .scope = OPTIONS_TABLE_WINDOW,
+         .choices = options_table_pane_border_indicators_list,
+         .default_num = PANE_BORDER_COLOUR,
+         .text = "Whether to indicate the active pane by colouring border or "
+                 "displaying arrow markers."
+       },
+
        { .name = "pane-border-lines",
          .type = OPTIONS_TABLE_CHOICE,
          .scope = OPTIONS_TABLE_WINDOW,
index 0fcec8f..77041cc 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: screen-redraw.c,v 1.92 2021/12/13 09:42:20 nicm Exp $ */
+/* $OpenBSD: screen-redraw.c,v 1.93 2022/02/01 14:46:41 nicm Exp $ */
 
 /*
  * Copyright (c) 2007 Nicholas Marriott <nicholas.marriott@gmail.com>
@@ -34,11 +34,16 @@ static void screen_redraw_set_context(struct client *,
 #define START_ISOLATE "\342\201\246"
 #define END_ISOLATE   "\342\201\251"
 
+/* Border in relation to a pane. */
 enum screen_redraw_border_type {
        SCREEN_REDRAW_OUTSIDE,
        SCREEN_REDRAW_INSIDE,
-       SCREEN_REDRAW_BORDER
+       SCREEN_REDRAW_BORDER_LEFT,
+       SCREEN_REDRAW_BORDER_RIGHT,
+       SCREEN_REDRAW_BORDER_TOP,
+       SCREEN_REDRAW_BORDER_BOTTOM
 };
+#define BORDER_MARKERS "  +,.-"
 
 /* Get cell border character. */
 static void
@@ -102,64 +107,74 @@ static enum screen_redraw_border_type
 screen_redraw_pane_border(struct window_pane *wp, u_int px, u_int py,
     int pane_status)
 {
-       u_int   ex = wp->xoff + wp->sx, ey = wp->yoff + wp->sy;
+       struct options  *oo = wp->window->options;
+       int              split = 0;
+       u_int            ex = wp->xoff + wp->sx, ey = wp->yoff + wp->sy;
 
        /* Inside pane. */
        if (px >= wp->xoff && px < ex && py >= wp->yoff && py < ey)
                return (SCREEN_REDRAW_INSIDE);
 
+       /* Get pane indicator. */
+       switch (options_get_number(oo, "pane-border-indicators")) {
+       case PANE_BORDER_COLOUR:
+       case PANE_BORDER_BOTH:
+               split = 1;
+               break;
+       }
+
        /* Left/right borders. */
        if (pane_status == PANE_STATUS_OFF) {
-               if (screen_redraw_two_panes(wp->window, 0)) {
+               if (screen_redraw_two_panes(wp->window, 0) && split) {
                        if (wp->xoff == 0 && px == wp->sx && py <= wp->sy / 2)
-                               return (SCREEN_REDRAW_BORDER);
+                               return (SCREEN_REDRAW_BORDER_RIGHT);
                        if (wp->xoff != 0 &&
                            px == wp->xoff - 1 &&
                            py > wp->sy / 2)
-                               return (SCREEN_REDRAW_BORDER);
+                               return (SCREEN_REDRAW_BORDER_LEFT);
                } else {
                        if ((wp->yoff == 0 || py >= wp->yoff - 1) && py <= ey) {
                                if (wp->xoff != 0 && px == wp->xoff - 1)
-                                       return (SCREEN_REDRAW_BORDER);
+                                       return (SCREEN_REDRAW_BORDER_LEFT);
                                if (px == ex)
-                                       return (SCREEN_REDRAW_BORDER);
+                                       return (SCREEN_REDRAW_BORDER_RIGHT);
                        }
                }
        } else {
                if ((wp->yoff == 0 || py >= wp->yoff - 1) && py <= ey) {
                        if (wp->xoff != 0 && px == wp->xoff - 1)
-                               return (SCREEN_REDRAW_BORDER);
+                               return (SCREEN_REDRAW_BORDER_LEFT);
                        if (px == ex)
-                               return (SCREEN_REDRAW_BORDER);
+                               return (SCREEN_REDRAW_BORDER_RIGHT);
                }
        }
 
        /* Top/bottom borders. */
        if (pane_status == PANE_STATUS_OFF) {
-               if (screen_redraw_two_panes(wp->window, 1)) {
+               if (screen_redraw_two_panes(wp->window, 1) && split) {
                        if (wp->yoff == 0 && py == wp->sy && px <= wp->sx / 2)
-                               return (SCREEN_REDRAW_BORDER);
+                               return (SCREEN_REDRAW_BORDER_BOTTOM);
                        if (wp->yoff != 0 &&
                            py == wp->yoff - 1 &&
                            px > wp->sx / 2)
-                               return (SCREEN_REDRAW_BORDER);
+                               return (SCREEN_REDRAW_BORDER_TOP);
                } else {
                        if ((wp->xoff == 0 || px >= wp->xoff - 1) && px <= ex) {
                                if (wp->yoff != 0 && py == wp->yoff - 1)
-                                       return (SCREEN_REDRAW_BORDER);
+                                       return (SCREEN_REDRAW_BORDER_TOP);
                                if (py == ey)
-                                       return (SCREEN_REDRAW_BORDER);
+                                       return (SCREEN_REDRAW_BORDER_BOTTOM);
                        }
                }
        } else if (pane_status == PANE_STATUS_TOP) {
                if ((wp->xoff == 0 || px >= wp->xoff - 1) && px <= ex) {
                        if (wp->yoff != 0 && py == wp->yoff - 1)
-                               return (SCREEN_REDRAW_BORDER);
+                               return (SCREEN_REDRAW_BORDER_TOP);
                }
        } else {
                if ((wp->xoff == 0 || px >= wp->xoff - 1) && px <= ex) {
                        if (py == ey)
-                               return (SCREEN_REDRAW_BORDER);
+                               return (SCREEN_REDRAW_BORDER_BOTTOM);
                }
        }
 
@@ -189,10 +204,10 @@ screen_redraw_cell_border(struct client *c, u_int px, u_int py, int pane_status)
                switch (screen_redraw_pane_border(wp, px, py, pane_status)) {
                case SCREEN_REDRAW_INSIDE:
                        return (0);
-               case SCREEN_REDRAW_BORDER:
-                       return (1);
                case SCREEN_REDRAW_OUTSIDE:
                        break;
+               default:
+                       return (1);
                }
        }
 
@@ -346,7 +361,7 @@ screen_redraw_check_is(u_int px, u_int py, int pane_status,
        enum screen_redraw_border_type  border;
 
        border = screen_redraw_pane_border(wp, px, py, pane_status);
-       if (border == SCREEN_REDRAW_BORDER)
+       if (border != SCREEN_REDRAW_INSIDE && border != SCREEN_REDRAW_OUTSIDE)
                return (1);
        return (0);
 }
@@ -637,11 +652,12 @@ screen_redraw_draw_borders_cell(struct screen_redraw_ctx *ctx, u_int i, u_int j)
        struct options          *oo = w->options;
        struct tty              *tty = &c->tty;
        struct format_tree      *ft;
-       struct window_pane      *wp;
+       struct window_pane      *wp, *active = server_client_get_pane(c);
        struct grid_cell         gc;
        const struct grid_cell  *tmp;
        struct overlay_ranges    r;
        u_int                    cell_type, x = ctx->ox + i, y = ctx->oy + j;
+       int                      arrows = 0, border;
        int                      pane_status = ctx->pane_status, isolates;
 
        if (c->overlay_check != NULL) {
@@ -689,6 +705,32 @@ screen_redraw_draw_borders_cell(struct screen_redraw_ctx *ctx, u_int i, u_int j)
                tty_cursor(tty, i, j);
        if (isolates)
                tty_puts(tty, END_ISOLATE);
+
+       switch (options_get_number(oo, "pane-border-indicators")) {
+       case PANE_BORDER_ARROWS:
+       case PANE_BORDER_BOTH:
+               arrows = 1;
+               break;
+       }
+
+       if (wp != NULL && arrows) {
+               border = screen_redraw_pane_border(active, x, y, pane_status);
+               if (((i == wp->xoff + 1 &&
+                   (cell_type == CELL_LEFTRIGHT ||
+                   (cell_type == CELL_TOPJOIN &&
+                   border == SCREEN_REDRAW_BORDER_BOTTOM) ||
+                   (cell_type == CELL_BOTTOMJOIN &&
+                   border == SCREEN_REDRAW_BORDER_TOP))) ||
+                   (j == wp->yoff + 1 &&
+                   (cell_type == CELL_TOPBOTTOM ||
+                   (cell_type == CELL_LEFTJOIN &&
+                   border == SCREEN_REDRAW_BORDER_RIGHT) ||
+                   (cell_type == CELL_RIGHTJOIN &&
+                   border == SCREEN_REDRAW_BORDER_LEFT)))) &&
+                   screen_redraw_check_is(x, y, pane_status, active))
+                       utf8_set(&gc.data, BORDER_MARKERS[border]);
+       }
+
        tty_cell(tty, &gc, &grid_default_cell, NULL);
        if (isolates)
                tty_puts(tty, START_ISOLATE);
index 5544294..7377829 100644 (file)
@@ -1,4 +1,4 @@
-.\" $OpenBSD: tmux.1,v 1.874 2022/02/01 12:05:42 nicm Exp $
+.\" $OpenBSD: tmux.1,v 1.875 2022/02/01 14:46:41 nicm Exp $
 .\"
 .\" Copyright (c) 2007 Nicholas Marriott <nicholas.marriott@gmail.com>
 .\"
@@ -4223,6 +4223,12 @@ but set the starting index for pane numbers.
 .It Ic pane-border-format Ar format
 Set the text shown in pane border status lines.
 .Pp
+.It Xo Ic pane-border-indicators
+.Op Ic off | colour | arrows | both
+.Xc
+Indicate active pane by colouring only half of the border in windows with
+exactly two panes, by displaying arrow markers, by drawing both or neither.
+.Pp
 .It Ic pane-border-lines Ar type
 Set the type of characters used for drawing pane borders.
 .Ar type
index 6017f6f..618d530 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: tmux.h,v 1.1157 2021/12/21 13:07:53 nicm Exp $ */
+/* $OpenBSD: tmux.h,v 1.1158 2022/02/01 14:46:42 nicm Exp $ */
 
 /*
  * Copyright (c) 2007 Nicholas Marriott <nicholas.marriott@gmail.com>
@@ -842,6 +842,12 @@ enum pane_lines {
        PANE_LINES_NUMBER
 };
 
+/* Pane border indicator option. */
+#define PANE_BORDER_OFF 0
+#define PANE_BORDER_COLOUR 1
+#define PANE_BORDER_ARROWS 2
+#define PANE_BORDER_BOTH 3
+
 /* Screen redraw context. */
 struct screen_redraw_ctx {
        struct client   *c;