summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--cmd-select-layout.c27
-rw-r--r--key-bindings.c1
-rw-r--r--layout-set.c82
-rw-r--r--layout.c58
-rw-r--r--tmux.16
-rw-r--r--tmux.h2
6 files changed, 93 insertions, 83 deletions
diff --git a/cmd-select-layout.c b/cmd-select-layout.c
index e32f115d..28737c18 100644
--- a/cmd-select-layout.c
+++ b/cmd-select-layout.c
@@ -33,10 +33,10 @@ const struct cmd_entry cmd_select_layout_entry = {
.name = "select-layout",
.alias = "selectl",
- .args = { "nopt:", 0, 1 },
- .usage = "[-nop] " CMD_TARGET_WINDOW_USAGE " [layout-name]",
+ .args = { "Enopt:", 0, 1 },
+ .usage = "[-Enop] " CMD_TARGET_PANE_USAGE " [layout-name]",
- .target = { 't', CMD_FIND_WINDOW, 0 },
+ .target = { 't', CMD_FIND_PANE, 0 },
.flags = CMD_AFTERHOOK,
.exec = cmd_select_layout_exec
@@ -71,14 +71,14 @@ const struct cmd_entry cmd_previous_layout_entry = {
static enum cmd_retval
cmd_select_layout_exec(struct cmd *self, struct cmdq_item *item)
{
- struct args *args = self->args;
- struct winlink *wl = item->target.wl;
- struct window *w;
- const char *layoutname;
- char *oldlayout;
- int next, previous, layout;
-
- w = wl->window;
+ struct args *args = self->args;
+ struct winlink *wl = item->target.wl;
+ struct window *w = wl->window;
+ struct window_pane *wp = item->target.wp;
+ const char *layoutname;
+ char *oldlayout;
+ int next, previous, layout;
+
server_unzoom_window(w);
next = self->entry == &cmd_next_layout_entry;
@@ -99,6 +99,11 @@ cmd_select_layout_exec(struct cmd *self, struct cmdq_item *item)
goto changed;
}
+ if (args_has(args, 'E')) {
+ layout_spread_out(wp);
+ goto changed;
+ }
+
if (!args_has(args, 'o')) {
if (args->argc == 0)
layout = w->lastlayout;
diff --git a/key-bindings.c b/key-bindings.c
index 76778009..a13c7977 100644
--- a/key-bindings.c
+++ b/key-bindings.c
@@ -186,6 +186,7 @@ key_bindings_init(void)
"bind = choose-buffer",
"bind ? list-keys",
"bind D choose-client",
+ "bind E select-layout -E",
"bind L switch-client -l",
"bind M select-pane -M",
"bind [ copy-mode",
diff --git a/layout-set.c b/layout-set.c
index 7ba18fea..0f01cbcc 100644
--- a/layout-set.c
+++ b/layout-set.c
@@ -115,11 +115,11 @@ layout_set_previous(struct window *w)
}
static void
-layout_set_even_h(struct window *w)
+layout_set_even(struct window *w, enum layout_type type)
{
struct window_pane *wp;
struct layout_cell *lc, *lcnew;
- u_int i, n, width, xoff;
+ u_int n;
layout_print_cell(w->layout_root, __func__, 1);
@@ -128,36 +128,21 @@ layout_set_even_h(struct window *w)
if (n <= 1)
return;
- /* How many can we fit? */
- width = (w->sx - (n - 1)) / n;
- if (width < PANE_MINIMUM)
- width = PANE_MINIMUM;
-
/* Free the old root and construct a new. */
layout_free(w);
lc = w->layout_root = layout_create_cell(NULL);
layout_set_size(lc, w->sx, w->sy, 0, 0);
- layout_make_node(lc, LAYOUT_LEFTRIGHT);
+ layout_make_node(lc, type);
/* Build new leaf cells. */
- i = xoff = 0;
TAILQ_FOREACH(wp, &w->panes, entry) {
- /* Create child cell. */
lcnew = layout_create_cell(lc);
- layout_set_size(lcnew, width, w->sy, xoff, 0);
layout_make_leaf(lcnew, wp);
TAILQ_INSERT_TAIL(&lc->cells, lcnew, entry);
-
- i++;
- xoff += width + 1;
}
- /* Allocate any remaining space. */
- if (w->sx > xoff - 1) {
- lc = TAILQ_LAST(&lc->cells, layout_cells);
- layout_resize_adjust(w, lc, LAYOUT_LEFTRIGHT,
- w->sx - (xoff - 1));
- }
+ /* Spread out cells. */
+ layout_spread_cell(w, lc);
/* Fix cell offsets. */
layout_fix_offsets(lc);
@@ -170,58 +155,15 @@ layout_set_even_h(struct window *w)
}
static void
-layout_set_even_v(struct window *w)
+layout_set_even_h(struct window *w)
{
- struct window_pane *wp;
- struct layout_cell *lc, *lcnew;
- u_int i, n, height, yoff;
-
- layout_print_cell(w->layout_root, __func__, 1);
-
- /* Get number of panes. */
- n = window_count_panes(w);
- if (n <= 1)
- return;
-
- /* How many can we fit? */
- height = (w->sy - (n - 1)) / n;
- if (height < PANE_MINIMUM)
- height = PANE_MINIMUM;
-
- /* Free the old root and construct a new. */
- layout_free(w);
- lc = w->layout_root = layout_create_cell(NULL);
- layout_set_size(lc, w->sx, w->sy, 0, 0);
- layout_make_node(lc, LAYOUT_TOPBOTTOM);
-
- /* Build new leaf cells. */
- i = yoff = 0;
- TAILQ_FOREACH(wp, &w->panes, entry) {
- /* Create child cell. */
- lcnew = layout_create_cell(lc);
- layout_set_size(lcnew, w->sx, height, 0, yoff);
- layout_make_leaf(lcnew, wp);
- TAILQ_INSERT_TAIL(&lc->cells, lcnew, entry);
-
- i++;
- yoff += height + 1;
- }
-
- /* Allocate any remaining space. */
- if (w->sy > yoff - 1) {
- lc = TAILQ_LAST(&lc->cells, layout_cells);
- layout_resize_adjust(w, lc, LAYOUT_TOPBOTTOM,
- w->sy - (yoff - 1));
- }
-
- /* Fix cell offsets. */
- layout_fix_offsets(lc);
- layout_fix_panes(w, w->sx, w->sy);
-
- layout_print_cell(w->layout_root, __func__, 1);
+ layout_set_even(w, LAYOUT_LEFTRIGHT);
+}
- notify_window("window-layout-changed", w);
- server_redraw_window(w);
+static void
+layout_set_even_v(struct window *w)
+{
+ layout_set_even(w, LAYOUT_TOPBOTTOM);
}
static void
diff --git a/layout.c b/layout.c
index 5c2224bb..2c6fe2b2 100644
--- a/layout.c
+++ b/layout.c
@@ -983,3 +983,61 @@ layout_close_pane(struct window_pane *wp)
}
notify_window("window-layout-changed", w);
}
+
+int
+layout_spread_cell(struct window *w, struct layout_cell *parent)
+{
+ struct layout_cell *lc;
+ u_int number, each, size;
+ int change, changed;
+
+ number = 0;
+ TAILQ_FOREACH (lc, &parent->cells, entry)
+ number++;
+ if (number <= 1)
+ return (0);
+
+ if (parent->type == LAYOUT_LEFTRIGHT)
+ size = parent->sx;
+ else if (parent->type == LAYOUT_TOPBOTTOM)
+ size = parent->sy;
+ else
+ return (0);
+ each = (size - (number - 1)) / number;
+
+ changed = 0;
+ TAILQ_FOREACH (lc, &parent->cells, entry) {
+ if (TAILQ_NEXT(lc, entry) == NULL)
+ each = size - (each * (number - 1));
+ change = 0;
+ if (parent->type == LAYOUT_LEFTRIGHT) {
+ change = each - (int)lc->sx;
+ layout_resize_adjust(w, lc, LAYOUT_LEFTRIGHT, change);
+ } else if (parent->type == LAYOUT_TOPBOTTOM) {
+ change = each - (int)lc->sy;
+ layout_resize_adjust(w, lc, LAYOUT_TOPBOTTOM, change);
+ }
+ if (change != 0)
+ changed = 1;
+ }
+ return (changed);
+}
+
+void
+layout_spread_out(struct window_pane *wp)
+{
+ struct layout_cell *parent;
+ struct window *w = wp->window;
+
+ parent = wp->layout_cell->parent;
+ if (parent == NULL)
+ return;
+
+ do {
+ if (layout_spread_cell(w, parent)) {
+ layout_fix_offsets(parent);
+ layout_fix_panes(w, w->sx, w->sy);
+ break;
+ }
+ } while ((parent = parent->parent) != NULL);
+}
diff --git a/tmux.1 b/tmux.1
index a67a7274..4451283f 100644
--- a/tmux.1
+++ b/tmux.1
@@ -1923,8 +1923,8 @@ lower) with
.Fl U
or downward (numerically higher).
.It Xo Ic select-layout
-.Op Fl nop
-.Op Fl t Ar target-window
+.Op Fl Enop
+.Op Fl t Ar target-pane
.Op Ar layout-name
.Xc
.D1 (alias: Ic selectl )
@@ -1942,6 +1942,8 @@ and
commands.
.Fl o
applies the last set layout if possible (undoes the most recent layout change).
+.Fl E
+spreads the current pane and any panes next to it out evenly.
.It Xo Ic select-pane
.Op Fl DdegLlMmRU
.Op Fl P Ar style
diff --git a/tmux.h b/tmux.h
index 6381ff00..43d9d846 100644
--- a/tmux.h
+++ b/tmux.h
@@ -2213,6 +2213,8 @@ void layout_assign_pane(struct layout_cell *, struct window_pane *);
struct layout_cell *layout_split_pane(struct window_pane *, enum layout_type,
int, int, int);
void layout_close_pane(struct window_pane *);
+int layout_spread_cell(struct window *, struct layout_cell *);
+void layout_spread_out(struct window_pane *);
/* layout-custom.c */
char *layout_dump(struct layout_cell *);