From be471c328ea0ae04026e4ff32fda7b7f11c74255 Mon Sep 17 00:00:00 2001 From: nicm Date: Fri, 5 Feb 2021 12:23:49 +0000 Subject: 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@. --- format.c | 61 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 60 insertions(+), 1 deletion(-) (limited to 'format.c') diff --git a/format.c b/format.c index 25b80249..ecf299d1 100644 --- a/format.c +++ b/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); -- cgit