diff options
author | Nicholas Marriott <nicm@cvs.openbsd.org> | 2019-03-13 15:37:29 +0000 |
---|---|---|
committer | Nicholas Marriott <nicm@cvs.openbsd.org> | 2019-03-13 15:37:29 +0000 |
commit | 857b442d2b84fe7a15c05415eb0aa89af3fedfd0 (patch) | |
tree | ff5ccaf91b82ecf8c4cb6891976e708af0a74caa /usr.bin/tmux | |
parent | c9b054f1c5d1477a93ac2a02c6e32c557a9364a7 (diff) |
Add formats to list sessions, windows or panes.
Diffstat (limited to 'usr.bin/tmux')
-rw-r--r-- | usr.bin/tmux/format.c | 140 | ||||
-rw-r--r-- | usr.bin/tmux/tmux.1 | 13 |
2 files changed, 148 insertions, 5 deletions
diff --git a/usr.bin/tmux/format.c b/usr.bin/tmux/format.c index e3ef8d061e4..38887f4c797 100644 --- a/usr.bin/tmux/format.c +++ b/usr.bin/tmux/format.c @@ -1,4 +1,4 @@ -/* $OpenBSD: format.c,v 1.171 2019/03/13 14:27:17 nicm Exp $ */ +/* $OpenBSD: format.c,v 1.172 2019/03/13 15:37:28 nicm Exp $ */ /* * Copyright (c) 2011 Nicholas Marriott <nicholas.marriott@gmail.com> @@ -95,6 +95,9 @@ format_job_cmp(struct format_job *fj1, struct format_job *fj2) #define FORMAT_QUOTE 0x8 #define FORMAT_LITERAL 0x10 #define FORMAT_EXPAND 0x20 +#define FORMAT_SESSIONS 0x40 +#define FORMAT_WINDOWS 0x80 +#define FORMAT_PANES 0x100 /* Entry in format tree. */ struct format_entry { @@ -113,6 +116,7 @@ struct format_tree { struct window *w; struct window_pane *wp; + struct cmdq_item *item; struct client *client; u_int tag; int flags; @@ -673,6 +677,7 @@ format_create(struct client *c, struct cmdq_item *item, int tag, int flags) ft->client = c; ft->client->references++; } + ft->item = item; ft->tag = tag; ft->flags = flags; @@ -1013,7 +1018,8 @@ format_build_modifiers(struct format_tree *ft, const char **s, u_int *count) cp++; /* Check single character modifiers with no arguments. */ - if (strchr("lmCbdtqE", cp[0]) != NULL && format_is_end(cp[1])) { + if (strchr("lmCbdtqESWP", cp[0]) != NULL && + format_is_end(cp[1])) { format_add_modifier(&list, count, cp, 1, NULL, 0); cp++; continue; @@ -1127,6 +1133,111 @@ format_substitute(const char *source, const char *from, const char *to) return (copy); } +/* Loop over sessions. */ +static char * +format_loop_sessions(struct format_tree *ft, const char *fmt) +{ + struct cmdq_item *item = ft->item; + char *expanded, *value; + size_t valuelen; + struct session *s; + + value = xcalloc(1, 1); + valuelen = 1; + + RB_FOREACH(s, sessions, &sessions) { + expanded = format_single(item, fmt, ft->c, ft->s, NULL, NULL); + + valuelen += strlen(expanded); + value = xrealloc(value, valuelen); + + strlcat(value, expanded, valuelen); + free(expanded); + } + + return (value); +} + +/* Loop over windows. */ +static char * +format_loop_windows(struct format_tree *ft, const char *fmt) +{ + struct cmdq_item *item = ft->item; + char *all, *active, *use, *expanded, *value; + size_t valuelen; + struct winlink *wl; + + if (ft->s == NULL) + return (NULL); + + if (format_choose(ft, fmt, &all, &active, 0) != 0) { + all = xstrdup(fmt); + active = NULL; + } + + value = xcalloc(1, 1); + valuelen = 1; + + RB_FOREACH(wl, winlinks, &ft->s->windows) { + if (active != NULL && wl == ft->s->curw) + use = active; + else + use = all; + expanded = format_single(item, use, ft->c, ft->s, wl, NULL); + + valuelen += strlen(expanded); + value = xrealloc(value, valuelen); + + strlcat(value, expanded, valuelen); + free(expanded); + } + + free(active); + free(all); + + return (value); +} + +/* Loop over panes. */ +static char * +format_loop_panes(struct format_tree *ft, const char *fmt) +{ + struct cmdq_item *item = ft->item; + char *all, *active, *use, *expanded, *value; + size_t valuelen; + struct window_pane *wp; + + if (ft->w == NULL) + return (NULL); + + if (format_choose(ft, fmt, &all, &active, 0) != 0) { + all = xstrdup(fmt); + active = NULL; + } + + value = xcalloc(1, 1); + valuelen = 1; + + TAILQ_FOREACH(wp, &ft->w->panes, entry) { + if (active != NULL && wp == ft->w->active) + use = active; + else + use = all; + expanded = format_single(item, use, ft->c, ft->s, ft->wl, wp); + + valuelen += strlen(expanded); + value = xrealloc(value, valuelen); + + strlcat(value, expanded, valuelen); + free(expanded); + } + + free(active); + free(all); + + return (value); +} + /* Replace a key. */ static int format_replace(struct format_tree *ft, const char *key, size_t keylen, @@ -1193,6 +1304,15 @@ format_replace(struct format_tree *ft, const char *key, size_t keylen, case 'E': modifiers |= FORMAT_EXPAND; break; + case 'S': + modifiers |= FORMAT_SESSIONS; + break; + case 'W': + modifiers |= FORMAT_WINDOWS; + break; + case 'P': + modifiers |= FORMAT_PANES; + break; } } else if (fm->size == 2) { if (strcmp(fm->modifier, "||") == 0 || @@ -1210,8 +1330,20 @@ format_replace(struct format_tree *ft, const char *key, size_t keylen, goto done; } - /* Is this a comparison or a conditional? */ - if (search != NULL) { + /* Is this a loop, comparison or condition? */ + if (modifiers & FORMAT_SESSIONS) { + value = format_loop_sessions(ft, copy); + if (value == NULL) + goto fail; + } else if (modifiers & FORMAT_WINDOWS) { + value = format_loop_windows(ft, copy); + if (value == NULL) + goto fail; + } else if (modifiers & FORMAT_PANES) { + value = format_loop_panes(ft, copy); + if (value == NULL) + goto fail; + } else if (search != NULL) { /* Search in pane. */ if (wp == NULL) value = xstrdup("0"); diff --git a/usr.bin/tmux/tmux.1 b/usr.bin/tmux/tmux.1 index 80664074e14..d50b6d75ddf 100644 --- a/usr.bin/tmux/tmux.1 +++ b/usr.bin/tmux/tmux.1 @@ -1,4 +1,4 @@ -.\" $OpenBSD: tmux.1,v 1.617 2019/03/13 14:19:54 nicm Exp $ +.\" $OpenBSD: tmux.1,v 1.618 2019/03/13 15:37:28 nicm Exp $ .\" .\" Copyright (c) 2007 Nicholas Marriott <nicholas.marriott@gmail.com> .\" @@ -3719,6 +3719,17 @@ will expand the format twice, for example is the result of expanding the content of the .Ic status-left option rather than the content itself. +.Ql S: , +.Ql W: +or +.Ql P: +will loop over each session, window or pane and insert the format once +for each. For windows and panes, two comma-separated formats may be +given, the second is used for the current window or active pane. For +example to get a list of windows formatted like the status line: +.Bd -literal -offset indent +#{W:#{E:window-status-format} ,#{E:window-status-current-format} } +.Ed A prefix of the form .Ql s/foo/bar/: will substitute |