xref: /netbsd-src/external/bsd/tmux/dist/format.c (revision bdc22b2e01993381dcefeff2bc9b56ca75a4235c)
1 /* $OpenBSD$ */
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 <errno.h>
23 #include <fnmatch.h>
24 #include <libgen.h>
25 #include <stdarg.h>
26 #include <stdlib.h>
27 #include <string.h>
28 #include <time.h>
29 #include <unistd.h>
30 
31 #include "tmux.h"
32 
33 /*
34  * Build a list of key-value pairs and use them to expand #{key} entries in a
35  * string.
36  */
37 
38 struct format_entry;
39 typedef void (*format_cb)(struct format_tree *, struct format_entry *);
40 
41 static char	*format_job_get(struct format_tree *, const char *);
42 static void	 format_job_timer(int, short, void *);
43 
44 static char	*format_find(struct format_tree *, const char *, int);
45 static void	 format_add_cb(struct format_tree *, const char *, format_cb);
46 static void	 format_add_tv(struct format_tree *, const char *,
47 		     struct timeval *);
48 static int	 format_replace(struct format_tree *, const char *, size_t,
49 		     char **, size_t *, size_t *);
50 
51 static void	 format_defaults_session(struct format_tree *,
52 		     struct session *);
53 static void	 format_defaults_client(struct format_tree *, struct client *);
54 static void	 format_defaults_winlink(struct format_tree *,
55 		     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_SUBSTITUTE 0x8
96 
97 /* Entry in format tree. */
98 struct format_entry {
99 	char			*key;
100 	char			*value;
101 	time_t			 t;
102 	format_cb		 cb;
103 	RB_ENTRY(format_entry)	 entry;
104 };
105 
106 /* Format entry tree. */
107 struct format_tree {
108 	struct window		*w;
109 	struct winlink		*wl;
110 	struct session		*s;
111 	struct window_pane	*wp;
112 
113 	struct client		*client;
114 	u_int			 tag;
115 	int			 flags;
116 
117 	RB_HEAD(format_entry_tree, format_entry) tree;
118 };
119 static int format_entry_cmp(struct format_entry *, struct format_entry *);
120 RB_GENERATE_STATIC(format_entry_tree, format_entry, entry, format_entry_cmp);
121 
122 /* Format entry tree comparison function. */
123 static int
124 format_entry_cmp(struct format_entry *fe1, struct format_entry *fe2)
125 {
126 	return (strcmp(fe1->key, fe2->key));
127 }
128 
129 /* Single-character uppercase aliases. */
130 static const char *format_upper[] = {
131 	NULL,		/* A */
132 	NULL,		/* B */
133 	NULL,		/* C */
134 	"pane_id",	/* D */
135 	NULL,		/* E */
136 	"window_flags",	/* F */
137 	NULL,		/* G */
138 	"host",		/* H */
139 	"window_index",	/* I */
140 	NULL,		/* J */
141 	NULL,		/* K */
142 	NULL,		/* L */
143 	NULL,		/* M */
144 	NULL,		/* N */
145 	NULL,		/* O */
146 	"pane_index",	/* P */
147 	NULL,		/* Q */
148 	NULL,		/* R */
149 	"session_name",	/* S */
150 	"pane_title",	/* T */
151 	NULL,		/* U */
152 	NULL,		/* V */
153 	"window_name",	/* W */
154 	NULL,		/* X */
155 	NULL,		/* Y */
156 	NULL 		/* Z */
157 };
158 
159 /* Single-character lowercase aliases. */
160 static const char *format_lower[] = {
161 	NULL,		/* a */
162 	NULL,		/* b */
163 	NULL,		/* c */
164 	NULL,		/* d */
165 	NULL,		/* e */
166 	NULL,		/* f */
167 	NULL,		/* g */
168 	"host_short",	/* h */
169 	NULL,		/* i */
170 	NULL,		/* j */
171 	NULL,		/* k */
172 	NULL,		/* l */
173 	NULL,		/* m */
174 	NULL,		/* n */
175 	NULL,		/* o */
176 	NULL,		/* p */
177 	NULL,		/* q */
178 	NULL,		/* r */
179 	NULL,		/* s */
180 	NULL,		/* t */
181 	NULL,		/* u */
182 	NULL,		/* v */
183 	NULL,		/* w */
184 	NULL,		/* x */
185 	NULL,		/* y */
186 	NULL		/* z */
187 };
188 
189 /* Format job update callback. */
190 static void
191 format_job_update(struct job *job)
192 {
193 	struct format_job	*fj = job->data;
194 	char			*line;
195 	time_t			 t;
196 
197 	if ((line = evbuffer_readline(job->event->input)) == NULL)
198 		return;
199 	fj->updated = 1;
200 
201 	free(fj->out);
202 	fj->out = line;
203 
204 	log_debug("%s: %p %s: %s", __func__, fj, fj->cmd, fj->out);
205 
206 	t = time(NULL);
207 	if (fj->status && fj->last != t) {
208 		if (fj->client != NULL)
209 			server_status_client(fj->client);
210 		fj->last = t;
211 	}
212 }
213 
214 /* Format job complete callback. */
215 static void
216 format_job_complete(struct job *job)
217 {
218 	struct format_job	*fj = job->data;
219 	char			*line, *buf;
220 	size_t			 len;
221 
222 	fj->job = NULL;
223 
224 	buf = NULL;
225 	if ((line = evbuffer_readline(job->event->input)) == NULL) {
226 		len = EVBUFFER_LENGTH(job->event->input);
227 		buf = xmalloc(len + 1);
228 		if (len != 0)
229 			memcpy(buf, EVBUFFER_DATA(job->event->input), len);
230 		buf[len] = '\0';
231 	} else
232 		buf = line;
233 
234 	log_debug("%s: %p %s: %s", __func__, fj, fj->cmd, buf);
235 
236 	if (*buf != '\0' || !fj->updated) {
237 		free(fj->out);
238 		fj->out = buf;
239 	} else
240 		free(buf);
241 
242 	if (fj->status) {
243 		if (fj->client != NULL)
244 			server_status_client(fj->client);
245 		fj->status = 0;
246 	}
247 }
248 
249 /* Find a job. */
250 static char *
251 format_job_get(struct format_tree *ft, const char *cmd)
252 {
253 	struct format_job_tree	*jobs;
254 	struct format_job	 fj0, *fj;
255 	time_t			 t;
256 	char			*expanded;
257 	int			 force;
258 
259 	if (ft->client == NULL)
260 		jobs = &format_jobs;
261 	else if (ft->client->jobs != NULL)
262 		jobs = ft->client->jobs;
263 	else {
264 		jobs = ft->client->jobs = xmalloc(sizeof *ft->client->jobs);
265 		RB_INIT(jobs);
266 	}
267 
268 	fj0.tag = ft->tag;
269 	fj0.cmd = cmd;
270 	if ((fj = RB_FIND(format_job_tree, jobs, &fj0)) == NULL) {
271 		fj = xcalloc(1, sizeof *fj);
272 		fj->client = ft->client;
273 		fj->tag = ft->tag;
274 		fj->cmd = xstrdup(cmd);
275 		fj->expanded = NULL;
276 
277 		xasprintf(&fj->out, "<'%s' not ready>", fj->cmd);
278 
279 		RB_INSERT(format_job_tree, jobs, fj);
280 	}
281 
282 	expanded = format_expand(ft, cmd);
283 	if (fj->expanded == NULL || strcmp(expanded, fj->expanded) != 0) {
284 		free(__UNCONST(fj->expanded));
285 		fj->expanded = xstrdup(expanded);
286 		force = 1;
287 	} else
288 		force = (ft->flags & FORMAT_FORCE);
289 
290 	t = time(NULL);
291 	if (fj->job == NULL && (force || fj->last != t)) {
292 		fj->job = job_run(expanded, NULL, NULL, format_job_update,
293 		    format_job_complete, NULL, fj);
294 		if (fj->job == NULL) {
295 			free(fj->out);
296 			xasprintf(&fj->out, "<'%s' didn't start>", fj->cmd);
297 		}
298 		fj->last = t;
299 		fj->updated = 0;
300 	}
301 
302 	if (ft->flags & FORMAT_STATUS)
303 		fj->status = 1;
304 
305 	free(expanded);
306 	return (format_expand(ft, fj->out));
307 }
308 
309 /* Remove old jobs. */
310 static void
311 format_job_tidy(struct format_job_tree *jobs, int force)
312 {
313 	struct format_job	*fj, *fj1;
314 	time_t			 now;
315 
316 	now = time(NULL);
317 	RB_FOREACH_SAFE(fj, format_job_tree, jobs, fj1) {
318 		if (!force && (fj->last > now || now - fj->last < 3600))
319 			continue;
320 		RB_REMOVE(format_job_tree, jobs, fj);
321 
322 		log_debug("%s: %s", __func__, fj->cmd);
323 
324 		if (fj->job != NULL)
325 			job_free(fj->job);
326 
327 		free(__UNCONST(fj->expanded));
328 		free(__UNCONST(fj->cmd));
329 		free(fj->out);
330 
331 		free(fj);
332 	}
333 }
334 
335 /* Remove old jobs for client. */
336 void
337 format_lost_client(struct client *c)
338 {
339 	if (c->jobs != NULL)
340 		format_job_tidy(c->jobs, 1);
341 	free(c->jobs);
342 }
343 
344 /* Remove old jobs periodically. */
345 static void
346 format_job_timer(__unused int fd, __unused short events, __unused void *arg)
347 {
348 	struct client	*c;
349 	struct timeval	 tv = { .tv_sec = 60 };
350 
351 	format_job_tidy(&format_jobs, 0);
352 	TAILQ_FOREACH(c, &clients, entry) {
353 		if (c->jobs != NULL)
354 			format_job_tidy(c->jobs, 0);
355 	}
356 
357 	evtimer_del(&format_job_event);
358 	evtimer_add(&format_job_event, &tv);
359 }
360 
361 /* Callback for host. */
362 static void
363 format_cb_host(__unused struct format_tree *ft, struct format_entry *fe)
364 {
365 	char host[HOST_NAME_MAX + 1];
366 
367 	if (gethostname(host, sizeof host) != 0)
368 		fe->value = xstrdup("");
369 	else
370 		fe->value = xstrdup(host);
371 }
372 
373 /* Callback for host_short. */
374 static void
375 format_cb_host_short(__unused struct format_tree *ft, struct format_entry *fe)
376 {
377 	char host[HOST_NAME_MAX + 1], *cp;
378 
379 	if (gethostname(host, sizeof host) != 0)
380 		fe->value = xstrdup("");
381 	else {
382 		if ((cp = strchr(host, '.')) != NULL)
383 			*cp = '\0';
384 		fe->value = xstrdup(host);
385 	}
386 }
387 
388 /* Callback for pid. */
389 static void
390 format_cb_pid(__unused struct format_tree *ft, struct format_entry *fe)
391 {
392 	xasprintf(&fe->value, "%ld", (long)getpid());
393 }
394 
395 /* Callback for session_alerts. */
396 static void
397 format_cb_session_alerts(struct format_tree *ft, struct format_entry *fe)
398 {
399 	struct session	*s = ft->s;
400 	struct winlink	*wl;
401 	char		 alerts[1024], tmp[16];
402 
403 	if (s == NULL)
404 		return;
405 
406 	*alerts = '\0';
407 	RB_FOREACH(wl, winlinks, &s->windows) {
408 		if ((wl->flags & WINLINK_ALERTFLAGS) == 0)
409 			continue;
410 		xsnprintf(tmp, sizeof tmp, "%u", wl->idx);
411 
412 		if (*alerts != '\0')
413 			strlcat(alerts, ",", sizeof alerts);
414 		strlcat(alerts, tmp, sizeof alerts);
415 		if (wl->flags & WINLINK_ACTIVITY)
416 			strlcat(alerts, "#", sizeof alerts);
417 		if (wl->flags & WINLINK_BELL)
418 			strlcat(alerts, "!", sizeof alerts);
419 		if (wl->flags & WINLINK_SILENCE)
420 			strlcat(alerts, "~", sizeof alerts);
421 	}
422 	fe->value = xstrdup(alerts);
423 }
424 
425 /* Callback for session_stack. */
426 static void
427 format_cb_session_stack(struct format_tree *ft, struct format_entry *fe)
428 {
429 	struct session	*s = ft->s;
430 	struct winlink	*wl;
431 	char		 result[1024], tmp[16];
432 
433 	if (s == NULL)
434 		return;
435 
436 	xsnprintf(result, sizeof result, "%u", s->curw->idx);
437 	TAILQ_FOREACH(wl, &s->lastw, sentry) {
438 		xsnprintf(tmp, sizeof tmp, "%u", wl->idx);
439 
440 		if (*result != '\0')
441 			strlcat(result, ",", sizeof result);
442 		strlcat(result, tmp, sizeof result);
443 	}
444 	fe->value = xstrdup(result);
445 }
446 
447 /* Callback for window_stack_index. */
448 static void
449 format_cb_window_stack_index(struct format_tree *ft, struct format_entry *fe)
450 {
451 	struct session	*s = ft->wl->session;
452 	struct winlink	*wl;
453 	u_int		 idx;
454 
455 	idx = 0;
456 	TAILQ_FOREACH(wl, &s->lastw, sentry) {
457 		idx++;
458 		if (wl == ft->wl)
459 			break;
460 	}
461 	if (wl != NULL)
462 		xasprintf(&fe->value, "%u", idx);
463 	else
464 		fe->value = xstrdup("0");
465 }
466 
467 /* Callback for window_layout. */
468 static void
469 format_cb_window_layout(struct format_tree *ft, struct format_entry *fe)
470 {
471 	struct window	*w = ft->w;
472 
473 	if (w == NULL)
474 		return;
475 
476 	if (w->saved_layout_root != NULL)
477 		fe->value = layout_dump(w->saved_layout_root);
478 	else
479 		fe->value = layout_dump(w->layout_root);
480 }
481 
482 /* Callback for window_visible_layout. */
483 static void
484 format_cb_window_visible_layout(struct format_tree *ft, struct format_entry *fe)
485 {
486 	struct window	*w = ft->w;
487 
488 	if (w == NULL)
489 		return;
490 
491 	fe->value = layout_dump(w->layout_root);
492 }
493 
494 /* Callback for pane_start_command. */
495 static void
496 format_cb_start_command(struct format_tree *ft, struct format_entry *fe)
497 {
498 	struct window_pane	*wp = ft->wp;
499 
500 	if (wp == NULL)
501 		return;
502 
503 	fe->value = cmd_stringify_argv(wp->argc, wp->argv);
504 }
505 
506 /* Callback for pane_current_command. */
507 static void
508 format_cb_current_command(struct format_tree *ft, struct format_entry *fe)
509 {
510 	struct window_pane	*wp = ft->wp;
511 	char			*cmd;
512 
513 	if (wp == NULL)
514 		return;
515 
516 	cmd = osdep_get_name(wp->fd, wp->tty);
517 	if (cmd == NULL || *cmd == '\0') {
518 		free(cmd);
519 		cmd = cmd_stringify_argv(wp->argc, wp->argv);
520 		if (cmd == NULL || *cmd == '\0') {
521 			free(cmd);
522 			cmd = xstrdup(wp->shell);
523 		}
524 	}
525 	fe->value = parse_window_name(cmd);
526 	free(cmd);
527 }
528 
529 /* Callback for pane_current_path. */
530 static void
531 format_cb_current_path(struct format_tree *ft, struct format_entry *fe)
532 {
533 	struct window_pane	*wp = ft->wp;
534 	char			*cwd;
535 
536 	if (wp == NULL)
537 		return;
538 
539 	cwd = osdep_get_cwd(wp->fd);
540 	if (cwd != NULL)
541 		fe->value = xstrdup(cwd);
542 }
543 
544 /* Callback for history_bytes. */
545 static void
546 format_cb_history_bytes(struct format_tree *ft, struct format_entry *fe)
547 {
548 	struct window_pane	*wp = ft->wp;
549 	struct grid		*gd;
550 	struct grid_line	*gl;
551 	unsigned long long	 size;
552 	u_int			 i;
553 
554 	if (wp == NULL)
555 		return;
556 	gd = wp->base.grid;
557 
558 	size = 0;
559 	for (i = 0; i < gd->hsize; i++) {
560 		gl = &gd->linedata[i];
561 		size += gl->cellsize * sizeof *gl->celldata;
562 		size += gl->extdsize * sizeof *gl->extddata;
563 	}
564 	size += gd->hsize * sizeof *gd->linedata;
565 
566 	xasprintf(&fe->value, "%llu", size);
567 }
568 
569 /* Callback for pane_tabs. */
570 static void
571 format_cb_pane_tabs(struct format_tree *ft, struct format_entry *fe)
572 {
573 	struct window_pane	*wp = ft->wp;
574 	struct evbuffer		*buffer;
575 	u_int			 i;
576 	int			 size;
577 
578 	if (wp == NULL)
579 		return;
580 
581 	buffer = evbuffer_new();
582 	for (i = 0; i < wp->base.grid->sx; i++) {
583 		if (!bit_test(wp->base.tabs, i))
584 			continue;
585 
586 		if (EVBUFFER_LENGTH(buffer) > 0)
587 			evbuffer_add(buffer, ",", 1);
588 		evbuffer_add_printf(buffer, "%u", i);
589 	}
590 	size = EVBUFFER_LENGTH(buffer);
591 	xasprintf(&fe->value, "%.*s", size, EVBUFFER_DATA(buffer));
592 	evbuffer_free(buffer);
593 }
594 
595 /* Merge a format tree. */
596 static void
597 format_merge(struct format_tree *ft, struct format_tree *from)
598 {
599 	struct format_entry	*fe;
600 
601 	RB_FOREACH(fe, format_entry_tree, &from->tree) {
602 		if (fe->value != NULL)
603 			format_add(ft, fe->key, "%s", fe->value);
604 	}
605 }
606 
607 /* Create a new tree. */
608 struct format_tree *
609 format_create(struct client *c, struct cmdq_item *item, int tag, int flags)
610 {
611 	struct format_tree	*ft;
612 
613 	if (!event_initialized(&format_job_event)) {
614 		evtimer_set(&format_job_event, format_job_timer, NULL);
615 		format_job_timer(-1, 0, NULL);
616 	}
617 
618 	ft = xcalloc(1, sizeof *ft);
619 	RB_INIT(&ft->tree);
620 
621 	if (c != NULL) {
622 		ft->client = c;
623 		ft->client->references++;
624 	}
625 
626 	ft->tag = tag;
627 	ft->flags = flags;
628 
629 	format_add(ft, "version", "%s", VERSION);
630 	format_add_cb(ft, "host", format_cb_host);
631 	format_add_cb(ft, "host_short", format_cb_host_short);
632 	format_add_cb(ft, "pid", format_cb_pid);
633 	format_add(ft, "socket_path", "%s", socket_path);
634 	format_add_tv(ft, "start_time", &start_time);
635 
636 	if (item != NULL) {
637 		if (item->cmd != NULL)
638 			format_add(ft, "command", "%s", item->cmd->entry->name);
639 		if (item->shared != NULL && item->shared->formats != NULL)
640 			format_merge(ft, item->shared->formats);
641 	}
642 
643 	return (ft);
644 }
645 
646 /* Free a tree. */
647 void
648 format_free(struct format_tree *ft)
649 {
650 	struct format_entry	*fe, *fe1;
651 
652 	RB_FOREACH_SAFE(fe, format_entry_tree, &ft->tree, fe1) {
653 		RB_REMOVE(format_entry_tree, &ft->tree, fe);
654 		free(fe->value);
655 		free(fe->key);
656 		free(fe);
657 	}
658 
659 	if (ft->client != NULL)
660 		server_client_unref(ft->client);
661 	free(ft);
662 }
663 
664 /* Add a key-value pair. */
665 void
666 format_add(struct format_tree *ft, const char *key, const char *fmt, ...)
667 {
668 	struct format_entry	*fe;
669 	struct format_entry	*fe_now;
670 	va_list			 ap;
671 
672 	fe = xmalloc(sizeof *fe);
673 	fe->key = xstrdup(key);
674 
675 	fe_now = RB_INSERT(format_entry_tree, &ft->tree, fe);
676 	if (fe_now != NULL) {
677 		free(fe->key);
678 		free(fe);
679 		free(fe_now->value);
680 		fe = fe_now;
681 	}
682 
683 	fe->cb = NULL;
684 	fe->t = 0;
685 
686 	va_start(ap, fmt);
687 	xvasprintf(&fe->value, fmt, ap);
688 	va_end(ap);
689 }
690 
691 /* Add a key and time. */
692 static void
693 format_add_tv(struct format_tree *ft, const char *key, struct timeval *tv)
694 {
695 	struct format_entry	*fe;
696 	struct format_entry	*fe_now;
697 
698 	fe = xmalloc(sizeof *fe);
699 	fe->key = xstrdup(key);
700 
701 	fe_now = RB_INSERT(format_entry_tree, &ft->tree, fe);
702 	if (fe_now != NULL) {
703 		free(fe->key);
704 		free(fe);
705 		free(fe_now->value);
706 		fe = fe_now;
707 	}
708 
709 	fe->cb = NULL;
710 	fe->t = tv->tv_sec;
711 
712 	fe->value = NULL;
713 }
714 
715 /* Add a key and function. */
716 static void
717 format_add_cb(struct format_tree *ft, const char *key, format_cb cb)
718 {
719 	struct format_entry	*fe;
720 	struct format_entry	*fe_now;
721 
722 	fe = xmalloc(sizeof *fe);
723 	fe->key = xstrdup(key);
724 
725 	fe_now = RB_INSERT(format_entry_tree, &ft->tree, fe);
726 	if (fe_now != NULL) {
727 		free(fe->key);
728 		free(fe);
729 		free(fe_now->value);
730 		fe = fe_now;
731 	}
732 
733 	fe->cb = cb;
734 	fe->t = 0;
735 
736 	fe->value = NULL;
737 }
738 
739 /* Find a format entry. */
740 static char *
741 format_find(struct format_tree *ft, const char *key, int modifiers)
742 {
743 	struct format_entry	*fe, fe_find;
744 	struct environ_entry	*envent;
745 	static char		 s[64];
746 	struct options_entry	*o;
747 	const char		*found;
748 	int			 idx;
749 	char			*copy, *saved;
750 
751 	if (~modifiers & FORMAT_TIMESTRING) {
752 		o = options_parse_get(global_options, key, &idx, 0);
753 		if (o == NULL && ft->w != NULL)
754 			o = options_parse_get(ft->w->options, key, &idx, 0);
755 		if (o == NULL)
756 			o = options_parse_get(global_w_options, key, &idx, 0);
757 		if (o == NULL && ft->s != NULL)
758 			o = options_parse_get(ft->s->options, key, &idx, 0);
759 		if (o == NULL)
760 			o = options_parse_get(global_s_options, key, &idx, 0);
761 		if (o != NULL) {
762 			found = options_tostring(o, idx, 1);
763 			goto found;
764 		}
765 	}
766 	found = NULL;
767 
768 	fe_find.key = __UNCONST(key);
769 	fe = RB_FIND(format_entry_tree, &ft->tree, &fe_find);
770 	if (fe != NULL) {
771 		if (modifiers & FORMAT_TIMESTRING) {
772 			if (fe->t == 0)
773 				return (NULL);
774 			ctime_r(&fe->t, s);
775 			s[strcspn(s, "\n")] = '\0';
776 			found = s;
777 			goto found;
778 		}
779 		if (fe->t != 0) {
780 			xsnprintf(s, sizeof s, "%lld", (long long)fe->t);
781 			found = s;
782 			goto found;
783 		}
784 		if (fe->value == NULL && fe->cb != NULL)
785 			fe->cb(ft, fe);
786 		found = fe->value;
787 		goto found;
788 	}
789 
790 	if (~modifiers & FORMAT_TIMESTRING) {
791 		envent = NULL;
792 		if (ft->s != NULL)
793 			envent = environ_find(ft->s->environ, key);
794 		if (envent == NULL)
795 			envent = environ_find(global_environ, key);
796 		if (envent != NULL) {
797 			found = envent->value;
798 			goto found;
799 		}
800 	}
801 
802 	return (NULL);
803 
804 found:
805 	if (found == NULL)
806 		return (NULL);
807 	copy = xstrdup(found);
808 	if (modifiers & FORMAT_BASENAME) {
809 		saved = copy;
810 		copy = xstrdup(basename(saved));
811 		free(saved);
812 	}
813 	if (modifiers & FORMAT_DIRNAME) {
814 		saved = copy;
815 		copy = xstrdup(dirname(saved));
816 		free(saved);
817 	}
818 	return (copy);
819 }
820 
821 /* Skip until comma. */
822 static char *
823 format_skip(char *s)
824 {
825 	int	brackets = 0;
826 
827 	for (; *s != '\0'; s++) {
828 		if (*s == '{')
829 			brackets++;
830 		if (*s == '}')
831 			brackets--;
832 		if (*s == ',' && brackets == 0)
833 			break;
834 	}
835 	if (*s == '\0')
836 		return (NULL);
837 	return (s);
838 }
839 
840 /* Return left and right alternatives separated by commas. */
841 static int
842 format_choose(char *s, char **left, char **right)
843 {
844 	char	*cp;
845 
846 	cp = format_skip(s);
847 	if (cp == NULL)
848 		return (-1);
849 	*cp = '\0';
850 
851 	*left = s;
852 	*right = cp + 1;
853 	return (0);
854 }
855 
856 /* Is this true? */
857 int
858 format_true(const char *s)
859 {
860 	if (s != NULL && *s != '\0' && (s[0] != '0' || s[1] != '\0'))
861 		return (1);
862 	return (0);
863 }
864 
865 /* Replace a key. */
866 static int
867 format_replace(struct format_tree *ft, const char *key, size_t keylen,
868     char **buf, size_t *len, size_t *off)
869 {
870 	struct window_pane	*wp = ft->wp;
871 	char			*copy, *copy0, *endptr, *ptr, *found, *new;
872 	char			*value, *from = NULL, *to = NULL, *left, *right;
873 	size_t			 valuelen, newlen, fromlen, tolen, used;
874 	long			 limit = 0;
875 	int			 modifiers = 0, compare = 0, search = 0;
876 
877 	/* Make a copy of the key. */
878 	copy0 = copy = xmalloc(keylen + 1);
879 	memcpy(copy, key, keylen);
880 	copy[keylen] = '\0';
881 
882 	/* Is there a length limit or whatnot? */
883 	switch (copy[0]) {
884 	case 'm':
885 		if (copy[1] != ':')
886 			break;
887 		compare = -2;
888 		copy += 2;
889 		break;
890 	case 'C':
891 		if (copy[1] != ':')
892 			break;
893 		search = 1;
894 		copy += 2;
895 		break;
896 	case '|':
897 		if (copy[1] != '|' || copy[2] != ':')
898 			break;
899 		compare = -3;
900 		copy += 3;
901 		break;
902 	case '&':
903 		if (copy[1] != '&' || copy[2] != ':')
904 			break;
905 		compare = -4;
906 		copy += 3;
907 		break;
908 	case '!':
909 		if (copy[1] == '=' && copy[2] == ':') {
910 			compare = -1;
911 			copy += 3;
912 			break;
913 		}
914 		break;
915 	case '=':
916 		if (copy[1] == '=' && copy[2] == ':') {
917 			compare = 1;
918 			copy += 3;
919 			break;
920 		}
921 		errno = 0;
922 		limit = strtol(copy + 1, &endptr, 10);
923 		if (errno == ERANGE && (limit == LONG_MIN || limit == LONG_MAX))
924 			break;
925 		if (*endptr != ':')
926 			break;
927 		copy = endptr + 1;
928 		break;
929 	case 'b':
930 		if (copy[1] != ':')
931 			break;
932 		modifiers |= FORMAT_BASENAME;
933 		copy += 2;
934 		break;
935 	case 'd':
936 		if (copy[1] != ':')
937 			break;
938 		modifiers |= FORMAT_DIRNAME;
939 		copy += 2;
940 		break;
941 	case 't':
942 		if (copy[1] != ':')
943 			break;
944 		modifiers |= FORMAT_TIMESTRING;
945 		copy += 2;
946 		break;
947 	case 's':
948 		if (copy[1] != '/')
949 			break;
950 		from = copy + 2;
951 		for (copy = from; *copy != '\0' && *copy != '/'; copy++)
952 			/* nothing */;
953 		if (copy[0] != '/' || copy == from) {
954 			copy = copy0;
955 			break;
956 		}
957 		copy[0] = '\0';
958 		to = copy + 1;
959 		for (copy = to; *copy != '\0' && *copy != '/'; copy++)
960 			/* nothing */;
961 		if (copy[0] != '/' || copy[1] != ':') {
962 			copy = copy0;
963 			break;
964 		}
965 		copy[0] = '\0';
966 
967 		modifiers |= FORMAT_SUBSTITUTE;
968 		copy += 2;
969 		break;
970 	}
971 
972 	/* Is this a comparison or a conditional? */
973 	if (search) {
974 		/* Search in pane. */
975 		if (wp == NULL)
976 			value = xstrdup("0");
977 		else
978 			xasprintf(&value, "%u", window_pane_search(wp, copy));
979 	} else if (compare != 0) {
980 		/* Comparison: compare comma-separated left and right. */
981 		if (format_choose(copy, &left, &right) != 0)
982 			goto fail;
983 		left = format_expand(ft, left);
984 		right = format_expand(ft, right);
985 		if (compare == -3 &&
986 		    (format_true(left) || format_true(right)))
987 			value = xstrdup("1");
988 		else if (compare == -4 &&
989 		    (format_true(left) && format_true(right)))
990 			value = xstrdup("1");
991 		else if (compare == 1 && strcmp(left, right) == 0)
992 			value = xstrdup("1");
993 		else if (compare == -1 && strcmp(left, right) != 0)
994 			value = xstrdup("1");
995 		else if (compare == -2 && fnmatch(left, right, 0) == 0)
996 			value = xstrdup("1");
997 		else
998 			value = xstrdup("0");
999 		free(right);
1000 		free(left);
1001 	} else if (*copy == '?') {
1002 		/* Conditional: check first and choose second or third. */
1003 		ptr = format_skip(copy);
1004 		if (ptr == NULL)
1005 			goto fail;
1006 		*ptr = '\0';
1007 
1008 		found = format_find(ft, copy + 1, modifiers);
1009 		if (found == NULL)
1010 			found = format_expand(ft, copy + 1);
1011 		if (format_choose(ptr + 1, &left, &right) != 0)
1012 			goto fail;
1013 
1014 		if (format_true(found))
1015 			value = format_expand(ft, left);
1016 		else
1017 			value = format_expand(ft, right);
1018 		free(found);
1019 	} else {
1020 		/* Neither: look up directly. */
1021 		value = format_find(ft, copy, modifiers);
1022 		if (value == NULL)
1023 			value = xstrdup("");
1024 	}
1025 
1026 	/* Perform substitution if any. */
1027 	if (modifiers & FORMAT_SUBSTITUTE) {
1028 		fromlen = strlen(from);
1029 		tolen = strlen(to);
1030 
1031 		newlen = strlen(value) + 1;
1032 		copy = new = xmalloc(newlen);
1033 		for (ptr = value; *ptr != '\0'; /* nothing */) {
1034 			if (strncmp(ptr, from, fromlen) != 0) {
1035 				*new++ = *ptr++;
1036 				continue;
1037 			}
1038 			used = new - copy;
1039 
1040 			newlen += tolen;
1041 			copy = xrealloc(copy, newlen);
1042 
1043 			new = copy + used;
1044 			memcpy(new, to, tolen);
1045 
1046 			new += tolen;
1047 			ptr += fromlen;
1048 		}
1049 		*new = '\0';
1050 		free(value);
1051 		value = copy;
1052 	}
1053 
1054 	/* Truncate the value if needed. */
1055 	if (limit > 0) {
1056 		new = utf8_trimcstr(value, limit);
1057 		free(value);
1058 		value = new;
1059 	} else if (limit < 0) {
1060 		new = utf8_rtrimcstr(value, -limit);
1061 		free(value);
1062 		value = new;
1063 	}
1064 
1065 	/* Expand the buffer and copy in the value. */
1066 	valuelen = strlen(value);
1067 	while (*len - *off < valuelen + 1) {
1068 		*buf = xreallocarray(*buf, 2, *len);
1069 		*len *= 2;
1070 	}
1071 	memcpy(*buf + *off, value, valuelen);
1072 	*off += valuelen;
1073 
1074 	free(value);
1075 	free(copy0);
1076 	return (0);
1077 
1078 fail:
1079 	free(copy0);
1080 	return (-1);
1081 }
1082 
1083 /* Expand keys in a template, passing through strftime first. */
1084 char *
1085 format_expand_time(struct format_tree *ft, const char *fmt, time_t t)
1086 {
1087 	struct tm	*tm;
1088 	char		 s[2048];
1089 
1090 	if (fmt == NULL || *fmt == '\0')
1091 		return (xstrdup(""));
1092 
1093 	tm = localtime(&t);
1094 
1095 	if (strftime(s, sizeof s, fmt, tm) == 0)
1096 		return (xstrdup(""));
1097 
1098 	return (format_expand(ft, s));
1099 }
1100 
1101 /* Expand keys in a template. */
1102 char *
1103 format_expand(struct format_tree *ft, const char *fmt)
1104 {
1105 	char		*buf, *out;
1106 	const char	*ptr, *s, *saved = fmt;
1107 	size_t		 off, len, n, outlen;
1108 	int     	 ch, brackets;
1109 
1110 	if (fmt == NULL)
1111 		return (xstrdup(""));
1112 
1113 	len = 64;
1114 	buf = xmalloc(len);
1115 	off = 0;
1116 
1117 	while (*fmt != '\0') {
1118 		if (*fmt != '#') {
1119 			while (len - off < 2) {
1120 				buf = xreallocarray(buf, 2, len);
1121 				len *= 2;
1122 			}
1123 			buf[off++] = *fmt++;
1124 			continue;
1125 		}
1126 		fmt++;
1127 
1128 		ch = (u_char) *fmt++;
1129 		switch (ch) {
1130 		case '(':
1131 			brackets = 1;
1132 			for (ptr = fmt; *ptr != '\0'; ptr++) {
1133 				if (*ptr == '(')
1134 					brackets++;
1135 				if (*ptr == ')' && --brackets == 0)
1136 					break;
1137 			}
1138 			if (*ptr != ')' || brackets != 0)
1139 				break;
1140 			n = ptr - fmt;
1141 
1142 			if (ft->flags & FORMAT_NOJOBS)
1143 				out = xstrdup("");
1144 			else
1145 				out = format_job_get(ft, xstrndup(fmt, n));
1146 			outlen = strlen(out);
1147 
1148 			while (len - off < outlen + 1) {
1149 				buf = xreallocarray(buf, 2, len);
1150 				len *= 2;
1151 			}
1152 			memcpy(buf + off, out, outlen);
1153 			off += outlen;
1154 
1155 			free(out);
1156 
1157 			fmt += n + 1;
1158 			continue;
1159 		case '{':
1160 			brackets = 1;
1161 			for (ptr = fmt; *ptr != '\0'; ptr++) {
1162 				if (*ptr == '{')
1163 					brackets++;
1164 				if (*ptr == '}' && --brackets == 0)
1165 					break;
1166 			}
1167 			if (*ptr != '}' || brackets != 0)
1168 				break;
1169 			n = ptr - fmt;
1170 
1171 			if (format_replace(ft, fmt, n, &buf, &len, &off) != 0)
1172 				break;
1173 			fmt += n + 1;
1174 			continue;
1175 		case '#':
1176 			while (len - off < 2) {
1177 				buf = xreallocarray(buf, 2, len);
1178 				len *= 2;
1179 			}
1180 			buf[off++] = '#';
1181 			continue;
1182 		default:
1183 			s = NULL;
1184 			if (ch >= 'A' && ch <= 'Z')
1185 				s = format_upper[ch - 'A'];
1186 			else if (ch >= 'a' && ch <= 'z')
1187 				s = format_lower[ch - 'a'];
1188 			if (s == NULL) {
1189 				while (len - off < 3) {
1190 					buf = xreallocarray(buf, 2, len);
1191 					len *= 2;
1192 				}
1193 				buf[off++] = '#';
1194 				buf[off++] = ch;
1195 				continue;
1196 			}
1197 			n = strlen(s);
1198 			if (format_replace(ft, s, n, &buf, &len, &off) != 0)
1199 				break;
1200 			continue;
1201 		}
1202 
1203 		break;
1204 	}
1205 	buf[off] = '\0';
1206 
1207 	log_debug("format '%s' -> '%s'", saved, buf);
1208 	return (buf);
1209 }
1210 
1211 /* Expand a single string. */
1212 char *
1213 format_single(struct cmdq_item *item, const char *fmt, struct client *c,
1214     struct session *s, struct winlink *wl, struct window_pane *wp)
1215 {
1216 	struct format_tree	*ft;
1217 	char			*expanded;
1218 
1219 	if (item != NULL)
1220 		ft = format_create(item->client, item, FORMAT_NONE, 0);
1221 	else
1222 		ft = format_create(NULL, item, FORMAT_NONE, 0);
1223 	format_defaults(ft, c, s, wl, wp);
1224 
1225 	expanded = format_expand(ft, fmt);
1226 	format_free(ft);
1227 	return (expanded);
1228 }
1229 
1230 /* Set defaults for any of arguments that are not NULL. */
1231 void
1232 format_defaults(struct format_tree *ft, struct client *c, struct session *s,
1233     struct winlink *wl, struct window_pane *wp)
1234 {
1235 	format_add(ft, "session_format", "%d", s != NULL);
1236 	format_add(ft, "window_format", "%d", wl != NULL);
1237 	format_add(ft, "pane_format", "%d", wp != NULL);
1238 
1239 	if (s == NULL && c != NULL)
1240 		s = c->session;
1241 	if (wl == NULL && s != NULL)
1242 		wl = s->curw;
1243 	if (wp == NULL && wl != NULL)
1244 		wp = wl->window->active;
1245 
1246 	if (c != NULL)
1247 		format_defaults_client(ft, c);
1248 	if (s != NULL)
1249 		format_defaults_session(ft, s);
1250 	if (wl != NULL)
1251 		format_defaults_winlink(ft, wl);
1252 	if (wp != NULL)
1253 		format_defaults_pane(ft, wp);
1254 }
1255 
1256 /* Set default format keys for a session. */
1257 static void
1258 format_defaults_session(struct format_tree *ft, struct session *s)
1259 {
1260 	struct session_group	*sg;
1261 
1262 	ft->s = s;
1263 
1264 	format_add(ft, "session_name", "%s", s->name);
1265 	format_add(ft, "session_windows", "%u", winlink_count(&s->windows));
1266 	format_add(ft, "session_width", "%u", s->sx);
1267 	format_add(ft, "session_height", "%u", s->sy);
1268 	format_add(ft, "session_id", "$%u", s->id);
1269 
1270 	sg = session_group_contains(s);
1271 	format_add(ft, "session_grouped", "%d", sg != NULL);
1272 	if (sg != NULL)
1273 		format_add(ft, "session_group", "%s", sg->name);
1274 
1275 	format_add_tv(ft, "session_created", &s->creation_time);
1276 	format_add_tv(ft, "session_last_attached", &s->last_attached_time);
1277 	format_add_tv(ft, "session_activity", &s->activity_time);
1278 
1279 	format_add(ft, "session_attached", "%u", s->attached);
1280 	format_add(ft, "session_many_attached", "%d", s->attached > 1);
1281 
1282 	format_add_cb(ft, "session_alerts", format_cb_session_alerts);
1283 	format_add_cb(ft, "session_stack", format_cb_session_stack);
1284 }
1285 
1286 /* Set default format keys for a client. */
1287 static void
1288 format_defaults_client(struct format_tree *ft, struct client *c)
1289 {
1290 	struct session	*s;
1291 	const char	*name;
1292 	struct tty	*tty = &c->tty;
1293 	const char	*types[] = TTY_TYPES;
1294 
1295 	if (ft->s == NULL)
1296 		ft->s = c->session;
1297 
1298 	format_add(ft, "client_name", "%s", c->name);
1299 	format_add(ft, "client_pid", "%ld", (long) c->pid);
1300 	format_add(ft, "client_height", "%u", tty->sy);
1301 	format_add(ft, "client_width", "%u", tty->sx);
1302 	format_add(ft, "client_tty", "%s", c->ttyname);
1303 	format_add(ft, "client_control_mode", "%d",
1304 		!!(c->flags & CLIENT_CONTROL));
1305 
1306 	if (tty->term_name != NULL)
1307 		format_add(ft, "client_termname", "%s", tty->term_name);
1308 	if (tty->term_name != NULL)
1309 		format_add(ft, "client_termtype", "%s", types[tty->term_type]);
1310 
1311 	format_add_tv(ft, "client_created", &c->creation_time);
1312 	format_add_tv(ft, "client_activity", &c->activity_time);
1313 
1314 	format_add(ft, "client_written", "%zu", c->written);
1315 	format_add(ft, "client_discarded", "%zu", c->discarded);
1316 
1317 	name = server_client_get_key_table(c);
1318 	if (strcmp(c->keytable->name, name) == 0)
1319 		format_add(ft, "client_prefix", "%d", 0);
1320 	else
1321 		format_add(ft, "client_prefix", "%d", 1);
1322 	format_add(ft, "client_key_table", "%s", c->keytable->name);
1323 
1324 	if (tty->flags & TTY_UTF8)
1325 		format_add(ft, "client_utf8", "%d", 1);
1326 	else
1327 		format_add(ft, "client_utf8", "%d", 0);
1328 
1329 	if (c->flags & CLIENT_READONLY)
1330 		format_add(ft, "client_readonly", "%d", 1);
1331 	else
1332 		format_add(ft, "client_readonly", "%d", 0);
1333 
1334 	s = c->session;
1335 	if (s != NULL)
1336 		format_add(ft, "client_session", "%s", s->name);
1337 	s = c->last_session;
1338 	if (s != NULL && session_alive(s))
1339 		format_add(ft, "client_last_session", "%s", s->name);
1340 }
1341 
1342 /* Set default format keys for a window. */
1343 void
1344 format_defaults_window(struct format_tree *ft, struct window *w)
1345 {
1346 	ft->w = w;
1347 
1348 	format_add_tv(ft, "window_activity", &w->activity_time);
1349 	format_add(ft, "window_id", "@%u", w->id);
1350 	format_add(ft, "window_name", "%s", w->name);
1351 	format_add(ft, "window_width", "%u", w->sx);
1352 	format_add(ft, "window_height", "%u", w->sy);
1353 	format_add_cb(ft, "window_layout", format_cb_window_layout);
1354 	format_add_cb(ft, "window_visible_layout",
1355 	    format_cb_window_visible_layout);
1356 	format_add(ft, "window_panes", "%u", window_count_panes(w));
1357 	format_add(ft, "window_zoomed_flag", "%d",
1358 	    !!(w->flags & WINDOW_ZOOMED));
1359 }
1360 
1361 /* Set default format keys for a winlink. */
1362 static void
1363 format_defaults_winlink(struct format_tree *ft, struct winlink *wl)
1364 {
1365 	struct session	*s = wl->session;
1366 	struct window	*w = wl->window;
1367 
1368 	if (ft->w == NULL)
1369 		ft->w = wl->window;
1370 	ft->wl = wl;
1371 
1372 	format_defaults_window(ft, w);
1373 
1374 	format_add(ft, "window_index", "%d", wl->idx);
1375 	format_add_cb(ft, "window_stack_index", format_cb_window_stack_index);
1376 	format_add(ft, "window_flags", "%s", window_printable_flags(wl));
1377 	format_add(ft, "window_active", "%d", wl == s->curw);
1378 
1379 	format_add(ft, "window_bell_flag", "%d",
1380 	    !!(wl->flags & WINLINK_BELL));
1381 	format_add(ft, "window_activity_flag", "%d",
1382 	    !!(wl->flags & WINLINK_ACTIVITY));
1383 	format_add(ft, "window_silence_flag", "%d",
1384 	    !!(wl->flags & WINLINK_SILENCE));
1385 	format_add(ft, "window_last_flag", "%d",
1386 	    !!(wl == TAILQ_FIRST(&s->lastw)));
1387 	format_add(ft, "window_linked", "%d", session_is_linked(s, wl->window));
1388 }
1389 
1390 /* Set default format keys for a window pane. */
1391 void
1392 format_defaults_pane(struct format_tree *ft, struct window_pane *wp)
1393 {
1394 	struct grid	*gd = wp->base.grid;
1395 	u_int		 idx;
1396 	int  		 status;
1397 
1398 	if (ft->w == NULL)
1399 		ft->w = wp->window;
1400 	ft->wp = wp;
1401 
1402 	format_add(ft, "history_size", "%u", gd->hsize);
1403 	format_add(ft, "history_limit", "%u", gd->hlimit);
1404 	format_add_cb(ft, "history_bytes", format_cb_history_bytes);
1405 
1406 	if (window_pane_index(wp, &idx) != 0)
1407 		fatalx("index not found");
1408 	format_add(ft, "pane_index", "%u", idx);
1409 
1410 	format_add(ft, "pane_width", "%u", wp->sx);
1411 	format_add(ft, "pane_height", "%u", wp->sy);
1412 	format_add(ft, "pane_title", "%s", wp->base.title);
1413 	format_add(ft, "pane_id", "%%%u", wp->id);
1414 	format_add(ft, "pane_active", "%d", wp == wp->window->active);
1415 	format_add(ft, "pane_input_off", "%d", !!(wp->flags & PANE_INPUTOFF));
1416 	format_add(ft, "pane_pipe", "%d", wp->pipe_fd != -1);
1417 
1418 	status = wp->status;
1419 	if (wp->fd == -1 && WIFEXITED(status))
1420 		format_add(ft, "pane_dead_status", "%d", WEXITSTATUS(status));
1421 	format_add(ft, "pane_dead", "%d", wp->fd == -1);
1422 
1423 	if (window_pane_visible(wp)) {
1424 		format_add(ft, "pane_left", "%u", wp->xoff);
1425 		format_add(ft, "pane_top", "%u", wp->yoff);
1426 		format_add(ft, "pane_right", "%u", wp->xoff + wp->sx - 1);
1427 		format_add(ft, "pane_bottom", "%u", wp->yoff + wp->sy - 1);
1428 		format_add(ft, "pane_at_left", "%d", wp->xoff == 0);
1429 		format_add(ft, "pane_at_top", "%d", wp->yoff == 0);
1430 		format_add(ft, "pane_at_right", "%d", wp->xoff + wp->sx == wp->window->sx);
1431 		format_add(ft, "pane_at_bottom", "%d", wp->yoff + wp->sy == wp->window->sy);
1432 	}
1433 
1434 	format_add(ft, "pane_in_mode", "%d", wp->screen != &wp->base);
1435 	if (wp->mode != NULL)
1436 		format_add(ft, "pane_mode", "%s", wp->mode->name);
1437 
1438 	format_add(ft, "pane_synchronized", "%d",
1439 	    !!options_get_number(wp->window->options, "synchronize-panes"));
1440 	if (wp->searchstr != NULL)
1441 		format_add(ft, "pane_search_string", "%s", wp->searchstr);
1442 
1443 	format_add(ft, "pane_tty", "%s", wp->tty);
1444 	format_add(ft, "pane_pid", "%ld", (long) wp->pid);
1445 	format_add_cb(ft, "pane_start_command", format_cb_start_command);
1446 	format_add_cb(ft, "pane_current_command", format_cb_current_command);
1447 	format_add_cb(ft, "pane_current_path", format_cb_current_path);
1448 
1449 	format_add(ft, "cursor_x", "%u", wp->base.cx);
1450 	format_add(ft, "cursor_y", "%u", wp->base.cy);
1451 	format_add(ft, "scroll_region_upper", "%u", wp->base.rupper);
1452 	format_add(ft, "scroll_region_lower", "%u", wp->base.rlower);
1453 
1454 	window_copy_add_formats(wp, ft);
1455 
1456 	format_add(ft, "alternate_on", "%d", wp->saved_grid ? 1 : 0);
1457 	format_add(ft, "alternate_saved_x", "%u", wp->saved_cx);
1458 	format_add(ft, "alternate_saved_y", "%u", wp->saved_cy);
1459 
1460 	format_add(ft, "cursor_flag", "%d",
1461 	    !!(wp->base.mode & MODE_CURSOR));
1462 	format_add(ft, "insert_flag", "%d",
1463 	    !!(wp->base.mode & MODE_INSERT));
1464 	format_add(ft, "keypad_cursor_flag", "%d",
1465 	    !!(wp->base.mode & MODE_KCURSOR));
1466 	format_add(ft, "keypad_flag", "%d",
1467 	    !!(wp->base.mode & MODE_KKEYPAD));
1468 	format_add(ft, "wrap_flag", "%d",
1469 	    !!(wp->base.mode & MODE_WRAP));
1470 
1471 	format_add(ft, "mouse_any_flag", "%d",
1472 	    !!(wp->base.mode & ALL_MOUSE_MODES));
1473 	format_add(ft, "mouse_standard_flag", "%d",
1474 	    !!(wp->base.mode & MODE_MOUSE_STANDARD));
1475 	format_add(ft, "mouse_button_flag", "%d",
1476 	    !!(wp->base.mode & MODE_MOUSE_BUTTON));
1477 	format_add(ft, "mouse_all_flag", "%d",
1478 	    !!(wp->base.mode & MODE_MOUSE_ALL));
1479 
1480 	format_add_cb(ft, "pane_tabs", format_cb_pane_tabs);
1481 }
1482 
1483 /* Set default format keys for paste buffer. */
1484 void
1485 format_defaults_paste_buffer(struct format_tree *ft, struct paste_buffer *pb)
1486 {
1487 	struct timeval	 tv;
1488 	size_t		 size;
1489 	char		*s;
1490 
1491 	timerclear(&tv);
1492 	tv.tv_sec = paste_buffer_created(pb);
1493 	paste_buffer_data(pb, &size);
1494 
1495 	format_add(ft, "buffer_size", "%zu", size);
1496 	format_add(ft, "buffer_name", "%s", paste_buffer_name(pb));
1497 	format_add_tv(ft, "buffer_created", &tv);
1498 
1499 	s = paste_make_sample(pb);
1500 	format_add(ft, "buffer_sample", "%s", s);
1501 	free(s);
1502 }
1503