mirror of
https://github.com/tmux/tmux.git
synced 2024-12-04 19:58:48 +00:00
Add a -S flag to new-window to make it select the existing window if one
with the given name already exists rather than failing with an error. Also add a format to check if a window or session name exists which allows the same with other commands. Requested by and discussed with kn@.
This commit is contained in:
parent
c13f2e1135
commit
be471c328e
@ -38,8 +38,8 @@ const struct cmd_entry cmd_new_window_entry = {
|
||||
.name = "new-window",
|
||||
.alias = "neww",
|
||||
|
||||
.args = { "abc:de:F:kn:Pt:", 0, -1 },
|
||||
.usage = "[-abdkP] [-c start-directory] [-e environment] [-F format] "
|
||||
.args = { "abc:de:F:kn:PSt:", 0, -1 },
|
||||
.usage = "[-abdkPS] [-c start-directory] [-e environment] [-F format] "
|
||||
"[-n window-name] " CMD_TARGET_WINDOW_USAGE " [command]",
|
||||
|
||||
.target = { 't', CMD_FIND_WINDOW, CMD_FIND_WINDOW_INDEX },
|
||||
@ -52,6 +52,7 @@ static enum cmd_retval
|
||||
cmd_new_window_exec(struct cmd *self, struct cmdq_item *item)
|
||||
{
|
||||
struct args *args = cmd_get_args(self);
|
||||
struct client *c = cmdq_get_client(item);
|
||||
struct cmd_find_state *current = cmdq_get_current(item);
|
||||
struct cmd_find_state *target = cmdq_get_target(item);
|
||||
struct spawn_context sc;
|
||||
@ -59,12 +60,41 @@ cmd_new_window_exec(struct cmd *self, struct cmdq_item *item)
|
||||
struct session *s = target->s;
|
||||
struct winlink *wl = target->wl;
|
||||
int idx = target->idx, before;
|
||||
struct winlink *new_wl;
|
||||
struct winlink *new_wl = NULL;
|
||||
char *cause = NULL, *cp;
|
||||
const char *template, *add;
|
||||
const char *template, *add, *name;
|
||||
struct cmd_find_state fs;
|
||||
struct args_value *value;
|
||||
|
||||
/*
|
||||
* If -S and -n are given and -t is not and a single window with this
|
||||
* name already exists, select it.
|
||||
*/
|
||||
name = args_get(args, 'n');
|
||||
if (args_has(args, 'S') && name != NULL && target->idx == -1) {
|
||||
RB_FOREACH(wl, winlinks, &s->windows) {
|
||||
if (strcmp(wl->window->name, name) != 0)
|
||||
continue;
|
||||
if (new_wl == NULL) {
|
||||
new_wl = wl;
|
||||
continue;
|
||||
}
|
||||
cmdq_error(item, "multiple windows named %s", name);
|
||||
return (CMD_RETURN_ERROR);
|
||||
}
|
||||
if (new_wl != NULL) {
|
||||
if (args_has(args, 'd'))
|
||||
return (CMD_RETURN_NORMAL);
|
||||
if (session_set_current(s, new_wl) == 0)
|
||||
server_redraw_session(s);
|
||||
if (c != NULL && c->session != NULL)
|
||||
s->curw->window->latest = c;
|
||||
recalculate_sizes();
|
||||
return (CMD_RETURN_NORMAL);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
before = args_has(args, 'b');
|
||||
if (args_has(args, 'a') || before) {
|
||||
idx = winlink_shuffle_up(s, wl, before);
|
||||
|
61
format.c
61
format.c
@ -100,6 +100,8 @@ format_job_cmp(struct format_job *fj1, struct format_job *fj2)
|
||||
#define FORMAT_LENGTH 0x800
|
||||
#define FORMAT_WIDTH 0x1000
|
||||
#define FORMAT_QUOTE_STYLE 0x2000
|
||||
#define FORMAT_WINDOW_NAME 0x4000
|
||||
#define FORMAT_SESSION_NAME 0x8000
|
||||
|
||||
/* Limit on recursion. */
|
||||
#define FORMAT_LOOP_LIMIT 10
|
||||
@ -1733,7 +1735,7 @@ format_build_modifiers(struct format_expand_state *es, const char **s,
|
||||
}
|
||||
|
||||
/* Now try single character with arguments. */
|
||||
if (strchr("mCst=peq", cp[0]) == NULL)
|
||||
if (strchr("mCNst=peq", cp[0]) == NULL)
|
||||
break;
|
||||
c = cp[0];
|
||||
|
||||
@ -1857,6 +1859,24 @@ format_search(struct format_modifier *fm, struct window_pane *wp, const char *s)
|
||||
return (value);
|
||||
}
|
||||
|
||||
/* Does session name exist? */
|
||||
static char *
|
||||
format_session_name(struct format_expand_state *es, const char *fmt)
|
||||
{
|
||||
char *name;
|
||||
struct session *s;
|
||||
|
||||
name = format_expand1(es, fmt);
|
||||
RB_FOREACH(s, sessions, &sessions) {
|
||||
if (strcmp(s->name, name) == 0) {
|
||||
free(name);
|
||||
return (xstrdup("1"));
|
||||
}
|
||||
}
|
||||
free(name);
|
||||
return (xstrdup("0"));
|
||||
}
|
||||
|
||||
/* Loop over sessions. */
|
||||
static char *
|
||||
format_loop_sessions(struct format_expand_state *es, const char *fmt)
|
||||
@ -1892,6 +1912,30 @@ format_loop_sessions(struct format_expand_state *es, const char *fmt)
|
||||
return (value);
|
||||
}
|
||||
|
||||
/* Does window name exist? */
|
||||
static char *
|
||||
format_window_name(struct format_expand_state *es, const char *fmt)
|
||||
{
|
||||
struct format_tree *ft = es->ft;
|
||||
char *name;
|
||||
struct winlink *wl;
|
||||
|
||||
if (ft->s == NULL) {
|
||||
format_log(es, "window name but no session");
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
name = format_expand1(es, fmt);
|
||||
RB_FOREACH(wl, winlinks, &ft->s->windows) {
|
||||
if (strcmp(wl->window->name, name) == 0) {
|
||||
free(name);
|
||||
return (xstrdup("1"));
|
||||
}
|
||||
}
|
||||
free(name);
|
||||
return (xstrdup("0"));
|
||||
}
|
||||
|
||||
/* Loop over windows. */
|
||||
static char *
|
||||
format_loop_windows(struct format_expand_state *es, const char *fmt)
|
||||
@ -2251,6 +2295,13 @@ format_replace(struct format_expand_state *es, const char *key, size_t keylen,
|
||||
case 'T':
|
||||
modifiers |= FORMAT_EXPANDTIME;
|
||||
break;
|
||||
case 'N':
|
||||
if (fm->argc < 1 ||
|
||||
strchr(fm->argv[0], 'w') != NULL)
|
||||
modifiers |= FORMAT_WINDOW_NAME;
|
||||
else if (strchr(fm->argv[0], 's') != NULL)
|
||||
modifiers |= FORMAT_SESSION_NAME;
|
||||
break;
|
||||
case 'S':
|
||||
modifiers |= FORMAT_SESSIONS;
|
||||
break;
|
||||
@ -2291,6 +2342,14 @@ format_replace(struct format_expand_state *es, const char *key, size_t keylen,
|
||||
value = format_loop_panes(es, copy);
|
||||
if (value == NULL)
|
||||
goto fail;
|
||||
} else if (modifiers & FORMAT_WINDOW_NAME) {
|
||||
value = format_window_name(es, copy);
|
||||
if (value == NULL)
|
||||
goto fail;
|
||||
} else if (modifiers & FORMAT_SESSION_NAME) {
|
||||
value = format_session_name(es, copy);
|
||||
if (value == NULL)
|
||||
goto fail;
|
||||
} else if (search != NULL) {
|
||||
/* Search in pane. */
|
||||
new = format_expand1(es, copy);
|
||||
|
21
tmux.1
21
tmux.1
@ -2348,7 +2348,7 @@ the
|
||||
.Ic base-index
|
||||
option.
|
||||
.It Xo Ic new-window
|
||||
.Op Fl abdkP
|
||||
.Op Fl abdkPS
|
||||
.Op Fl c Ar start-directory
|
||||
.Op Fl e Ar environment
|
||||
.Op Fl F Ar format
|
||||
@ -2377,6 +2377,14 @@ represents the window to be created; if the target already exists an error is
|
||||
shown, unless the
|
||||
.Fl k
|
||||
flag is used, in which case it is destroyed.
|
||||
If
|
||||
.Fl S
|
||||
is given and a window named
|
||||
.Ar window-name
|
||||
already exists, it is selected (unless
|
||||
.Fl d
|
||||
is also given in which case the command does nothing).
|
||||
.Pp
|
||||
.Ar shell-command
|
||||
is the command to execute.
|
||||
If
|
||||
@ -4688,6 +4696,17 @@ For example, to get a list of windows formatted like the status line:
|
||||
#{W:#{E:window-status-format} ,#{E:window-status-current-format} }
|
||||
.Ed
|
||||
.Pp
|
||||
.Ql N:\&
|
||||
checks if a window (without any suffix or with the
|
||||
.Ql w
|
||||
suffix) or a session (with the
|
||||
.Ql s
|
||||
suffix) name exists, for example
|
||||
.Ql `N/w:foo`
|
||||
is replaced with 1 if a window named
|
||||
.Ql foo
|
||||
exists.
|
||||
.Pp
|
||||
A prefix of the form
|
||||
.Ql s/foo/bar/:\&
|
||||
will substitute
|
||||
|
Loading…
Reference in New Issue
Block a user