=================================================================== RCS file: /cvsrepo/anoncvs/cvs/src/usr.bin/tmux/format.c,v retrieving revision 1.310 retrieving revision 1.311 diff -u -r1.310 -r1.311 --- src/usr.bin/tmux/format.c 2022/11/04 08:03:23 1.310 +++ src/usr.bin/tmux/format.c 2023/02/07 10:21:01 1.311 @@ -1,4 +1,4 @@ -/* $OpenBSD: format.c,v 1.310 2022/11/04 08:03:23 nicm Exp $ */ +/* $OpenBSD: format.c,v 1.311 2023/02/07 10:21:01 nicm Exp $ */ /* * Copyright (c) 2011 Nicholas Marriott @@ -103,6 +103,7 @@ #define FORMAT_SESSION_NAME 0x8000 #define FORMAT_CHARACTER 0x10000 #define FORMAT_COLOUR 0x20000 +#define FORMAT_CLIENTS 0x40000 /* Limit on recursion. */ #define FORMAT_LOOP_LIMIT 100 @@ -3747,7 +3748,7 @@ cp++; /* Check single character modifiers with no arguments. */ - if (strchr("labcdnwETSWP<>", cp[0]) != NULL && + if (strchr("labcdnwETSWPL<>", cp[0]) != NULL && format_is_end(cp[1])) { format_add_modifier(&list, count, cp, 1, NULL, 0); cp++; @@ -4075,7 +4076,41 @@ return (value); } +/* Loop over clients. */ static char * +format_loop_clients(struct format_expand_state *es, const char *fmt) +{ + struct format_tree *ft = es->ft; + struct client *c = ft->client; + struct cmdq_item *item = ft->item; + struct format_tree *nft; + struct format_expand_state next; + char *expanded, *value; + size_t valuelen; + + value = xcalloc(1, 1); + valuelen = 1; + + TAILQ_FOREACH(c, &clients, entry) { + format_log(es, "client loop: %s", c->name); + nft = format_create(c, item, 0, ft->flags); + format_defaults(nft, c, ft->s, ft->wl, ft->wp); + format_copy_state(&next, es, 0); + next.ft = nft; + expanded = format_expand1(&next, fmt); + format_free(nft); + + valuelen += strlen(expanded); + value = xrealloc(value, valuelen); + + strlcat(value, expanded, valuelen); + free(expanded); + } + + return (value); +} + +static char * format_replace_expression(struct format_modifier *mexp, struct format_expand_state *es, const char *copy) { @@ -4349,6 +4384,9 @@ case 'P': modifiers |= FORMAT_PANES; break; + case 'L': + modifiers |= FORMAT_CLIENTS; + break; } } else if (fm->size == 2) { if (strcmp(fm->modifier, "||") == 0 || @@ -4403,6 +4441,10 @@ goto fail; } else if (modifiers & FORMAT_PANES) { value = format_loop_panes(es, copy); + if (value == NULL) + goto fail; + } else if (modifiers & FORMAT_CLIENTS) { + value = format_loop_clients(es, copy); if (value == NULL) goto fail; } else if (modifiers & FORMAT_WINDOW_NAME) {