xref: /openbsd-src/usr.bin/tmux/format.c (revision 78745eb8cbbe4d7c8432e3f7c7f05c3d56e3121b)
1 /* $OpenBSD: format.c,v 1.273 2021/02/09 14:25:40 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 <math.h>
27 #include <regex.h>
28 #include <stdarg.h>
29 #include <stdlib.h>
30 #include <string.h>
31 #include <time.h>
32 #include <unistd.h>
33 
34 #include "tmux.h"
35 
36 /*
37  * Build a list of key-value pairs and use them to expand #{key} entries in a
38  * string.
39  */
40 
41 struct format_expand_state;
42 
43 static char	*format_job_get(struct format_expand_state *, const char *);
44 static void	 format_job_timer(int, short, void *);
45 static char	*format_expand1(struct format_expand_state *, const char *);
46 static int	 format_replace(struct format_expand_state *, const char *,
47 		     size_t, char **, size_t *, size_t *);
48 static void	 format_defaults_session(struct format_tree *,
49 		     struct session *);
50 static void	 format_defaults_client(struct format_tree *, struct client *);
51 static void	 format_defaults_winlink(struct format_tree *,
52 		     struct winlink *);
53 
54 /* Entry in format job tree. */
55 struct format_job {
56 	struct client		*client;
57 	u_int			 tag;
58 	const char		*cmd;
59 	const char		*expanded;
60 
61 	time_t			 last;
62 	char			*out;
63 	int			 updated;
64 
65 	struct job		*job;
66 	int			 status;
67 
68 	RB_ENTRY(format_job)	 entry;
69 };
70 
71 /* Format job tree. */
72 static struct event format_job_event;
73 static int format_job_cmp(struct format_job *, struct format_job *);
74 static RB_HEAD(format_job_tree, format_job) format_jobs = RB_INITIALIZER();
75 RB_GENERATE_STATIC(format_job_tree, format_job, entry, format_job_cmp);
76 
77 /* Format job tree comparison function. */
78 static int
79 format_job_cmp(struct format_job *fj1, struct format_job *fj2)
80 {
81 	if (fj1->tag < fj2->tag)
82 		return (-1);
83 	if (fj1->tag > fj2->tag)
84 		return (1);
85 	return (strcmp(fj1->cmd, fj2->cmd));
86 }
87 
88 /* Format modifiers. */
89 #define FORMAT_TIMESTRING 0x1
90 #define FORMAT_BASENAME 0x2
91 #define FORMAT_DIRNAME 0x4
92 #define FORMAT_QUOTE_SHELL 0x8
93 #define FORMAT_LITERAL 0x10
94 #define FORMAT_EXPAND 0x20
95 #define FORMAT_EXPANDTIME 0x40
96 #define FORMAT_SESSIONS 0x80
97 #define FORMAT_WINDOWS 0x100
98 #define FORMAT_PANES 0x200
99 #define FORMAT_PRETTY 0x400
100 #define FORMAT_LENGTH 0x800
101 #define FORMAT_WIDTH 0x1000
102 #define FORMAT_QUOTE_STYLE 0x2000
103 #define FORMAT_WINDOW_NAME 0x4000
104 #define FORMAT_SESSION_NAME 0x8000
105 
106 /* Limit on recursion. */
107 #define FORMAT_LOOP_LIMIT 10
108 
109 /* Format expand flags. */
110 #define FORMAT_EXPAND_TIME 0x1
111 #define FORMAT_EXPAND_NOJOBS 0x2
112 
113 /* Entry in format tree. */
114 struct format_entry {
115 	char			*key;
116 	char			*value;
117 	time_t			 time;
118 	format_cb		 cb;
119 	RB_ENTRY(format_entry)	 entry;
120 };
121 
122 /* Format entry tree. */
123 struct format_tree {
124 	struct client		*c;
125 	struct session		*s;
126 	struct winlink		*wl;
127 	struct window		*w;
128 	struct window_pane	*wp;
129 
130 	struct cmdq_item	*item;
131 	struct client		*client;
132 	int			 flags;
133 	u_int			 tag;
134 
135 	struct mouse_event	 m;
136 
137 	RB_HEAD(format_entry_tree, format_entry) tree;
138 };
139 static int format_entry_cmp(struct format_entry *, struct format_entry *);
140 RB_GENERATE_STATIC(format_entry_tree, format_entry, entry, format_entry_cmp);
141 
142 /* Format expand state. */
143 struct format_expand_state {
144 	struct format_tree	*ft;
145 	u_int			 loop;
146 	time_t			 time;
147 	int			 flags;
148 };
149 
150 /* Format modifier. */
151 struct format_modifier {
152 	char	  modifier[3];
153 	u_int	  size;
154 
155 	char	**argv;
156 	int	  argc;
157 };
158 
159 /* Format entry tree comparison function. */
160 static int
161 format_entry_cmp(struct format_entry *fe1, struct format_entry *fe2)
162 {
163 	return (strcmp(fe1->key, fe2->key));
164 }
165 
166 /* Single-character uppercase aliases. */
167 static const char *format_upper[] = {
168 	NULL,		/* A */
169 	NULL,		/* B */
170 	NULL,		/* C */
171 	"pane_id",	/* D */
172 	NULL,		/* E */
173 	"window_flags",	/* F */
174 	NULL,		/* G */
175 	"host",		/* H */
176 	"window_index",	/* I */
177 	NULL,		/* J */
178 	NULL,		/* K */
179 	NULL,		/* L */
180 	NULL,		/* M */
181 	NULL,		/* N */
182 	NULL,		/* O */
183 	"pane_index",	/* P */
184 	NULL,		/* Q */
185 	NULL,		/* R */
186 	"session_name",	/* S */
187 	"pane_title",	/* T */
188 	NULL,		/* U */
189 	NULL,		/* V */
190 	"window_name",	/* W */
191 	NULL,		/* X */
192 	NULL,		/* Y */
193 	NULL 		/* Z */
194 };
195 
196 /* Single-character lowercase aliases. */
197 static const char *format_lower[] = {
198 	NULL,		/* a */
199 	NULL,		/* b */
200 	NULL,		/* c */
201 	NULL,		/* d */
202 	NULL,		/* e */
203 	NULL,		/* f */
204 	NULL,		/* g */
205 	"host_short",	/* h */
206 	NULL,		/* i */
207 	NULL,		/* j */
208 	NULL,		/* k */
209 	NULL,		/* l */
210 	NULL,		/* m */
211 	NULL,		/* n */
212 	NULL,		/* o */
213 	NULL,		/* p */
214 	NULL,		/* q */
215 	NULL,		/* r */
216 	NULL,		/* s */
217 	NULL,		/* t */
218 	NULL,		/* u */
219 	NULL,		/* v */
220 	NULL,		/* w */
221 	NULL,		/* x */
222 	NULL,		/* y */
223 	NULL		/* z */
224 };
225 
226 /* Is logging enabled? */
227 static inline int
228 format_logging(struct format_tree *ft)
229 {
230 	return (log_get_level() != 0 || (ft->flags & FORMAT_VERBOSE));
231 }
232 
233 /* Log a message if verbose. */
234 static void printflike(3, 4)
235 format_log1(struct format_expand_state *es, const char *from, const char *fmt,
236     ...)
237 {
238 	struct format_tree	*ft = es->ft;
239 	va_list			 ap;
240 	char			*s;
241 	static const char	 spaces[] = "          ";
242 
243 	if (!format_logging(ft))
244 		return;
245 
246 	va_start(ap, fmt);
247 	xvasprintf(&s, fmt, ap);
248 	va_end(ap);
249 
250 	log_debug("%s: %s", from, s);
251 	if (ft->item != NULL && (ft->flags & FORMAT_VERBOSE))
252 		cmdq_print(ft->item, "#%.*s%s", es->loop, spaces, s);
253 
254 	free(s);
255 }
256 #define format_log(es, fmt, ...) format_log1(es, __func__, fmt, ##__VA_ARGS__)
257 
258 /* Copy expand state. */
259 static void
260 format_copy_state(struct format_expand_state *to,
261     struct format_expand_state *from, int flags)
262 {
263 	to->ft = from->ft;
264 	to->loop = from->loop;
265 	to->time = from->time;
266 	to->flags = from->flags|flags;
267 }
268 
269 /* Format job update callback. */
270 static void
271 format_job_update(struct job *job)
272 {
273 	struct format_job	*fj = job_get_data(job);
274 	struct evbuffer		*evb = job_get_event(job)->input;
275 	char			*line = NULL, *next;
276 	time_t			 t;
277 
278 	while ((next = evbuffer_readline(evb)) != NULL) {
279 		free(line);
280 		line = next;
281 	}
282 	if (line == NULL)
283 		return;
284 	fj->updated = 1;
285 
286 	free(fj->out);
287 	fj->out = line;
288 
289 	log_debug("%s: %p %s: %s", __func__, fj, fj->cmd, fj->out);
290 
291 	t = time(NULL);
292 	if (fj->status && fj->last != t) {
293 		if (fj->client != NULL)
294 			server_status_client(fj->client);
295 		fj->last = t;
296 	}
297 }
298 
299 /* Format job complete callback. */
300 static void
301 format_job_complete(struct job *job)
302 {
303 	struct format_job	*fj = job_get_data(job);
304 	struct evbuffer		*evb = job_get_event(job)->input;
305 	char			*line, *buf;
306 	size_t			 len;
307 
308 	fj->job = NULL;
309 
310 	buf = NULL;
311 	if ((line = evbuffer_readline(evb)) == NULL) {
312 		len = EVBUFFER_LENGTH(evb);
313 		buf = xmalloc(len + 1);
314 		if (len != 0)
315 			memcpy(buf, EVBUFFER_DATA(evb), len);
316 		buf[len] = '\0';
317 	} else
318 		buf = line;
319 
320 	log_debug("%s: %p %s: %s", __func__, fj, fj->cmd, buf);
321 
322 	if (*buf != '\0' || !fj->updated) {
323 		free(fj->out);
324 		fj->out = buf;
325 	} else
326 		free(buf);
327 
328 	if (fj->status) {
329 		if (fj->client != NULL)
330 			server_status_client(fj->client);
331 		fj->status = 0;
332 	}
333 }
334 
335 /* Find a job. */
336 static char *
337 format_job_get(struct format_expand_state *es, const char *cmd)
338 {
339 	struct format_tree		*ft = es->ft;
340 	struct format_job_tree		*jobs;
341 	struct format_job		 fj0, *fj;
342 	time_t				 t;
343 	char				*expanded;
344 	int				 force;
345 	struct format_expand_state	 next;
346 
347 	if (ft->client == NULL)
348 		jobs = &format_jobs;
349 	else if (ft->client->jobs != NULL)
350 		jobs = ft->client->jobs;
351 	else {
352 		jobs = ft->client->jobs = xmalloc(sizeof *ft->client->jobs);
353 		RB_INIT(jobs);
354 	}
355 
356 	fj0.tag = ft->tag;
357 	fj0.cmd = cmd;
358 	if ((fj = RB_FIND(format_job_tree, jobs, &fj0)) == NULL) {
359 		fj = xcalloc(1, sizeof *fj);
360 		fj->client = ft->client;
361 		fj->tag = ft->tag;
362 		fj->cmd = xstrdup(cmd);
363 		fj->expanded = NULL;
364 
365 		xasprintf(&fj->out, "<'%s' not ready>", fj->cmd);
366 
367 		RB_INSERT(format_job_tree, jobs, fj);
368 	}
369 
370 	format_copy_state(&next, es, FORMAT_EXPAND_NOJOBS);
371 	next.flags &= ~FORMAT_EXPAND_TIME;
372 
373 	expanded = format_expand1(&next, cmd);
374 	if (fj->expanded == NULL || strcmp(expanded, fj->expanded) != 0) {
375 		free((void *)fj->expanded);
376 		fj->expanded = xstrdup(expanded);
377 		force = 1;
378 	} else
379 		force = (ft->flags & FORMAT_FORCE);
380 
381 	t = time(NULL);
382 	if (force && fj->job != NULL)
383 	       job_free(fj->job);
384 	if (force || (fj->job == NULL && fj->last != t)) {
385 		fj->job = job_run(expanded, NULL,
386 		    server_client_get_cwd(ft->client, NULL), format_job_update,
387 		    format_job_complete, NULL, fj, JOB_NOWAIT, -1, -1);
388 		if (fj->job == NULL) {
389 			free(fj->out);
390 			xasprintf(&fj->out, "<'%s' didn't start>", fj->cmd);
391 		}
392 		fj->last = t;
393 		fj->updated = 0;
394 	}
395 	free(expanded);
396 
397 	if (ft->flags & FORMAT_STATUS)
398 		fj->status = 1;
399 	return (format_expand1(&next, fj->out));
400 }
401 
402 /* Remove old jobs. */
403 static void
404 format_job_tidy(struct format_job_tree *jobs, int force)
405 {
406 	struct format_job	*fj, *fj1;
407 	time_t			 now;
408 
409 	now = time(NULL);
410 	RB_FOREACH_SAFE(fj, format_job_tree, jobs, fj1) {
411 		if (!force && (fj->last > now || now - fj->last < 3600))
412 			continue;
413 		RB_REMOVE(format_job_tree, jobs, fj);
414 
415 		log_debug("%s: %s", __func__, fj->cmd);
416 
417 		if (fj->job != NULL)
418 			job_free(fj->job);
419 
420 		free((void *)fj->expanded);
421 		free((void *)fj->cmd);
422 		free(fj->out);
423 
424 		free(fj);
425 	}
426 }
427 
428 /* Remove old jobs for client. */
429 void
430 format_lost_client(struct client *c)
431 {
432 	if (c->jobs != NULL)
433 		format_job_tidy(c->jobs, 1);
434 	free(c->jobs);
435 }
436 
437 /* Remove old jobs periodically. */
438 static void
439 format_job_timer(__unused int fd, __unused short events, __unused void *arg)
440 {
441 	struct client	*c;
442 	struct timeval	 tv = { .tv_sec = 60 };
443 
444 	format_job_tidy(&format_jobs, 0);
445 	TAILQ_FOREACH(c, &clients, entry) {
446 		if (c->jobs != NULL)
447 			format_job_tidy(c->jobs, 0);
448 	}
449 
450 	evtimer_del(&format_job_event);
451 	evtimer_add(&format_job_event, &tv);
452 }
453 
454 /* Callback for host. */
455 static char *
456 format_cb_host(__unused struct format_tree *ft)
457 {
458 	char host[HOST_NAME_MAX + 1];
459 
460 	if (gethostname(host, sizeof host) != 0)
461 		return (xstrdup(""));
462 	return (xstrdup(host));
463 }
464 
465 /* Callback for host_short. */
466 static char *
467 format_cb_host_short(__unused struct format_tree *ft)
468 {
469 	char host[HOST_NAME_MAX + 1], *cp;
470 
471 	if (gethostname(host, sizeof host) != 0)
472 		return (xstrdup(""));
473 	if ((cp = strchr(host, '.')) != NULL)
474 		*cp = '\0';
475 	return (xstrdup(host));
476 }
477 
478 /* Callback for pid. */
479 static char *
480 format_cb_pid(__unused struct format_tree *ft)
481 {
482 	char	*value;
483 
484 	xasprintf(&value, "%ld", (long)getpid());
485 	return (value);
486 }
487 
488 /* Callback for session_attached_list. */
489 static char *
490 format_cb_session_attached_list(struct format_tree *ft)
491 {
492 	struct session	*s = ft->s;
493 	struct client	*loop;
494 	struct evbuffer	*buffer;
495 	int		 size;
496 	char		*value = NULL;
497 
498 	if (s == NULL)
499 		return (NULL);
500 
501 	buffer = evbuffer_new();
502 	if (buffer == NULL)
503 		fatalx("out of memory");
504 
505 	TAILQ_FOREACH(loop, &clients, entry) {
506 		if (loop->session == s) {
507 			if (EVBUFFER_LENGTH(buffer) > 0)
508 				evbuffer_add(buffer, ",", 1);
509 			evbuffer_add_printf(buffer, "%s", loop->name);
510 		}
511 	}
512 
513 	if ((size = EVBUFFER_LENGTH(buffer)) != 0)
514 		xasprintf(&value, "%.*s", size, EVBUFFER_DATA(buffer));
515 	evbuffer_free(buffer);
516 	return (value);
517 }
518 
519 /* Callback for session_alerts. */
520 static char *
521 format_cb_session_alerts(struct format_tree *ft)
522 {
523 	struct session	*s = ft->s;
524 	struct winlink	*wl;
525 	char		 alerts[1024], tmp[16];
526 
527 	if (s == NULL)
528 		return (NULL);
529 
530 	*alerts = '\0';
531 	RB_FOREACH(wl, winlinks, &s->windows) {
532 		if ((wl->flags & WINLINK_ALERTFLAGS) == 0)
533 			continue;
534 		xsnprintf(tmp, sizeof tmp, "%u", wl->idx);
535 
536 		if (*alerts != '\0')
537 			strlcat(alerts, ",", sizeof alerts);
538 		strlcat(alerts, tmp, sizeof alerts);
539 		if (wl->flags & WINLINK_ACTIVITY)
540 			strlcat(alerts, "#", sizeof alerts);
541 		if (wl->flags & WINLINK_BELL)
542 			strlcat(alerts, "!", sizeof alerts);
543 		if (wl->flags & WINLINK_SILENCE)
544 			strlcat(alerts, "~", sizeof alerts);
545 	}
546 	return (xstrdup(alerts));
547 }
548 
549 /* Callback for session_stack. */
550 static char *
551 format_cb_session_stack(struct format_tree *ft)
552 {
553 	struct session	*s = ft->s;
554 	struct winlink	*wl;
555 	char		 result[1024], tmp[16];
556 
557 	if (s == NULL)
558 		return (NULL);
559 
560 	xsnprintf(result, sizeof result, "%u", s->curw->idx);
561 	TAILQ_FOREACH(wl, &s->lastw, sentry) {
562 		xsnprintf(tmp, sizeof tmp, "%u", wl->idx);
563 
564 		if (*result != '\0')
565 			strlcat(result, ",", sizeof result);
566 		strlcat(result, tmp, sizeof result);
567 	}
568 	return (xstrdup(result));
569 }
570 
571 /* Callback for window_stack_index. */
572 static char *
573 format_cb_window_stack_index(struct format_tree *ft)
574 {
575 	struct session	*s = ft->wl->session;
576 	struct winlink	*wl;
577 	u_int		 idx;
578 	char		*value = NULL;
579 
580 	idx = 0;
581 	TAILQ_FOREACH(wl, &s->lastw, sentry) {
582 		idx++;
583 		if (wl == ft->wl)
584 			break;
585 	}
586 	if (wl == NULL)
587 		return (xstrdup("0"));
588 	xasprintf(&value, "%u", idx);
589 	return (value);
590 }
591 
592 /* Callback for window_linked_sessions_list. */
593 static char *
594 format_cb_window_linked_sessions_list(struct format_tree *ft)
595 {
596 	struct window	*w = ft->wl->window;
597 	struct winlink	*wl;
598 	struct evbuffer	*buffer;
599 	int		 size;
600 	char		*value = NULL;
601 
602 	buffer = evbuffer_new();
603 	if (buffer == NULL)
604 		fatalx("out of memory");
605 
606 	TAILQ_FOREACH(wl, &w->winlinks, wentry) {
607 		if (EVBUFFER_LENGTH(buffer) > 0)
608 			evbuffer_add(buffer, ",", 1);
609 		evbuffer_add_printf(buffer, "%s", wl->session->name);
610 	}
611 
612 	if ((size = EVBUFFER_LENGTH(buffer)) != 0)
613 		xasprintf(&value, "%.*s", size, EVBUFFER_DATA(buffer));
614 	evbuffer_free(buffer);
615 	return (value);
616 }
617 
618 /* Callback for window_active_sessions. */
619 static char *
620 format_cb_window_active_sessions(struct format_tree *ft)
621 {
622 	struct window	*w = ft->wl->window;
623 	struct winlink	*wl;
624 	u_int		 n = 0;
625 	char		*value;
626 
627 	TAILQ_FOREACH(wl, &w->winlinks, wentry) {
628 		if (wl->session->curw == wl)
629 			n++;
630 	}
631 
632 	xasprintf(&value, "%u", n);
633 	return (value);
634 }
635 
636 /* Callback for window_active_sessions_list. */
637 static char *
638 format_cb_window_active_sessions_list(struct format_tree *ft)
639 {
640 	struct window	*w = ft->wl->window;
641 	struct winlink	*wl;
642 	struct evbuffer	*buffer;
643 	int		 size;
644 	char		*value = NULL;
645 
646 	buffer = evbuffer_new();
647 	if (buffer == NULL)
648 		fatalx("out of memory");
649 
650 	TAILQ_FOREACH(wl, &w->winlinks, wentry) {
651 		if (wl->session->curw == wl) {
652 			if (EVBUFFER_LENGTH(buffer) > 0)
653 				evbuffer_add(buffer, ",", 1);
654 			evbuffer_add_printf(buffer, "%s", wl->session->name);
655 		}
656 	}
657 
658 	if ((size = EVBUFFER_LENGTH(buffer)) != 0)
659 		xasprintf(&value, "%.*s", size, EVBUFFER_DATA(buffer));
660 	evbuffer_free(buffer);
661 	return (value);
662 }
663 
664 /* Callback for window_active_clients. */
665 static char *
666 format_cb_window_active_clients(struct format_tree *ft)
667 {
668 	struct window	*w = ft->wl->window;
669 	struct client	*loop;
670 	struct session	*client_session;
671 	u_int		 n = 0;
672 	char		*value;
673 
674 	TAILQ_FOREACH(loop, &clients, entry) {
675 		client_session = loop->session;
676 		if (client_session == NULL)
677 			continue;
678 
679 		if (w == client_session->curw->window)
680 			n++;
681 	}
682 
683 	xasprintf(&value, "%u", n);
684 	return (value);
685 }
686 
687 /* Callback for window_active_clients_list. */
688 static char *
689 format_cb_window_active_clients_list(struct format_tree *ft)
690 {
691 	struct window	*w = ft->wl->window;
692 	struct client	*loop;
693 	struct session	*client_session;
694 	struct evbuffer	*buffer;
695 	int		 size;
696 	char		*value = NULL;
697 
698 	buffer = evbuffer_new();
699 	if (buffer == NULL)
700 		fatalx("out of memory");
701 
702 	TAILQ_FOREACH(loop, &clients, entry) {
703 		client_session = loop->session;
704 		if (client_session == NULL)
705 			continue;
706 
707 		if (w == client_session->curw->window) {
708 			if (EVBUFFER_LENGTH(buffer) > 0)
709 				evbuffer_add(buffer, ",", 1);
710 			evbuffer_add_printf(buffer, "%s", loop->name);
711 		}
712 	}
713 
714 	if ((size = EVBUFFER_LENGTH(buffer)) != 0)
715 		xasprintf(&value, "%.*s", size, EVBUFFER_DATA(buffer));
716 	evbuffer_free(buffer);
717 	return (value);
718 }
719 
720 /* Callback for window_layout. */
721 static char *
722 format_cb_window_layout(struct format_tree *ft)
723 {
724 	struct window	*w = ft->w;
725 
726 	if (w == NULL)
727 		return (NULL);
728 
729 	if (w->saved_layout_root != NULL)
730 		return (layout_dump(w->saved_layout_root));
731 	return (layout_dump(w->layout_root));
732 }
733 
734 /* Callback for window_visible_layout. */
735 static char *
736 format_cb_window_visible_layout(struct format_tree *ft)
737 {
738 	struct window	*w = ft->w;
739 
740 	if (w == NULL)
741 		return (NULL);
742 
743 	return (layout_dump(w->layout_root));
744 }
745 
746 /* Callback for pane_start_command. */
747 static char *
748 format_cb_start_command(struct format_tree *ft)
749 {
750 	struct window_pane	*wp = ft->wp;
751 
752 	if (wp == NULL)
753 		return (NULL);
754 
755 	return (cmd_stringify_argv(wp->argc, wp->argv));
756 }
757 
758 /* Callback for pane_current_command. */
759 static char *
760 format_cb_current_command(struct format_tree *ft)
761 {
762 	struct window_pane	*wp = ft->wp;
763 	char			*cmd, *value;
764 
765 	if (wp == NULL || wp->shell == NULL)
766 		return (NULL);
767 
768 	cmd = get_proc_name(wp->fd, wp->tty);
769 	if (cmd == NULL || *cmd == '\0') {
770 		free(cmd);
771 		cmd = cmd_stringify_argv(wp->argc, wp->argv);
772 		if (cmd == NULL || *cmd == '\0') {
773 			free(cmd);
774 			cmd = xstrdup(wp->shell);
775 		}
776 	}
777 	value = parse_window_name(cmd);
778 	free(cmd);
779 	return (value);
780 }
781 
782 /* Callback for pane_current_path. */
783 static char *
784 format_cb_current_path(struct format_tree *ft)
785 {
786 	struct window_pane	*wp = ft->wp;
787 	char			*cwd;
788 
789 	if (wp == NULL)
790 		return (NULL);
791 
792 	cwd = get_proc_cwd(wp->fd);
793 	if (cwd == NULL)
794 		return (NULL);
795 	return (xstrdup(cwd));
796 }
797 
798 /* Callback for history_bytes. */
799 static char *
800 format_cb_history_bytes(struct format_tree *ft)
801 {
802 	struct window_pane	*wp = ft->wp;
803 	struct grid		*gd;
804 	struct grid_line	*gl;
805 	size_t		         size = 0;
806 	u_int			 i;
807 	char			*value;
808 
809 	if (wp == NULL)
810 		return (NULL);
811 	gd = wp->base.grid;
812 
813 	for (i = 0; i < gd->hsize + gd->sy; i++) {
814 		gl = grid_get_line(gd, i);
815 		size += gl->cellsize * sizeof *gl->celldata;
816 		size += gl->extdsize * sizeof *gl->extddata;
817 	}
818 	size += (gd->hsize + gd->sy) * sizeof *gl;
819 
820 	xasprintf(&value, "%zu", size);
821 	return (value);
822 }
823 
824 /* Callback for history_all_bytes. */
825 static char *
826 format_cb_history_all_bytes(struct format_tree *ft)
827 {
828 	struct window_pane	*wp = ft->wp;
829 	struct grid		*gd;
830 	struct grid_line	*gl;
831 	u_int			 i, lines, cells = 0, extended_cells = 0;
832 	char			*value;
833 
834 	if (wp == NULL)
835 		return (NULL);
836 	gd = wp->base.grid;
837 
838 	lines = gd->hsize + gd->sy;
839 	for (i = 0; i < lines; i++) {
840 		gl = grid_get_line(gd, i);
841 		cells += gl->cellsize;
842 		extended_cells += gl->extdsize;
843 	}
844 
845 	xasprintf(&value, "%u,%zu,%u,%zu,%u,%zu", lines,
846 	    lines * sizeof *gl, cells, cells * sizeof *gl->celldata,
847 	    extended_cells, extended_cells * sizeof *gl->extddata);
848 	return (value);
849 }
850 
851 /* Callback for pane_tabs. */
852 static char *
853 format_cb_pane_tabs(struct format_tree *ft)
854 {
855 	struct window_pane	*wp = ft->wp;
856 	struct evbuffer		*buffer;
857 	u_int			 i;
858 	int			 size;
859 	char			*value = NULL;
860 
861 	if (wp == NULL)
862 		return (NULL);
863 
864 	buffer = evbuffer_new();
865 	if (buffer == NULL)
866 		fatalx("out of memory");
867 	for (i = 0; i < wp->base.grid->sx; i++) {
868 		if (!bit_test(wp->base.tabs, i))
869 			continue;
870 
871 		if (EVBUFFER_LENGTH(buffer) > 0)
872 			evbuffer_add(buffer, ",", 1);
873 		evbuffer_add_printf(buffer, "%u", i);
874 	}
875 	if ((size = EVBUFFER_LENGTH(buffer)) != 0)
876 		xasprintf(&value, "%.*s", size, EVBUFFER_DATA(buffer));
877 	evbuffer_free(buffer);
878 	return (value);
879 }
880 
881 /* Callback for session_group_list. */
882 static char *
883 format_cb_session_group_list(struct format_tree *ft)
884 {
885 	struct session		*s = ft->s;
886 	struct session_group	*sg;
887 	struct session		*loop;
888 	struct evbuffer		*buffer;
889 	int			 size;
890 	char			*value = NULL;
891 
892 	if (s == NULL)
893 		return (NULL);
894 	sg = session_group_contains(s);
895 	if (sg == NULL)
896 		return (NULL);
897 
898 	buffer = evbuffer_new();
899 	if (buffer == NULL)
900 		fatalx("out of memory");
901 
902 	TAILQ_FOREACH(loop, &sg->sessions, gentry) {
903 		if (EVBUFFER_LENGTH(buffer) > 0)
904 			evbuffer_add(buffer, ",", 1);
905 		evbuffer_add_printf(buffer, "%s", loop->name);
906 	}
907 
908 	if ((size = EVBUFFER_LENGTH(buffer)) != 0)
909 		xasprintf(&value, "%.*s", size, EVBUFFER_DATA(buffer));
910 	evbuffer_free(buffer);
911 	return (value);
912 }
913 
914 /* Callback for session_group_attached_list. */
915 static char *
916 format_cb_session_group_attached_list(struct format_tree *ft)
917 {
918 	struct session		*s = ft->s, *client_session, *session_loop;
919 	struct session_group	*sg;
920 	struct client		*loop;
921 	struct evbuffer		*buffer;
922 	int			 size;
923 	char			*value = NULL;
924 
925 	if (s == NULL)
926 		return (NULL);
927 	sg = session_group_contains(s);
928 	if (sg == NULL)
929 		return (NULL);
930 
931 	buffer = evbuffer_new();
932 	if (buffer == NULL)
933 		fatalx("out of memory");
934 
935 	TAILQ_FOREACH(loop, &clients, entry) {
936 		client_session = loop->session;
937 		if (client_session == NULL)
938 			continue;
939 		TAILQ_FOREACH(session_loop, &sg->sessions, gentry) {
940 			if (session_loop == client_session){
941 				if (EVBUFFER_LENGTH(buffer) > 0)
942 					evbuffer_add(buffer, ",", 1);
943 				evbuffer_add_printf(buffer, "%s", loop->name);
944 			}
945 		}
946 	}
947 
948 	if ((size = EVBUFFER_LENGTH(buffer)) != 0)
949 		xasprintf(&value, "%.*s", size, EVBUFFER_DATA(buffer));
950 	evbuffer_free(buffer);
951 	return (value);
952 }
953 
954 /* Callback for pane_in_mode. */
955 static char *
956 format_cb_pane_in_mode(struct format_tree *ft)
957 {
958 	struct window_pane		*wp = ft->wp;
959 	u_int				 n = 0;
960 	struct window_mode_entry	*wme;
961 	char				*value;
962 
963 	if (wp == NULL)
964 		return (NULL);
965 
966 	TAILQ_FOREACH(wme, &wp->modes, entry)
967 	    n++;
968 	xasprintf(&value, "%u", n);
969 	return (value);
970 }
971 
972 /* Callback for pane_at_top. */
973 static char *
974 format_cb_pane_at_top(struct format_tree *ft)
975 {
976 	struct window_pane	*wp = ft->wp;
977 	struct window		*w;
978 	int			 status, flag;
979 	char			*value;
980 
981 	if (wp == NULL)
982 		return (NULL);
983 	w = wp->window;
984 
985 	status = options_get_number(w->options, "pane-border-status");
986 	if (status == PANE_STATUS_TOP)
987 		flag = (wp->yoff == 1);
988 	else
989 		flag = (wp->yoff == 0);
990 	xasprintf(&value, "%d", flag);
991 	return (value);
992 }
993 
994 /* Callback for pane_at_bottom. */
995 static char *
996 format_cb_pane_at_bottom(struct format_tree *ft)
997 {
998 	struct window_pane	*wp = ft->wp;
999 	struct window		*w;
1000 	int			 status, flag;
1001 	char			*value;
1002 
1003 	if (wp == NULL)
1004 		return (NULL);
1005 	w = wp->window;
1006 
1007 	status = options_get_number(w->options, "pane-border-status");
1008 	if (status == PANE_STATUS_BOTTOM)
1009 		flag = (wp->yoff + wp->sy == w->sy - 1);
1010 	else
1011 		flag = (wp->yoff + wp->sy == w->sy);
1012 	xasprintf(&value, "%d", flag);
1013 	return (value);
1014 }
1015 
1016 /* Callback for cursor_character. */
1017 static char *
1018 format_cb_cursor_character(struct format_tree *ft)
1019 {
1020 	struct window_pane	*wp = ft->wp;
1021 	struct grid_cell	 gc;
1022 	char			*value = NULL;
1023 
1024 	if (wp == NULL)
1025 		return (NULL);
1026 
1027 	grid_view_get_cell(wp->base.grid, wp->base.cx, wp->base.cy, &gc);
1028 	if (~gc.flags & GRID_FLAG_PADDING)
1029 		xasprintf(&value, "%.*s", (int)gc.data.size, gc.data.data);
1030 	return (value);
1031 }
1032 
1033 /* Return word at given coordinates. Caller frees. */
1034 char *
1035 format_grid_word(struct grid *gd, u_int x, u_int y)
1036 {
1037 	const struct grid_line	*gl;
1038 	struct grid_cell	 gc;
1039 	const char		*ws;
1040 	struct utf8_data	*ud = NULL;
1041 	u_int			 end;
1042 	size_t			 size = 0;
1043 	int			 found = 0;
1044 	char			*s = NULL;
1045 
1046 	ws = options_get_string(global_s_options, "word-separators");
1047 
1048 	for (;;) {
1049 		grid_get_cell(gd, x, y, &gc);
1050 		if (gc.flags & GRID_FLAG_PADDING)
1051 			break;
1052 		if (utf8_cstrhas(ws, &gc.data)) {
1053 			found = 1;
1054 			break;
1055 		}
1056 
1057 		if (x == 0) {
1058 			if (y == 0)
1059 				break;
1060 			gl = grid_peek_line(gd, y - 1);
1061 			if (~gl->flags & GRID_LINE_WRAPPED)
1062 				break;
1063 			y--;
1064 			x = grid_line_length(gd, y);
1065 			if (x == 0)
1066 				break;
1067 		}
1068 		x--;
1069 	}
1070 	for (;;) {
1071 		if (found) {
1072 			end = grid_line_length(gd, y);
1073 			if (end == 0 || x == end - 1) {
1074 				if (y == gd->hsize + gd->sy - 1)
1075 					break;
1076 				gl = grid_peek_line(gd, y);
1077 				if (~gl->flags & GRID_LINE_WRAPPED)
1078 					break;
1079 				y++;
1080 				x = 0;
1081 			} else
1082 				x++;
1083 		}
1084 		found = 1;
1085 
1086 		grid_get_cell(gd, x, y, &gc);
1087 		if (gc.flags & GRID_FLAG_PADDING)
1088 			break;
1089 		if (utf8_cstrhas(ws, &gc.data))
1090 			break;
1091 
1092 		ud = xreallocarray(ud, size + 2, sizeof *ud);
1093 		memcpy(&ud[size++], &gc.data, sizeof *ud);
1094 	}
1095 	if (size != 0) {
1096 		ud[size].size = 0;
1097 		s = utf8_tocstr(ud);
1098 		free(ud);
1099 	}
1100 	return (s);
1101 }
1102 
1103 /* Callback for mouse_word. */
1104 static char *
1105 format_cb_mouse_word(struct format_tree *ft)
1106 {
1107 	struct window_pane	*wp;
1108 	struct grid		*gd;
1109 	u_int			 x, y;
1110 	char			*s;
1111 
1112 	if (!ft->m.valid)
1113 		return (NULL);
1114 	wp = cmd_mouse_pane(&ft->m, NULL, NULL);
1115 	if (wp == NULL)
1116 		return (NULL);
1117 	if (cmd_mouse_at(wp, &ft->m, &x, &y, 0) != 0)
1118 		return (NULL);
1119 
1120 	if (!TAILQ_EMPTY(&wp->modes)) {
1121 		if (TAILQ_FIRST(&wp->modes)->mode == &window_copy_mode ||
1122 		    TAILQ_FIRST(&wp->modes)->mode == &window_view_mode)
1123 			return (s = window_copy_get_word(wp, x, y));
1124 		return (NULL);
1125 	}
1126 	gd = wp->base.grid;
1127 	return (format_grid_word(gd, x, gd->hsize + y));
1128 }
1129 
1130 /* Return line at given coordinates. Caller frees. */
1131 char *
1132 format_grid_line(struct grid *gd, u_int y)
1133 {
1134 	struct grid_cell	 gc;
1135 	struct utf8_data	*ud = NULL;
1136 	u_int			 x;
1137 	size_t			 size = 0;
1138 	char			*s = NULL;
1139 
1140 	for (x = 0; x < grid_line_length(gd, y); x++) {
1141 		grid_get_cell(gd, x, y, &gc);
1142 		if (gc.flags & GRID_FLAG_PADDING)
1143 			break;
1144 
1145 		ud = xreallocarray(ud, size + 2, sizeof *ud);
1146 		memcpy(&ud[size++], &gc.data, sizeof *ud);
1147 	}
1148 	if (size != 0) {
1149 		ud[size].size = 0;
1150 		s = utf8_tocstr(ud);
1151 		free(ud);
1152 	}
1153 	return (s);
1154 }
1155 
1156 /* Callback for mouse_line. */
1157 static char *
1158 format_cb_mouse_line(struct format_tree *ft)
1159 {
1160 	struct window_pane	*wp;
1161 	struct grid		*gd;
1162 	u_int			 x, y;
1163 
1164 	if (!ft->m.valid)
1165 		return (NULL);
1166 	wp = cmd_mouse_pane(&ft->m, NULL, NULL);
1167 	if (wp == NULL)
1168 		return (NULL);
1169 	if (cmd_mouse_at(wp, &ft->m, &x, &y, 0) != 0)
1170 		return (NULL);
1171 
1172 	if (!TAILQ_EMPTY(&wp->modes)) {
1173 		if (TAILQ_FIRST(&wp->modes)->mode == &window_copy_mode ||
1174 		    TAILQ_FIRST(&wp->modes)->mode == &window_view_mode)
1175 			return (window_copy_get_line(wp, y));
1176 		return (NULL);
1177 	}
1178 	gd = wp->base.grid;
1179 	return (format_grid_line(gd, gd->hsize + y));
1180 }
1181 
1182 /* Merge one format tree into another. */
1183 void
1184 format_merge(struct format_tree *ft, struct format_tree *from)
1185 {
1186 	struct format_entry	*fe;
1187 
1188 	RB_FOREACH(fe, format_entry_tree, &from->tree) {
1189 		if (fe->value != NULL)
1190 			format_add(ft, fe->key, "%s", fe->value);
1191 	}
1192 }
1193 
1194 /* Get format pane. */
1195 struct window_pane *
1196 format_get_pane(struct format_tree *ft)
1197 {
1198 	return (ft->wp);
1199 }
1200 
1201 /* Add item bits to tree. */
1202 static void
1203 format_create_add_item(struct format_tree *ft, struct cmdq_item *item)
1204 {
1205 	struct key_event	*event = cmdq_get_event(item);
1206 	struct mouse_event	*m = &event->m;
1207 	struct window_pane	*wp;
1208 	u_int			 x, y;
1209 
1210 	cmdq_merge_formats(item, ft);
1211 
1212 	if (m->valid && ((wp = cmd_mouse_pane(m, NULL, NULL)) != NULL)) {
1213 		format_add(ft, "mouse_pane", "%%%u", wp->id);
1214 		if (cmd_mouse_at(wp, m, &x, &y, 0) == 0) {
1215 			format_add(ft, "mouse_x", "%u", x);
1216 			format_add(ft, "mouse_y", "%u", y);
1217 			format_add_cb(ft, "mouse_word", format_cb_mouse_word);
1218 			format_add_cb(ft, "mouse_line", format_cb_mouse_line);
1219 		}
1220 	}
1221 	memcpy(&ft->m, m, sizeof ft->m);
1222 }
1223 
1224 /* Create a new tree. */
1225 struct format_tree *
1226 format_create(struct client *c, struct cmdq_item *item, int tag, int flags)
1227 {
1228 	struct format_tree		 *ft;
1229 	const struct window_mode	**wm;
1230 	char				  tmp[64];
1231 
1232 	if (!event_initialized(&format_job_event)) {
1233 		evtimer_set(&format_job_event, format_job_timer, NULL);
1234 		format_job_timer(-1, 0, NULL);
1235 	}
1236 
1237 	ft = xcalloc(1, sizeof *ft);
1238 	RB_INIT(&ft->tree);
1239 
1240 	if (c != NULL) {
1241 		ft->client = c;
1242 		ft->client->references++;
1243 	}
1244 	ft->item = item;
1245 
1246 	ft->tag = tag;
1247 	ft->flags = flags;
1248 
1249 	format_add(ft, "version", "%s", getversion());
1250 	format_add_cb(ft, "host", format_cb_host);
1251 	format_add_cb(ft, "host_short", format_cb_host_short);
1252 	format_add_cb(ft, "pid", format_cb_pid);
1253 	format_add(ft, "socket_path", "%s", socket_path);
1254 	format_add_tv(ft, "start_time", &start_time);
1255 
1256 	for (wm = all_window_modes; *wm != NULL; wm++) {
1257 		if ((*wm)->default_format != NULL) {
1258 			xsnprintf(tmp, sizeof tmp, "%s_format", (*wm)->name);
1259 			tmp[strcspn(tmp, "-")] = '_';
1260 			format_add(ft, tmp, "%s", (*wm)->default_format);
1261 		}
1262 	}
1263 
1264 	if (item != NULL)
1265 		format_create_add_item(ft, item);
1266 
1267 	return (ft);
1268 }
1269 
1270 /* Free a tree. */
1271 void
1272 format_free(struct format_tree *ft)
1273 {
1274 	struct format_entry	*fe, *fe1;
1275 
1276 	RB_FOREACH_SAFE(fe, format_entry_tree, &ft->tree, fe1) {
1277 		RB_REMOVE(format_entry_tree, &ft->tree, fe);
1278 		free(fe->value);
1279 		free(fe->key);
1280 		free(fe);
1281 	}
1282 
1283 	if (ft->client != NULL)
1284 		server_client_unref(ft->client);
1285 	free(ft);
1286 }
1287 
1288 /* Walk each format. */
1289 void
1290 format_each(struct format_tree *ft, void (*cb)(const char *, const char *,
1291     void *), void *arg)
1292 {
1293 	struct format_entry	*fe;
1294 	char			 s[64];
1295 
1296 	RB_FOREACH(fe, format_entry_tree, &ft->tree) {
1297 		if (fe->time != 0) {
1298 			xsnprintf(s, sizeof s, "%lld", (long long)fe->time);
1299 			cb(fe->key, s, arg);
1300 		} else {
1301 			if (fe->value == NULL && fe->cb != NULL) {
1302 				fe->value = fe->cb(ft);
1303 				if (fe->value == NULL)
1304 					fe->value = xstrdup("");
1305 			}
1306 			cb(fe->key, fe->value, arg);
1307 		}
1308 	}
1309 }
1310 
1311 /* Add a key-value pair. */
1312 void
1313 format_add(struct format_tree *ft, const char *key, const char *fmt, ...)
1314 {
1315 	struct format_entry	*fe;
1316 	struct format_entry	*fe_now;
1317 	va_list			 ap;
1318 
1319 	fe = xmalloc(sizeof *fe);
1320 	fe->key = xstrdup(key);
1321 
1322 	fe_now = RB_INSERT(format_entry_tree, &ft->tree, fe);
1323 	if (fe_now != NULL) {
1324 		free(fe->key);
1325 		free(fe);
1326 		free(fe_now->value);
1327 		fe = fe_now;
1328 	}
1329 
1330 	fe->cb = NULL;
1331 	fe->time = 0;
1332 
1333 	va_start(ap, fmt);
1334 	xvasprintf(&fe->value, fmt, ap);
1335 	va_end(ap);
1336 }
1337 
1338 /* Add a key and time. */
1339 void
1340 format_add_tv(struct format_tree *ft, const char *key, struct timeval *tv)
1341 {
1342 	struct format_entry	*fe, *fe_now;
1343 
1344 	fe = xmalloc(sizeof *fe);
1345 	fe->key = xstrdup(key);
1346 
1347 	fe_now = RB_INSERT(format_entry_tree, &ft->tree, fe);
1348 	if (fe_now != NULL) {
1349 		free(fe->key);
1350 		free(fe);
1351 		free(fe_now->value);
1352 		fe = fe_now;
1353 	}
1354 
1355 	fe->cb = NULL;
1356 	fe->time = tv->tv_sec;
1357 
1358 	fe->value = NULL;
1359 }
1360 
1361 /* Add a key and function. */
1362 void
1363 format_add_cb(struct format_tree *ft, const char *key, format_cb cb)
1364 {
1365 	struct format_entry	*fe;
1366 	struct format_entry	*fe_now;
1367 
1368 	fe = xmalloc(sizeof *fe);
1369 	fe->key = xstrdup(key);
1370 
1371 	fe_now = RB_INSERT(format_entry_tree, &ft->tree, fe);
1372 	if (fe_now != NULL) {
1373 		free(fe->key);
1374 		free(fe);
1375 		free(fe_now->value);
1376 		fe = fe_now;
1377 	}
1378 
1379 	fe->cb = cb;
1380 	fe->time = 0;
1381 
1382 	fe->value = NULL;
1383 }
1384 
1385 /* Quote shell special characters in string. */
1386 static char *
1387 format_quote_shell(const char *s)
1388 {
1389 	const char	*cp;
1390 	char		*out, *at;
1391 
1392 	at = out = xmalloc(strlen(s) * 2 + 1);
1393 	for (cp = s; *cp != '\0'; cp++) {
1394 		if (strchr("|&;<>()$`\\\"'*?[# =%", *cp) != NULL)
1395 			*at++ = '\\';
1396 		*at++ = *cp;
1397 	}
1398 	*at = '\0';
1399 	return (out);
1400 }
1401 
1402 /* Quote #s in string. */
1403 static char *
1404 format_quote_style(const char *s)
1405 {
1406 	const char	*cp;
1407 	char		*out, *at;
1408 
1409 	at = out = xmalloc(strlen(s) * 2 + 1);
1410 	for (cp = s; *cp != '\0'; cp++) {
1411 		if (*cp == '#')
1412 			*at++ = '#';
1413 		*at++ = *cp;
1414 	}
1415 	*at = '\0';
1416 	return (out);
1417 }
1418 
1419 /* Make a prettier time. */
1420 static char *
1421 format_pretty_time(time_t t)
1422 {
1423 	struct tm       now_tm, tm;
1424 	time_t		now, age;
1425 	char		s[6];
1426 
1427 	time(&now);
1428 	if (now < t)
1429 		now = t;
1430 	age = now - t;
1431 
1432 	localtime_r(&now, &now_tm);
1433 	localtime_r(&t, &tm);
1434 
1435 	/* Last 24 hours. */
1436 	if (age < 24 * 3600) {
1437 		strftime(s, sizeof s, "%H:%M", &tm);
1438 		return (xstrdup(s));
1439 	}
1440 
1441 	/* This month or last 28 days. */
1442 	if ((tm.tm_year == now_tm.tm_year && tm.tm_mon == now_tm.tm_mon) ||
1443 	    age < 28 * 24 * 3600) {
1444 		strftime(s, sizeof s, "%a%d", &tm);
1445 		return (xstrdup(s));
1446 	}
1447 
1448 	/* Last 12 months. */
1449 	if ((tm.tm_year == now_tm.tm_year && tm.tm_mon < now_tm.tm_mon) ||
1450 	    (tm.tm_year == now_tm.tm_year - 1 && tm.tm_mon > now_tm.tm_mon)) {
1451 		strftime(s, sizeof s, "%d%b", &tm);
1452 		return (xstrdup(s));
1453 	}
1454 
1455 	/* Older than that. */
1456 	strftime(s, sizeof s, "%h%y", &tm);
1457 	return (xstrdup(s));
1458 }
1459 
1460 /* Find a format entry. */
1461 static char *
1462 format_find(struct format_tree *ft, const char *key, int modifiers,
1463     const char *time_format)
1464 {
1465 	struct format_entry	*fe, fe_find;
1466 	struct environ_entry	*envent;
1467 	struct options_entry	*o;
1468 	int			 idx;
1469 	char			*found = NULL, *saved, s[512];
1470 	const char		*errstr;
1471 	time_t			 t = 0;
1472 	struct tm		 tm;
1473 
1474 	o = options_parse_get(global_options, key, &idx, 0);
1475 	if (o == NULL && ft->wp != NULL)
1476 		o = options_parse_get(ft->wp->options, key, &idx, 0);
1477 	if (o == NULL && ft->w != NULL)
1478 		o = options_parse_get(ft->w->options, key, &idx, 0);
1479 	if (o == NULL)
1480 		o = options_parse_get(global_w_options, key, &idx, 0);
1481 	if (o == NULL && ft->s != NULL)
1482 		o = options_parse_get(ft->s->options, key, &idx, 0);
1483 	if (o == NULL)
1484 		o = options_parse_get(global_s_options, key, &idx, 0);
1485 	if (o != NULL) {
1486 		found = options_to_string(o, idx, 1);
1487 		goto found;
1488 	}
1489 
1490 	fe_find.key = (char *)key;
1491 	fe = RB_FIND(format_entry_tree, &ft->tree, &fe_find);
1492 	if (fe != NULL) {
1493 		if (fe->time != 0) {
1494 			t = fe->time;
1495 			goto found;
1496 		}
1497 		if (fe->value == NULL && fe->cb != NULL) {
1498 			fe->value = fe->cb(ft);
1499 			if (fe->value == NULL)
1500 				fe->value = xstrdup("");
1501 		}
1502 		found = xstrdup(fe->value);
1503 		goto found;
1504 	}
1505 
1506 	if (~modifiers & FORMAT_TIMESTRING) {
1507 		envent = NULL;
1508 		if (ft->s != NULL)
1509 			envent = environ_find(ft->s->environ, key);
1510 		if (envent == NULL)
1511 			envent = environ_find(global_environ, key);
1512 		if (envent != NULL && envent->value != NULL) {
1513 			found = xstrdup(envent->value);
1514 			goto found;
1515 		}
1516 	}
1517 
1518 	return (NULL);
1519 
1520 found:
1521 	if (modifiers & FORMAT_TIMESTRING) {
1522 		if (t == 0 && found != NULL) {
1523 			t = strtonum(found, 0, INT64_MAX, &errstr);
1524 			if (errstr != NULL)
1525 				t = 0;
1526 			free(found);
1527 		}
1528 		if (t == 0)
1529 			return (NULL);
1530 		if (modifiers & FORMAT_PRETTY)
1531 			found = format_pretty_time(t);
1532 		else {
1533 			if (time_format != NULL) {
1534 				localtime_r(&t, &tm);
1535 				strftime(s, sizeof s, time_format, &tm);
1536 			} else {
1537 				ctime_r(&t, s);
1538 				s[strcspn(s, "\n")] = '\0';
1539 			}
1540 			found = xstrdup(s);
1541 		}
1542 		return (found);
1543 	}
1544 
1545 	if (t != 0)
1546 		xasprintf(&found, "%lld", (long long)t);
1547 	else if (found == NULL)
1548 		return (NULL);
1549 	if (modifiers & FORMAT_BASENAME) {
1550 		saved = found;
1551 		found = xstrdup(basename(saved));
1552 		free(saved);
1553 	}
1554 	if (modifiers & FORMAT_DIRNAME) {
1555 		saved = found;
1556 		found = xstrdup(dirname(saved));
1557 		free(saved);
1558 	}
1559 	if (modifiers & FORMAT_QUOTE_SHELL) {
1560 		saved = found;
1561 		found = xstrdup(format_quote_shell(saved));
1562 		free(saved);
1563 	}
1564 	if (modifiers & FORMAT_QUOTE_STYLE) {
1565 		saved = found;
1566 		found = xstrdup(format_quote_style(saved));
1567 		free(saved);
1568 	}
1569 	return (found);
1570 }
1571 
1572 /* Remove escaped characters from string. */
1573 static char *
1574 format_strip(const char *s)
1575 {
1576 	char	*out, *cp;
1577 	int	 brackets = 0;
1578 
1579 	cp = out = xmalloc(strlen(s) + 1);
1580 	for (; *s != '\0'; s++) {
1581 		if (*s == '#' && s[1] == '{')
1582 			brackets++;
1583 		if (*s == '#' && strchr(",#{}:", s[1]) != NULL) {
1584 			if (brackets != 0)
1585 				*cp++ = *s;
1586 			continue;
1587 		}
1588 		if (*s == '}')
1589 			brackets--;
1590 		*cp++ = *s;
1591 	}
1592 	*cp = '\0';
1593 	return (out);
1594 }
1595 
1596 /* Skip until end. */
1597 const char *
1598 format_skip(const char *s, const char *end)
1599 {
1600 	int	brackets = 0;
1601 
1602 	for (; *s != '\0'; s++) {
1603 		if (*s == '#' && s[1] == '{')
1604 			brackets++;
1605 		if (*s == '#' && strchr(",#{}:", s[1]) != NULL) {
1606 			s++;
1607 			continue;
1608 		}
1609 		if (*s == '}')
1610 			brackets--;
1611 		if (strchr(end, *s) != NULL && brackets == 0)
1612 			break;
1613 	}
1614 	if (*s == '\0')
1615 		return (NULL);
1616 	return (s);
1617 }
1618 
1619 /* Return left and right alternatives separated by commas. */
1620 static int
1621 format_choose(struct format_expand_state *es, const char *s, char **left,
1622     char **right, int expand)
1623 {
1624 	const char	*cp;
1625 	char		*left0, *right0;
1626 
1627 	cp = format_skip(s, ",");
1628 	if (cp == NULL)
1629 		return (-1);
1630 	left0 = xstrndup(s, cp - s);
1631 	right0 = xstrdup(cp + 1);
1632 
1633 	if (expand) {
1634 		*left = format_expand1(es, left0);
1635 		free(left0);
1636 		*right = format_expand1(es, right0);
1637 		free(right0);
1638 	} else {
1639 		*left = left0;
1640 		*right = right0;
1641 	}
1642 	return (0);
1643 }
1644 
1645 /* Is this true? */
1646 int
1647 format_true(const char *s)
1648 {
1649 	if (s != NULL && *s != '\0' && (s[0] != '0' || s[1] != '\0'))
1650 		return (1);
1651 	return (0);
1652 }
1653 
1654 /* Check if modifier end. */
1655 static int
1656 format_is_end(char c)
1657 {
1658 	return (c == ';' || c == ':');
1659 }
1660 
1661 /* Add to modifier list. */
1662 static void
1663 format_add_modifier(struct format_modifier **list, u_int *count,
1664     const char *c, size_t n, char **argv, int argc)
1665 {
1666 	struct format_modifier *fm;
1667 
1668 	*list = xreallocarray(*list, (*count) + 1, sizeof **list);
1669 	fm = &(*list)[(*count)++];
1670 
1671 	memcpy(fm->modifier, c, n);
1672 	fm->modifier[n] = '\0';
1673 	fm->size = n;
1674 
1675 	fm->argv = argv;
1676 	fm->argc = argc;
1677 }
1678 
1679 /* Free modifier list. */
1680 static void
1681 format_free_modifiers(struct format_modifier *list, u_int count)
1682 {
1683 	u_int	i;
1684 
1685 	for (i = 0; i < count; i++)
1686 		cmd_free_argv(list[i].argc, list[i].argv);
1687 	free(list);
1688 }
1689 
1690 /* Build modifier list. */
1691 static struct format_modifier *
1692 format_build_modifiers(struct format_expand_state *es, const char **s,
1693     u_int *count)
1694 {
1695 	const char		*cp = *s, *end;
1696 	struct format_modifier	*list = NULL;
1697 	char			 c, last[] = "X;:", **argv, *value;
1698 	int			 argc;
1699 
1700 	/*
1701 	 * Modifiers are a ; separated list of the forms:
1702 	 *      l,m,C,b,d,n,t,w,q,E,T,S,W,P,<,>
1703 	 *	=a
1704 	 *	=/a
1705 	 *      =/a/
1706 	 *	s/a/b/
1707 	 *	s/a/b
1708 	 *	||,&&,!=,==,<=,>=
1709 	 */
1710 
1711 	*count = 0;
1712 
1713 	while (*cp != '\0' && *cp != ':') {
1714 		/* Skip any separator character. */
1715 		if (*cp == ';')
1716 			cp++;
1717 
1718 		/* Check single character modifiers with no arguments. */
1719 		if (strchr("lbdnwETSWP<>", cp[0]) != NULL &&
1720 		    format_is_end(cp[1])) {
1721 			format_add_modifier(&list, count, cp, 1, NULL, 0);
1722 			cp++;
1723 			continue;
1724 		}
1725 
1726 		/* Then try double character with no arguments. */
1727 		if ((memcmp("||", cp, 2) == 0 ||
1728 		    memcmp("&&", cp, 2) == 0 ||
1729 		    memcmp("!=", cp, 2) == 0 ||
1730 		    memcmp("==", cp, 2) == 0 ||
1731 		    memcmp("<=", cp, 2) == 0 ||
1732 		    memcmp(">=", cp, 2) == 0) &&
1733 		    format_is_end(cp[2])) {
1734 			format_add_modifier(&list, count, cp, 2, NULL, 0);
1735 			cp += 2;
1736 			continue;
1737 		}
1738 
1739 		/* Now try single character with arguments. */
1740 		if (strchr("mCNst=peq", cp[0]) == NULL)
1741 			break;
1742 		c = cp[0];
1743 
1744 		/* No arguments provided. */
1745 		if (format_is_end(cp[1])) {
1746 			format_add_modifier(&list, count, cp, 1, NULL, 0);
1747 			cp++;
1748 			continue;
1749 		}
1750 		argv = NULL;
1751 		argc = 0;
1752 
1753 		/* Single argument with no wrapper character. */
1754 		if (!ispunct(cp[1]) || cp[1] == '-') {
1755 			end = format_skip(cp + 1, ":;");
1756 			if (end == NULL)
1757 				break;
1758 
1759 			argv = xcalloc(1, sizeof *argv);
1760 			value = xstrndup(cp + 1, end - (cp + 1));
1761 			argv[0] = format_expand1(es, value);
1762 			free(value);
1763 			argc = 1;
1764 
1765 			format_add_modifier(&list, count, &c, 1, argv, argc);
1766 			cp = end;
1767 			continue;
1768 		}
1769 
1770 		/* Multiple arguments with a wrapper character. */
1771 		last[0] = cp[1];
1772 		cp++;
1773 		do {
1774 			if (cp[0] == last[0] && format_is_end(cp[1])) {
1775 				cp++;
1776 				break;
1777 			}
1778 			end = format_skip(cp + 1, last);
1779 			if (end == NULL)
1780 				break;
1781 			cp++;
1782 
1783 			argv = xreallocarray (argv, argc + 1, sizeof *argv);
1784 			value = xstrndup(cp, end - cp);
1785 			argv[argc++] = format_expand1(es, value);
1786 			free(value);
1787 
1788 			cp = end;
1789 		} while (!format_is_end(cp[0]));
1790 		format_add_modifier(&list, count, &c, 1, argv, argc);
1791 	}
1792 	if (*cp != ':') {
1793 		format_free_modifiers(list, *count);
1794 		*count = 0;
1795 		return (NULL);
1796 	}
1797 	*s = cp + 1;
1798 	return (list);
1799 }
1800 
1801 /* Match against an fnmatch(3) pattern or regular expression. */
1802 static char *
1803 format_match(struct format_modifier *fm, const char *pattern, const char *text)
1804 {
1805 	const char	*s = "";
1806 	regex_t		 r;
1807 	int		 flags = 0;
1808 
1809 	if (fm->argc >= 1)
1810 		s = fm->argv[0];
1811 	if (strchr(s, 'r') == NULL) {
1812 		if (strchr(s, 'i') != NULL)
1813 			flags |= FNM_CASEFOLD;
1814 		if (fnmatch(pattern, text, flags) != 0)
1815 			return (xstrdup("0"));
1816 	} else {
1817 		flags = REG_EXTENDED|REG_NOSUB;
1818 		if (strchr(s, 'i') != NULL)
1819 			flags |= REG_ICASE;
1820 		if (regcomp(&r, pattern, flags) != 0)
1821 			return (xstrdup("0"));
1822 		if (regexec(&r, text, 0, NULL, 0) != 0) {
1823 			regfree(&r);
1824 			return (xstrdup("0"));
1825 		}
1826 		regfree(&r);
1827 	}
1828 	return (xstrdup("1"));
1829 }
1830 
1831 /* Perform substitution in string. */
1832 static char *
1833 format_sub(struct format_modifier *fm, const char *text, const char *pattern,
1834     const char *with)
1835 {
1836 	char	*value;
1837 	int	 flags = REG_EXTENDED;
1838 
1839 	if (fm->argc >= 3 && strchr(fm->argv[2], 'i') != NULL)
1840 		flags |= REG_ICASE;
1841 	value = regsub(pattern, with, text, flags);
1842 	if (value == NULL)
1843 		return (xstrdup(text));
1844 	return (value);
1845 }
1846 
1847 /* Search inside pane. */
1848 static char *
1849 format_search(struct format_modifier *fm, struct window_pane *wp, const char *s)
1850 {
1851 	int	 ignore = 0, regex = 0;
1852 	char	*value;
1853 
1854 	if (fm->argc >= 1) {
1855 		if (strchr(fm->argv[0], 'i') != NULL)
1856 			ignore = 1;
1857 		if (strchr(fm->argv[0], 'r') != NULL)
1858 			regex = 1;
1859 	}
1860 	xasprintf(&value, "%u", window_pane_search(wp, s, regex, ignore));
1861 	return (value);
1862 }
1863 
1864 /* Does session name exist? */
1865 static char *
1866 format_session_name(struct format_expand_state *es, const char *fmt)
1867 {
1868 	char		*name;
1869 	struct session	*s;
1870 
1871 	name = format_expand1(es, fmt);
1872 	RB_FOREACH(s, sessions, &sessions) {
1873 		if (strcmp(s->name, name) == 0) {
1874 			free(name);
1875 			return (xstrdup("1"));
1876 		}
1877 	}
1878 	free(name);
1879 	return (xstrdup("0"));
1880 }
1881 
1882 /* Loop over sessions. */
1883 static char *
1884 format_loop_sessions(struct format_expand_state *es, const char *fmt)
1885 {
1886 	struct format_tree		*ft = es->ft;
1887 	struct client			*c = ft->client;
1888 	struct cmdq_item		*item = ft->item;
1889 	struct format_tree		*nft;
1890 	struct format_expand_state	 next;
1891 	char				*expanded, *value;
1892 	size_t				 valuelen;
1893 	struct session			*s;
1894 
1895 	value = xcalloc(1, 1);
1896 	valuelen = 1;
1897 
1898 	RB_FOREACH(s, sessions, &sessions) {
1899 		format_log(es, "session loop: $%u", s->id);
1900 		nft = format_create(c, item, FORMAT_NONE, ft->flags);
1901 		format_defaults(nft, ft->c, s, NULL, NULL);
1902 		format_copy_state(&next, es, 0);
1903 		next.ft = nft;
1904 		expanded = format_expand1(&next, fmt);
1905 		format_free(next.ft);
1906 
1907 		valuelen += strlen(expanded);
1908 		value = xrealloc(value, valuelen);
1909 
1910 		strlcat(value, expanded, valuelen);
1911 		free(expanded);
1912 	}
1913 
1914 	return (value);
1915 }
1916 
1917 /* Does window name exist? */
1918 static char *
1919 format_window_name(struct format_expand_state *es, const char *fmt)
1920 {
1921 	struct format_tree	*ft = es->ft;
1922 	char			*name;
1923 	struct winlink		*wl;
1924 
1925 	if (ft->s == NULL) {
1926 		format_log(es, "window name but no session");
1927 		return (NULL);
1928 	}
1929 
1930 	name = format_expand1(es, fmt);
1931 	RB_FOREACH(wl, winlinks, &ft->s->windows) {
1932 		if (strcmp(wl->window->name, name) == 0) {
1933 			free(name);
1934 			return (xstrdup("1"));
1935 		}
1936 	}
1937 	free(name);
1938 	return (xstrdup("0"));
1939 }
1940 
1941 /* Loop over windows. */
1942 static char *
1943 format_loop_windows(struct format_expand_state *es, const char *fmt)
1944 {
1945 	struct format_tree		*ft = es->ft;
1946 	struct client			*c = ft->client;
1947 	struct cmdq_item		*item = ft->item;
1948 	struct format_tree		*nft;
1949 	struct format_expand_state	 next;
1950 	char				*all, *active, *use, *expanded, *value;
1951 	size_t				 valuelen;
1952 	struct winlink			*wl;
1953 	struct window			*w;
1954 
1955 	if (ft->s == NULL) {
1956 		format_log(es, "window loop but no session");
1957 		return (NULL);
1958 	}
1959 
1960 	if (format_choose(es, fmt, &all, &active, 0) != 0) {
1961 		all = xstrdup(fmt);
1962 		active = NULL;
1963 	}
1964 
1965 	value = xcalloc(1, 1);
1966 	valuelen = 1;
1967 
1968 	RB_FOREACH(wl, winlinks, &ft->s->windows) {
1969 		w = wl->window;
1970 		format_log(es, "window loop: %u @%u", wl->idx, w->id);
1971 		if (active != NULL && wl == ft->s->curw)
1972 			use = active;
1973 		else
1974 			use = all;
1975 		nft = format_create(c, item, FORMAT_WINDOW|w->id, ft->flags);
1976 		format_defaults(nft, ft->c, ft->s, wl, NULL);
1977 		format_copy_state(&next, es, 0);
1978 		next.ft = nft;
1979 		expanded = format_expand1(&next, use);
1980 		format_free(nft);
1981 
1982 		valuelen += strlen(expanded);
1983 		value = xrealloc(value, valuelen);
1984 
1985 		strlcat(value, expanded, valuelen);
1986 		free(expanded);
1987 	}
1988 
1989 	free(active);
1990 	free(all);
1991 
1992 	return (value);
1993 }
1994 
1995 /* Loop over panes. */
1996 static char *
1997 format_loop_panes(struct format_expand_state *es, const char *fmt)
1998 {
1999 	struct format_tree		*ft = es->ft;
2000 	struct client			*c = ft->client;
2001 	struct cmdq_item		*item = ft->item;
2002 	struct format_tree		*nft;
2003 	struct format_expand_state	 next;
2004 	char				*all, *active, *use, *expanded, *value;
2005 	size_t				 valuelen;
2006 	struct window_pane		*wp;
2007 
2008 	if (ft->w == NULL) {
2009 		format_log(es, "pane loop but no window");
2010 		return (NULL);
2011 	}
2012 
2013 	if (format_choose(es, fmt, &all, &active, 0) != 0) {
2014 		all = xstrdup(fmt);
2015 		active = NULL;
2016 	}
2017 
2018 	value = xcalloc(1, 1);
2019 	valuelen = 1;
2020 
2021 	TAILQ_FOREACH(wp, &ft->w->panes, entry) {
2022 		format_log(es, "pane loop: %%%u", wp->id);
2023 		if (active != NULL && wp == ft->w->active)
2024 			use = active;
2025 		else
2026 			use = all;
2027 		nft = format_create(c, item, FORMAT_PANE|wp->id, ft->flags);
2028 		format_defaults(nft, ft->c, ft->s, ft->wl, wp);
2029 		format_copy_state(&next, es, 0);
2030 		next.ft = nft;
2031 		expanded = format_expand1(&next, use);
2032 		format_free(nft);
2033 
2034 		valuelen += strlen(expanded);
2035 		value = xrealloc(value, valuelen);
2036 
2037 		strlcat(value, expanded, valuelen);
2038 		free(expanded);
2039 	}
2040 
2041 	free(active);
2042 	free(all);
2043 
2044 	return (value);
2045 }
2046 
2047 static char *
2048 format_replace_expression(struct format_modifier *mexp,
2049     struct format_expand_state *es, const char *copy)
2050 {
2051 	int			 argc = mexp->argc;
2052 	const char		*errstr;
2053 	char			*endch, *value, *left = NULL, *right = NULL;
2054 	int			 use_fp = 0;
2055 	u_int			 prec = 0;
2056 	double			 mleft, mright, result;
2057 	enum { ADD,
2058 	       SUBTRACT,
2059 	       MULTIPLY,
2060 	       DIVIDE,
2061 	       MODULUS,
2062 	       EQUAL,
2063 	       NOT_EQUAL,
2064 	       GREATER_THAN,
2065 	       GREATER_THAN_EQUAL,
2066 	       LESS_THAN,
2067 	       LESS_THAN_EQUAL } operator;
2068 
2069 	if (strcmp(mexp->argv[0], "+") == 0)
2070 		operator = ADD;
2071 	else if (strcmp(mexp->argv[0], "-") == 0)
2072 		operator = SUBTRACT;
2073 	else if (strcmp(mexp->argv[0], "*") == 0)
2074 		operator = MULTIPLY;
2075 	else if (strcmp(mexp->argv[0], "/") == 0)
2076 		operator = DIVIDE;
2077 	else if (strcmp(mexp->argv[0], "%") == 0 ||
2078 	    strcmp(mexp->argv[0], "m") == 0)
2079 		operator = MODULUS;
2080 	else if (strcmp(mexp->argv[0], "==") == 0)
2081 		operator = EQUAL;
2082 	else if (strcmp(mexp->argv[0], "!=") == 0)
2083 		operator = NOT_EQUAL;
2084 	else if (strcmp(mexp->argv[0], ">") == 0)
2085 		operator = GREATER_THAN;
2086 	else if (strcmp(mexp->argv[0], "<") == 0)
2087 		operator = LESS_THAN;
2088 	else if (strcmp(mexp->argv[0], ">=") == 0)
2089 		operator = GREATER_THAN_EQUAL;
2090 	else if (strcmp(mexp->argv[0], "<=") == 0)
2091 		operator = LESS_THAN_EQUAL;
2092 	else {
2093 		format_log(es, "expression has no valid operator: '%s'",
2094 		    mexp->argv[0]);
2095 		goto fail;
2096 	}
2097 
2098 	/* The second argument may be flags. */
2099 	if (argc >= 2 && strchr(mexp->argv[1], 'f') != NULL) {
2100 		use_fp = 1;
2101 		prec = 2;
2102 	}
2103 
2104 	/* The third argument may be precision. */
2105 	if (argc >= 3) {
2106 		prec = strtonum(mexp->argv[2], INT_MIN, INT_MAX, &errstr);
2107 		if (errstr != NULL) {
2108 			format_log(es, "expression precision %s: %s", errstr,
2109 			    mexp->argv[2]);
2110 			goto fail;
2111 		}
2112 	}
2113 
2114 	if (format_choose(es, copy, &left, &right, 1) != 0) {
2115 		format_log(es, "expression syntax error");
2116 		goto fail;
2117 	}
2118 
2119 	mleft = strtod(left, &endch);
2120 	if (*endch != '\0') {
2121 		format_log(es, "expression left side is invalid: %s", left);
2122 		goto fail;
2123 	}
2124 
2125 	mright = strtod(right, &endch);
2126 	if (*endch != '\0') {
2127 		format_log(es, "expression right side is invalid: %s", right);
2128 		goto fail;
2129 	}
2130 
2131 	if (!use_fp) {
2132 		mleft = (long long)mleft;
2133 		mright = (long long)mright;
2134 	}
2135 	format_log(es, "expression left side is: %.*f", prec, mleft);
2136 	format_log(es, "expression right side is:  %.*f", prec, mright);
2137 
2138 	switch (operator) {
2139 	case ADD:
2140 		result = mleft + mright;
2141 		break;
2142 	case SUBTRACT:
2143 		result = mleft - mright;
2144 		break;
2145 	case MULTIPLY:
2146 		result = mleft * mright;
2147 		break;
2148 	case DIVIDE:
2149 		result = mleft / mright;
2150 		break;
2151 	case MODULUS:
2152 		result = fmod(mleft, mright);
2153 		break;
2154 	case EQUAL:
2155 		result = fabs(mleft - mright) < 1e-9;
2156 		break;
2157 	case NOT_EQUAL:
2158 		result = fabs(mleft - mright) > 1e-9;
2159 		break;
2160 	case GREATER_THAN:
2161 		result = (mleft > mright);
2162 		break;
2163 	case GREATER_THAN_EQUAL:
2164 		result = (mleft >= mright);
2165 		break;
2166 	case LESS_THAN:
2167 		result = (mleft < mright);
2168 		break;
2169 	case LESS_THAN_EQUAL:
2170 		result = (mleft > mright);
2171 		break;
2172 	}
2173 	if (use_fp)
2174 		xasprintf(&value, "%.*f", prec, result);
2175 	else
2176 		xasprintf(&value, "%.*f", prec, (double)(long long)result);
2177 	format_log(es, "expression result is %s", value);
2178 
2179 	free(right);
2180 	free(left);
2181 	return (value);
2182 
2183 fail:
2184 	free(right);
2185 	free(left);
2186 	return (NULL);
2187 }
2188 
2189 /* Replace a key. */
2190 static int
2191 format_replace(struct format_expand_state *es, const char *key, size_t keylen,
2192     char **buf, size_t *len, size_t *off)
2193 {
2194 	struct format_tree		 *ft = es->ft;
2195 	struct window_pane		 *wp = ft->wp;
2196 	const char			 *errptr, *copy, *cp, *marker = NULL;
2197 	const char			 *time_format = NULL;
2198 	char				 *copy0, *condition, *found, *new;
2199 	char				 *value, *left, *right;
2200 	size_t				  valuelen;
2201 	int				  modifiers = 0, limit = 0, width = 0;
2202 	int				  j;
2203 	struct format_modifier		 *list, *cmp = NULL, *search = NULL;
2204 	struct format_modifier		**sub = NULL, *mexp = NULL, *fm;
2205 	u_int				  i, count, nsub = 0;
2206 	struct format_expand_state	  next;
2207 
2208 	/* Make a copy of the key. */
2209 	copy = copy0 = xstrndup(key, keylen);
2210 
2211 	/* Process modifier list. */
2212 	list = format_build_modifiers(es, &copy, &count);
2213 	for (i = 0; i < count; i++) {
2214 		fm = &list[i];
2215 		if (format_logging(ft)) {
2216 			format_log(es, "modifier %u is %s", i, fm->modifier);
2217 			for (j = 0; j < fm->argc; j++) {
2218 				format_log(es, "modifier %u argument %d: %s", i,
2219 				    j, fm->argv[j]);
2220 			}
2221 		}
2222 		if (fm->size == 1) {
2223 			switch (fm->modifier[0]) {
2224 			case 'm':
2225 			case '<':
2226 			case '>':
2227 				cmp = fm;
2228 				break;
2229 			case 'C':
2230 				search = fm;
2231 				break;
2232 			case 's':
2233 				if (fm->argc < 2)
2234 					break;
2235 				sub = xreallocarray (sub, nsub + 1,
2236 				    sizeof *sub);
2237 				sub[nsub++] = fm;
2238 				break;
2239 			case '=':
2240 				if (fm->argc < 1)
2241 					break;
2242 				limit = strtonum(fm->argv[0], INT_MIN, INT_MAX,
2243 				    &errptr);
2244 				if (errptr != NULL)
2245 					limit = 0;
2246 				if (fm->argc >= 2 && fm->argv[1] != NULL)
2247 					marker = fm->argv[1];
2248 				break;
2249 			case 'p':
2250 				if (fm->argc < 1)
2251 					break;
2252 				width = strtonum(fm->argv[0], INT_MIN, INT_MAX,
2253 				    &errptr);
2254 				if (errptr != NULL)
2255 					width = 0;
2256 				break;
2257 			case 'w':
2258 				modifiers |= FORMAT_WIDTH;
2259 				break;
2260 			case 'e':
2261 				if (fm->argc < 1 || fm->argc > 3)
2262 					break;
2263 				mexp = fm;
2264 				break;
2265 			case 'l':
2266 				modifiers |= FORMAT_LITERAL;
2267 				break;
2268 			case 'b':
2269 				modifiers |= FORMAT_BASENAME;
2270 				break;
2271 			case 'd':
2272 				modifiers |= FORMAT_DIRNAME;
2273 				break;
2274 			case 'n':
2275 				modifiers |= FORMAT_LENGTH;
2276 				break;
2277 			case 't':
2278 				modifiers |= FORMAT_TIMESTRING;
2279 				if (fm->argc < 1)
2280 					break;
2281 				if (strchr(fm->argv[0], 'p') != NULL)
2282 					modifiers |= FORMAT_PRETTY;
2283 				else if (fm->argc >= 2 &&
2284 				    strchr(fm->argv[0], 'f') != NULL)
2285 					time_format = format_strip(fm->argv[1]);
2286 				break;
2287 			case 'q':
2288 				if (fm->argc < 1)
2289 					modifiers |= FORMAT_QUOTE_SHELL;
2290 				else if (strchr(fm->argv[0], 'e') != NULL ||
2291 				    strchr(fm->argv[0], 'h') != NULL)
2292 					modifiers |= FORMAT_QUOTE_STYLE;
2293 				break;
2294 			case 'E':
2295 				modifiers |= FORMAT_EXPAND;
2296 				break;
2297 			case 'T':
2298 				modifiers |= FORMAT_EXPANDTIME;
2299 				break;
2300 			case 'N':
2301 				if (fm->argc < 1 ||
2302 				    strchr(fm->argv[0], 'w') != NULL)
2303 					modifiers |= FORMAT_WINDOW_NAME;
2304 				else if (strchr(fm->argv[0], 's') != NULL)
2305 					modifiers |= FORMAT_SESSION_NAME;
2306 				break;
2307 			case 'S':
2308 				modifiers |= FORMAT_SESSIONS;
2309 				break;
2310 			case 'W':
2311 				modifiers |= FORMAT_WINDOWS;
2312 				break;
2313 			case 'P':
2314 				modifiers |= FORMAT_PANES;
2315 				break;
2316 			}
2317 		} else if (fm->size == 2) {
2318 			if (strcmp(fm->modifier, "||") == 0 ||
2319 			    strcmp(fm->modifier, "&&") == 0 ||
2320 			    strcmp(fm->modifier, "==") == 0 ||
2321 			    strcmp(fm->modifier, "!=") == 0 ||
2322 			    strcmp(fm->modifier, ">=") == 0 ||
2323 			    strcmp(fm->modifier, "<=") == 0)
2324 				cmp = fm;
2325 		}
2326 	}
2327 
2328 	/* Is this a literal string? */
2329 	if (modifiers & FORMAT_LITERAL) {
2330 		value = xstrdup(copy);
2331 		goto done;
2332 	}
2333 
2334 	/* Is this a loop, comparison or condition? */
2335 	if (modifiers & FORMAT_SESSIONS) {
2336 		value = format_loop_sessions(es, copy);
2337 		if (value == NULL)
2338 			goto fail;
2339 	} else if (modifiers & FORMAT_WINDOWS) {
2340 		value = format_loop_windows(es, copy);
2341 		if (value == NULL)
2342 			goto fail;
2343 	} else if (modifiers & FORMAT_PANES) {
2344 		value = format_loop_panes(es, copy);
2345 		if (value == NULL)
2346 			goto fail;
2347 	} else if (modifiers & FORMAT_WINDOW_NAME) {
2348 		value = format_window_name(es, copy);
2349 		if (value == NULL)
2350 			goto fail;
2351 	} else if (modifiers & FORMAT_SESSION_NAME) {
2352 		value = format_session_name(es, copy);
2353 		if (value == NULL)
2354 			goto fail;
2355 	} else if (search != NULL) {
2356 		/* Search in pane. */
2357 		new = format_expand1(es, copy);
2358 		if (wp == NULL) {
2359 			format_log(es, "search '%s' but no pane", new);
2360 			value = xstrdup("0");
2361 		} else {
2362 			format_log(es, "search '%s' pane %%%u", new, wp->id);
2363 			value = format_search(fm, wp, new);
2364 		}
2365 		free(new);
2366 	} else if (cmp != NULL) {
2367 		/* Comparison of left and right. */
2368 		if (format_choose(es, copy, &left, &right, 1) != 0) {
2369 			format_log(es, "compare %s syntax error: %s",
2370 			    cmp->modifier, copy);
2371 			goto fail;
2372 		}
2373 		format_log(es, "compare %s left is: %s", cmp->modifier, left);
2374 		format_log(es, "compare %s right is: %s", cmp->modifier, right);
2375 
2376 		if (strcmp(cmp->modifier, "||") == 0) {
2377 			if (format_true(left) || format_true(right))
2378 				value = xstrdup("1");
2379 			else
2380 				value = xstrdup("0");
2381 		} else if (strcmp(cmp->modifier, "&&") == 0) {
2382 			if (format_true(left) && format_true(right))
2383 				value = xstrdup("1");
2384 			else
2385 				value = xstrdup("0");
2386 		} else if (strcmp(cmp->modifier, "==") == 0) {
2387 			if (strcmp(left, right) == 0)
2388 				value = xstrdup("1");
2389 			else
2390 				value = xstrdup("0");
2391 		} else if (strcmp(cmp->modifier, "!=") == 0) {
2392 			if (strcmp(left, right) != 0)
2393 				value = xstrdup("1");
2394 			else
2395 				value = xstrdup("0");
2396 		} else if (strcmp(cmp->modifier, "<") == 0) {
2397 			if (strcmp(left, right) < 0)
2398 				value = xstrdup("1");
2399 			else
2400 				value = xstrdup("0");
2401 		} else if (strcmp(cmp->modifier, ">") == 0) {
2402 			if (strcmp(left, right) > 0)
2403 				value = xstrdup("1");
2404 			else
2405 				value = xstrdup("0");
2406 		} else if (strcmp(cmp->modifier, "<=") == 0) {
2407 			if (strcmp(left, right) <= 0)
2408 				value = xstrdup("1");
2409 			else
2410 				value = xstrdup("0");
2411 		} else if (strcmp(cmp->modifier, ">=") == 0) {
2412 			if (strcmp(left, right) >= 0)
2413 				value = xstrdup("1");
2414 			else
2415 				value = xstrdup("0");
2416 		} else if (strcmp(cmp->modifier, "m") == 0)
2417 			value = format_match(cmp, left, right);
2418 
2419 		free(right);
2420 		free(left);
2421 	} else if (*copy == '?') {
2422 		/* Conditional: check first and choose second or third. */
2423 		cp = format_skip(copy + 1, ",");
2424 		if (cp == NULL) {
2425 			format_log(es, "condition syntax error: %s", copy + 1);
2426 			goto fail;
2427 		}
2428 		condition = xstrndup(copy + 1, cp - (copy + 1));
2429 		format_log(es, "condition is: %s", condition);
2430 
2431 		found = format_find(ft, condition, modifiers, time_format);
2432 		if (found == NULL) {
2433 			/*
2434 			 * If the condition not found, try to expand it. If
2435 			 * the expansion doesn't have any effect, then assume
2436 			 * false.
2437 			 */
2438 			found = format_expand1(es, condition);
2439 			if (strcmp(found, condition) == 0) {
2440 				free(found);
2441 				found = xstrdup("");
2442 				format_log(es, "condition '%s' found: %s",
2443 				    condition, found);
2444 			} else {
2445 				format_log(es,
2446 				    "condition '%s' not found; assuming false",
2447 				    condition);
2448 			}
2449 		} else
2450 			format_log(es, "condition '%s' found", condition);
2451 
2452 		if (format_choose(es, cp + 1, &left, &right, 0) != 0) {
2453 			format_log(es, "condition '%s' syntax error: %s",
2454 			    condition, cp + 1);
2455 			free(found);
2456 			goto fail;
2457 		}
2458 		if (format_true(found)) {
2459 			format_log(es, "condition '%s' is true", condition);
2460 			value = format_expand1(es, left);
2461 		} else {
2462 			format_log(es, "condition '%s' is false", condition);
2463 			value = format_expand1(es, right);
2464 		}
2465 		free(right);
2466 		free(left);
2467 
2468 		free(condition);
2469 		free(found);
2470 	} else if (mexp != NULL) {
2471 		value = format_replace_expression(mexp, es, copy);
2472 		if (value == NULL)
2473 			value = xstrdup("");
2474 	} else {
2475 		if (strstr(copy, "#{") != 0) {
2476 			format_log(es, "expanding inner format '%s'", copy);
2477 			value = format_expand1(es, copy);
2478 		} else {
2479 			value = format_find(ft, copy, modifiers, time_format);
2480 			if (value == NULL) {
2481 				format_log(es, "format '%s' not found", copy);
2482 				value = xstrdup("");
2483 			} else {
2484 				format_log(es, "format '%s' found: %s", copy,
2485 				    value);
2486 			}
2487 		}
2488 	}
2489 
2490 done:
2491 	/* Expand again if required. */
2492 	if (modifiers & FORMAT_EXPAND) {
2493 		new = format_expand1(es, value);
2494 		free(value);
2495 		value = new;
2496 	} else if (modifiers & FORMAT_EXPANDTIME) {
2497 		format_copy_state(&next, es, FORMAT_EXPAND_TIME);
2498 		new = format_expand1(&next, value);
2499 		free(value);
2500 		value = new;
2501 	}
2502 
2503 	/* Perform substitution if any. */
2504 	for (i = 0; i < nsub; i++) {
2505 		left = format_expand1(es, sub[i]->argv[0]);
2506 		right = format_expand1(es, sub[i]->argv[1]);
2507 		new = format_sub(sub[i], value, left, right);
2508 		format_log(es, "substitute '%s' to '%s': %s", left, right, new);
2509 		free(value);
2510 		value = new;
2511 		free(right);
2512 		free(left);
2513 	}
2514 
2515 	/* Truncate the value if needed. */
2516 	if (limit > 0) {
2517 		new = format_trim_left(value, limit);
2518 		if (marker != NULL && strcmp(new, value) != 0) {
2519 			free(value);
2520 			xasprintf(&value, "%s%s", new, marker);
2521 		} else {
2522 			free(value);
2523 			value = new;
2524 		}
2525 		format_log(es, "applied length limit %d: %s", limit, value);
2526 	} else if (limit < 0) {
2527 		new = format_trim_right(value, -limit);
2528 		if (marker != NULL && strcmp(new, value) != 0) {
2529 			free(value);
2530 			xasprintf(&value, "%s%s", marker, new);
2531 		} else {
2532 			free(value);
2533 			value = new;
2534 		}
2535 		format_log(es, "applied length limit %d: %s", limit, value);
2536 	}
2537 
2538 	/* Pad the value if needed. */
2539 	if (width > 0) {
2540 		new = utf8_padcstr(value, width);
2541 		free(value);
2542 		value = new;
2543 		format_log(es, "applied padding width %d: %s", width, value);
2544 	} else if (width < 0) {
2545 		new = utf8_rpadcstr(value, -width);
2546 		free(value);
2547 		value = new;
2548 		format_log(es, "applied padding width %d: %s", width, value);
2549 	}
2550 
2551 	/* Replace with the length or width if needed. */
2552 	if (modifiers & FORMAT_LENGTH) {
2553 		xasprintf(&new, "%zu", strlen(value));
2554 		free(value);
2555 		value = new;
2556 		format_log(es, "replacing with length: %s", new);
2557 	}
2558 	if (modifiers & FORMAT_WIDTH) {
2559 		xasprintf(&new, "%u", format_width(value));
2560 		free(value);
2561 		value = new;
2562 		format_log(es, "replacing with width: %s", new);
2563 	}
2564 
2565 	/* Expand the buffer and copy in the value. */
2566 	valuelen = strlen(value);
2567 	while (*len - *off < valuelen + 1) {
2568 		*buf = xreallocarray(*buf, 2, *len);
2569 		*len *= 2;
2570 	}
2571 	memcpy(*buf + *off, value, valuelen);
2572 	*off += valuelen;
2573 
2574 	format_log(es, "replaced '%s' with '%s'", copy0, value);
2575 	free(value);
2576 
2577 	free(sub);
2578 	format_free_modifiers(list, count);
2579 	free(copy0);
2580 	return (0);
2581 
2582 fail:
2583 	format_log(es, "failed %s", copy0);
2584 
2585 	free(sub);
2586 	format_free_modifiers(list, count);
2587 	free(copy0);
2588 	return (-1);
2589 }
2590 
2591 /* Expand keys in a template. */
2592 static char *
2593 format_expand1(struct format_expand_state *es, const char *fmt)
2594 {
2595 	struct format_tree	*ft = es->ft;
2596 	char			*buf, *out, *name;
2597 	const char		*ptr, *s;
2598 	size_t			 off, len, n, outlen;
2599 	int     		 ch, brackets;
2600 	struct tm		*tm;
2601 	char			 expanded[8192];
2602 
2603 	if (fmt == NULL || *fmt == '\0')
2604 		return (xstrdup(""));
2605 
2606 	if (es->loop == FORMAT_LOOP_LIMIT)
2607 		return (xstrdup(""));
2608 	es->loop++;
2609 
2610 	format_log(es, "expanding format: %s", fmt);
2611 
2612 	if (es->flags & FORMAT_EXPAND_TIME) {
2613 		if (es->time == 0)
2614 			es->time = time(NULL);
2615 		tm = localtime(&es->time);
2616 		if (strftime(expanded, sizeof expanded, fmt, tm) == 0) {
2617 			format_log(es, "format is too long");
2618 			return (xstrdup(""));
2619 		}
2620 		if (format_logging(ft) && strcmp(expanded, fmt) != 0)
2621 			format_log(es, "after time expanded: %s", expanded);
2622 		fmt = expanded;
2623 	}
2624 
2625 	len = 64;
2626 	buf = xmalloc(len);
2627 	off = 0;
2628 
2629 	while (*fmt != '\0') {
2630 		if (*fmt != '#') {
2631 			while (len - off < 2) {
2632 				buf = xreallocarray(buf, 2, len);
2633 				len *= 2;
2634 			}
2635 			buf[off++] = *fmt++;
2636 			continue;
2637 		}
2638 		fmt++;
2639 
2640 		ch = (u_char)*fmt++;
2641 		switch (ch) {
2642 		case '(':
2643 			brackets = 1;
2644 			for (ptr = fmt; *ptr != '\0'; ptr++) {
2645 				if (*ptr == '(')
2646 					brackets++;
2647 				if (*ptr == ')' && --brackets == 0)
2648 					break;
2649 			}
2650 			if (*ptr != ')' || brackets != 0)
2651 				break;
2652 			n = ptr - fmt;
2653 
2654 			name = xstrndup(fmt, n);
2655 			format_log(es, "found #(): %s", name);
2656 
2657 			if ((ft->flags & FORMAT_NOJOBS) ||
2658 			    (es->flags & FORMAT_EXPAND_NOJOBS)) {
2659 				out = xstrdup("");
2660 				format_log(es, "#() is disabled");
2661 			} else {
2662 				out = format_job_get(es, name);
2663 				format_log(es, "#() result: %s", out);
2664 			}
2665 			free(name);
2666 
2667 			outlen = strlen(out);
2668 			while (len - off < outlen + 1) {
2669 				buf = xreallocarray(buf, 2, len);
2670 				len *= 2;
2671 			}
2672 			memcpy(buf + off, out, outlen);
2673 			off += outlen;
2674 
2675 			free(out);
2676 
2677 			fmt += n + 1;
2678 			continue;
2679 		case '{':
2680 			ptr = format_skip((char *)fmt - 2, "}");
2681 			if (ptr == NULL)
2682 				break;
2683 			n = ptr - fmt;
2684 
2685 			format_log(es, "found #{}: %.*s", (int)n, fmt);
2686 			if (format_replace(es, fmt, n, &buf, &len, &off) != 0)
2687 				break;
2688 			fmt += n + 1;
2689 			continue;
2690 		case '#':
2691 			/*
2692 			 * If ##[ (with two or more #s), then it is a style and
2693 			 * can be left for format_draw to handle.
2694 			 */
2695 			ptr = fmt;
2696 			n = 2;
2697 			while (*ptr == '#') {
2698 				ptr++;
2699 				n++;
2700 			}
2701 			if (*ptr == '[') {
2702 				format_log(es, "found #*%zu[", n);
2703 				while (len - off < n + 2) {
2704 					buf = xreallocarray(buf, 2, len);
2705 					len *= 2;
2706 				}
2707 				memcpy(buf + off, fmt - 2, n + 1);
2708 				off += n + 1;
2709 				fmt = ptr + 1;
2710 				continue;
2711 			}
2712 			/* FALLTHROUGH */
2713 		case '}':
2714 		case ',':
2715 			format_log(es, "found #%c", ch);
2716 			while (len - off < 2) {
2717 				buf = xreallocarray(buf, 2, len);
2718 				len *= 2;
2719 			}
2720 			buf[off++] = ch;
2721 			continue;
2722 		default:
2723 			s = NULL;
2724 			if (ch >= 'A' && ch <= 'Z')
2725 				s = format_upper[ch - 'A'];
2726 			else if (ch >= 'a' && ch <= 'z')
2727 				s = format_lower[ch - 'a'];
2728 			if (s == NULL) {
2729 				while (len - off < 3) {
2730 					buf = xreallocarray(buf, 2, len);
2731 					len *= 2;
2732 				}
2733 				buf[off++] = '#';
2734 				buf[off++] = ch;
2735 				continue;
2736 			}
2737 			n = strlen(s);
2738 			format_log(es, "found #%c: %s", ch, s);
2739 			if (format_replace(es, s, n, &buf, &len, &off) != 0)
2740 				break;
2741 			continue;
2742 		}
2743 
2744 		break;
2745 	}
2746 	buf[off] = '\0';
2747 
2748 	format_log(es, "result is: %s", buf);
2749 	es->loop--;
2750 
2751 	return (buf);
2752 }
2753 
2754 /* Expand keys in a template, passing through strftime first. */
2755 char *
2756 format_expand_time(struct format_tree *ft, const char *fmt)
2757 {
2758 	struct format_expand_state	es;
2759 
2760 	memset(&es, 0, sizeof es);
2761 	es.ft = ft;
2762 	es.flags = FORMAT_EXPAND_TIME;
2763 	return (format_expand1(&es, fmt));
2764 }
2765 
2766 /* Expand keys in a template. */
2767 char *
2768 format_expand(struct format_tree *ft, const char *fmt)
2769 {
2770 	struct format_expand_state	es;
2771 
2772 	memset(&es, 0, sizeof es);
2773 	es.ft = ft;
2774 	es.flags = 0;
2775 	return (format_expand1(&es, fmt));
2776 }
2777 
2778 /* Expand a single string. */
2779 char *
2780 format_single(struct cmdq_item *item, const char *fmt, struct client *c,
2781     struct session *s, struct winlink *wl, struct window_pane *wp)
2782 {
2783 	struct format_tree	*ft;
2784 	char			*expanded;
2785 
2786 	ft = format_create_defaults(item, c, s, wl, wp);
2787 	expanded = format_expand(ft, fmt);
2788 	format_free(ft);
2789 	return (expanded);
2790 }
2791 
2792 /* Expand a single string using state. */
2793 char *
2794 format_single_from_state(struct cmdq_item *item, const char *fmt,
2795     struct client *c, struct cmd_find_state *fs)
2796 {
2797 	return (format_single(item, fmt, c, fs->s, fs->wl, fs->wp));
2798 }
2799 
2800 /* Expand a single string using target. */
2801 char *
2802 format_single_from_target(struct cmdq_item *item, const char *fmt)
2803 {
2804 	struct client	*tc = cmdq_get_target_client(item);
2805 
2806 	return (format_single_from_state(item, fmt, tc, cmdq_get_target(item)));
2807 }
2808 
2809 /* Create and add defaults. */
2810 struct format_tree *
2811 format_create_defaults(struct cmdq_item *item, struct client *c,
2812     struct session *s, struct winlink *wl, struct window_pane *wp)
2813 {
2814 	struct format_tree	*ft;
2815 
2816 	if (item != NULL)
2817 		ft = format_create(cmdq_get_client(item), item, FORMAT_NONE, 0);
2818 	else
2819 		ft = format_create(NULL, item, FORMAT_NONE, 0);
2820 	format_defaults(ft, c, s, wl, wp);
2821 	return (ft);
2822 }
2823 
2824 /* Create and add defaults using state. */
2825 struct format_tree *
2826 format_create_from_state(struct cmdq_item *item, struct client *c,
2827     struct cmd_find_state *fs)
2828 {
2829 	return (format_create_defaults(item, c, fs->s, fs->wl, fs->wp));
2830 }
2831 
2832 /* Create and add defaults using target. */
2833 struct format_tree *
2834 format_create_from_target(struct cmdq_item *item)
2835 {
2836 	struct client	*tc = cmdq_get_target_client(item);
2837 
2838 	return (format_create_from_state(item, tc, cmdq_get_target(item)));
2839 }
2840 
2841 /* Set defaults for any of arguments that are not NULL. */
2842 void
2843 format_defaults(struct format_tree *ft, struct client *c, struct session *s,
2844     struct winlink *wl, struct window_pane *wp)
2845 {
2846 	struct paste_buffer	*pb;
2847 
2848 	if (c != NULL && c->name != NULL)
2849 		log_debug("%s: c=%s", __func__, c->name);
2850 	else
2851 		log_debug("%s: c=none", __func__);
2852 	if (s != NULL)
2853 		log_debug("%s: s=$%u", __func__, s->id);
2854 	else
2855 		log_debug("%s: s=none", __func__);
2856 	if (wl != NULL)
2857 		log_debug("%s: wl=%u", __func__, wl->idx);
2858 	else
2859 		log_debug("%s: wl=none", __func__);
2860 	if (wp != NULL)
2861 		log_debug("%s: wp=%%%u", __func__, wp->id);
2862 	else
2863 		log_debug("%s: wp=none", __func__);
2864 
2865 	if (c != NULL && s != NULL && c->session != s)
2866 		log_debug("%s: session does not match", __func__);
2867 
2868 	format_add(ft, "session_format", "%d", s != NULL);
2869 	format_add(ft, "window_format", "%d", wl != NULL);
2870 	format_add(ft, "pane_format", "%d", wp != NULL);
2871 
2872 	if (s == NULL && c != NULL)
2873 		s = c->session;
2874 	if (wl == NULL && s != NULL)
2875 		wl = s->curw;
2876 	if (wp == NULL && wl != NULL)
2877 		wp = wl->window->active;
2878 
2879 	if (c != NULL)
2880 		format_defaults_client(ft, c);
2881 	if (s != NULL)
2882 		format_defaults_session(ft, s);
2883 	if (wl != NULL)
2884 		format_defaults_winlink(ft, wl);
2885 	if (wp != NULL)
2886 		format_defaults_pane(ft, wp);
2887 
2888 	pb = paste_get_top (NULL);
2889 	if (pb != NULL)
2890 		format_defaults_paste_buffer(ft, pb);
2891 }
2892 
2893 /* Set default format keys for a session. */
2894 static void
2895 format_defaults_session(struct format_tree *ft, struct session *s)
2896 {
2897 	struct session_group	*sg;
2898 
2899 	ft->s = s;
2900 
2901 	format_add(ft, "session_name", "%s", s->name);
2902 	format_add(ft, "session_path", "%s", s->cwd);
2903 	format_add(ft, "session_windows", "%u", winlink_count(&s->windows));
2904 	format_add(ft, "session_id", "$%u", s->id);
2905 
2906 	sg = session_group_contains(s);
2907 	format_add(ft, "session_grouped", "%d", sg != NULL);
2908 	if (sg != NULL) {
2909 		format_add(ft, "session_group", "%s", sg->name);
2910 		format_add(ft, "session_group_size", "%u",
2911 		    session_group_count (sg));
2912 		format_add(ft, "session_group_attached", "%u",
2913 		    session_group_attached_count (sg));
2914 		format_add(ft, "session_group_many_attached", "%u",
2915 		    session_group_attached_count (sg) > 1);
2916 		format_add_cb(ft, "session_group_list",
2917 		    format_cb_session_group_list);
2918 		format_add_cb(ft, "session_group_attached_list",
2919 		    format_cb_session_group_attached_list);
2920 	}
2921 
2922 	format_add_tv(ft, "session_created", &s->creation_time);
2923 	format_add_tv(ft, "session_last_attached", &s->last_attached_time);
2924 	format_add_tv(ft, "session_activity", &s->activity_time);
2925 
2926 	format_add(ft, "session_attached", "%u", s->attached);
2927 	format_add(ft, "session_many_attached", "%d", s->attached > 1);
2928 	format_add_cb(ft, "session_attached_list",
2929 	    format_cb_session_attached_list);
2930 
2931 	format_add_cb(ft, "session_alerts", format_cb_session_alerts);
2932 	format_add_cb(ft, "session_stack", format_cb_session_stack);
2933 
2934 	if (server_check_marked() && marked_pane.s == s)
2935 	    format_add(ft, "session_marked", "1");
2936 	else
2937 	    format_add(ft, "session_marked", "0");
2938 }
2939 
2940 /* Set default format keys for a client. */
2941 static void
2942 format_defaults_client(struct format_tree *ft, struct client *c)
2943 {
2944 	struct session	*s;
2945 	const char	*name;
2946 	struct tty	*tty = &c->tty;
2947 
2948 	if (ft->s == NULL)
2949 		ft->s = c->session;
2950 	ft->c = c;
2951 
2952 	format_add(ft, "client_name", "%s", c->name);
2953 	format_add(ft, "client_pid", "%ld", (long) c->pid);
2954 	format_add(ft, "client_height", "%u", tty->sy);
2955 	format_add(ft, "client_width", "%u", tty->sx);
2956 	format_add(ft, "client_cell_width", "%u", tty->xpixel);
2957 	format_add(ft, "client_cell_height", "%u", tty->ypixel);
2958 	format_add(ft, "client_tty", "%s", c->ttyname);
2959 	format_add(ft, "client_control_mode", "%d",
2960 		!!(c->flags & CLIENT_CONTROL));
2961 
2962 	format_add(ft, "client_termname", "%s", c->term_name);
2963 	format_add(ft, "client_termfeatures", "%s",
2964 	    tty_get_features(c->term_features));
2965 	if (c->term_type != NULL)
2966 		format_add(ft, "client_termtype", "%s", c->term_type);
2967 
2968 	format_add_tv(ft, "client_created", &c->creation_time);
2969 	format_add_tv(ft, "client_activity", &c->activity_time);
2970 
2971 	format_add(ft, "client_written", "%zu", c->written);
2972 	format_add(ft, "client_discarded", "%zu", c->discarded);
2973 
2974 	name = server_client_get_key_table(c);
2975 	if (strcmp(c->keytable->name, name) == 0)
2976 		format_add(ft, "client_prefix", "%d", 0);
2977 	else
2978 		format_add(ft, "client_prefix", "%d", 1);
2979 	format_add(ft, "client_key_table", "%s", c->keytable->name);
2980 
2981 	if (c->flags & CLIENT_UTF8)
2982 		format_add(ft, "client_utf8", "%d", 1);
2983 	else
2984 		format_add(ft, "client_utf8", "%d", 0);
2985 	if (c->flags & CLIENT_READONLY)
2986 		format_add(ft, "client_readonly", "%d", 1);
2987 	else
2988 		format_add(ft, "client_readonly", "%d", 0);
2989 	format_add(ft, "client_flags", "%s", server_client_get_flags(c));
2990 
2991 	s = c->session;
2992 	if (s != NULL)
2993 		format_add(ft, "client_session", "%s", s->name);
2994 	s = c->last_session;
2995 	if (s != NULL && session_alive(s))
2996 		format_add(ft, "client_last_session", "%s", s->name);
2997 }
2998 
2999 /* Set default format keys for a window. */
3000 void
3001 format_defaults_window(struct format_tree *ft, struct window *w)
3002 {
3003 	ft->w = w;
3004 
3005 	format_add_tv(ft, "window_activity", &w->activity_time);
3006 	format_add(ft, "window_id", "@%u", w->id);
3007 	format_add(ft, "window_name", "%s", w->name);
3008 	format_add(ft, "window_width", "%u", w->sx);
3009 	format_add(ft, "window_height", "%u", w->sy);
3010 	format_add(ft, "window_cell_width", "%u", w->xpixel);
3011 	format_add(ft, "window_cell_height", "%u", w->ypixel);
3012 	format_add_cb(ft, "window_layout", format_cb_window_layout);
3013 	format_add_cb(ft, "window_visible_layout",
3014 	    format_cb_window_visible_layout);
3015 	format_add(ft, "window_panes", "%u", window_count_panes(w));
3016 	format_add(ft, "window_zoomed_flag", "%d",
3017 	    !!(w->flags & WINDOW_ZOOMED));
3018 }
3019 
3020 /* Set default format keys for a winlink. */
3021 static void
3022 format_defaults_winlink(struct format_tree *ft, struct winlink *wl)
3023 {
3024 	struct client	*c = ft->c;
3025 	struct session	*s = wl->session;
3026 	struct window	*w = wl->window;
3027 	int		 flag;
3028 	u_int		 ox, oy, sx, sy;
3029 
3030 	if (ft->w == NULL)
3031 		format_defaults_window(ft, w);
3032 	ft->wl = wl;
3033 
3034 	if (c != NULL) {
3035 		flag = tty_window_offset(&c->tty, &ox, &oy, &sx, &sy);
3036 		format_add(ft, "window_bigger", "%d", flag);
3037 		if (flag) {
3038 			format_add(ft, "window_offset_x", "%u", ox);
3039 			format_add(ft, "window_offset_y", "%u", oy);
3040 		}
3041 	}
3042 
3043 	format_add(ft, "window_index", "%d", wl->idx);
3044 	format_add_cb(ft, "window_stack_index", format_cb_window_stack_index);
3045 	format_add(ft, "window_flags", "%s", window_printable_flags(wl, 1));
3046 	format_add(ft, "window_raw_flags", "%s", window_printable_flags(wl, 0));
3047 	format_add(ft, "window_active", "%d", wl == s->curw);
3048 	format_add_cb(ft, "window_active_sessions",
3049 	    format_cb_window_active_sessions);
3050 	format_add_cb(ft, "window_active_sessions_list",
3051 	    format_cb_window_active_sessions_list);
3052 	format_add_cb(ft, "window_active_clients",
3053 	    format_cb_window_active_clients);
3054 	format_add_cb(ft, "window_active_clients_list",
3055 	    format_cb_window_active_clients_list);
3056 
3057 	format_add(ft, "window_start_flag", "%d",
3058 	    !!(wl == RB_MIN(winlinks, &s->windows)));
3059 	format_add(ft, "window_end_flag", "%d",
3060 	    !!(wl == RB_MAX(winlinks, &s->windows)));
3061 
3062 	if (server_check_marked() && marked_pane.wl == wl)
3063 	    format_add(ft, "window_marked_flag", "1");
3064 	else
3065 	    format_add(ft, "window_marked_flag", "0");
3066 
3067 	format_add(ft, "window_bell_flag", "%d",
3068 	    !!(wl->flags & WINLINK_BELL));
3069 	format_add(ft, "window_activity_flag", "%d",
3070 	    !!(wl->flags & WINLINK_ACTIVITY));
3071 	format_add(ft, "window_silence_flag", "%d",
3072 	    !!(wl->flags & WINLINK_SILENCE));
3073 	format_add(ft, "window_last_flag", "%d",
3074 	    !!(wl == TAILQ_FIRST(&s->lastw)));
3075 	format_add(ft, "window_linked", "%d", session_is_linked(s, wl->window));
3076 
3077 	format_add_cb(ft, "window_linked_sessions_list",
3078 	    format_cb_window_linked_sessions_list);
3079 	format_add(ft, "window_linked_sessions", "%u",
3080 	    wl->window->references);
3081 }
3082 
3083 /* Set default format keys for a window pane. */
3084 void
3085 format_defaults_pane(struct format_tree *ft, struct window_pane *wp)
3086 {
3087 	struct window			*w = wp->window;
3088 	struct grid			*gd = wp->base.grid;
3089 	int  				 status = wp->status;
3090 	u_int				 idx;
3091 	struct window_mode_entry	*wme;
3092 
3093 	if (ft->w == NULL)
3094 		format_defaults_window(ft, w);
3095 	ft->wp = wp;
3096 
3097 	format_add(ft, "history_size", "%u", gd->hsize);
3098 	format_add(ft, "history_limit", "%u", gd->hlimit);
3099 	format_add_cb(ft, "history_bytes", format_cb_history_bytes);
3100 	format_add_cb(ft, "history_all_bytes", format_cb_history_all_bytes);
3101 
3102 	if (window_pane_index(wp, &idx) != 0)
3103 		fatalx("index not found");
3104 	format_add(ft, "pane_index", "%u", idx);
3105 
3106 	format_add(ft, "pane_width", "%u", wp->sx);
3107 	format_add(ft, "pane_height", "%u", wp->sy);
3108 	format_add(ft, "pane_title", "%s", wp->base.title);
3109 	if (wp->base.path != NULL)
3110 	    format_add(ft, "pane_path", "%s", wp->base.path);
3111 	format_add(ft, "pane_id", "%%%u", wp->id);
3112 	format_add(ft, "pane_active", "%d", wp == w->active);
3113 	format_add(ft, "pane_input_off", "%d", !!(wp->flags & PANE_INPUTOFF));
3114 	format_add(ft, "pane_pipe", "%d", wp->pipe_fd != -1);
3115 
3116 	if ((wp->flags & PANE_STATUSREADY) && WIFEXITED(status))
3117 		format_add(ft, "pane_dead_status", "%d", WEXITSTATUS(status));
3118 	if (~wp->flags & PANE_EMPTY)
3119 		format_add(ft, "pane_dead", "%d", wp->fd == -1);
3120 	else
3121 		format_add(ft, "pane_dead", "0");
3122 	format_add(ft, "pane_last", "%d", wp == w->last);
3123 
3124 	if (server_check_marked() && marked_pane.wp == wp)
3125 		format_add(ft, "pane_marked", "1");
3126 	else
3127 		format_add(ft, "pane_marked", "0");
3128 	format_add(ft, "pane_marked_set", "%d", server_check_marked());
3129 
3130 	format_add(ft, "pane_left", "%u", wp->xoff);
3131 	format_add(ft, "pane_top", "%u", wp->yoff);
3132 	format_add(ft, "pane_right", "%u", wp->xoff + wp->sx - 1);
3133 	format_add(ft, "pane_bottom", "%u", wp->yoff + wp->sy - 1);
3134 	format_add(ft, "pane_at_left", "%d", wp->xoff == 0);
3135 	format_add_cb(ft, "pane_at_top", format_cb_pane_at_top);
3136 	format_add(ft, "pane_at_right", "%d", wp->xoff + wp->sx == w->sx);
3137 	format_add_cb(ft, "pane_at_bottom", format_cb_pane_at_bottom);
3138 
3139 	wme = TAILQ_FIRST(&wp->modes);
3140 	if (wme != NULL) {
3141 		format_add(ft, "pane_mode", "%s", wme->mode->name);
3142 		if (wme->mode->formats != NULL)
3143 			wme->mode->formats(wme, ft);
3144 	}
3145 	format_add_cb(ft, "pane_in_mode", format_cb_pane_in_mode);
3146 
3147 	format_add(ft, "pane_synchronized", "%d",
3148 	    !!options_get_number(wp->options, "synchronize-panes"));
3149 	if (wp->searchstr != NULL)
3150 		format_add(ft, "pane_search_string", "%s", wp->searchstr);
3151 
3152 	format_add(ft, "pane_tty", "%s", wp->tty);
3153 	format_add(ft, "pane_pid", "%ld", (long) wp->pid);
3154 	format_add_cb(ft, "pane_start_command", format_cb_start_command);
3155 	format_add_cb(ft, "pane_current_command", format_cb_current_command);
3156 	format_add_cb(ft, "pane_current_path", format_cb_current_path);
3157 
3158 	format_add(ft, "cursor_x", "%u", wp->base.cx);
3159 	format_add(ft, "cursor_y", "%u", wp->base.cy);
3160 	format_add_cb(ft, "cursor_character", format_cb_cursor_character);
3161 
3162 	format_add(ft, "scroll_region_upper", "%u", wp->base.rupper);
3163 	format_add(ft, "scroll_region_lower", "%u", wp->base.rlower);
3164 
3165 	format_add(ft, "alternate_on", "%d", wp->base.saved_grid != NULL);
3166 	if (wp->base.saved_cx != UINT_MAX)
3167 		format_add(ft, "alternate_saved_x", "%u", wp->base.saved_cx);
3168 	if (wp->base.saved_cy != UINT_MAX)
3169 		format_add(ft, "alternate_saved_y", "%u", wp->base.saved_cy);
3170 
3171 	format_add(ft, "cursor_flag", "%d",
3172 	    !!(wp->base.mode & MODE_CURSOR));
3173 	format_add(ft, "insert_flag", "%d",
3174 	    !!(wp->base.mode & MODE_INSERT));
3175 	format_add(ft, "keypad_cursor_flag", "%d",
3176 	    !!(wp->base.mode & MODE_KCURSOR));
3177 	format_add(ft, "keypad_flag", "%d",
3178 	    !!(wp->base.mode & MODE_KKEYPAD));
3179 	format_add(ft, "wrap_flag", "%d",
3180 	    !!(wp->base.mode & MODE_WRAP));
3181 	format_add(ft, "origin_flag", "%d",
3182 	    !!(wp->base.mode & MODE_ORIGIN));
3183 
3184 	format_add(ft, "mouse_any_flag", "%d",
3185 	    !!(wp->base.mode & ALL_MOUSE_MODES));
3186 	format_add(ft, "mouse_standard_flag", "%d",
3187 	    !!(wp->base.mode & MODE_MOUSE_STANDARD));
3188 	format_add(ft, "mouse_button_flag", "%d",
3189 	    !!(wp->base.mode & MODE_MOUSE_BUTTON));
3190 	format_add(ft, "mouse_all_flag", "%d",
3191 	    !!(wp->base.mode & MODE_MOUSE_ALL));
3192 	format_add(ft, "mouse_utf8_flag", "%d",
3193 	    !!(wp->base.mode & MODE_MOUSE_UTF8));
3194 	format_add(ft, "mouse_sgr_flag", "%d",
3195 	    !!(wp->base.mode & MODE_MOUSE_SGR));
3196 
3197 	format_add_cb(ft, "pane_tabs", format_cb_pane_tabs);
3198 }
3199 
3200 /* Set default format keys for paste buffer. */
3201 void
3202 format_defaults_paste_buffer(struct format_tree *ft, struct paste_buffer *pb)
3203 {
3204 	struct timeval	 tv;
3205 	size_t		 size;
3206 	char		*s;
3207 
3208 	timerclear(&tv);
3209 	tv.tv_sec = paste_buffer_created(pb);
3210 	paste_buffer_data(pb, &size);
3211 
3212 	format_add(ft, "buffer_size", "%zu", size);
3213 	format_add(ft, "buffer_name", "%s", paste_buffer_name(pb));
3214 	format_add_tv(ft, "buffer_created", &tv);
3215 
3216 	s = paste_make_sample(pb);
3217 	format_add(ft, "buffer_sample", "%s", s);
3218 	free(s);
3219 }
3220