-/* $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 <nicholas.marriott@gmail.com>
#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
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++;
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)
case 'P':
modifiers |= FORMAT_PANES;
break;
+ case 'L':
+ modifiers |= FORMAT_CLIENTS;
+ break;
}
} else if (fm->size == 2) {
if (strcmp(fm->modifier, "||") == 0 ||
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) {
value = format_window_name(es, copy);
if (value == NULL)
-.\" $OpenBSD: tmux.1,v 1.915 2023/02/06 09:20:30 nicm Exp $
+.\" $OpenBSD: tmux.1,v 1.916 2023/02/07 10:21:01 nicm Exp $
.\"
.\" Copyright (c) 2007 Nicholas Marriott <nicholas.marriott@gmail.com>
.\"
.\" IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
.\" OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
.\"
-.Dd $Mdocdate: February 6 2023 $
+.Dd $Mdocdate: February 7 2023 $
.Dt TMUX 1
.Os
.Sh NAME
.Ic confirm-before ,
parse their argument to create a new command which is inserted immediately
after themselves.
-This means that arguments can be parsed twice or more - once when the parent command (such as
+This means that arguments can be parsed twice or more - once when the parent
+command (such as
.Ic if-shell )
is parsed and again when it parses and executes its command.
Commands like
.Ql {mouse}
(alternative form
.Ql = )
-to specify the session, window or pane where the most recent mouse event occurred
-(see the
+to specify the session, window or pane where the most recent mouse event
+occurred (see the
.Sx MOUSE SUPPORT
section)
or
.Xr xterm 1
escape sequence.
If
-Ar target-pane
+.Ar target-pane
is given, the clipboard is sent (in encoded form), otherwise it is stored in a
new paste buffer.
.Pp
.Pp
Note that as by default the
.Nm
-server will exit with no sessions, this is only useful if a session is created in
+server will exit with no sessions, this is only useful if a session is created
+in
.Pa ~/.tmux.conf ,
.Ic exit-empty
is turned off, or another command is run as part of the same command sequence.
.Ed
.El
.Pp
-A number of preset arrangements of panes are available, these are called layouts.
+A number of preset arrangements of panes are available, these are called
+layouts.
These may be selected with the
.Ic select-layout
command or cycled with
.Pp
Hooks are stored as array options, members of the array are executed in
order when the hook is triggered.
-Like options different hooks may be global or belong to a session, window or pane.
+Like options different hooks may be global or belong to a session, window or
+pane.
Hooks may be configured with the
.Ic set-hook
or
.Ar target-pane
in commands bound to mouse key bindings.
It resolves to the window or pane over which the mouse event took place
-(for example, the window in the status line over which button 1 was released for a
+(for example, the window in the status line over which button 1 was released
+for a
.Ql MouseUp1Status
binding, or the pane over which the wheel was scrolled for a
.Ql WheelDownPane
For example:
.Ql #{C/r:^Start}
.Pp
-Numeric operators may be performed by prefixing two comma-separated alternatives with an
+Numeric operators may be performed by prefixing two comma-separated alternatives
+with an
.Ql e
and an operator.
An optional
.Ql f
-flag may be given after the operator to use floating point numbers, otherwise integers are used.
-This may be followed by a number giving the number of decimal places to use for the result.
+flag may be given after the operator to use floating point numbers, otherwise
+integers are used.
+This may be followed by a number giving the number of decimal places to use for
+the result.
The available operators are:
addition
.Ql + ,
.Xr strftime 3
specifiers.
.Ql S:\& ,
-.Ql W:\&
-or
+.Ql W:\& ,
.Ql P:\&
-will loop over each session, window or pane and insert the format once
+or
+.Ql L:\&
+will loop over each session, window, pane or client 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.
with
.Ql bar
throughout.
-The first argument may be an extended regular expression and a final argument may be
+The first argument may be an extended regular expression and a final argument
+may be
.Ql i
to ignore case, for example
.Ql s/a(.)/\e1x/i:\&
A different delimiter character may also be used, to avoid collisions with
literal slashes in the pattern.
For example,
-.Ql s|foo/|bar/|:
+.Ql s|foo/|bar/|:\&
will substitute
.Ql foo/
with
.Nm
does not wait for
.Ql #()
-commands to finish; instead, the previous result from running the same command is used,
-or a placeholder if the command has not been run before.
-If the command hasn't exited, the most recent line of output will be used, but the status
-line will not be updated more than once a second.
+commands to finish; instead, the previous result from running the same command
+is used, or a placeholder if the command has not been run before.
+If the command hasn't exited, the most recent line of output will be used, but
+the status line will not be updated more than once a second.
Commands are executed using
.Pa /bin/sh
and with the
.Ic list=on
marks the start of the list;
.Ic list=focus
-is the part of the list that should be kept in focus if the entire list won't fit
-in the available space (typically the current window);
+is the part of the list that should be kept in focus if the entire list won't
+fit in the available space (typically the current window);
.Ic list=left-marker
and
.Ic list=right-marker
.Em %end
or
.Em %error
-have three arguments: an integer time (as seconds from epoch), command number and
-flags (currently not used).
+have three arguments: an integer time (as seconds from epoch), command number
+and flags (currently not used).
For example:
.Bd -literal -offset indent
%begin 1363006971 2 1
.Ar pause-after
flag is set.
.Ar age
-is the time in milliseconds for which tmux had buffered the output before it was sent.
+is the time in milliseconds for which tmux had buffered the output before it
+was sent.
Any subsequent arguments up until a single
.Ql \&:
are for future use and should be ignored.
-.It Ic %layout-change Ar window-id Ar window-layout Ar window-visible-layout Ar window-flags
+.It Xo Ic %layout-change
+.Ar window-id
+.Ar window-layout
+.Ar window-visible-layout
+.Ar window-flags
+.Xc
The layout of a window with ID
.Ar window-id
changed.