diff --git a/Makefile.am b/Makefile.am index a956035e..999e9909 100644 --- a/Makefile.am +++ b/Makefile.am @@ -115,7 +115,6 @@ dist_tmux_SOURCES = \ cmd-lock-server.c \ cmd-minimise-pane.c \ cmd-move-window.c \ - cmd-new-pane.c \ cmd-new-session.c \ cmd-new-window.c \ cmd-parse.y \ diff --git a/cmd-new-pane.c b/cmd-new-pane.c deleted file mode 100644 index 82a600e2..00000000 --- a/cmd-new-pane.c +++ /dev/null @@ -1,280 +0,0 @@ -/* $OpenBSD$ */ - -/* - * Copyright (c) 2009 Nicholas Marriott - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER - * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING - * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#include - -#include -#include -#include -#include -#include - -#include "tmux.h" - -#define NEW_PANE_TEMPLATE "#{session_name}:#{window_index}.#{pane_index}" - -static enum cmd_retval cmd_new_pane_exec(struct cmd *, - struct cmdq_item *); - -const struct cmd_entry cmd_new_pane_entry = { - .name = "new-pane", - .alias = "newp", - - .args = { "bc:de:fF:h:Iklm:p:PR:s:S:t:w:x:y:Z", 0, -1, NULL }, - .usage = "[-bdefhIklPvZ] [-c start-directory] [-e environment] " - "[-F format] [-l size] [-m message] " - "[-R inactive-border-style] [-s style] [-S active-border-style] " - CMD_TARGET_PANE_USAGE " [shell-command [argument ...]]", - - .target = { 't', CMD_FIND_PANE, 0 }, - - .flags = 0, - .exec = cmd_new_pane_exec -}; - - -static enum cmd_retval -cmd_new_pane_exec(struct cmd *self, struct cmdq_item *item) -{ - struct args *args = cmd_get_args(self); - struct cmd_find_state *current = cmdq_get_current(item); - struct cmd_find_state *target = cmdq_get_target(item); - struct spawn_context sc = { 0 }; - struct client *tc = cmdq_get_target_client(item); - struct session *s = target->s; - struct winlink *wl = target->wl; - struct window *w = wl->window; - struct window_pane *wp = target->wp, *new_wp; - struct layout_cell *lc; - struct cmd_find_state fs; - int flags, input; - const char *template, *style; - char *cause = NULL, *cp; - struct args_value *av; - u_int count = args_count(args); - int x, y; - u_int sx, sy, pct; - static int last_x = 0, last_y = 0; - - if (args_has(args, 'f')) { - sx = w->sx; - sy = w->sy; - } else { - if (args_has(args, 'l')) { - sx = args_percentage_and_expand(args, 'l', 0, INT_MAX, w->sx, - item, &cause); - sy = args_percentage_and_expand(args, 'l', 0, INT_MAX, w->sy, - item, &cause); - } else if (args_has(args, 'p')) { - pct = args_strtonum_and_expand(args, 'p', 0, 100, item, - &cause); - if (cause == NULL) { - sx = w->sx * pct / 100; - sy = w->sy * pct / 100; - } - } else if (cause == NULL) { - sx = w->sx / 2; - sy = w->sy / 2; - } - if (cause != NULL) { - cmdq_error(item, "size %s", cause); - free(cause); - return (CMD_RETURN_ERROR); - } - } - if (args_has(args, 'w')) { - sx = args_strtonum_and_expand(args, 'w', 1, USHRT_MAX, item, - &cause); - if (cause != NULL) { - cmdq_error(item, "size %s", cause); - free(cause); - return (CMD_RETURN_ERROR); - } - } - if (args_has(args, 'h')) { - sy = args_strtonum_and_expand(args, 'h', 1, USHRT_MAX, item, - &cause); - if (cause != NULL) { - cmdq_error(item, "size %s", cause); - free(cause); - return (CMD_RETURN_ERROR); - } - } - if (args_has(args, 'x')) { - x = args_strtonum_and_expand(args, 'x', SHRT_MIN, SHRT_MAX, - item, &cause); - if (cause != NULL) { - cmdq_error(item, "size %s", cause); - free(cause); - return (CMD_RETURN_ERROR); - } - } else { - if (last_x == 0) { - x = 5; - } else { - x = (last_x += 5); - if (last_x > (int)w->sx) - x = 5; - } - } - if (args_has(args, 'y')) { - y = args_strtonum_and_expand(args, 'y', SHRT_MIN, SHRT_MAX, - item, &cause); - if (cause != NULL) { - cmdq_error(item, "size %s", cause); - free(cause); - return (CMD_RETURN_ERROR); - } - } else { - if (last_y == 0) { - y = 5; - } else { - y = (last_y += 5); - if (last_y > (int)w->sy) - y = 5; - } - } - - input = (args_has(args, 'I') && count == 0); - - flags = SPAWN_FLOATING; - if (args_has(args, 'b')) - flags |= SPAWN_BEFORE; - if (args_has(args, 'f')) - flags |= SPAWN_FULLSIZE; - if (input || (count == 1 && *args_string(args, 0) == '\0')) - flags |= SPAWN_EMPTY; - - sc.item = item; - sc.s = s; - sc.wl = wl; - - sc.wp0 = wp; - - /* Floating panes sit in layout cells which are not in the layout_root - * tree so we call it with parent == NULL. - */ - lc = layout_create_cell(NULL); - lc->xoff = x; - lc->yoff = y; - lc->sx = sx; - lc->sy = sy; - sc.lc = lc; - - last_x = x; /* Statically save last xoff & yoff so that new */ - last_y = y; /* floating panes offset so they don't overlap. */ - - args_to_vector(args, &sc.argc, &sc.argv); - sc.environ = environ_create(); - - av = args_first_value(args, 'e'); - while (av != NULL) { - environ_put(sc.environ, av->string, 0); - av = args_next_value(av); - } - - sc.idx = -1; - sc.cwd = args_get(args, 'c'); - - sc.flags = flags; - if (args_has(args, 'd')) - sc.flags |= SPAWN_DETACHED; - if (args_has(args, 'Z')) - sc.flags |= SPAWN_ZOOM; - - if ((new_wp = spawn_pane(&sc, &cause)) == NULL) { - cmdq_error(item, "create pane failed: %s", cause); - free(cause); - if (sc.argv != NULL) - cmd_free_argv(sc.argc, sc.argv); - environ_free(sc.environ); - return (CMD_RETURN_ERROR); - } - style = args_get(args, 's'); - if (style != NULL) { - if (options_set_string(new_wp->options, "window-style", 0, - "%s", style) == NULL) { - cmdq_error(item, "bad style: %s", style); - return (CMD_RETURN_ERROR); - } - options_set_string(new_wp->options, "window-active-style", 0, - "%s", style); - new_wp->flags |= (PANE_REDRAW|PANE_STYLECHANGED|PANE_THEMECHANGED); - } - style = args_get(args, 'S'); - if (style != NULL) { - if (options_set_string(new_wp->options, - "pane-active-border-style", 0, "%s", style) == NULL) { - cmdq_error(item, "bad active border style: %s", style); - return (CMD_RETURN_ERROR); - } - } - style = args_get(args, 'R'); - if (style != NULL) { - if (options_set_string(new_wp->options, "pane-border-style", 0, - "%s", style) == NULL) { - cmdq_error(item, "bad inactive border style: %s", style); - return (CMD_RETURN_ERROR); - } - } - if (args_has(args, 'k') || args_has(args, 'm')) { - options_set_number(new_wp->options, "remain-on-exit", 3); - if (args_has(args, 'm')) - options_set_string(new_wp->options, "remain-on-exit-format", - 0, "%s", args_get(args, 'm')); - } - if (input) { - switch (window_pane_start_input(new_wp, item, &cause)) { - case -1: - server_client_remove_pane(new_wp); - window_remove_pane(wp->window, new_wp); - cmdq_error(item, "%s", cause); - free(cause); - if (sc.argv != NULL) - cmd_free_argv(sc.argc, sc.argv); - environ_free(sc.environ); - return (CMD_RETURN_ERROR); - case 1: - input = 0; - break; - } - } - if (!args_has(args, 'd')) - cmd_find_from_winlink_pane(current, wl, new_wp, 0); - window_pop_zoom(wp->window); - server_redraw_window(wp->window); - server_status_session(s); - - if (args_has(args, 'P')) { - if ((template = args_get(args, 'F')) == NULL) - template = NEW_PANE_TEMPLATE; - cp = format_single(item, template, tc, s, wl, new_wp); - cmdq_print(item, "%s", cp); - free(cp); - } - - cmd_find_from_winlink_pane(&fs, wl, new_wp, 0); - cmdq_insert_hook(s, item, &fs, "after-split-window"); - - if (sc.argv != NULL) - cmd_free_argv(sc.argc, sc.argv); - environ_free(sc.environ); - if (input) - return (CMD_RETURN_WAIT); - return (CMD_RETURN_NORMAL); -} diff --git a/cmd-split-window.c b/cmd-split-window.c index bd2a4b48..046dc66e 100644 --- a/cmd-split-window.c +++ b/cmd-split-window.c @@ -27,22 +27,24 @@ #include "tmux.h" /* - * Split a window (add a new pane). + * Create a new pane. */ #define SPLIT_WINDOW_TEMPLATE "#{session_name}:#{window_index}.#{pane_index}" -static enum cmd_retval cmd_split_window_exec(struct cmd *, - struct cmdq_item *); +static enum cmd_retval cmd_split_window_exec(struct cmd *, struct cmdq_item *); -const struct cmd_entry cmd_split_window_entry = { - .name = "split-window", - .alias = "splitw", +const struct cmd_entry cmd_new_pane_entry = { + .name = "new-pane", + .alias = "newp", - .args = { "bc:de:fF:hIl:p:Pt:vZ", 0, -1, NULL }, - .usage = "[-bdefhIPvZ] [-c start-directory] [-e environment] " - "[-F format] [-l size] " CMD_TARGET_PANE_USAGE - " [shell-command [argument ...]]", + .args = { "bc:de:fF:hIkl:m:M:p:PR:s:S:t:x:X:y:Y:vZ", 0, -1, NULL }, + .usage = "[-bdefhIklPvZ] [-c start-directory] [-e environment] " + "[-F format] [-l size] [-m message] [-M mode] " + "[-R inactive-border-style] [-s style] " + "[-S active-border-style] [-x width] [-X x-position]" + "[-y length] [-Y y-position]" CMD_TARGET_PANE_USAGE + "[shell-command [argument ...]]", .target = { 't', CMD_FIND_PANE, 0 }, @@ -50,30 +52,122 @@ const struct cmd_entry cmd_split_window_entry = { .exec = cmd_split_window_exec }; -static enum cmd_retval -cmd_split_window_exec(struct cmd *self, struct cmdq_item *item) +const struct cmd_entry cmd_split_window_entry = { + .name = "split-window", + .alias = "splitw", + + .args = { "bc:de:fF:hIkl:m:M:p:PR:s:S:t:x:X:y:Y:vZ", 0, -1, NULL }, + .usage = "[-bdefhIklPvZ] [-c start-directory] [-e environment] " + "[-F format] [-l size] [-m message] [-M mode] " + "[-R inactive-border-style] [-s style] " + "[-S active-border-style] [-x width] [-X x-position]" + "[-y length] [-Y y-position]" CMD_TARGET_PANE_USAGE + "[shell-command [argument ...]]", + + .target = { 't', CMD_FIND_PANE, 0 }, + + .flags = 0, + .exec = cmd_split_window_exec +}; + +enum new_pane_mode { + FLOATING, + TILED, + NONE, +}; + +static struct layout_cell * +cmd_split_window_get_floating_layout_cell(struct cmdq_item *item, + struct args *args, struct window *w) +{ + struct layout_cell *lc = NULL; + char *cause = NULL; + int x, y; + u_int sx, sy; + static int last_x = 0, last_y = 0; + + /* Default size. */ + sx = w->sx / 2; + sy = w->sy / 2; + + if (args_has(args, 'x')) { + sx = args_percentage_and_expand(args, 'x', 0, USHRT_MAX, w->sx, + item, &cause); + if (cause != NULL) { + cmdq_error(item, "size %s", cause); + free(cause); + return (NULL); + } + } + if (args_has(args, 'y')) { + sy = args_percentage_and_expand(args, 'y', 0, USHRT_MAX, w->sy, + item, &cause); + if (cause != NULL) { + cmdq_error(item, "size %s", cause); + free(cause); + return (NULL); + } + } + + /* If a position is not defined, it defaults to cascading. */ + if (args_has(args, 'X')) { + x = args_percentage_and_expand(args, 'X', 0, USHRT_MAX, w->sx, + item, &cause); + if (cause != NULL) { + cmdq_error(item, "size %s", cause); + free(cause); + return (NULL); + } + } else if (last_x == 0) + x = 4; + else { + x = (last_x += 4); + if (last_x > (int)w->sx) + x = 4; + } + if (args_has(args, 'Y')) { + y = args_percentage_and_expand(args, 'Y', 0, USHRT_MAX, w->sy, + item, &cause); + if (cause != NULL) { + cmdq_error(item, "size %s", cause); + free(cause); + return (NULL); + } + } else if (last_y == 0) + y = 2; + else { + y = (last_y += 2); + if (last_y > (int)w->sy) + y = 2; + } + + /* Floating panes sit in layout cells which are not in the layout_root + * tree so we call it with parent == NULL. + */ + lc = layout_create_cell(NULL); + lc->xoff = x; + lc->yoff = y; + lc->sx = sx; + lc->sy = sy; + last_x = x; /* Statically save last xoff & yoff so that new */ + last_y = y; /* floating panes offset so they don't overlap. */ + + return (lc); +} + +static struct layout_cell * +cmd_split_window_get_tiled_layout_cell(struct cmdq_item *item, + struct args *args, struct window *w, struct window_pane *wp, int flags) { - struct args *args = cmd_get_args(self); - struct cmd_find_state *current = cmdq_get_current(item); - struct cmd_find_state *target = cmdq_get_target(item); - struct spawn_context sc = { 0 }; - struct client *tc = cmdq_get_target_client(item); - struct session *s = target->s; - struct winlink *wl = target->wl; - struct window *w = wl->window; - struct window_pane *wp = target->wp, *new_wp; enum layout_type type; - struct layout_cell *lc; - struct cmd_find_state fs; - int size, flags, input; - const char *template; - char *cause = NULL, *cp; - struct args_value *av; - u_int count = args_count(args), curval = 0; + struct layout_cell *lc = NULL; + char *cause = NULL; + int size; + u_int curval = 0; if (wp->flags & PANE_FLOATING) { cmdq_error(item, "can't split a floating pane"); - return (CMD_RETURN_ERROR); + return (NULL); } type = LAYOUT_TOPBOTTOM; @@ -108,13 +202,55 @@ cmd_split_window_exec(struct cmd *self, struct cmdq_item *item) if (cause != NULL) { cmdq_error(item, "size %s", cause); free(cause); - return (CMD_RETURN_ERROR); + return (NULL); } window_push_zoom(wp->window, 1, args_has(args, 'Z')); + lc = layout_split_pane(wp, type, size, flags); + if (lc == NULL) + cmdq_error(item, "no space for new pane"); + + return (lc); +} + +static enum cmd_retval +cmd_split_window_exec(struct cmd *self, struct cmdq_item *item) +{ + struct args *args = cmd_get_args(self); + struct cmd_find_state *current = cmdq_get_current(item); + struct cmd_find_state *target = cmdq_get_target(item); + struct spawn_context sc = { 0 }; + struct client *tc = cmdq_get_target_client(item); + struct session *s = target->s; + struct winlink *wl = target->wl; + struct window *w = wl->window; + struct window_pane *wp = target->wp, *new_wp; + struct layout_cell *lc = NULL; + struct cmd_find_state fs; + int flags, input; + const char *template, *style; + char *cause = NULL, *cp; + struct args_value *av; + u_int count = args_count(args); + enum new_pane_mode pane_mode = NONE; + + if (args_has(args, 'M')) { + if (strcasecmp(args_get(args, 'M'), "f") == 0) + pane_mode = FLOATING; + else if (strcasecmp(args_get(args, 'M'), "t") == 0) + pane_mode = TILED; + else + pane_mode = NONE; + } else { + if (cmd_get_entry(self) == &cmd_new_pane_entry) + pane_mode = FLOATING; + else + pane_mode = TILED; + } + input = (args_has(args, 'I') && count == 0); - flags = 0; + flags = pane_mode == FLOATING ? SPAWN_FLOATING : 0; if (args_has(args, 'b')) flags |= SPAWN_BEFORE; if (args_has(args, 'f')) @@ -122,11 +258,19 @@ cmd_split_window_exec(struct cmd *self, struct cmdq_item *item) if (input || (count == 1 && *args_string(args, 0) == '\0')) flags |= SPAWN_EMPTY; - lc = layout_split_pane(wp, type, size, flags); - if (lc == NULL) { - cmdq_error(item, "no space for new pane"); + + if (pane_mode == FLOATING) + lc = cmd_split_window_get_floating_layout_cell(item, args, w); + else if (pane_mode == TILED) + lc = cmd_split_window_get_tiled_layout_cell(item, args, w, wp, + flags); + else { + cmdq_error(item, "unrecognized pane mode '%s'", + args_get(args, 'M')); return (CMD_RETURN_ERROR); } + if (lc == NULL) + return (CMD_RETURN_ERROR); sc.item = item; sc.s = s; @@ -161,11 +305,48 @@ cmd_split_window_exec(struct cmd *self, struct cmdq_item *item) environ_free(sc.environ); return (CMD_RETURN_ERROR); } + + style = args_get(args, 's'); + if (style != NULL) { + if (options_set_string(new_wp->options, "window-style", 0, + "%s", style) == NULL) { + cmdq_error(item, "bad style: %s", style); + return (CMD_RETURN_ERROR); + } + options_set_string(new_wp->options, "window-active-style", 0, + "%s", style); + new_wp->flags |= (PANE_REDRAW|PANE_STYLECHANGED|PANE_THEMECHANGED); + } + style = args_get(args, 'S'); + if (style != NULL) { + if (options_set_string(new_wp->options, + "pane-active-border-style", 0, "%s", style) == NULL) { + cmdq_error(item, "bad active border style: %s", style); + return (CMD_RETURN_ERROR); + } + } + style = args_get(args, 'R'); + if (style != NULL) { + if (options_set_string(new_wp->options, "pane-border-style", 0, + "%s", style) == NULL) { + cmdq_error(item, "bad inactive border style: %s", style); + return (CMD_RETURN_ERROR); + } + } + if (args_has(args, 'k') || args_has(args, 'm')) { + options_set_number(new_wp->options, "remain-on-exit", 3); + if (args_has(args, 'm')) + options_set_string(new_wp->options, + "remain-on-exit-format", + 0, "%s", args_get(args, 'm')); + } + if (input) { switch (window_pane_start_input(new_wp, item, &cause)) { case -1: server_client_remove_pane(new_wp); - layout_close_pane(new_wp); + if (pane_mode == TILED) + layout_close_pane(new_wp); window_remove_pane(wp->window, new_wp); cmdq_error(item, "%s", cause); free(cause); diff --git a/tmux.1 b/tmux.1 index fe874a1c..0ae9241f 100644 --- a/tmux.1 +++ b/tmux.1 @@ -3323,53 +3323,63 @@ but a different format may be specified with .Fl F . .Tg newp .It Xo Ic new-pane -.Op Fl bdefIPZ +.Op Fl bdefhIkPvZ .Op Fl c Ar start-directory .Op Fl e Ar environment .Op Fl F Ar format -.Op Fl h Ar height -.Op Fl k .Op Fl l Ar size .Op Fl m Ar message +.Op Fl M Ar mode .Op Fl p Ar percentage .Op Fl R Ar inactive-border-style .Op Fl s Ar style .Op Fl S Ar active-border-style .Op Fl t Ar target-pane -.Op Fl w Ar width -.Op Fl x Ar x-position -.Op Fl y Ar y-position +.Op Fl x Ar width +.Op Fl X Ar x-position +.Op Fl y Ar length +.Op Fl Y Ar y-position .Op Ar shell-command Op Ar argument ... .Xc .D1 Pq alias: Ic newp -Create a new floating pane. -The -.Fl w , -.Fl h , -.Fl x , -and -.Fl y -options set the width, height, and position of the pane; if not given, -the pane is sized to half the window dimensions and offset from the -previous floating pane. -The -.Fl l -and -.Fl p -options set the size in lines or as a percentage. -The -.Fl f -option uses the full window dimensions. +Create a new pane. +A +.Ar mode +may be specified with the +.Fl M +option and must be followed by one of the following special values: +.Bl -column "XXXXX" -offset indent +.It Sy "Value" Ta Sy "Meaning" +.It Li "f" Ta "floating pane above the current layout" +.It Li "t" Ta "tiled into the layout by splitting a pane" +.El +.Pp +If no +.Ar mode +is specified, +.Ic f +is assumed. +When creating a tiled pane, a target pane may be specified with +.Fl t . +Note that some options will only affect one +.Ar mode . .Pp If .Fl d is given, the session does not make the new pane the current pane. .Fl Z -zooms if the window is not zoomed. -.Pp +zooms if the window is not zoomed, or keeps it zoomed if already zoomed. +.Fl s +sets the style for the pane content. +.Fl S +sets the border style when the pane is active and +.Fl R +sets the border style when the pane is inactive (see +.Sx STYLES ) . .Fl k -keeps the pane open after the shell command exits and waits for a -keypress (any non-mouse key) before closing it. +keeps the pane open after the optional +.Ar shell-command +exits and waits for a keypress (any non-mouse key) before closing it. The message shown is controlled by the .Ic remain-on-exit-format option. @@ -3380,7 +3390,6 @@ but also sets the .Ic remain-on-exit-format option for this pane to .Ar message . -.Pp An empty .Ar shell-command (\[aq]\[aq]) will create a pane with no command running in it. @@ -3390,14 +3399,50 @@ flag (if .Ar shell-command is not specified or empty) will create an empty pane and forward any output from stdin to it. +For example: +.Bd -literal -offset indent +$ make 2>&1|tmux splitw \-dI & +.Ed .Pp -.Fl s -sets the style for the pane content. -.Fl S -sets the border style when the pane is active and -.Fl R -sets the border style when the pane is inactive (see -.Sx STYLES ) . +For floating panes, the following options are availible: +The +.Fl x , +.Fl y , +.Fl X , +and +.Fl Y +options set the width, height, and position of the pane. +If not given, the pane is sized to half the window dimensions and offset from +the previous floating pane. +These four options may be followed by '%' to specify a percentage of the +current window dimensions. +.Pp +For tiled panes, the following options are availible: +.Fl h +does a horizontal split and +.Fl v +a vertical split; if neither is specified, +.Fl v +is assumed. +The +.Fl l +option specifies the size of the new pane in lines (for vertical split) or in +columns (for horizontal split); +.Ar size +may be followed by +.Ql % +to specify a percentage of the available space. +The +.Fl b +option causes the new pane to be created to the left of or above +.Ar target\-pane . +The +.Fl f +option creates a new pane spanning the full window height (with +.Fl h ) +or full window width (with +.Fl v ) , +instead of splitting the active pane. .Pp All other options have the same meaning as for the .Ic new-window @@ -3726,65 +3771,33 @@ the command behaves like .Ic last\-window . .Tg splitw .It Xo Ic split\-window -.Op Fl bdfhIvPZ -.Op Fl c Ar start\-directory +.Op Fl bdefhIkPvZ +.Op Fl c Ar start-directory .Op Fl e Ar environment .Op Fl F Ar format +.Op Fl H Ar height .Op Fl l Ar size -.Op Fl t Ar target\-pane -.Op Ar shell\-command Op Ar argument ... +.Op Fl m Ar message +.Op Fl M Ar mode +.Op Fl p Ar percentage +.Op Fl R Ar inactive-border-style +.Op Fl s Ar style +.Op Fl S Ar active-border-style +.Op Fl t Ar target-pane +.Op Fl w Ar width +.Op Fl x Ar x-position +.Op Fl y Ar y-position +.Op Ar shell-command Op Ar argument ... .Xc .D1 Pq alias: Ic splitw -Create a new pane by splitting -.Ar target\-pane : -.Fl h -does a horizontal split and -.Fl v -a vertical split; if neither is specified, -.Fl v -is assumed. -The -.Fl l -option specifies the size of the new pane in lines (for vertical split) or in -columns (for horizontal split); -.Ar size -may be followed by -.Ql % -to specify a percentage of the available space. -The -.Fl b -option causes the new pane to be created to the left of or above -.Ar target\-pane . -The -.Fl f -option creates a new pane spanning the full window height (with -.Fl h ) -or full window width (with -.Fl v ) , -instead of splitting the active pane. -.Fl Z -zooms if the window is not zoomed, or keeps it zoomed if already zoomed. +Creates a new pane. +Default behavior is to split the pane in a tiled layout. +Shares behavior with +.Ic new-pane . .Pp -An empty -.Ar shell\-command -(\[aq]\[aq]) will create a pane with no command running in it. -Output can be sent to such a pane with the -.Ic display\-message -command. -The -.Fl I -flag (if -.Ar shell\-command -is not specified or empty) -will create an empty pane and forward any output from stdin to it. -For example: -.Bd -literal -offset indent -$ make 2>&1|tmux splitw \-dI & -.Ed -.Pp -All other options have the same meaning as for the -.Ic new\-window -command. +See +.Ic new-pane +for more details. .Tg swapp .It Xo Ic swap\-pane .Op Fl dDUZ