Add mirrored versions of the main-horizontal and main-vertical layouts where
authornicm <nicm@openbsd.org>
Wed, 21 Aug 2024 05:03:13 +0000 (05:03 +0000)
committernicm <nicm@openbsd.org>
Wed, 21 Aug 2024 05:03:13 +0000 (05:03 +0000)
the main pane is bottom or right instead of top or left, from Sherwyn Sen.

usr.bin/tmux/key-bindings.c
usr.bin/tmux/layout-set.c
usr.bin/tmux/status.c
usr.bin/tmux/tmux.1

index d2fa869..c900084 100644 (file)
@@ -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 }",
index e289b69..4050196 100644 (file)
@@ -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 },
 };
 
@@ -279,6 +283,104 @@ layout_set_main_h(struct window *w)
        server_redraw_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)
 {
@@ -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)
 {
index f85937f..17c7d4e 100644 (file)
@@ -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;
index 983383c..2008f39 100644 (file)
@@ -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.