summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authornicm <nicm>2022-02-01 14:46:41 +0000
committernicm <nicm>2022-02-01 14:46:41 +0000
commit7e34645fcbe93984461343d67373a29e552fec20 (patch)
treeb4b81dc0308de7512d854bfbe38167272684fbb3
parent7a4ba6d4a5458f4e2450024d72f0e16905dd5c64 (diff)
Add option to show arrows for active pane indicator, GitHub issue 3022
from Marcel Partap.
-rw-r--r--options-table.c12
-rw-r--r--screen-redraw.c82
-rw-r--r--tmux.16
-rw-r--r--tmux.h6
4 files changed, 86 insertions, 20 deletions
diff --git a/options-table.c b/options-table.c
index cfb8162e..5cbec546 100644
--- a/options-table.c
+++ b/options-table.c
@@ -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,
diff --git a/screen-redraw.c b/screen-redraw.c
index 5ef9e64c..8dd75f40 100644
--- a/screen-redraw.c
+++ b/screen-redraw.c
@@ -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);
diff --git a/tmux.1 b/tmux.1
index 5310b97f..7a8b9f24 100644
--- a/tmux.1
+++ b/tmux.1
@@ -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
diff --git a/tmux.h b/tmux.h
index 4f8016d3..6fc1490a 100644
--- a/tmux.h
+++ b/tmux.h
@@ -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;