summaryrefslogtreecommitdiff
path: root/usr.bin/tmux
diff options
context:
space:
mode:
authorNicholas Marriott <nicm@cvs.openbsd.org>2024-08-21 05:03:14 +0000
committerNicholas Marriott <nicm@cvs.openbsd.org>2024-08-21 05:03:14 +0000
commitdae59270f9a4603c63e6cedfb23356f8f0e24461 (patch)
tree63c26b304005fb76c38ffee92c4778a2c686d279 /usr.bin/tmux
parentc521036e8b2da3d5e8149d4555c4d84e9575d8e4 (diff)
Add mirrored versions of the main-horizontal and main-vertical layouts where
the main pane is bottom or right instead of top or left, from Sherwyn Sen.
Diffstat (limited to 'usr.bin/tmux')
-rw-r--r--usr.bin/tmux/key-bindings.c4
-rw-r--r--usr.bin/tmux/layout-set.c202
-rw-r--r--usr.bin/tmux/status.c7
-rw-r--r--usr.bin/tmux/tmux.140
4 files changed, 235 insertions, 18 deletions
diff --git a/usr.bin/tmux/key-bindings.c b/usr.bin/tmux/key-bindings.c
index d2fa869ede3..c900084c726 100644
--- a/usr.bin/tmux/key-bindings.c
+++ b/usr.bin/tmux/key-bindings.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: key-bindings.c,v 1.148 2023/08/15 09:51:48 nicm Exp $ */
+/* $OpenBSD: key-bindings.c,v 1.149 2024/08/21 05:03:13 nicm Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicholas.marriott@gmail.com>
@@ -413,6 +413,8 @@ key_bindings_init(void)
"bind -N 'Set the main-horizontal layout' M-3 { select-layout main-horizontal }",
"bind -N 'Set the main-vertical layout' M-4 { select-layout main-vertical }",
"bind -N 'Select the tiled layout' M-5 { select-layout tiled }",
+ "bind -N 'Set the main-horizontal-mirrored layout' M-6 { select-layout main-horizontal-mirrored }",
+ "bind -N 'Set the main-vertical-mirrored layout' M-7 { select-layout main-vertical-mirrored }",
"bind -N 'Select the next window with an alert' M-n { next-window -a }",
"bind -N 'Rotate through the panes in reverse' M-o { rotate-window -D }",
"bind -N 'Select the previous window with an alert' M-p { previous-window -a }",
diff --git a/usr.bin/tmux/layout-set.c b/usr.bin/tmux/layout-set.c
index e289b690d79..40501964e91 100644
--- a/usr.bin/tmux/layout-set.c
+++ b/usr.bin/tmux/layout-set.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: layout-set.c,v 1.30 2021/03/11 06:31:05 nicm Exp $ */
+/* $OpenBSD: layout-set.c,v 1.31 2024/08/21 05:03:13 nicm Exp $ */
/*
* Copyright (c) 2009 Nicholas Marriott <nicholas.marriott@gmail.com>
@@ -31,7 +31,9 @@
static void layout_set_even_h(struct window *);
static void layout_set_even_v(struct window *);
static void layout_set_main_h(struct window *);
+static void layout_set_main_h_mirrored(struct window *);
static void layout_set_main_v(struct window *);
+static void layout_set_main_v_mirrored(struct window *);
static void layout_set_tiled(struct window *);
static const struct {
@@ -41,7 +43,9 @@ static const struct {
{ "even-horizontal", layout_set_even_h },
{ "even-vertical", layout_set_even_v },
{ "main-horizontal", layout_set_main_h },
+ { "main-horizontal-mirrored", layout_set_main_h_mirrored },
{ "main-vertical", layout_set_main_v },
+ { "main-vertical-mirrored", layout_set_main_v_mirrored },
{ "tiled", layout_set_tiled },
};
@@ -280,6 +284,104 @@ layout_set_main_h(struct window *w)
}
static void
+layout_set_main_h_mirrored(struct window *w)
+{
+ struct window_pane *wp;
+ struct layout_cell *lc, *lcmain, *lcother, *lcchild;
+ u_int n, mainh, otherh, sx, sy;
+ char *cause;
+ const char *s;
+
+ layout_print_cell(w->layout_root, __func__, 1);
+
+ /* Get number of panes. */
+ n = window_count_panes(w);
+ if (n <= 1)
+ return;
+ n--; /* take off main pane */
+
+ /* Find available height - take off one line for the border. */
+ sy = w->sy - 1;
+
+ /* Get the main pane height. */
+ s = options_get_string(w->options, "main-pane-height");
+ mainh = args_string_percentage(s, 0, sy, sy, &cause);
+ if (cause != NULL) {
+ mainh = 24;
+ free(cause);
+ }
+
+ /* Work out the other pane height. */
+ if (mainh + PANE_MINIMUM >= sy) {
+ if (sy <= PANE_MINIMUM + PANE_MINIMUM)
+ mainh = PANE_MINIMUM;
+ else
+ mainh = sy - PANE_MINIMUM;
+ otherh = PANE_MINIMUM;
+ } else {
+ s = options_get_string(w->options, "other-pane-height");
+ otherh = args_string_percentage(s, 0, sy, sy, &cause);
+ if (cause != NULL || otherh == 0) {
+ otherh = sy - mainh;
+ free(cause);
+ } else if (otherh > sy || sy - otherh < mainh)
+ otherh = sy - mainh;
+ else
+ mainh = sy - otherh;
+ }
+
+ /* Work out what width is needed. */
+ sx = (n * (PANE_MINIMUM + 1)) - 1;
+ if (sx < w->sx)
+ sx = w->sx;
+
+ /* Free old tree and create a new root. */
+ layout_free(w);
+ lc = w->layout_root = layout_create_cell(NULL);
+ layout_set_size(lc, sx, mainh + otherh + 1, 0, 0);
+ layout_make_node(lc, LAYOUT_TOPBOTTOM);
+
+ /* Create the other pane. */
+ lcother = layout_create_cell(lc);
+ layout_set_size(lcother, sx, otherh, 0, 0);
+ if (n == 1) {
+ wp = TAILQ_NEXT(TAILQ_FIRST(&w->panes), entry);
+ layout_make_leaf(lcother, wp);
+ TAILQ_INSERT_TAIL(&lc->cells, lcother, entry);
+ } else {
+ layout_make_node(lcother, LAYOUT_LEFTRIGHT);
+ TAILQ_INSERT_TAIL(&lc->cells, lcother, entry);
+
+ /* Add the remaining panes as children. */
+ TAILQ_FOREACH(wp, &w->panes, entry) {
+ if (wp == TAILQ_FIRST(&w->panes))
+ continue;
+ lcchild = layout_create_cell(lcother);
+ layout_set_size(lcchild, PANE_MINIMUM, otherh, 0, 0);
+ layout_make_leaf(lcchild, wp);
+ TAILQ_INSERT_TAIL(&lcother->cells, lcchild, entry);
+ }
+ layout_spread_cell(w, lcother);
+ }
+
+ /* Create the main pane. */
+ lcmain = layout_create_cell(lc);
+ layout_set_size(lcmain, sx, mainh, 0, 0);
+ layout_make_leaf(lcmain, TAILQ_FIRST(&w->panes));
+ TAILQ_INSERT_TAIL(&lc->cells, lcmain, entry);
+
+ /* Fix cell offsets. */
+ layout_fix_offsets(w);
+ layout_fix_panes(w, NULL);
+
+ layout_print_cell(w->layout_root, __func__, 1);
+
+ window_resize(w, lc->sx, lc->sy, -1, -1);
+ notify_window("window-layout-changed", w);
+ server_redraw_window(w);
+}
+
+static void
layout_set_main_v(struct window *w)
{
struct window_pane *wp;
@@ -377,6 +479,104 @@ layout_set_main_v(struct window *w)
server_redraw_window(w);
}
+static void
+layout_set_main_v_mirrored(struct window *w)
+{
+ struct window_pane *wp;
+ struct layout_cell *lc, *lcmain, *lcother, *lcchild;
+ u_int n, mainw, otherw, sx, sy;
+ char *cause;
+ const char *s;
+
+ layout_print_cell(w->layout_root, __func__, 1);
+
+ /* Get number of panes. */
+ n = window_count_panes(w);
+ if (n <= 1)
+ return;
+ n--; /* take off main pane */
+
+ /* Find available width - take off one line for the border. */
+ sx = w->sx - 1;
+
+ /* Get the main pane width. */
+ s = options_get_string(w->options, "main-pane-width");
+ mainw = args_string_percentage(s, 0, sx, sx, &cause);
+ if (cause != NULL) {
+ mainw = 80;
+ free(cause);
+ }
+
+ /* Work out the other pane width. */
+ if (mainw + PANE_MINIMUM >= sx) {
+ if (sx <= PANE_MINIMUM + PANE_MINIMUM)
+ mainw = PANE_MINIMUM;
+ else
+ mainw = sx - PANE_MINIMUM;
+ otherw = PANE_MINIMUM;
+ } else {
+ s = options_get_string(w->options, "other-pane-width");
+ otherw = args_string_percentage(s, 0, sx, sx, &cause);
+ if (cause != NULL || otherw == 0) {
+ otherw = sx - mainw;
+ free(cause);
+ } else if (otherw > sx || sx - otherw < mainw)
+ otherw = sx - mainw;
+ else
+ mainw = sx - otherw;
+ }
+
+ /* Work out what height is needed. */
+ sy = (n * (PANE_MINIMUM + 1)) - 1;
+ if (sy < w->sy)
+ sy = w->sy;
+
+ /* Free old tree and create a new root. */
+ layout_free(w);
+ lc = w->layout_root = layout_create_cell(NULL);
+ layout_set_size(lc, mainw + otherw + 1, sy, 0, 0);
+ layout_make_node(lc, LAYOUT_LEFTRIGHT);
+
+ /* Create the other pane. */
+ lcother = layout_create_cell(lc);
+ layout_set_size(lcother, otherw, sy, 0, 0);
+ if (n == 1) {
+ wp = TAILQ_NEXT(TAILQ_FIRST(&w->panes), entry);
+ layout_make_leaf(lcother, wp);
+ TAILQ_INSERT_TAIL(&lc->cells, lcother, entry);
+ } else {
+ layout_make_node(lcother, LAYOUT_TOPBOTTOM);
+ TAILQ_INSERT_TAIL(&lc->cells, lcother, entry);
+
+ /* Add the remaining panes as children. */
+ TAILQ_FOREACH(wp, &w->panes, entry) {
+ if (wp == TAILQ_FIRST(&w->panes))
+ continue;
+ lcchild = layout_create_cell(lcother);
+ layout_set_size(lcchild, otherw, PANE_MINIMUM, 0, 0);
+ layout_make_leaf(lcchild, wp);
+ TAILQ_INSERT_TAIL(&lcother->cells, lcchild, entry);
+ }
+ layout_spread_cell(w, lcother);
+ }
+
+ /* Create the main pane. */
+ lcmain = layout_create_cell(lc);
+ layout_set_size(lcmain, mainw, sy, 0, 0);
+ layout_make_leaf(lcmain, TAILQ_FIRST(&w->panes));
+ TAILQ_INSERT_TAIL(&lc->cells, lcmain, entry);
+
+ /* Fix cell offsets. */
+ layout_fix_offsets(w);
+ layout_fix_panes(w, NULL);
+
+ layout_print_cell(w->layout_root, __func__, 1);
+
+ window_resize(w, lc->sx, lc->sy, -1, -1);
+ notify_window("window-layout-changed", w);
+ server_redraw_window(w);
+}
+
void
layout_set_tiled(struct window *w)
{
diff --git a/usr.bin/tmux/status.c b/usr.bin/tmux/status.c
index f85937fd961..17c7d4e69b6 100644
--- a/usr.bin/tmux/status.c
+++ b/usr.bin/tmux/status.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: status.c,v 1.243 2024/08/21 04:17:09 nicm Exp $ */
+/* $OpenBSD: status.c,v 1.244 2024/08/21 05:03:13 nicm Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicholas.marriott@gmail.com>
@@ -1626,8 +1626,9 @@ status_prompt_complete_list(u_int *size, const char *s, int at_start)
struct options_entry *o;
struct options_array_item *a;
const char *layouts[] = {
- "even-horizontal", "even-vertical", "main-horizontal",
- "main-vertical", "tiled", NULL
+ "even-horizontal", "even-vertical",
+ "main-horizontal", "main-horizontal-mirrored",
+ "main-vertical", "main-vertical-mirrored", "tiled", NULL
};
*size = 0;
diff --git a/usr.bin/tmux/tmux.1 b/usr.bin/tmux/tmux.1
index 983383c4f74..2008f393d48 100644
--- a/usr.bin/tmux/tmux.1
+++ b/usr.bin/tmux/tmux.1
@@ -1,4 +1,4 @@
-.\" $OpenBSD: tmux.1,v 1.948 2024/08/21 04:17:09 nicm Exp $
+.\" $OpenBSD: tmux.1,v 1.949 2024/08/21 05:03:13 nicm Exp $
.\"
.\" Copyright (c) 2007 Nicholas Marriott <nicholas.marriott@gmail.com>
.\"
@@ -370,8 +370,10 @@ Enter copy mode and scroll one page up.
Change to the pane above, below, to the left, or to the right of the current
pane.
.It M-1 to M-5
-Arrange panes in one of the five preset layouts: even-horizontal,
-even-vertical, main-horizontal, main-vertical, or tiled.
+Arrange panes in one of the seven preset layouts:
+even-horizontal, even-vertical,
+main-horizontal, main-horizontal-mirrored,
+main-vertical, main-vertical, or tiled.
.It Space
Arrange the current window in the next preset layout.
.It M-n
@@ -2162,14 +2164,20 @@ are spread from left to right in the leftover space at the bottom.
Use the
.Em main-pane-height
window option to specify the height of the top pane.
-.It Ic main-vertical
-Similar to
+.It Ic main-horizontal-mirrored
+The same as
.Ic main-horizontal
-but the large pane is placed on the left and the others spread from top to
-bottom along the right.
-See the
+but mirrored so the main pane is at the bottom of the window.
+.It Ic main-vertical
+A large (main) pane is shown on the left of the window and the remaining panes
+are spread from top to bottom in the leftover space on the right.
+Use the
.Em main-pane-width
-window option.
+window option to specify the width of the left pane.
+.It Ic main-vertical-mirrored
+The same as
+.Ic main-vertical
+but mirrored so the main pane is on the right of the window.
.It Ic tiled
Panes are spread out as evenly as possible over the window in both rows and
columns.
@@ -4483,9 +4491,11 @@ Set the character used to fill areas of the terminal unused by a window.
.It Ic main-pane-height Ar height
.It Ic main-pane-width Ar width
Set the width or height of the main (left or top) pane in the
-.Ic main-horizontal
+.Ic main-horizontal,
+.Ic main-horizontal-mirrored,
+.Ic main-vertical,
or
-.Ic main-vertical
+.Ic main-vertical-mirrored
layouts.
If suffixed by
.Ql % ,
@@ -4559,7 +4569,9 @@ An interval of zero disables the monitoring.
.It Ic other-pane-height Ar height
Set the height of the other panes (not the main pane) in the
.Ic main-horizontal
-layout.
+and
+.Ic main-horizontal-mirrored
+layouts.
If this option is set to 0 (the default), it will have no effect.
If both the
.Ic main-pane-height
@@ -4576,7 +4588,9 @@ Like
.Ic other-pane-height ,
but set the width of other panes in the
.Ic main-vertical
-layout.
+and
+.Ic main-vertical-mirrored
+layouts.
.Pp
.It Ic pane-active-border-style Ar style
Set the pane border style for the currently active pane.