Add -b flags to insert a window before (like the existing -a for after)

to break-pane, move-window, new-window. GitHub issue 2261.
This commit is contained in:
nicm 2020-06-13 09:05:53 +00:00
parent d52ac7d027
commit 1c78155e70
6 changed files with 56 additions and 40 deletions

View File

@ -34,8 +34,8 @@ const struct cmd_entry cmd_break_pane_entry = {
.name = "break-pane", .name = "break-pane",
.alias = "breakp", .alias = "breakp",
.args = { "adPF:n:s:t:", 0, 0 }, .args = { "abdPF:n:s:t:", 0, 0 },
.usage = "[-adP] [-F format] [-n window-name] [-s src-pane] " .usage = "[-abdP] [-F format] [-n window-name] [-s src-pane] "
"[-t dst-window]", "[-t dst-window]",
.source = { 's', CMD_FIND_PANE, 0 }, .source = { 's', CMD_FIND_PANE, 0 },
@ -58,16 +58,16 @@ cmd_break_pane_exec(struct cmd *self, struct cmdq_item *item)
struct session *dst_s = target->s; struct session *dst_s = target->s;
struct window_pane *wp = source->wp; struct window_pane *wp = source->wp;
struct window *w = wl->window; struct window *w = wl->window;
char *name, *cause; char *name, *cause, *cp;
int idx = target->idx; int idx = target->idx, before;
const char *template; const char *template;
char *cp;
if (args_has(args, 'a')) { before = args_has(args, 'b');
if (args_has(args, 'a') || before) {
if (target->wl != NULL) if (target->wl != NULL)
idx = winlink_shuffle_up(dst_s, target->wl); idx = winlink_shuffle_up(dst_s, target->wl, before);
else else
idx = winlink_shuffle_up(dst_s, dst_s->curw); idx = winlink_shuffle_up(dst_s, dst_s->curw, before);
if (idx == -1) if (idx == -1)
return (CMD_RETURN_ERROR); return (CMD_RETURN_ERROR);
} }

View File

@ -32,8 +32,8 @@ const struct cmd_entry cmd_move_window_entry = {
.name = "move-window", .name = "move-window",
.alias = "movew", .alias = "movew",
.args = { "adkrs:t:", 0, 0 }, .args = { "abdkrs:t:", 0, 0 },
.usage = "[-dkr] " CMD_SRCDST_WINDOW_USAGE, .usage = "[-abdkr] " CMD_SRCDST_WINDOW_USAGE,
.source = { 's', CMD_FIND_WINDOW, 0 }, .source = { 's', CMD_FIND_WINDOW, 0 },
/* -t is special */ /* -t is special */
@ -46,8 +46,8 @@ const struct cmd_entry cmd_link_window_entry = {
.name = "link-window", .name = "link-window",
.alias = "linkw", .alias = "linkw",
.args = { "adks:t:", 0, 0 }, .args = { "abdks:t:", 0, 0 },
.usage = "[-dk] " CMD_SRCDST_WINDOW_USAGE, .usage = "[-abdk] " CMD_SRCDST_WINDOW_USAGE,
.source = { 's', CMD_FIND_WINDOW, 0 }, .source = { 's', CMD_FIND_WINDOW, 0 },
/* -t is special */ /* -t is special */
@ -67,7 +67,7 @@ cmd_move_window_exec(struct cmd *self, struct cmdq_item *item)
struct session *dst; struct session *dst;
struct winlink *wl = source->wl; struct winlink *wl = source->wl;
char *cause; char *cause;
int idx, kflag, dflag, sflag; int idx, kflag, dflag, sflag, before;
if (args_has(args, 'r')) { if (args_has(args, 'r')) {
if (cmd_find_target(&target, item, tflag, CMD_FIND_SESSION, if (cmd_find_target(&target, item, tflag, CMD_FIND_SESSION,
@ -90,11 +90,12 @@ cmd_move_window_exec(struct cmd *self, struct cmdq_item *item)
dflag = args_has(args, 'd'); dflag = args_has(args, 'd');
sflag = args_has(args, 's'); sflag = args_has(args, 's');
if (args_has(args, 'a')) { before = args_has(args, 'b');
if (args_has(args, 'a') || before) {
if (target.wl != NULL) if (target.wl != NULL)
idx = winlink_shuffle_up(dst, target.wl); idx = winlink_shuffle_up(dst, target.wl, before);
else else
idx = winlink_shuffle_up(dst, dst->curw); idx = winlink_shuffle_up(dst, dst->curw, before);
if (idx == -1) if (idx == -1)
return (CMD_RETURN_ERROR); return (CMD_RETURN_ERROR);
} }

View File

@ -38,8 +38,8 @@ const struct cmd_entry cmd_new_window_entry = {
.name = "new-window", .name = "new-window",
.alias = "neww", .alias = "neww",
.args = { "ac:de:F:kn:Pt:", 0, -1 }, .args = { "abc:de:F:kn:Pt:", 0, -1 },
.usage = "[-adkP] [-c start-directory] [-e environment] [-F format] " .usage = "[-abdkP] [-c start-directory] [-e environment] [-F format] "
"[-n window-name] " CMD_TARGET_WINDOW_USAGE " [command]", "[-n window-name] " CMD_TARGET_WINDOW_USAGE " [command]",
.target = { 't', CMD_FIND_WINDOW, CMD_FIND_WINDOW_INDEX }, .target = { 't', CMD_FIND_WINDOW, CMD_FIND_WINDOW_INDEX },
@ -58,16 +58,20 @@ cmd_new_window_exec(struct cmd *self, struct cmdq_item *item)
struct client *tc = cmdq_get_target_client(item); struct client *tc = cmdq_get_target_client(item);
struct session *s = target->s; struct session *s = target->s;
struct winlink *wl = target->wl; struct winlink *wl = target->wl;
int idx = target->idx; int idx = target->idx, before;
struct winlink *new_wl; struct winlink *new_wl;
char *cause = NULL, *cp; char *cause = NULL, *cp;
const char *template, *add; const char *template, *add;
struct cmd_find_state fs; struct cmd_find_state fs;
struct args_value *value; struct args_value *value;
if (args_has(args, 'a') && (idx = winlink_shuffle_up(s, wl)) == -1) { before = args_has(args, 'b');
cmdq_error(item, "couldn't get a window index"); if (args_has(args, 'a') || before) {
return (CMD_RETURN_ERROR); idx = winlink_shuffle_up(s, wl, before);
if (idx == -1) {
cmdq_error(item, "couldn't get a window index");
return (CMD_RETURN_ERROR);
}
} }
memset(&sc, 0, sizeof sc); memset(&sc, 0, sizeof sc);

33
tmux.1
View File

@ -1792,7 +1792,7 @@ from which the layout was originally defined.
Commands related to windows and panes are as follows: Commands related to windows and panes are as follows:
.Bl -tag -width Ds .Bl -tag -width Ds
.It Xo Ic break-pane .It Xo Ic break-pane
.Op Fl adP .Op Fl abdP
.Op Fl F Ar format .Op Fl F Ar format
.Op Fl n Ar window-name .Op Fl n Ar window-name
.Op Fl s Ar src-pane .Op Fl s Ar src-pane
@ -1804,9 +1804,11 @@ Break
off from its containing window to make it the only pane in off from its containing window to make it the only pane in
.Ar dst-window . .Ar dst-window .
With With
.Fl a , .Fl a
the window is moved to the next index up (following windows or
are moved if necessary). .Fl b ,
the window is moved to the next index after or before (existing windows are
moved if necessary).
If If
.Fl d .Fl d
is given, the new window does not become the current window. is given, the new window does not become the current window.
@ -2188,7 +2190,7 @@ If no
.Ar target-session .Ar target-session
is specified, select the last window of the current session. is specified, select the last window of the current session.
.It Xo Ic link-window .It Xo Ic link-window
.Op Fl adk .Op Fl abdk
.Op Fl s Ar src-window .Op Fl s Ar src-window
.Op Fl t Ar dst-window .Op Fl t Ar dst-window
.Xc .Xc
@ -2203,9 +2205,12 @@ is specified and no such window exists, the
.Ar src-window .Ar src-window
is linked there. is linked there.
With With
.Fl a , .Fl a
the window is moved to the next index up (following windows or
are moved if necessary). .Fl b
the window is moved to the next index after or before
.Ar dst-window
(existing windows are moved if necessary).
If If
.Fl k .Fl k
is given and is given and
@ -2272,7 +2277,7 @@ section.
Does the same as Does the same as
.Ic join-pane . .Ic join-pane .
.It Xo Ic move-window .It Xo Ic move-window
.Op Fl ardk .Op Fl abrdk
.Op Fl s Ar src-window .Op Fl s Ar src-window
.Op Fl t Ar dst-window .Op Fl t Ar dst-window
.Xc .Xc
@ -2290,7 +2295,7 @@ the
.Ic base-index .Ic base-index
option. option.
.It Xo Ic new-window .It Xo Ic new-window
.Op Fl adkP .Op Fl abdkP
.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
@ -2301,10 +2306,12 @@ option.
.D1 (alias: Ic neww ) .D1 (alias: Ic neww )
Create a new window. Create a new window.
With With
.Fl a , .Fl a
the new window is inserted at the next index up from the specified or
.Fl b ,
the new window is inserted at the next index after or before the specified
.Ar target-window , .Ar target-window ,
moving windows up if necessary, moving windows up if necessary;
otherwise otherwise
.Ar target-window .Ar target-window
is the new window location. is the new window location.

2
tmux.h
View File

@ -2720,7 +2720,7 @@ void window_set_name(struct window *, const char *);
void window_add_ref(struct window *, const char *); void window_add_ref(struct window *, const char *);
void window_remove_ref(struct window *, const char *); void window_remove_ref(struct window *, const char *);
void winlink_clear_flags(struct winlink *); void winlink_clear_flags(struct winlink *);
int winlink_shuffle_up(struct session *, struct winlink *); int winlink_shuffle_up(struct session *, struct winlink *, int);
int window_pane_start_input(struct window_pane *, int window_pane_start_input(struct window_pane *,
struct cmdq_item *, char **); struct cmdq_item *, char **);
void *window_pane_get_new_data(struct window_pane *, void *window_pane_get_new_data(struct window_pane *,

View File

@ -1490,13 +1490,16 @@ winlink_clear_flags(struct winlink *wl)
/* Shuffle window indexes up. */ /* Shuffle window indexes up. */
int int
winlink_shuffle_up(struct session *s, struct winlink *wl) winlink_shuffle_up(struct session *s, struct winlink *wl, int before)
{ {
int idx, last; int idx, last;
if (wl == NULL) if (wl == NULL)
return (-1); return (-1);
idx = wl->idx + 1; if (before)
idx = wl->idx;
else
idx = wl->idx + 1;
/* Find the next free index. */ /* Find the next free index. */
for (last = idx; last < INT_MAX; last++) { for (last = idx; last < INT_MAX; last++) {
@ -1509,8 +1512,9 @@ winlink_shuffle_up(struct session *s, struct winlink *wl)
/* Move everything from last - 1 to idx up a bit. */ /* Move everything from last - 1 to idx up a bit. */
for (; last > idx; last--) { for (; last > idx; last--) {
wl = winlink_find_by_index(&s->windows, last - 1); wl = winlink_find_by_index(&s->windows, last - 1);
server_link_window(s, wl, s, last, 0, 0, NULL); RB_REMOVE(winlinks, &s->windows, wl);
server_unlink_window(s, wl); wl->idx++;
RB_INSERT(winlinks, &s->windows, wl);
} }
return (idx); return (idx);