Tested the new commands and updated documentation.

This commit is contained in:
Dane Jensen
2026-04-13 13:50:13 -07:00
parent 950194fb63
commit 4bb7a86753
3 changed files with 159 additions and 194 deletions

View File

@@ -1030,7 +1030,7 @@ cmd_find_target(struct cmd_find_state *fs, struct cmdq_item *item,
fs->w = fs->wl->window; fs->w = fs->wl->window;
fs->wp = fs->w->active; fs->wp = fs->w->active;
} }
goto found; break;
} }
if (fs->wp == NULL) { if (fs->wp == NULL) {
if (~flags & CMD_FIND_QUIET) if (~flags & CMD_FIND_QUIET)

View File

@@ -38,11 +38,13 @@ const struct cmd_entry cmd_new_pane_entry = {
.name = "new-pane", .name = "new-pane",
.alias = "newp", .alias = "newp",
.args = { "bc:de:fF:h:Iklm:p:PR:s:S:t:T:w:x:y:Z", 0, -1, NULL }, .args = { "bc:de:fF:hH:Ikl:m:p:PR:s:S:t:T:w:x:y:vZ", 0, -1, NULL },
.usage = "[-bdefhIklPvZ] [-c start-directory] [-e environment] " .usage = "[-bdefhIklPvZ] [-c start-directory] [-e environment] "
"[-F format] [-l size] [-m message] " "[-F format] [-H height] [-l size] [-m message] "
"[-R inactive-border-style] [-s style] [-S active-border-style] " "[-R inactive-border-style] [-s style] "
CMD_TARGET_PANE_USAGE " [shell-command [argument ...]]", "[-S active-border-style] [-w width] [-x x-position] "
"[-y y-position]" CMD_TARGET_PANE_USAGE "[-T type] "
" [shell-command [argument ...]]",
.target = { 't', CMD_FIND_PANE, 0 }, .target = { 't', CMD_FIND_PANE, 0 },
@@ -54,9 +56,12 @@ const struct cmd_entry cmd_split_window_entry = {
.name = "split-window", .name = "split-window",
.alias = "splitw", .alias = "splitw",
.args = { "bc:de:fF:hIl:p:Pt:T:vZ", 0, -1, NULL }, .args = { "bc:de:fF:hH:Ikl:m:p:PR:s:S:t:T:w:x:y:vZ", 0, -1, NULL },
.usage = "[-bdefhIPvZ] [-c start-directory] [-e environment] " .usage = "[-bdefhIklPvZ] [-c start-directory] [-e environment] "
"[-F format] [-l size] " CMD_TARGET_PANE_USAGE "[-F format] [-H height] [-l size] [-m message] "
"[-R inactive-border-style] [-s style] "
"[-S active-border-style] [-w width] [-x x-position] "
"[-y y-position]" CMD_TARGET_PANE_USAGE "[-T type] "
" [shell-command [argument ...]]", " [shell-command [argument ...]]",
.target = { 't', CMD_FIND_PANE, 0 }, .target = { 't', CMD_FIND_PANE, 0 },
@@ -84,53 +89,41 @@ cmd_new_pane_get_type(const char* val)
} }
static struct layout_cell * static struct layout_cell *
cmd_new_pane_get_float_layout_cell(struct cmdq_item *item, struct args *args, cmd_new_pane_get_floating_layout_cell(struct cmdq_item *item, struct args *args,
struct window *w) struct window *w)
{ {
struct layout_cell *lc = NULL; struct layout_cell *lc = NULL;
char *cause = NULL; char *cause = NULL;
int x, y; int x, y;
u_int sx, sy, pct; u_int sx = w->sx / 2, sy = w->sy / 2;
static int last_x = 0, last_y = 0; static int last_x = 0, last_y = 0;
if (args_has(args, 'f')) { if (last_x == 0) {
sx = w->sx; x = 4;
sy = w->sy;
} else { } else {
if (args_has(args, 'l')) { x = (last_x += 4);
sx = args_percentage_and_expand(args, 'l', 0, INT_MAX, w->sx, if (last_x > (int)w->sx)
item, &cause); x = 4;
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 (NULL);
} }
if (last_y == 0) {
y = 2;
} else {
y = (last_y += 2);
if (last_y > (int)w->sy)
y = 2;
} }
if (args_has(args, 'w')) { if (args_has(args, 'w')) {
sx = args_strtonum_and_expand(args, 'w', 1, USHRT_MAX, item, sx = args_percentage_and_expand(args, 'w', 0, USHRT_MAX, w->sx,
&cause); item, &cause);
if (cause != NULL) { if (cause != NULL) {
cmdq_error(item, "size %s", cause); cmdq_error(item, "size %s", cause);
free(cause); free(cause);
return (NULL); return (NULL);
} }
} }
if (args_has(args, 'h')) { if (args_has(args, 'H')) {
sy = args_strtonum_and_expand(args, 'h', 1, USHRT_MAX, item, sy = args_percentage_and_expand(args, 'H', 0, USHRT_MAX, w->sy,
&cause); item, &cause);
if (cause != NULL) { if (cause != NULL) {
cmdq_error(item, "size %s", cause); cmdq_error(item, "size %s", cause);
free(cause); free(cause);
@@ -138,38 +131,22 @@ cmd_new_pane_get_float_layout_cell(struct cmdq_item *item, struct args *args,
} }
} }
if (args_has(args, 'x')) { if (args_has(args, 'x')) {
x = args_strtonum_and_expand(args, 'x', SHRT_MIN, SHRT_MAX, x = args_percentage_and_expand(args, 'x', 0, USHRT_MAX, w->sx,
item, &cause); item, &cause);
if (cause != NULL) { if (cause != NULL) {
cmdq_error(item, "size %s", cause); cmdq_error(item, "size %s", cause);
free(cause); free(cause);
return (NULL); return (NULL);
} }
} 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')) { if (args_has(args, 'y')) {
y = args_strtonum_and_expand(args, 'y', SHRT_MIN, SHRT_MAX, y = args_percentage_and_expand(args, 'y', 0, USHRT_MAX, w->sy,
item, &cause); item, &cause);
if (cause != NULL) { if (cause != NULL) {
cmdq_error(item, "size %s", cause); cmdq_error(item, "size %s", cause);
free(cause); free(cause);
return (NULL); return (NULL);
} }
} else {
if (last_y == 0) {
y = 5;
} else {
y = (last_y += 5);
if (last_y > (int)w->sy)
y = 5;
}
} }
/* Floating panes sit in layout cells which are not in the layout_root /* Floating panes sit in layout cells which are not in the layout_root
@@ -186,50 +163,8 @@ cmd_new_pane_get_float_layout_cell(struct cmdq_item *item, struct args *args,
return (lc); return (lc);
} }
static int
cmd_new_pane_style_floating_pane(struct cmdq_item *item, struct args *args,
struct window_pane *new_wp)
{
const char *style;
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 (-1);
}
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 (-1);
}
}
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 (-1);
}
}
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'));
}
return (0);
}
static struct layout_cell * static struct layout_cell *
cmd_new_pane_get_split_layout_cell(struct cmdq_item *item, struct args *args, cmd_new_pane_get_tiled_layout_cell(struct cmdq_item *item, struct args *args,
struct window *w, struct window_pane *wp, int flags) struct window *w, struct window_pane *wp, int flags)
{ {
enum layout_type type; enum layout_type type;
@@ -301,7 +236,7 @@ cmd_new_pane_exec(struct cmd *self, struct cmdq_item *item)
struct layout_cell *lc = NULL; struct layout_cell *lc = NULL;
struct cmd_find_state fs; struct cmd_find_state fs;
int flags, input; int flags, input;
const char *template; const char *template, *style;
char *cause = NULL, *cp; char *cause = NULL, *cp;
struct args_value *av; struct args_value *av;
u_int count = args_count(args); u_int count = args_count(args);
@@ -328,10 +263,9 @@ cmd_new_pane_exec(struct cmd *self, struct cmdq_item *item)
if (pane_type == FLOATING) { if (pane_type == FLOATING) {
// return (cmd_new_pane_exec(self, item)); lc = cmd_new_pane_get_floating_layout_cell(item, args, w);
lc = cmd_new_pane_get_float_layout_cell(item, args, w);
} else if (pane_type == TILED) } else if (pane_type == TILED)
lc = cmd_new_pane_get_split_layout_cell(item, args, w, wp, lc = cmd_new_pane_get_tiled_layout_cell(item, args, w, wp,
flags); flags);
else else
cmdq_error(item, "unrecognized pane type '%s'", args_get(args, 'T')); cmdq_error(item, "unrecognized pane type '%s'", args_get(args, 'T'));
@@ -372,9 +306,40 @@ cmd_new_pane_exec(struct cmd *self, struct cmdq_item *item)
return (CMD_RETURN_ERROR); return (CMD_RETURN_ERROR);
} }
if (pane_type == FLOATING) style = args_get(args, 's');
if (cmd_new_pane_style_floating_pane(item, args, new_wp) != 0) 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); 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) { if (input) {
switch (window_pane_start_input(new_wp, item, &cause)) { switch (window_pane_start_input(new_wp, item, &cause)) {

176
tmux.1
View File

@@ -3323,12 +3323,11 @@ but a different format may be specified with
.Fl F . .Fl F .
.Tg newp .Tg newp
.It Xo Ic new-pane .It Xo Ic new-pane
.Op Fl bdefIPZ .Op Fl bdefhIkPvZ
.Op Fl c Ar start-directory .Op Fl c Ar start-directory
.Op Fl e Ar environment .Op Fl e Ar environment
.Op Fl F Ar format .Op Fl F Ar format
.Op Fl h Ar height .Op Fl H Ar height
.Op Fl k
.Op Fl l Ar size .Op Fl l Ar size
.Op Fl m Ar message .Op Fl m Ar message
.Op Fl p Ar percentage .Op Fl p Ar percentage
@@ -3342,35 +3341,36 @@ but a different format may be specified with
.Op Ar shell-command Op Ar argument ... .Op Ar shell-command Op Ar argument ...
.Xc .Xc
.D1 Pq alias: Ic newp .D1 Pq alias: Ic newp
Create a new floating pane. Create a new pane. The new pane may be floating by specifying the type with
The .Fl Tf
.Fl w , /
.Fl h , .Fl Tfloating ,
.Fl x , or tiled into the layout by splitting an existing pane with
and .Fl Tt
.Fl y /
options set the width, height, and position of the pane; if not given, .Fl Ttiled .
the pane is sized to half the window dimensions and offset from the When creating a tiled pane, a target pane may be specified with
previous floating pane. .Fl t .
The Note that some options are related to dimensions/layout and so will only affect
.Fl l one pane type. Those options will be in their own sections.
and
.Fl p
options set the size in lines or as a percentage.
The
.Fl f
option uses the full window dimensions.
.Pp .Pp
If If
.Fl d .Fl d
is given, the session does not make the new pane the current pane. is given, the session does not make the new pane the current pane.
.Fl Z .Fl Z
zooms if the window is not zoomed. zooms if the window is not zoomed, or keeps it zoomed if already zoomed.
.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 ) .
.Fl k .Fl k
keeps the pane open after the shell command exits and waits for a keeps the pane open after the optional
keypress (any non-mouse key) before closing it. .Ar shell-command
The message shown is controlled by the 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 .Ic remain-on-exit-format
option. option.
.Fl m Ar message .Fl m Ar message
@@ -3380,7 +3380,6 @@ but also sets the
.Ic remain-on-exit-format .Ic remain-on-exit-format
option for this pane to option for this pane to
.Ar message . .Ar message .
.Pp
An empty An empty
.Ar shell-command .Ar shell-command
(\[aq]\[aq]) will create a pane with no command running in it. (\[aq]\[aq]) will create a pane with no command running in it.
@@ -3389,15 +3388,49 @@ The
flag (if flag (if
.Ar shell-command .Ar shell-command
is not specified or empty) is not specified or empty)
will create an empty pane and forward any output from stdin to it. 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 .Pp
.Fl s For floating panes, the following flags are availible:
sets the style for the pane content. The
.Fl S .Fl w ,
sets the border style when the pane is active and .Fl h ,
.Fl R .Fl x ,
sets the border style when the pane is inactive (see and
.Sx STYLES ) . .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 flags 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 .Pp
All other options have the same meaning as for the All other options have the same meaning as for the
.Ic new-window .Ic new-window
@@ -3726,65 +3759,32 @@ the command behaves like
.Ic last\-window . .Ic last\-window .
.Tg splitw .Tg splitw
.It Xo Ic split\-window .It Xo Ic split\-window
.Op Fl bdfhIvPZ .Op Fl bdefhIkPvZ
.Op Fl c Ar start\-directory .Op Fl c Ar start-directory
.Op Fl e Ar environment .Op Fl e Ar environment
.Op Fl F Ar format .Op Fl F Ar format
.Op Fl H Ar height
.Op Fl l Ar size .Op Fl l Ar size
.Op Fl t Ar target\-pane .Op Fl m Ar message
.Op Ar shell\-command Op Ar argument ... .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 T Ar type
.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 .Xc
.D1 Pq alias: Ic splitw .D1 Pq alias: Ic splitw
Create a new pane by splitting Creates a new pane. Default behavior is to split the pane in a tiled layout.
.Ar target\-pane : Shares behavior with
.Fl h .Ic new-pane .
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.
.Pp .Pp
An empty See
.Ar shell\-command .Ic new-pane
(\[aq]\[aq]) will create a pane with no command running in it. for more details.
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.
.Tg swapp .Tg swapp
.It Xo Ic swap\-pane .It Xo Ic swap\-pane
.Op Fl dDUZ .Op Fl dDUZ