xref: /openbsd-src/usr.bin/tmux/format.c (revision 4b70baf6e17fc8b27fc1f7fa7929335753fa94c3)
1 /* $OpenBSD: format.c,v 1.190 2019/05/03 20:44:24 nicm Exp $ */
2 
3 /*
4  * Copyright (c) 2011 Nicholas Marriott <nicholas.marriott@gmail.com>
5  *
6  * Permission to use, copy, modify, and distribute this software for any
7  * purpose with or without fee is hereby granted, provided that the above
8  * copyright notice and this permission notice appear in all copies.
9  *
10  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14  * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
15  * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
16  * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17  */
18 
19 #include <sys/types.h>
20 #include <sys/wait.h>
21 
22 #include <ctype.h>
23 #include <errno.h>
24 #include <fnmatch.h>
25 #include <libgen.h>
26 #include <stdarg.h>
27 #include <stdlib.h>
28 #include <string.h>
29 #include <time.h>
30 #include <unistd.h>
31 
32 #include "tmux.h"
33 
34 /*
35  * Build a list of key-value pairs and use them to expand #{key} entries in a
36  * string.
37  */
38 
39 struct format_entry;
40 typedef void (*format_cb)(struct format_tree *, struct format_entry *);
41 
42 static char	*format_job_get(struct format_tree *, const char *);
43 static void	 format_job_timer(int, short, void *);
44 
45 static char	*format_find(struct format_tree *, const char *, int);
46 static void	 format_add_cb(struct format_tree *, const char *, format_cb);
47 static void	 format_add_tv(struct format_tree *, const char *,
48 		     struct timeval *);
49 static int	 format_replace(struct format_tree *, const char *, size_t,
50 		     char **, size_t *, size_t *);
51 
52 static void	 format_defaults_session(struct format_tree *,
53 		     struct session *);
54 static void	 format_defaults_client(struct format_tree *, struct client *);
55 static void	 format_defaults_winlink(struct format_tree *, struct winlink *);
56 
57 /* Entry in format job tree. */
58 struct format_job {
59 	struct client		*client;
60 	u_int			 tag;
61 	const char		*cmd;
62 	const char		*expanded;
63 
64 	time_t			 last;
65 	char			*out;
66 	int			 updated;
67 
68 	struct job		*job;
69 	int			 status;
70 
71 	RB_ENTRY(format_job)	 entry;
72 };
73 
74 /* Format job tree. */
75 static struct event format_job_event;
76 static int format_job_cmp(struct format_job *, struct format_job *);
77 static RB_HEAD(format_job_tree, format_job) format_jobs = RB_INITIALIZER();
78 RB_GENERATE_STATIC(format_job_tree, format_job, entry, format_job_cmp);
79 
80 /* Format job tree comparison function. */
81 static int
82 format_job_cmp(struct format_job *fj1, struct format_job *fj2)
83 {
84 	if (fj1->tag < fj2->tag)
85 		return (-1);
86 	if (fj1->tag > fj2->tag)
87 		return (1);
88 	return (strcmp(fj1->cmd, fj2->cmd));
89 }
90 
91 /* Format modifiers. */
92 #define FORMAT_TIMESTRING 0x1
93 #define FORMAT_BASENAME 0x2
94 #define FORMAT_DIRNAME 0x4
95 #define FORMAT_QUOTE 0x8
96 #define FORMAT_LITERAL 0x10
97 #define FORMAT_EXPAND 0x20
98 #define FORMAT_EXPANDTIME 0x40
99 #define FORMAT_SESSIONS 0x80
100 #define FORMAT_WINDOWS 0x100
101 #define FORMAT_PANES 0x200
102 
103 /* Limit on recursion. */
104 #define FORMAT_LOOP_LIMIT 10
105 
106 /* Entry in format tree. */
107 struct format_entry {
108 	char			*key;
109 	char			*value;
110 	time_t			 t;
111 	format_cb		 cb;
112 	RB_ENTRY(format_entry)	 entry;
113 };
114 
115 /* Format entry tree. */
116 struct format_tree {
117 	struct client		*c;
118 	struct session		*s;
119 	struct winlink		*wl;
120 	struct window		*w;
121 	struct window_pane	*wp;
122 
123 	struct cmdq_item	*item;
124 	struct client		*client;
125 	u_int			 tag;
126 	int			 flags;
127 	time_t			 time;
128 	u_int			 loop;
129 
130 	RB_HEAD(format_entry_tree, format_entry) tree;
131 };
132 static int format_entry_cmp(struct format_entry *, struct format_entry *);
133 RB_GENERATE_STATIC(format_entry_tree, format_entry, entry, format_entry_cmp);
134 
135 /* Format modifier. */
136 struct format_modifier {
137 	char	  modifier[3];
138 	u_int	  size;
139 
140 	char	**argv;
141 	int	  argc;
142 };
143 
144 /* Format entry tree comparison function. */
145 static int
146 format_entry_cmp(struct format_entry *fe1, struct format_entry *fe2)
147 {
148 	return (strcmp(fe1->key, fe2->key));
149 }
150 
151 /* Single-character uppercase aliases. */
152 static const char *format_upper[] = {
153 	NULL,		/* A */
154 	NULL,		/* B */
155 	NULL,		/* C */
156 	"pane_id",	/* D */
157 	NULL,		/* E */
158 	"window_flags",	/* F */
159 	NULL,		/* G */
160 	"host",		/* H */
161 	"window_index",	/* I */
162 	NULL,		/* J */
163 	NULL,		/* K */
164 	NULL,		/* L */
165 	NULL,		/* M */
166 	NULL,		/* N */
167 	NULL,		/* O */
168 	"pane_index",	/* P */
169 	NULL,		/* Q */
170 	NULL,		/* R */
171 	"session_name",	/* S */
172 	"pane_title",	/* T */
173 	NULL,		/* U */
174 	NULL,		/* V */
175 	"window_name",	/* W */
176 	NULL,		/* X */
177 	NULL,		/* Y */
178 	NULL 		/* Z */
179 };
180 
181 /* Single-character lowercase aliases. */
182 static const char *format_lower[] = {
183 	NULL,		/* a */
184 	NULL,		/* b */
185 	NULL,		/* c */
186 	NULL,		/* d */
187 	NULL,		/* e */
188 	NULL,		/* f */
189 	NULL,		/* g */
190 	"host_short",	/* h */
191 	NULL,		/* i */
192 	NULL,		/* j */
193 	NULL,		/* k */
194 	NULL,		/* l */
195 	NULL,		/* m */
196 	NULL,		/* n */
197 	NULL,		/* o */
198 	NULL,		/* p */
199 	NULL,		/* q */
200 	NULL,		/* r */
201 	NULL,		/* s */
202 	NULL,		/* t */
203 	NULL,		/* u */
204 	NULL,		/* v */
205 	NULL,		/* w */
206 	NULL,		/* x */
207 	NULL,		/* y */
208 	NULL		/* z */
209 };
210 
211 /* Is logging enabled? */
212 static inline int
213 format_logging(struct format_tree *ft)
214 {
215 	return (log_get_level() != 0 || (ft->flags & FORMAT_VERBOSE));
216 }
217 
218 /* Log a message if verbose. */
219 static void printflike(3, 4)
220 format_log1(struct format_tree *ft, const char *from, const char *fmt, ...)
221 {
222 	va_list			 ap;
223 	char			*s;
224 	static const char	 spaces[] = "          ";
225 
226 	if (!format_logging(ft))
227 		return;
228 
229 	va_start(ap, fmt);
230 	vasprintf(&s, fmt, ap);
231 	va_end(ap);
232 
233 	log_debug("%s: %s", from, s);
234 	if (ft->item != NULL && (ft->flags & FORMAT_VERBOSE))
235 		cmdq_print(ft->item, "#%.*s%s", ft->loop, spaces, s);
236 
237 	free(s);
238 }
239 #define format_log(ft, fmt, ...) format_log1(ft, __func__, fmt, ##__VA_ARGS__)
240 
241 /* Format job update callback. */
242 static void
243 format_job_update(struct job *job)
244 {
245 	struct format_job	*fj = job_get_data(job);
246 	struct evbuffer		*evb = job_get_event(job)->input;
247 	char			*line = NULL, *next;
248 	time_t			 t;
249 
250 	while ((next = evbuffer_readline(evb)) != NULL) {
251 		free(line);
252 		line = next;
253 	}
254 	if (line == NULL)
255 		return;
256 	fj->updated = 1;
257 
258 	free(fj->out);
259 	fj->out = line;
260 
261 	log_debug("%s: %p %s: %s", __func__, fj, fj->cmd, fj->out);
262 
263 	t = time(NULL);
264 	if (fj->status && fj->last != t) {
265 		if (fj->client != NULL)
266 			server_status_client(fj->client);
267 		fj->last = t;
268 	}
269 }
270 
271 /* Format job complete callback. */
272 static void
273 format_job_complete(struct job *job)
274 {
275 	struct format_job	*fj = job_get_data(job);
276 	struct evbuffer		*evb = job_get_event(job)->input;
277 	char			*line, *buf;
278 	size_t			 len;
279 
280 	fj->job = NULL;
281 
282 	buf = NULL;
283 	if ((line = evbuffer_readline(evb)) == NULL) {
284 		len = EVBUFFER_LENGTH(evb);
285 		buf = xmalloc(len + 1);
286 		if (len != 0)
287 			memcpy(buf, EVBUFFER_DATA(evb), len);
288 		buf[len] = '\0';
289 	} else
290 		buf = line;
291 
292 	log_debug("%s: %p %s: %s", __func__, fj, fj->cmd, buf);
293 
294 	if (*buf != '\0' || !fj->updated) {
295 		free(fj->out);
296 		fj->out = buf;
297 	} else
298 		free(buf);
299 
300 	if (fj->status) {
301 		if (fj->client != NULL)
302 			server_status_client(fj->client);
303 		fj->status = 0;
304 	}
305 }
306 
307 /* Find a job. */
308 static char *
309 format_job_get(struct format_tree *ft, const char *cmd)
310 {
311 	struct format_job_tree	*jobs;
312 	struct format_job	 fj0, *fj;
313 	time_t			 t;
314 	char			*expanded;
315 	int			 force;
316 
317 	if (ft->client == NULL)
318 		jobs = &format_jobs;
319 	else if (ft->client->jobs != NULL)
320 		jobs = ft->client->jobs;
321 	else {
322 		jobs = ft->client->jobs = xmalloc(sizeof *ft->client->jobs);
323 		RB_INIT(jobs);
324 	}
325 
326 	fj0.tag = ft->tag;
327 	fj0.cmd = cmd;
328 	if ((fj = RB_FIND(format_job_tree, jobs, &fj0)) == NULL) {
329 		fj = xcalloc(1, sizeof *fj);
330 		fj->client = ft->client;
331 		fj->tag = ft->tag;
332 		fj->cmd = xstrdup(cmd);
333 		fj->expanded = NULL;
334 
335 		xasprintf(&fj->out, "<'%s' not ready>", fj->cmd);
336 
337 		RB_INSERT(format_job_tree, jobs, fj);
338 	}
339 
340 	expanded = format_expand(ft, cmd);
341 	if (fj->expanded == NULL || strcmp(expanded, fj->expanded) != 0) {
342 		free((void *)fj->expanded);
343 		fj->expanded = xstrdup(expanded);
344 		force = 1;
345 	} else
346 		force = (ft->flags & FORMAT_FORCE);
347 
348 	t = time(NULL);
349 	if (force && fj->job != NULL)
350 	       job_free(fj->job);
351 	if (force || (fj->job == NULL && fj->last != t)) {
352 		fj->job = job_run(expanded, NULL,
353 		    server_client_get_cwd(ft->client, NULL), format_job_update,
354 		    format_job_complete, NULL, fj, JOB_NOWAIT);
355 		if (fj->job == NULL) {
356 			free(fj->out);
357 			xasprintf(&fj->out, "<'%s' didn't start>", fj->cmd);
358 		}
359 		fj->last = t;
360 		fj->updated = 0;
361 	}
362 
363 	if (ft->flags & FORMAT_STATUS)
364 		fj->status = 1;
365 
366 	free(expanded);
367 	return (format_expand(ft, fj->out));
368 }
369 
370 /* Remove old jobs. */
371 static void
372 format_job_tidy(struct format_job_tree *jobs, int force)
373 {
374 	struct format_job	*fj, *fj1;
375 	time_t			 now;
376 
377 	now = time(NULL);
378 	RB_FOREACH_SAFE(fj, format_job_tree, jobs, fj1) {
379 		if (!force && (fj->last > now || now - fj->last < 3600))
380 			continue;
381 		RB_REMOVE(format_job_tree, jobs, fj);
382 
383 		log_debug("%s: %s", __func__, fj->cmd);
384 
385 		if (fj->job != NULL)
386 			job_free(fj->job);
387 
388 		free((void *)fj->expanded);
389 		free((void *)fj->cmd);
390 		free(fj->out);
391 
392 		free(fj);
393 	}
394 }
395 
396 /* Remove old jobs for client. */
397 void
398 format_lost_client(struct client *c)
399 {
400 	if (c->jobs != NULL)
401 		format_job_tidy(c->jobs, 1);
402 	free(c->jobs);
403 }
404 
405 /* Remove old jobs periodically. */
406 static void
407 format_job_timer(__unused int fd, __unused short events, __unused void *arg)
408 {
409 	struct client	*c;
410 	struct timeval	 tv = { .tv_sec = 60 };
411 
412 	format_job_tidy(&format_jobs, 0);
413 	TAILQ_FOREACH(c, &clients, entry) {
414 		if (c->jobs != NULL)
415 			format_job_tidy(c->jobs, 0);
416 	}
417 
418 	evtimer_del(&format_job_event);
419 	evtimer_add(&format_job_event, &tv);
420 }
421 
422 /* Callback for host. */
423 static void
424 format_cb_host(__unused struct format_tree *ft, struct format_entry *fe)
425 {
426 	char host[HOST_NAME_MAX + 1];
427 
428 	if (gethostname(host, sizeof host) != 0)
429 		fe->value = xstrdup("");
430 	else
431 		fe->value = xstrdup(host);
432 }
433 
434 /* Callback for host_short. */
435 static void
436 format_cb_host_short(__unused struct format_tree *ft, struct format_entry *fe)
437 {
438 	char host[HOST_NAME_MAX + 1], *cp;
439 
440 	if (gethostname(host, sizeof host) != 0)
441 		fe->value = xstrdup("");
442 	else {
443 		if ((cp = strchr(host, '.')) != NULL)
444 			*cp = '\0';
445 		fe->value = xstrdup(host);
446 	}
447 }
448 
449 /* Callback for pid. */
450 static void
451 format_cb_pid(__unused struct format_tree *ft, struct format_entry *fe)
452 {
453 	xasprintf(&fe->value, "%ld", (long)getpid());
454 }
455 
456 /* Callback for session_alerts. */
457 static void
458 format_cb_session_alerts(struct format_tree *ft, struct format_entry *fe)
459 {
460 	struct session	*s = ft->s;
461 	struct winlink	*wl;
462 	char		 alerts[1024], tmp[16];
463 
464 	if (s == NULL)
465 		return;
466 
467 	*alerts = '\0';
468 	RB_FOREACH(wl, winlinks, &s->windows) {
469 		if ((wl->flags & WINLINK_ALERTFLAGS) == 0)
470 			continue;
471 		xsnprintf(tmp, sizeof tmp, "%u", wl->idx);
472 
473 		if (*alerts != '\0')
474 			strlcat(alerts, ",", sizeof alerts);
475 		strlcat(alerts, tmp, sizeof alerts);
476 		if (wl->flags & WINLINK_ACTIVITY)
477 			strlcat(alerts, "#", sizeof alerts);
478 		if (wl->flags & WINLINK_BELL)
479 			strlcat(alerts, "!", sizeof alerts);
480 		if (wl->flags & WINLINK_SILENCE)
481 			strlcat(alerts, "~", sizeof alerts);
482 	}
483 	fe->value = xstrdup(alerts);
484 }
485 
486 /* Callback for session_stack. */
487 static void
488 format_cb_session_stack(struct format_tree *ft, struct format_entry *fe)
489 {
490 	struct session	*s = ft->s;
491 	struct winlink	*wl;
492 	char		 result[1024], tmp[16];
493 
494 	if (s == NULL)
495 		return;
496 
497 	xsnprintf(result, sizeof result, "%u", s->curw->idx);
498 	TAILQ_FOREACH(wl, &s->lastw, sentry) {
499 		xsnprintf(tmp, sizeof tmp, "%u", wl->idx);
500 
501 		if (*result != '\0')
502 			strlcat(result, ",", sizeof result);
503 		strlcat(result, tmp, sizeof result);
504 	}
505 	fe->value = xstrdup(result);
506 }
507 
508 /* Callback for window_stack_index. */
509 static void
510 format_cb_window_stack_index(struct format_tree *ft, struct format_entry *fe)
511 {
512 	struct session	*s = ft->wl->session;
513 	struct winlink	*wl;
514 	u_int		 idx;
515 
516 	idx = 0;
517 	TAILQ_FOREACH(wl, &s->lastw, sentry) {
518 		idx++;
519 		if (wl == ft->wl)
520 			break;
521 	}
522 	if (wl != NULL)
523 		xasprintf(&fe->value, "%u", idx);
524 	else
525 		fe->value = xstrdup("0");
526 }
527 
528 /* Callback for window_layout. */
529 static void
530 format_cb_window_layout(struct format_tree *ft, struct format_entry *fe)
531 {
532 	struct window	*w = ft->w;
533 
534 	if (w == NULL)
535 		return;
536 
537 	if (w->saved_layout_root != NULL)
538 		fe->value = layout_dump(w->saved_layout_root);
539 	else
540 		fe->value = layout_dump(w->layout_root);
541 }
542 
543 /* Callback for window_visible_layout. */
544 static void
545 format_cb_window_visible_layout(struct format_tree *ft, struct format_entry *fe)
546 {
547 	struct window	*w = ft->w;
548 
549 	if (w == NULL)
550 		return;
551 
552 	fe->value = layout_dump(w->layout_root);
553 }
554 
555 /* Callback for pane_start_command. */
556 static void
557 format_cb_start_command(struct format_tree *ft, struct format_entry *fe)
558 {
559 	struct window_pane	*wp = ft->wp;
560 
561 	if (wp == NULL)
562 		return;
563 
564 	fe->value = cmd_stringify_argv(wp->argc, wp->argv);
565 }
566 
567 /* Callback for pane_current_command. */
568 static void
569 format_cb_current_command(struct format_tree *ft, struct format_entry *fe)
570 {
571 	struct window_pane	*wp = ft->wp;
572 	char			*cmd;
573 
574 	if (wp == NULL)
575 		return;
576 
577 	cmd = get_proc_name(wp->fd, wp->tty);
578 	if (cmd == NULL || *cmd == '\0') {
579 		free(cmd);
580 		cmd = cmd_stringify_argv(wp->argc, wp->argv);
581 		if (cmd == NULL || *cmd == '\0') {
582 			free(cmd);
583 			cmd = xstrdup(wp->shell);
584 		}
585 	}
586 	fe->value = parse_window_name(cmd);
587 	free(cmd);
588 }
589 
590 /* Callback for history_bytes. */
591 static void
592 format_cb_history_bytes(struct format_tree *ft, struct format_entry *fe)
593 {
594 	struct window_pane	*wp = ft->wp;
595 	struct grid		*gd;
596 	struct grid_line	*gl;
597 	unsigned long long	 size;
598 	u_int			 i;
599 
600 	if (wp == NULL)
601 		return;
602 	gd = wp->base.grid;
603 
604 	size = 0;
605 	for (i = 0; i < gd->hsize; i++) {
606 		gl = grid_get_line(gd, i);
607 		size += gl->cellsize * sizeof *gl->celldata;
608 		size += gl->extdsize * sizeof *gl->extddata;
609 	}
610 	size += gd->hsize * sizeof *gl;
611 
612 	xasprintf(&fe->value, "%llu", size);
613 }
614 
615 /* Callback for pane_tabs. */
616 static void
617 format_cb_pane_tabs(struct format_tree *ft, struct format_entry *fe)
618 {
619 	struct window_pane	*wp = ft->wp;
620 	struct evbuffer		*buffer;
621 	u_int			 i;
622 	int			 size;
623 
624 	if (wp == NULL)
625 		return;
626 
627 	buffer = evbuffer_new();
628 	if (buffer == NULL)
629 		fatalx("out of memory");
630 	for (i = 0; i < wp->base.grid->sx; i++) {
631 		if (!bit_test(wp->base.tabs, i))
632 			continue;
633 
634 		if (EVBUFFER_LENGTH(buffer) > 0)
635 			evbuffer_add(buffer, ",", 1);
636 		evbuffer_add_printf(buffer, "%u", i);
637 	}
638 	if ((size = EVBUFFER_LENGTH(buffer)) != 0)
639 		xasprintf(&fe->value, "%.*s", size, EVBUFFER_DATA(buffer));
640 	evbuffer_free(buffer);
641 }
642 
643 /* Callback for session_group_list. */
644 static void
645 format_cb_session_group_list(struct format_tree *ft, struct format_entry *fe)
646 {
647 	struct session		*s = ft->s;
648 	struct session_group	*sg;
649 	struct session		*loop;
650 	struct evbuffer		*buffer;
651 	int			 size;
652 
653 	if (s == NULL)
654 		return;
655 	sg = session_group_contains(s);
656 	if (sg == NULL)
657 		return;
658 
659 	buffer = evbuffer_new();
660 	if (buffer == NULL)
661 		fatalx("out of memory");
662 	TAILQ_FOREACH(loop, &sg->sessions, gentry) {
663 		if (EVBUFFER_LENGTH(buffer) > 0)
664 			evbuffer_add(buffer, ",", 1);
665 		evbuffer_add_printf(buffer, "%s", loop->name);
666 	}
667 	if ((size = EVBUFFER_LENGTH(buffer)) != 0)
668 		xasprintf(&fe->value, "%.*s", size, EVBUFFER_DATA(buffer));
669 	evbuffer_free(buffer);
670 }
671 
672 /* Callback for pane_in_mode. */
673 static void
674 format_cb_pane_in_mode(struct format_tree *ft, struct format_entry *fe)
675 {
676 	struct window_pane		*wp = ft->wp;
677 	u_int				 n = 0;
678 	struct window_mode_entry	*wme;
679 
680 	if (wp == NULL)
681 		return;
682 
683 	TAILQ_FOREACH(wme, &wp->modes, entry)
684 	    n++;
685 	xasprintf(&fe->value, "%u", n);
686 }
687 
688 /* Callback for cursor_character. */
689 static void
690 format_cb_cursor_character(struct format_tree *ft, struct format_entry *fe)
691 {
692 	struct window_pane	*wp = ft->wp;
693 	struct grid_cell	 gc;
694 
695 	if (wp == NULL)
696 		return;
697 
698 	grid_view_get_cell(wp->base.grid, wp->base.cx, wp->base.cy, &gc);
699 	if (~gc.flags & GRID_FLAG_PADDING)
700 		xasprintf(&fe->value, "%.*s", (int)gc.data.size, gc.data.data);
701 }
702 
703 /* Merge a format tree. */
704 static void
705 format_merge(struct format_tree *ft, struct format_tree *from)
706 {
707 	struct format_entry	*fe;
708 
709 	RB_FOREACH(fe, format_entry_tree, &from->tree) {
710 		if (fe->value != NULL)
711 			format_add(ft, fe->key, "%s", fe->value);
712 	}
713 }
714 
715 /* Create a new tree. */
716 struct format_tree *
717 format_create(struct client *c, struct cmdq_item *item, int tag, int flags)
718 {
719 	struct format_tree		 *ft;
720 	const struct window_mode	**wm;
721 	char				  tmp[64];
722 
723 	if (!event_initialized(&format_job_event)) {
724 		evtimer_set(&format_job_event, format_job_timer, NULL);
725 		format_job_timer(-1, 0, NULL);
726 	}
727 
728 	ft = xcalloc(1, sizeof *ft);
729 	RB_INIT(&ft->tree);
730 
731 	if (c != NULL) {
732 		ft->client = c;
733 		ft->client->references++;
734 	}
735 	ft->item = item;
736 
737 	ft->tag = tag;
738 	ft->flags = flags;
739 	ft->time = time(NULL);
740 
741 	format_add_cb(ft, "host", format_cb_host);
742 	format_add_cb(ft, "host_short", format_cb_host_short);
743 	format_add_cb(ft, "pid", format_cb_pid);
744 	format_add(ft, "socket_path", "%s", socket_path);
745 	format_add_tv(ft, "start_time", &start_time);
746 
747 	for (wm = all_window_modes; *wm != NULL; wm++) {
748 		if ((*wm)->default_format != NULL) {
749 			xsnprintf(tmp, sizeof tmp, "%s_format", (*wm)->name);
750 			tmp[strcspn(tmp, "-")] = '_';
751 			format_add(ft, tmp, "%s", (*wm)->default_format);
752 		}
753 	}
754 
755 	if (item != NULL) {
756 		if (item->cmd != NULL)
757 			format_add(ft, "command", "%s", item->cmd->entry->name);
758 		if (item->shared != NULL && item->shared->formats != NULL)
759 			format_merge(ft, item->shared->formats);
760 	}
761 
762 	return (ft);
763 }
764 
765 /* Free a tree. */
766 void
767 format_free(struct format_tree *ft)
768 {
769 	struct format_entry	*fe, *fe1;
770 
771 	RB_FOREACH_SAFE(fe, format_entry_tree, &ft->tree, fe1) {
772 		RB_REMOVE(format_entry_tree, &ft->tree, fe);
773 		free(fe->value);
774 		free(fe->key);
775 		free(fe);
776 	}
777 
778 	if (ft->client != NULL)
779 		server_client_unref(ft->client);
780 	free(ft);
781 }
782 
783 /* Walk each format. */
784 void
785 format_each(struct format_tree *ft, void (*cb)(const char *, const char *,
786     void *), void *arg)
787 {
788 	struct format_entry	*fe;
789 	static char		 s[64];
790 
791 	RB_FOREACH(fe, format_entry_tree, &ft->tree) {
792 		if (fe->t != 0) {
793 			xsnprintf(s, sizeof s, "%lld", (long long)fe->t);
794 			cb(fe->key, fe->value, s);
795 		} else {
796 			if (fe->value == NULL && fe->cb != NULL) {
797 				fe->cb(ft, fe);
798 				if (fe->value == NULL)
799 					fe->value = xstrdup("");
800 			}
801 			cb(fe->key, fe->value, arg);
802 		}
803 	}
804 }
805 
806 
807 /* Add a key-value pair. */
808 void
809 format_add(struct format_tree *ft, const char *key, const char *fmt, ...)
810 {
811 	struct format_entry	*fe;
812 	struct format_entry	*fe_now;
813 	va_list			 ap;
814 
815 	fe = xmalloc(sizeof *fe);
816 	fe->key = xstrdup(key);
817 
818 	fe_now = RB_INSERT(format_entry_tree, &ft->tree, fe);
819 	if (fe_now != NULL) {
820 		free(fe->key);
821 		free(fe);
822 		free(fe_now->value);
823 		fe = fe_now;
824 	}
825 
826 	fe->cb = NULL;
827 	fe->t = 0;
828 
829 	va_start(ap, fmt);
830 	xvasprintf(&fe->value, fmt, ap);
831 	va_end(ap);
832 }
833 
834 /* Add a key and time. */
835 static void
836 format_add_tv(struct format_tree *ft, const char *key, struct timeval *tv)
837 {
838 	struct format_entry	*fe;
839 	struct format_entry	*fe_now;
840 
841 	fe = xmalloc(sizeof *fe);
842 	fe->key = xstrdup(key);
843 
844 	fe_now = RB_INSERT(format_entry_tree, &ft->tree, fe);
845 	if (fe_now != NULL) {
846 		free(fe->key);
847 		free(fe);
848 		free(fe_now->value);
849 		fe = fe_now;
850 	}
851 
852 	fe->cb = NULL;
853 	fe->t = tv->tv_sec;
854 
855 	fe->value = NULL;
856 }
857 
858 /* Add a key and function. */
859 static void
860 format_add_cb(struct format_tree *ft, const char *key, format_cb cb)
861 {
862 	struct format_entry	*fe;
863 	struct format_entry	*fe_now;
864 
865 	fe = xmalloc(sizeof *fe);
866 	fe->key = xstrdup(key);
867 
868 	fe_now = RB_INSERT(format_entry_tree, &ft->tree, fe);
869 	if (fe_now != NULL) {
870 		free(fe->key);
871 		free(fe);
872 		free(fe_now->value);
873 		fe = fe_now;
874 	}
875 
876 	fe->cb = cb;
877 	fe->t = 0;
878 
879 	fe->value = NULL;
880 }
881 
882 /* Quote special characters in string. */
883 static char *
884 format_quote(const char *s)
885 {
886 	const char	*cp;
887 	char		*out, *at;
888 
889 	at = out = xmalloc(strlen(s) * 2 + 1);
890 	for (cp = s; *cp != '\0'; cp++) {
891 		if (strchr("|&;<>()$`\\\"'*?[# =%", *cp) != NULL)
892 			*at++ = '\\';
893 		*at++ = *cp;
894 	}
895 	*at = '\0';
896 	return (out);
897 }
898 
899 /* Find a format entry. */
900 static char *
901 format_find(struct format_tree *ft, const char *key, int modifiers)
902 {
903 	struct format_entry	*fe, fe_find;
904 	struct environ_entry	*envent;
905 	static char		 s[64];
906 	struct options_entry	*o;
907 	int			 idx;
908 	char			*found, *saved;
909 
910 	if (~modifiers & FORMAT_TIMESTRING) {
911 		o = options_parse_get(global_options, key, &idx, 0);
912 		if (o == NULL && ft->w != NULL)
913 			o = options_parse_get(ft->w->options, key, &idx, 0);
914 		if (o == NULL)
915 			o = options_parse_get(global_w_options, key, &idx, 0);
916 		if (o == NULL && ft->s != NULL)
917 			o = options_parse_get(ft->s->options, key, &idx, 0);
918 		if (o == NULL)
919 			o = options_parse_get(global_s_options, key, &idx, 0);
920 		if (o != NULL) {
921 			found = options_tostring(o, idx, 1);
922 			goto found;
923 		}
924 	}
925 	found = NULL;
926 
927 	fe_find.key = (char *) key;
928 	fe = RB_FIND(format_entry_tree, &ft->tree, &fe_find);
929 	if (fe != NULL) {
930 		if (modifiers & FORMAT_TIMESTRING) {
931 			if (fe->t == 0)
932 				return (NULL);
933 			ctime_r(&fe->t, s);
934 			s[strcspn(s, "\n")] = '\0';
935 			found = xstrdup(s);
936 			goto found;
937 		}
938 		if (fe->t != 0) {
939 			xasprintf(&found, "%lld", (long long)fe->t);
940 			goto found;
941 		}
942 		if (fe->value == NULL && fe->cb != NULL) {
943 			fe->cb(ft, fe);
944 			if (fe->value == NULL)
945 				fe->value = xstrdup("");
946 		}
947 		found = xstrdup(fe->value);
948 		goto found;
949 	}
950 
951 	if (~modifiers & FORMAT_TIMESTRING) {
952 		envent = NULL;
953 		if (ft->s != NULL)
954 			envent = environ_find(ft->s->environ, key);
955 		if (envent == NULL)
956 			envent = environ_find(global_environ, key);
957 		if (envent != NULL) {
958 			found = xstrdup(envent->value);
959 			goto found;
960 		}
961 	}
962 
963 	return (NULL);
964 
965 found:
966 	if (found == NULL)
967 		return (NULL);
968 	if (modifiers & FORMAT_BASENAME) {
969 		saved = found;
970 		found = xstrdup(basename(saved));
971 		free(saved);
972 	}
973 	if (modifiers & FORMAT_DIRNAME) {
974 		saved = found;
975 		found = xstrdup(dirname(saved));
976 		free(saved);
977 	}
978 	if (modifiers & FORMAT_QUOTE) {
979 		saved = found;
980 		found = xstrdup(format_quote(saved));
981 		free(saved);
982 	}
983 	return (found);
984 }
985 
986 /* Skip until end. */
987 const char *
988 format_skip(const char *s, const char *end)
989 {
990 	int	brackets = 0;
991 
992 	for (; *s != '\0'; s++) {
993 		if (*s == '#' && s[1] == '{')
994 			brackets++;
995 		if (*s == '#' && strchr(",#{}", s[1]) != NULL) {
996 			s++;
997 			continue;
998 		}
999 		if (*s == '}')
1000 			brackets--;
1001 		if (strchr(end, *s) != NULL && brackets == 0)
1002 			break;
1003 	}
1004 	if (*s == '\0')
1005 		return (NULL);
1006 	return (s);
1007 }
1008 
1009 /* Return left and right alternatives separated by commas. */
1010 static int
1011 format_choose(struct format_tree *ft, const char *s, char **left, char **right,
1012     int expand)
1013 {
1014 	const char	*cp;
1015 	char		*left0, *right0;
1016 
1017 	cp = format_skip(s, ",");
1018 	if (cp == NULL)
1019 		return (-1);
1020 	left0 = xstrndup(s, cp - s);
1021 	right0 = xstrdup(cp + 1);
1022 
1023 	if (expand) {
1024 		*left = format_expand(ft, left0);
1025 		free(left0);
1026 		*right = format_expand(ft, right0);
1027 		free(right0);
1028 	} else {
1029 		*left = left0;
1030 		*right = right0;
1031 	}
1032 	return (0);
1033 }
1034 
1035 /* Is this true? */
1036 int
1037 format_true(const char *s)
1038 {
1039 	if (s != NULL && *s != '\0' && (s[0] != '0' || s[1] != '\0'))
1040 		return (1);
1041 	return (0);
1042 }
1043 
1044 /* Check if modifier end. */
1045 static int
1046 format_is_end(char c)
1047 {
1048 	return (c == ';' || c == ':');
1049 }
1050 
1051 /* Add to modifier list. */
1052 static void
1053 format_add_modifier(struct format_modifier **list, u_int *count,
1054     const char *c, size_t n, char **argv, int argc)
1055 {
1056 	struct format_modifier *fm;
1057 
1058 	*list = xreallocarray(*list, (*count) + 1, sizeof **list);
1059 	fm = &(*list)[(*count)++];
1060 
1061 	memcpy(fm->modifier, c, n);
1062 	fm->modifier[n] = '\0';
1063 	fm->size = n;
1064 
1065 	fm->argv = argv;
1066 	fm->argc = argc;
1067 }
1068 
1069 /* Free modifier list. */
1070 static void
1071 format_free_modifiers(struct format_modifier *list, u_int count)
1072 {
1073 	u_int	i;
1074 
1075 	for (i = 0; i < count; i++)
1076 		cmd_free_argv(list[i].argc, list[i].argv);
1077 	free(list);
1078 }
1079 
1080 /* Build modifier list. */
1081 static struct format_modifier *
1082 format_build_modifiers(struct format_tree *ft, const char **s, u_int *count)
1083 {
1084 	const char		*cp = *s, *end;
1085 	struct format_modifier	*list = NULL;
1086 	char			 c, last[] = "X;:", **argv, *value;
1087 	int			 argc;
1088 
1089 	/*
1090 	 * Modifiers are a ; separated list of the forms:
1091 	 *      l,m,C,b,d,t,q,E,T,S,W,P
1092 	 *	=a
1093 	 *	=/a
1094 	 *      =/a/
1095 	 *	s/a/b/
1096 	 *	s/a/b
1097 	 *	||,&&,!=,==
1098 	 */
1099 
1100 	*count = 0;
1101 
1102 	while (*cp != '\0' && *cp != ':') {
1103 		/* Skip and separator character. */
1104 		if (*cp == ';')
1105 			cp++;
1106 
1107 		/* Check single character modifiers with no arguments. */
1108 		if (strchr("lmCbdtqETSWP", cp[0]) != NULL &&
1109 		    format_is_end(cp[1])) {
1110 			format_add_modifier(&list, count, cp, 1, NULL, 0);
1111 			cp++;
1112 			continue;
1113 		}
1114 
1115 		/* Then try double character with no arguments. */
1116 		if ((memcmp("||", cp, 2) == 0 ||
1117 		    memcmp("&&", cp, 2) == 0 ||
1118 		    memcmp("!=", cp, 2) == 0 ||
1119 		    memcmp("==", cp, 2) == 0) &&
1120 		    format_is_end(cp[2])) {
1121 			format_add_modifier(&list, count, cp, 2, NULL, 0);
1122 			cp += 2;
1123 			continue;
1124 		}
1125 
1126 		/* Now try single character with arguments. */
1127 		if (strchr("s=", cp[0]) == NULL)
1128 			break;
1129 		c = cp[0];
1130 
1131 		/* No arguments provided. */
1132 		if (format_is_end(cp[1])) {
1133 			format_add_modifier(&list, count, cp, 1, NULL, 0);
1134 			cp++;
1135 			continue;
1136 		}
1137 		argv = NULL;
1138 		argc = 0;
1139 
1140 		/* Single argument with no wrapper character. */
1141 		if (!ispunct(cp[1]) || cp[1] == '-') {
1142 			end = format_skip(cp + 1, ":;");
1143 			if (end == NULL)
1144 				break;
1145 
1146 			argv = xcalloc(1, sizeof *argv);
1147 			value = xstrndup(cp + 1, end - (cp + 1));
1148 			argv[0] = format_expand(ft, value);
1149 			free(value);
1150 			argc = 1;
1151 
1152 			format_add_modifier(&list, count, &c, 1, argv, argc);
1153 			cp = end;
1154 			continue;
1155 		}
1156 
1157 		/* Multiple arguments with a wrapper character. */
1158 		last[0] = cp[1];
1159 		cp++;
1160 		do {
1161 			if (cp[0] == last[0] && format_is_end(cp[1])) {
1162 				cp++;
1163 				break;
1164 			}
1165 			end = format_skip(cp + 1, last);
1166 			if (end == NULL)
1167 				break;
1168 			cp++;
1169 
1170 			argv = xreallocarray (argv, argc + 1, sizeof *argv);
1171 			value = xstrndup(cp, end - cp);
1172 			argv[argc++] = format_expand(ft, value);
1173 			free(value);
1174 
1175 			cp = end;
1176 		} while (!format_is_end(cp[0]));
1177 		format_add_modifier(&list, count, &c, 1, argv, argc);
1178 	}
1179 	if (*cp != ':') {
1180 		format_free_modifiers(list, *count);
1181 		*count = 0;
1182 		return (NULL);
1183 	}
1184 	*s = cp + 1;
1185 	return list;
1186 }
1187 
1188 /* Perform substitution in string. */
1189 static char *
1190 format_substitute(const char *source, const char *from, const char *to)
1191 {
1192 	char		*copy, *new;
1193 	const char	*cp;
1194 	size_t		 fromlen, tolen, newlen, used;
1195 
1196 	fromlen = strlen(from);
1197 	tolen = strlen(to);
1198 
1199 	newlen = strlen(source) + 1;
1200 	copy = new = xmalloc(newlen);
1201 
1202 	for (cp = source; *cp != '\0'; /* nothing */) {
1203 		if (strncmp(cp, from, fromlen) != 0) {
1204 			*new++ = *cp++;
1205 			continue;
1206 		}
1207 		used = new - copy;
1208 
1209 		newlen += tolen;
1210 		copy = xrealloc(copy, newlen);
1211 
1212 		new = copy + used;
1213 		memcpy(new, to, tolen);
1214 
1215 		new += tolen;
1216 		cp += fromlen;
1217 	}
1218 
1219 	*new = '\0';
1220 	return (copy);
1221 }
1222 
1223 /* Loop over sessions. */
1224 static char *
1225 format_loop_sessions(struct format_tree *ft, const char *fmt)
1226 {
1227 	struct client		*c = ft->client;
1228 	struct cmdq_item	*item = ft->item;
1229 	struct format_tree	*nft;
1230 	char			*expanded, *value;
1231 	size_t			 valuelen;
1232 	struct session		*s;
1233 
1234 	value = xcalloc(1, 1);
1235 	valuelen = 1;
1236 
1237 	RB_FOREACH(s, sessions, &sessions) {
1238 		format_log(ft, "session loop: $%u", s->id);
1239 		nft = format_create(c, item, FORMAT_NONE, ft->flags);
1240 		nft->loop = ft->loop;
1241 		format_defaults(nft, ft->c, s, NULL, NULL);
1242 		expanded = format_expand(nft, fmt);
1243 		format_free(nft);
1244 
1245 		valuelen += strlen(expanded);
1246 		value = xrealloc(value, valuelen);
1247 
1248 		strlcat(value, expanded, valuelen);
1249 		free(expanded);
1250 	}
1251 
1252 	return (value);
1253 }
1254 
1255 /* Loop over windows. */
1256 static char *
1257 format_loop_windows(struct format_tree *ft, const char *fmt)
1258 {
1259 	struct client		*c = ft->client;
1260 	struct cmdq_item	*item = ft->item;
1261 	struct format_tree	*nft;
1262 	char			*all, *active, *use, *expanded, *value;
1263 	size_t			 valuelen;
1264 	struct winlink		*wl;
1265 	struct window		*w;
1266 
1267 	if (ft->s == NULL) {
1268 		format_log(ft, "window loop but no session");
1269 		return (NULL);
1270 	}
1271 
1272 	if (format_choose(ft, fmt, &all, &active, 0) != 0) {
1273 		all = xstrdup(fmt);
1274 		active = NULL;
1275 	}
1276 
1277 	value = xcalloc(1, 1);
1278 	valuelen = 1;
1279 
1280 	RB_FOREACH(wl, winlinks, &ft->s->windows) {
1281 		w = wl->window;
1282 		format_log(ft, "window loop: %u @%u", wl->idx, w->id);
1283 		if (active != NULL && wl == ft->s->curw)
1284 			use = active;
1285 		else
1286 			use = all;
1287 		nft = format_create(c, item, FORMAT_WINDOW|w->id, ft->flags);
1288 		nft->loop = ft->loop;
1289 		format_defaults(nft, ft->c, ft->s, wl, NULL);
1290 		expanded = format_expand(nft, use);
1291 		format_free(nft);
1292 
1293 		valuelen += strlen(expanded);
1294 		value = xrealloc(value, valuelen);
1295 
1296 		strlcat(value, expanded, valuelen);
1297 		free(expanded);
1298 	}
1299 
1300 	free(active);
1301 	free(all);
1302 
1303 	return (value);
1304 }
1305 
1306 /* Loop over panes. */
1307 static char *
1308 format_loop_panes(struct format_tree *ft, const char *fmt)
1309 {
1310 	struct client		*c = ft->client;
1311 	struct cmdq_item	*item = ft->item;
1312 	struct format_tree	*nft;
1313 	char			*all, *active, *use, *expanded, *value;
1314 	size_t			 valuelen;
1315 	struct window_pane	*wp;
1316 
1317 	if (ft->w == NULL) {
1318 		format_log(ft, "pane loop but no window");
1319 		return (NULL);
1320 	}
1321 
1322 	if (format_choose(ft, fmt, &all, &active, 0) != 0) {
1323 		all = xstrdup(fmt);
1324 		active = NULL;
1325 	}
1326 
1327 	value = xcalloc(1, 1);
1328 	valuelen = 1;
1329 
1330 	TAILQ_FOREACH(wp, &ft->w->panes, entry) {
1331 		format_log(ft, "pane loop: %%%u", wp->id);
1332 		if (active != NULL && wp == ft->w->active)
1333 			use = active;
1334 		else
1335 			use = all;
1336 		nft = format_create(c, item, FORMAT_PANE|wp->id, ft->flags);
1337 		nft->loop = ft->loop;
1338 		format_defaults(nft, ft->c, ft->s, ft->wl, wp);
1339 		expanded = format_expand(nft, use);
1340 		format_free(nft);
1341 
1342 		valuelen += strlen(expanded);
1343 		value = xrealloc(value, valuelen);
1344 
1345 		strlcat(value, expanded, valuelen);
1346 		free(expanded);
1347 	}
1348 
1349 	free(active);
1350 	free(all);
1351 
1352 	return (value);
1353 }
1354 
1355 /* Replace a key. */
1356 static int
1357 format_replace(struct format_tree *ft, const char *key, size_t keylen,
1358     char **buf, size_t *len, size_t *off)
1359 {
1360 	struct window_pane	*wp = ft->wp;
1361 	const char		*errptr, *copy, *cp;
1362 	char			*copy0, *condition, *found, *new;
1363 	char			*value, *left, *right;
1364 	size_t			 valuelen;
1365 	int			 modifiers = 0, limit = 0;
1366 	struct format_modifier  *list, *fm, *cmp = NULL, *search = NULL;
1367 	struct format_modifier  *sub = NULL;
1368 	u_int			 i, count;
1369 	int			 j;
1370 
1371 	/* Make a copy of the key. */
1372 	copy = copy0 = xstrndup(key, keylen);
1373 
1374 	/* Process modifier list. */
1375 	list = format_build_modifiers(ft, &copy, &count);
1376 	for (i = 0; i < count; i++) {
1377 		fm = &list[i];
1378 		if (format_logging(ft)) {
1379 			format_log(ft, "modifier %u is %s", i, fm->modifier);
1380 			for (j = 0; j < fm->argc; j++) {
1381 				format_log(ft, "modifier %u argument %d: %s", i,
1382 				    j, fm->argv[j]);
1383 			}
1384 		}
1385 		if (fm->size == 1) {
1386 			switch (fm->modifier[0]) {
1387 			case 'm':
1388 				cmp = fm;
1389 				break;
1390 			case 'C':
1391 				search = fm;
1392 				break;
1393 			case 's':
1394 				if (fm->argc != 2)
1395 					break;
1396 				sub = fm;
1397 				break;
1398 			case '=':
1399 				if (fm->argc != 1)
1400 					break;
1401 				limit = strtonum(fm->argv[0], INT_MIN, INT_MAX,
1402 				    &errptr);
1403 				if (errptr != NULL)
1404 					limit = 0;
1405 				break;
1406 			case 'l':
1407 				modifiers |= FORMAT_LITERAL;
1408 				break;
1409 			case 'b':
1410 				modifiers |= FORMAT_BASENAME;
1411 				break;
1412 			case 'd':
1413 				modifiers |= FORMAT_DIRNAME;
1414 				break;
1415 			case 't':
1416 				modifiers |= FORMAT_TIMESTRING;
1417 				break;
1418 			case 'q':
1419 				modifiers |= FORMAT_QUOTE;
1420 				break;
1421 			case 'E':
1422 				modifiers |= FORMAT_EXPAND;
1423 				break;
1424 			case 'T':
1425 				modifiers |= FORMAT_EXPANDTIME;
1426 				break;
1427 			case 'S':
1428 				modifiers |= FORMAT_SESSIONS;
1429 				break;
1430 			case 'W':
1431 				modifiers |= FORMAT_WINDOWS;
1432 				break;
1433 			case 'P':
1434 				modifiers |= FORMAT_PANES;
1435 				break;
1436 			}
1437 		} else if (fm->size == 2) {
1438 			if (strcmp(fm->modifier, "||") == 0 ||
1439 			    strcmp(fm->modifier, "&&") == 0 ||
1440 			    strcmp(fm->modifier, "==") == 0 ||
1441 			    strcmp(fm->modifier, "!=") == 0)
1442 				cmp = fm;
1443 		}
1444 	}
1445 
1446 	/* Is this a literal string? */
1447 	if (modifiers & FORMAT_LITERAL) {
1448 		value = xstrdup(copy);
1449 		goto done;
1450 	}
1451 
1452 	/* Is this a loop, comparison or condition? */
1453 	if (modifiers & FORMAT_SESSIONS) {
1454 		value = format_loop_sessions(ft, copy);
1455 		if (value == NULL)
1456 			goto fail;
1457 	} else if (modifiers & FORMAT_WINDOWS) {
1458 		value = format_loop_windows(ft, copy);
1459 		if (value == NULL)
1460 			goto fail;
1461 	} else if (modifiers & FORMAT_PANES) {
1462 		value = format_loop_panes(ft, copy);
1463 		if (value == NULL)
1464 			goto fail;
1465 	} else if (search != NULL) {
1466 		/* Search in pane. */
1467 		if (wp == NULL) {
1468 			format_log(ft, "search '%s' but no pane", copy);
1469 			value = xstrdup("0");
1470 		} else {
1471 			format_log(ft, "search '%s' pane %%%u", copy,  wp->id);
1472 			xasprintf(&value, "%u", window_pane_search(wp, copy));
1473 		}
1474 	} else if (cmp != NULL) {
1475 		/* Comparison of left and right. */
1476 		if (format_choose(ft, copy, &left, &right, 1) != 0) {
1477 			format_log(ft, "compare %s syntax error: %s",
1478 			    cmp->modifier, copy);
1479 			goto fail;
1480 		}
1481 		format_log(ft, "compare %s left is: %s", cmp->modifier, left);
1482 		format_log(ft, "compare %s right is: %s", cmp->modifier, right);
1483 
1484 		if (strcmp(cmp->modifier, "||") == 0) {
1485 			if (format_true(left) || format_true(right))
1486 				value = xstrdup("1");
1487 			else
1488 				value = xstrdup("0");
1489 		} else if (strcmp(cmp->modifier, "&&") == 0) {
1490 			if (format_true(left) && format_true(right))
1491 				value = xstrdup("1");
1492 			else
1493 				value = xstrdup("0");
1494 		} else if (strcmp(cmp->modifier, "==") == 0) {
1495 			if (strcmp(left, right) == 0)
1496 				value = xstrdup("1");
1497 			else
1498 				value = xstrdup("0");
1499 		} else if (strcmp(cmp->modifier, "!=") == 0) {
1500 			if (strcmp(left, right) != 0)
1501 				value = xstrdup("1");
1502 			else
1503 				value = xstrdup("0");
1504 		}
1505 		else if (strcmp(cmp->modifier, "m") == 0) {
1506 			if (fnmatch(left, right, 0) == 0)
1507 				value = xstrdup("1");
1508 			else
1509 				value = xstrdup("0");
1510 		}
1511 
1512 		free(right);
1513 		free(left);
1514 	} else if (*copy == '?') {
1515 		/* Conditional: check first and choose second or third. */
1516 		cp = format_skip(copy + 1, ",");
1517 		if (cp == NULL) {
1518 			format_log(ft, "condition syntax error: %s", copy + 1);
1519 			goto fail;
1520 		}
1521 		condition = xstrndup(copy + 1, cp - (copy + 1));
1522 		format_log(ft, "condition is: %s", condition);
1523 
1524 		found = format_find(ft, condition, modifiers);
1525 		if (found == NULL) {
1526 			/*
1527 			 * If the condition not found, try to expand it. If
1528 			 * the expansion doesn't have any effect, then assume
1529 			 * false.
1530 			 */
1531 			found = format_expand(ft, condition);
1532 			if (strcmp(found, condition) == 0) {
1533 				free(found);
1534 				found = xstrdup("");
1535 				format_log(ft, "condition '%s' found: %s",
1536 				    condition, found);
1537 			} else {
1538 				format_log(ft,
1539 				    "condition '%s' not found; assuming false",
1540 				    condition);
1541 			}
1542 		} else
1543 			format_log(ft, "condition '%s' found", condition);
1544 
1545 		if (format_choose(ft, cp + 1, &left, &right, 0) != 0) {
1546 			format_log(ft, "condition '%s' syntax error: %s",
1547 			    condition, cp + 1);
1548 			free(found);
1549 			goto fail;
1550 		}
1551 		if (format_true(found)) {
1552 			format_log(ft, "condition '%s' is true", condition);
1553 			value = format_expand(ft, left);
1554 		} else {
1555 			format_log(ft, "condition '%s' is false", condition);
1556 			value = format_expand(ft, right);
1557 		}
1558 		free(right);
1559 		free(left);
1560 
1561 		free(condition);
1562 		free(found);
1563 	} else {
1564 		/* Neither: look up directly. */
1565 		value = format_find(ft, copy, modifiers);
1566 		if (value == NULL) {
1567 			format_log(ft, "format '%s' not found", copy);
1568 			value = xstrdup("");
1569 		} else
1570 			format_log(ft, "format '%s' found: %s", copy, value);
1571 	}
1572 
1573 done:
1574 	/* Expand again if required. */
1575 	if (modifiers & FORMAT_EXPAND) {
1576 		new = format_expand(ft, value);
1577 		free(value);
1578 		value = new;
1579 	}
1580 	else if (modifiers & FORMAT_EXPANDTIME) {
1581 		new = format_expand_time(ft, value);
1582 		free(value);
1583 		value = new;
1584 	}
1585 
1586 	/* Perform substitution if any. */
1587 	if (sub != NULL) {
1588 		new = format_substitute(value, sub->argv[0], sub->argv[1]);
1589 		format_log(ft, "substituted '%s' to '%s: %s", sub->argv[0],
1590 		    sub->argv[1], new);
1591 		free(value);
1592 		value = new;
1593 	}
1594 
1595 	/* Truncate the value if needed. */
1596 	if (limit > 0) {
1597 		new = format_trim_left(value, limit);
1598 		format_log(ft, "applied length limit %d: %s", limit, new);
1599 		free(value);
1600 		value = new;
1601 	} else if (limit < 0) {
1602 		new = format_trim_right(value, -limit);
1603 		format_log(ft, "applied length limit %d: %s", limit, new);
1604 		free(value);
1605 		value = new;
1606 	}
1607 
1608 	/* Expand the buffer and copy in the value. */
1609 	valuelen = strlen(value);
1610 	while (*len - *off < valuelen + 1) {
1611 		*buf = xreallocarray(*buf, 2, *len);
1612 		*len *= 2;
1613 	}
1614 	memcpy(*buf + *off, value, valuelen);
1615 	*off += valuelen;
1616 
1617 	format_log(ft, "replaced '%s' with '%s'", copy0, value);
1618 	free(value);
1619 
1620 	format_free_modifiers(list, count);
1621 	free(copy0);
1622 	return (0);
1623 
1624 fail:
1625 	format_log(ft, "failed %s", copy0);
1626 	format_free_modifiers(list, count);
1627 	free(copy0);
1628 	return (-1);
1629 }
1630 
1631 /* Expand keys in a template. */
1632 static char *
1633 format_expand1(struct format_tree *ft, const char *fmt, int time)
1634 {
1635 	char		*buf, *out, *name;
1636 	const char	*ptr, *s;
1637 	size_t		 off, len, n, outlen;
1638 	int     	 ch, brackets;
1639 	struct tm	*tm;
1640 	char		 expanded[8192];
1641 
1642 	if (fmt == NULL || *fmt == '\0')
1643 		return (xstrdup(""));
1644 
1645 	if (ft->loop == FORMAT_LOOP_LIMIT)
1646 		return (xstrdup(""));
1647 	ft->loop++;
1648 
1649 	format_log(ft, "expanding format: %s", fmt);
1650 
1651 	if (time) {
1652 		tm = localtime(&ft->time);
1653 		if (strftime(expanded, sizeof expanded, fmt, tm) == 0) {
1654 			format_log(ft, "format is too long");
1655 			return (xstrdup(""));
1656 		}
1657 		if (format_logging(ft) && strcmp(expanded, fmt) != 0)
1658 			format_log(ft, "after time expanded: %s", expanded);
1659 		fmt = expanded;
1660 	}
1661 
1662 	len = 64;
1663 	buf = xmalloc(len);
1664 	off = 0;
1665 
1666 	while (*fmt != '\0') {
1667 		if (*fmt != '#') {
1668 			while (len - off < 2) {
1669 				buf = xreallocarray(buf, 2, len);
1670 				len *= 2;
1671 			}
1672 			buf[off++] = *fmt++;
1673 			continue;
1674 		}
1675 		fmt++;
1676 
1677 		ch = (u_char)*fmt++;
1678 		switch (ch) {
1679 		case '(':
1680 			brackets = 1;
1681 			for (ptr = fmt; *ptr != '\0'; ptr++) {
1682 				if (*ptr == '(')
1683 					brackets++;
1684 				if (*ptr == ')' && --brackets == 0)
1685 					break;
1686 			}
1687 			if (*ptr != ')' || brackets != 0)
1688 				break;
1689 			n = ptr - fmt;
1690 
1691 			name = xstrndup(fmt, n);
1692 			format_log(ft, "found #(): %s", name);
1693 
1694 			if (ft->flags & FORMAT_NOJOBS) {
1695 				out = xstrdup("");
1696 				format_log(ft, "#() is disabled");
1697 			} else {
1698 				out = format_job_get(ft, name);
1699 				format_log(ft, "#() result: %s", out);
1700 			}
1701 			free(name);
1702 
1703 			outlen = strlen(out);
1704 			while (len - off < outlen + 1) {
1705 				buf = xreallocarray(buf, 2, len);
1706 				len *= 2;
1707 			}
1708 			memcpy(buf + off, out, outlen);
1709 			off += outlen;
1710 
1711 			free(out);
1712 
1713 			fmt += n + 1;
1714 			continue;
1715 		case '{':
1716 			ptr = format_skip((char *)fmt - 2, "}");
1717 			if (ptr == NULL)
1718 				break;
1719 			n = ptr - fmt;
1720 
1721 			format_log(ft, "found #{}: %.*s", (int)n, fmt);
1722 			if (format_replace(ft, fmt, n, &buf, &len, &off) != 0)
1723 				break;
1724 			fmt += n + 1;
1725 			continue;
1726 		case '}':
1727 		case '#':
1728 		case ',':
1729 			format_log(ft, "found #%c", ch);
1730 			while (len - off < 2) {
1731 				buf = xreallocarray(buf, 2, len);
1732 				len *= 2;
1733 			}
1734 			buf[off++] = ch;
1735 			continue;
1736 		default:
1737 			s = NULL;
1738 			if (ch >= 'A' && ch <= 'Z')
1739 				s = format_upper[ch - 'A'];
1740 			else if (ch >= 'a' && ch <= 'z')
1741 				s = format_lower[ch - 'a'];
1742 			if (s == NULL) {
1743 				while (len - off < 3) {
1744 					buf = xreallocarray(buf, 2, len);
1745 					len *= 2;
1746 				}
1747 				buf[off++] = '#';
1748 				buf[off++] = ch;
1749 				continue;
1750 			}
1751 			n = strlen(s);
1752 			format_log(ft, "found #%c: %s", ch, s);
1753 			if (format_replace(ft, s, n, &buf, &len, &off) != 0)
1754 				break;
1755 			continue;
1756 		}
1757 
1758 		break;
1759 	}
1760 	buf[off] = '\0';
1761 
1762 	format_log(ft, "result is: %s", buf);
1763 	ft->loop--;
1764 
1765 	return (buf);
1766 }
1767 
1768 /* Expand keys in a template, passing through strftime first. */
1769 char *
1770 format_expand_time(struct format_tree *ft, const char *fmt)
1771 {
1772 	return (format_expand1(ft, fmt, 1));
1773 }
1774 
1775 /* Expand keys in a template. */
1776 char *
1777 format_expand(struct format_tree *ft, const char *fmt)
1778 {
1779 	return (format_expand1(ft, fmt, 0));
1780 }
1781 
1782 /* Expand a single string. */
1783 char *
1784 format_single(struct cmdq_item *item, const char *fmt, struct client *c,
1785     struct session *s, struct winlink *wl, struct window_pane *wp)
1786 {
1787 	struct format_tree	*ft;
1788 	char			*expanded;
1789 
1790 	if (item != NULL)
1791 		ft = format_create(item->client, item, FORMAT_NONE, 0);
1792 	else
1793 		ft = format_create(NULL, item, FORMAT_NONE, 0);
1794 	format_defaults(ft, c, s, wl, wp);
1795 
1796 	expanded = format_expand(ft, fmt);
1797 	format_free(ft);
1798 	return (expanded);
1799 }
1800 
1801 /* Set defaults for any of arguments that are not NULL. */
1802 void
1803 format_defaults(struct format_tree *ft, struct client *c, struct session *s,
1804     struct winlink *wl, struct window_pane *wp)
1805 {
1806 	if (c != NULL)
1807 		log_debug("%s: c=%s", __func__, c->name);
1808 	else
1809 		log_debug("%s: s=none", __func__);
1810 	if (s != NULL)
1811 		log_debug("%s: s=$%u", __func__, s->id);
1812 	else
1813 		log_debug("%s: s=none", __func__);
1814 	if (wl != NULL)
1815 		log_debug("%s: wl=%u w=@%u", __func__, wl->idx, wl->window->id);
1816 	else
1817 		log_debug("%s: wl=none", __func__);
1818 	if (wp != NULL)
1819 		log_debug("%s: wp=%%%u", __func__, wp->id);
1820 	else
1821 		log_debug("%s: wp=none", __func__);
1822 
1823 	if (c != NULL && s != NULL && c->session != s)
1824 		log_debug("%s: session does not match", __func__);
1825 
1826 	format_add(ft, "session_format", "%d", s != NULL);
1827 	format_add(ft, "window_format", "%d", wl != NULL);
1828 	format_add(ft, "pane_format", "%d", wp != NULL);
1829 
1830 	if (s == NULL && c != NULL)
1831 		s = c->session;
1832 	if (wl == NULL && s != NULL)
1833 		wl = s->curw;
1834 	if (wp == NULL && wl != NULL)
1835 		wp = wl->window->active;
1836 
1837 	if (c != NULL)
1838 		format_defaults_client(ft, c);
1839 	if (s != NULL)
1840 		format_defaults_session(ft, s);
1841 	if (wl != NULL)
1842 		format_defaults_winlink(ft, wl);
1843 	if (wp != NULL)
1844 		format_defaults_pane(ft, wp);
1845 }
1846 
1847 /* Set default format keys for a session. */
1848 static void
1849 format_defaults_session(struct format_tree *ft, struct session *s)
1850 {
1851 	struct session_group	*sg;
1852 
1853 	ft->s = s;
1854 
1855 	format_add(ft, "session_name", "%s", s->name);
1856 	format_add(ft, "session_windows", "%u", winlink_count(&s->windows));
1857 	format_add(ft, "session_id", "$%u", s->id);
1858 
1859 	sg = session_group_contains(s);
1860 	format_add(ft, "session_grouped", "%d", sg != NULL);
1861 	if (sg != NULL) {
1862 		format_add(ft, "session_group", "%s", sg->name);
1863 		format_add(ft, "session_group_size", "%u",
1864 		    session_group_count (sg));
1865 		format_add_cb(ft, "session_group_list",
1866 		    format_cb_session_group_list);
1867 	}
1868 
1869 	format_add_tv(ft, "session_created", &s->creation_time);
1870 	format_add_tv(ft, "session_last_attached", &s->last_attached_time);
1871 	format_add_tv(ft, "session_activity", &s->activity_time);
1872 
1873 	format_add(ft, "session_attached", "%u", s->attached);
1874 	format_add(ft, "session_many_attached", "%d", s->attached > 1);
1875 
1876 	format_add_cb(ft, "session_alerts", format_cb_session_alerts);
1877 	format_add_cb(ft, "session_stack", format_cb_session_stack);
1878 }
1879 
1880 /* Set default format keys for a client. */
1881 static void
1882 format_defaults_client(struct format_tree *ft, struct client *c)
1883 {
1884 	struct session	*s;
1885 	const char	*name;
1886 	struct tty	*tty = &c->tty;
1887 	const char	*types[] = TTY_TYPES;
1888 
1889 	if (ft->s == NULL)
1890 		ft->s = c->session;
1891 	ft->c = c;
1892 
1893 	format_add(ft, "client_name", "%s", c->name);
1894 	format_add(ft, "client_pid", "%ld", (long) c->pid);
1895 	format_add(ft, "client_height", "%u", tty->sy);
1896 	format_add(ft, "client_width", "%u", tty->sx);
1897 	format_add(ft, "client_tty", "%s", c->ttyname);
1898 	format_add(ft, "client_control_mode", "%d",
1899 		!!(c->flags & CLIENT_CONTROL));
1900 
1901 	if (tty->term_name != NULL)
1902 		format_add(ft, "client_termname", "%s", tty->term_name);
1903 	if (tty->term_name != NULL)
1904 		format_add(ft, "client_termtype", "%s", types[tty->term_type]);
1905 
1906 	format_add_tv(ft, "client_created", &c->creation_time);
1907 	format_add_tv(ft, "client_activity", &c->activity_time);
1908 
1909 	format_add(ft, "client_written", "%zu", c->written);
1910 	format_add(ft, "client_discarded", "%zu", c->discarded);
1911 
1912 	name = server_client_get_key_table(c);
1913 	if (strcmp(c->keytable->name, name) == 0)
1914 		format_add(ft, "client_prefix", "%d", 0);
1915 	else
1916 		format_add(ft, "client_prefix", "%d", 1);
1917 	format_add(ft, "client_key_table", "%s", c->keytable->name);
1918 
1919 	if (tty->flags & TTY_UTF8)
1920 		format_add(ft, "client_utf8", "%d", 1);
1921 	else
1922 		format_add(ft, "client_utf8", "%d", 0);
1923 
1924 	if (c->flags & CLIENT_READONLY)
1925 		format_add(ft, "client_readonly", "%d", 1);
1926 	else
1927 		format_add(ft, "client_readonly", "%d", 0);
1928 
1929 	s = c->session;
1930 	if (s != NULL)
1931 		format_add(ft, "client_session", "%s", s->name);
1932 	s = c->last_session;
1933 	if (s != NULL && session_alive(s))
1934 		format_add(ft, "client_last_session", "%s", s->name);
1935 }
1936 
1937 /* Set default format keys for a window. */
1938 void
1939 format_defaults_window(struct format_tree *ft, struct window *w)
1940 {
1941 	ft->w = w;
1942 
1943 	format_add_tv(ft, "window_activity", &w->activity_time);
1944 	format_add(ft, "window_id", "@%u", w->id);
1945 	format_add(ft, "window_name", "%s", w->name);
1946 	format_add(ft, "window_width", "%u", w->sx);
1947 	format_add(ft, "window_height", "%u", w->sy);
1948 	format_add_cb(ft, "window_layout", format_cb_window_layout);
1949 	format_add_cb(ft, "window_visible_layout",
1950 	    format_cb_window_visible_layout);
1951 	format_add(ft, "window_panes", "%u", window_count_panes(w));
1952 	format_add(ft, "window_zoomed_flag", "%d",
1953 	    !!(w->flags & WINDOW_ZOOMED));
1954 }
1955 
1956 /* Set default format keys for a winlink. */
1957 static void
1958 format_defaults_winlink(struct format_tree *ft, struct winlink *wl)
1959 {
1960 	struct client	*c = ft->c;
1961 	struct session	*s = wl->session;
1962 	struct window	*w = wl->window;
1963 	int		 flag;
1964 	u_int		 ox, oy, sx, sy;
1965 
1966 	if (ft->w == NULL)
1967 		ft->w = wl->window;
1968 	ft->wl = wl;
1969 
1970 	format_defaults_window(ft, w);
1971 
1972 	if (c != NULL) {
1973 		flag = tty_window_offset(&c->tty, &ox, &oy, &sx, &sy);
1974 		format_add(ft, "window_bigger", "%d", flag);
1975 		if (flag) {
1976 			format_add(ft, "window_offset_x", "%u", ox);
1977 			format_add(ft, "window_offset_y", "%u", oy);
1978 		}
1979 	}
1980 
1981 	format_add(ft, "window_index", "%d", wl->idx);
1982 	format_add_cb(ft, "window_stack_index", format_cb_window_stack_index);
1983 	format_add(ft, "window_flags", "%s", window_printable_flags(wl));
1984 	format_add(ft, "window_active", "%d", wl == s->curw);
1985 
1986 	format_add(ft, "window_start_flag", "%d",
1987 	    !!(wl == RB_MIN(winlinks, &s->windows)));
1988 	format_add(ft, "window_end_flag", "%d",
1989 	    !!(wl == RB_MAX(winlinks, &s->windows)));
1990 
1991 	format_add(ft, "window_bell_flag", "%d",
1992 	    !!(wl->flags & WINLINK_BELL));
1993 	format_add(ft, "window_activity_flag", "%d",
1994 	    !!(wl->flags & WINLINK_ACTIVITY));
1995 	format_add(ft, "window_silence_flag", "%d",
1996 	    !!(wl->flags & WINLINK_SILENCE));
1997 	format_add(ft, "window_last_flag", "%d",
1998 	    !!(wl == TAILQ_FIRST(&s->lastw)));
1999 	format_add(ft, "window_linked", "%d", session_is_linked(s, wl->window));
2000 }
2001 
2002 /* Set default format keys for a window pane. */
2003 void
2004 format_defaults_pane(struct format_tree *ft, struct window_pane *wp)
2005 {
2006 	struct window			*w = wp->window;
2007 	struct grid			*gd = wp->base.grid;
2008 	int  				 status = wp->status;
2009 	u_int				 idx;
2010 	struct window_mode_entry	*wme;
2011 
2012 	if (ft->w == NULL)
2013 		ft->w = w;
2014 	ft->wp = wp;
2015 
2016 	format_add(ft, "history_size", "%u", gd->hsize);
2017 	format_add(ft, "history_limit", "%u", gd->hlimit);
2018 	format_add_cb(ft, "history_bytes", format_cb_history_bytes);
2019 
2020 	if (window_pane_index(wp, &idx) != 0)
2021 		fatalx("index not found");
2022 	format_add(ft, "pane_index", "%u", idx);
2023 
2024 	format_add(ft, "pane_width", "%u", wp->sx);
2025 	format_add(ft, "pane_height", "%u", wp->sy);
2026 	format_add(ft, "pane_title", "%s", wp->base.title);
2027 	format_add(ft, "pane_id", "%%%u", wp->id);
2028 	format_add(ft, "pane_active", "%d", wp == w->active);
2029 	format_add(ft, "pane_input_off", "%d", !!(wp->flags & PANE_INPUTOFF));
2030 	format_add(ft, "pane_pipe", "%d", wp->pipe_fd != -1);
2031 
2032 	if ((wp->flags & PANE_STATUSREADY) && WIFEXITED(status))
2033 		format_add(ft, "pane_dead_status", "%d", WEXITSTATUS(status));
2034 	if (~wp->flags & PANE_EMPTY)
2035 		format_add(ft, "pane_dead", "%d", wp->fd == -1);
2036 	else
2037 		format_add(ft, "pane_dead", "0");
2038 
2039 	format_add(ft, "pane_left", "%u", wp->xoff);
2040 	format_add(ft, "pane_top", "%u", wp->yoff);
2041 	format_add(ft, "pane_right", "%u", wp->xoff + wp->sx - 1);
2042 	format_add(ft, "pane_bottom", "%u", wp->yoff + wp->sy - 1);
2043 	format_add(ft, "pane_at_left", "%d", wp->xoff == 0);
2044 	format_add(ft, "pane_at_top", "%d", wp->yoff == 0);
2045 	format_add(ft, "pane_at_right", "%d", wp->xoff + wp->sx == w->sx);
2046 	format_add(ft, "pane_at_bottom", "%d", wp->yoff + wp->sy == w->sy);
2047 
2048 	wme = TAILQ_FIRST(&wp->modes);
2049 	if (wme != NULL) {
2050 		format_add(ft, "pane_mode", "%s", wme->mode->name);
2051 		if (wme->mode->formats != NULL)
2052 			wme->mode->formats(wme, ft);
2053 	}
2054 	format_add_cb(ft, "pane_in_mode", format_cb_pane_in_mode);
2055 
2056 	format_add(ft, "pane_synchronized", "%d",
2057 	    !!options_get_number(w->options, "synchronize-panes"));
2058 	if (wp->searchstr != NULL)
2059 		format_add(ft, "pane_search_string", "%s", wp->searchstr);
2060 
2061 	format_add(ft, "pane_tty", "%s", wp->tty);
2062 	format_add(ft, "pane_pid", "%ld", (long) wp->pid);
2063 	format_add_cb(ft, "pane_start_command", format_cb_start_command);
2064 	format_add_cb(ft, "pane_current_command", format_cb_current_command);
2065 
2066 	format_add(ft, "cursor_x", "%u", wp->base.cx);
2067 	format_add(ft, "cursor_y", "%u", wp->base.cy);
2068 	format_add_cb(ft, "cursor_character", format_cb_cursor_character);
2069 
2070 	format_add(ft, "scroll_region_upper", "%u", wp->base.rupper);
2071 	format_add(ft, "scroll_region_lower", "%u", wp->base.rlower);
2072 
2073 	format_add(ft, "alternate_on", "%d", wp->saved_grid ? 1 : 0);
2074 	format_add(ft, "alternate_saved_x", "%u", wp->saved_cx);
2075 	format_add(ft, "alternate_saved_y", "%u", wp->saved_cy);
2076 
2077 	format_add(ft, "cursor_flag", "%d",
2078 	    !!(wp->base.mode & MODE_CURSOR));
2079 	format_add(ft, "insert_flag", "%d",
2080 	    !!(wp->base.mode & MODE_INSERT));
2081 	format_add(ft, "keypad_cursor_flag", "%d",
2082 	    !!(wp->base.mode & MODE_KCURSOR));
2083 	format_add(ft, "keypad_flag", "%d",
2084 	    !!(wp->base.mode & MODE_KKEYPAD));
2085 	format_add(ft, "wrap_flag", "%d",
2086 	    !!(wp->base.mode & MODE_WRAP));
2087 
2088 	format_add(ft, "mouse_any_flag", "%d",
2089 	    !!(wp->base.mode & ALL_MOUSE_MODES));
2090 	format_add(ft, "mouse_standard_flag", "%d",
2091 	    !!(wp->base.mode & MODE_MOUSE_STANDARD));
2092 	format_add(ft, "mouse_button_flag", "%d",
2093 	    !!(wp->base.mode & MODE_MOUSE_BUTTON));
2094 	format_add(ft, "mouse_all_flag", "%d",
2095 	    !!(wp->base.mode & MODE_MOUSE_ALL));
2096 
2097 	format_add_cb(ft, "pane_tabs", format_cb_pane_tabs);
2098 }
2099 
2100 /* Set default format keys for paste buffer. */
2101 void
2102 format_defaults_paste_buffer(struct format_tree *ft, struct paste_buffer *pb)
2103 {
2104 	struct timeval	 tv;
2105 	size_t		 size;
2106 	char		*s;
2107 
2108 	timerclear(&tv);
2109 	tv.tv_sec = paste_buffer_created(pb);
2110 	paste_buffer_data(pb, &size);
2111 
2112 	format_add(ft, "buffer_size", "%zu", size);
2113 	format_add(ft, "buffer_name", "%s", paste_buffer_name(pb));
2114 	format_add_tv(ft, "buffer_created", &tv);
2115 
2116 	s = paste_make_sample(pb);
2117 	format_add(ft, "buffer_sample", "%s", s);
2118 	free(s);
2119 }
2120