xref: /openbsd-src/usr.bin/tmux/format.c (revision fc405d53b73a2d73393cb97f684863d17b583e38)
1 /* $OpenBSD: format.c,v 1.313 2023/05/19 07:46:34 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 <pwd.h>
28 #include <regex.h>
29 #include <stdarg.h>
30 #include <stdlib.h>
31 #include <string.h>
32 #include <time.h>
33 #include <unistd.h>
34 
35 #include "tmux.h"
36 
37 /*
38  * Build a list of key-value pairs and use them to expand #{key} entries in a
39  * string.
40  */
41 
42 struct format_expand_state;
43 
44 static char	*format_job_get(struct format_expand_state *, const char *);
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 int format_job_cmp(struct format_job *, struct format_job *);
73 static RB_HEAD(format_job_tree, format_job) format_jobs = RB_INITIALIZER();
74 RB_GENERATE_STATIC(format_job_tree, format_job, entry, format_job_cmp);
75 
76 /* Format job tree comparison function. */
77 static int
78 format_job_cmp(struct format_job *fj1, struct format_job *fj2)
79 {
80 	if (fj1->tag < fj2->tag)
81 		return (-1);
82 	if (fj1->tag > fj2->tag)
83 		return (1);
84 	return (strcmp(fj1->cmd, fj2->cmd));
85 }
86 
87 /* Format modifiers. */
88 #define FORMAT_TIMESTRING 0x1
89 #define FORMAT_BASENAME 0x2
90 #define FORMAT_DIRNAME 0x4
91 #define FORMAT_QUOTE_SHELL 0x8
92 #define FORMAT_LITERAL 0x10
93 #define FORMAT_EXPAND 0x20
94 #define FORMAT_EXPANDTIME 0x40
95 #define FORMAT_SESSIONS 0x80
96 #define FORMAT_WINDOWS 0x100
97 #define FORMAT_PANES 0x200
98 #define FORMAT_PRETTY 0x400
99 #define FORMAT_LENGTH 0x800
100 #define FORMAT_WIDTH 0x1000
101 #define FORMAT_QUOTE_STYLE 0x2000
102 #define FORMAT_WINDOW_NAME 0x4000
103 #define FORMAT_SESSION_NAME 0x8000
104 #define FORMAT_CHARACTER 0x10000
105 #define FORMAT_COLOUR 0x20000
106 #define FORMAT_CLIENTS 0x40000
107 
108 /* Limit on recursion. */
109 #define FORMAT_LOOP_LIMIT 100
110 
111 /* Format expand flags. */
112 #define FORMAT_EXPAND_TIME 0x1
113 #define FORMAT_EXPAND_NOJOBS 0x2
114 
115 /* Entry in format tree. */
116 struct format_entry {
117 	char			*key;
118 	char			*value;
119 	time_t			 time;
120 	format_cb		 cb;
121 	RB_ENTRY(format_entry)	 entry;
122 };
123 
124 /* Format type. */
125 enum format_type {
126 	FORMAT_TYPE_UNKNOWN,
127 	FORMAT_TYPE_SESSION,
128 	FORMAT_TYPE_WINDOW,
129 	FORMAT_TYPE_PANE
130 };
131 
132 struct format_tree {
133 	enum format_type	 type;
134 
135 	struct client		*c;
136 	struct session		*s;
137 	struct winlink		*wl;
138 	struct window		*w;
139 	struct window_pane	*wp;
140 	struct paste_buffer	*pb;
141 
142 	struct cmdq_item	*item;
143 	struct client		*client;
144 	int			 flags;
145 	u_int			 tag;
146 
147 	struct mouse_event	 m;
148 
149 	RB_HEAD(format_entry_tree, format_entry) tree;
150 };
151 static int format_entry_cmp(struct format_entry *, struct format_entry *);
152 RB_GENERATE_STATIC(format_entry_tree, format_entry, entry, format_entry_cmp);
153 
154 /* Format expand state. */
155 struct format_expand_state {
156 	struct format_tree	*ft;
157 	u_int			 loop;
158 	time_t			 time;
159 	struct tm		 tm;
160 	int			 flags;
161 };
162 
163 /* Format modifier. */
164 struct format_modifier {
165 	char	  modifier[3];
166 	u_int	  size;
167 
168 	char	**argv;
169 	int	  argc;
170 };
171 
172 /* Format entry tree comparison function. */
173 static int
174 format_entry_cmp(struct format_entry *fe1, struct format_entry *fe2)
175 {
176 	return (strcmp(fe1->key, fe2->key));
177 }
178 
179 /* Single-character uppercase aliases. */
180 static const char *format_upper[] = {
181 	NULL,		/* A */
182 	NULL,		/* B */
183 	NULL,		/* C */
184 	"pane_id",	/* D */
185 	NULL,		/* E */
186 	"window_flags",	/* F */
187 	NULL,		/* G */
188 	"host",		/* H */
189 	"window_index",	/* I */
190 	NULL,		/* J */
191 	NULL,		/* K */
192 	NULL,		/* L */
193 	NULL,		/* M */
194 	NULL,		/* N */
195 	NULL,		/* O */
196 	"pane_index",	/* P */
197 	NULL,		/* Q */
198 	NULL,		/* R */
199 	"session_name",	/* S */
200 	"pane_title",	/* T */
201 	NULL,		/* U */
202 	NULL,		/* V */
203 	"window_name",	/* W */
204 	NULL,		/* X */
205 	NULL,		/* Y */
206 	NULL 		/* Z */
207 };
208 
209 /* Single-character lowercase aliases. */
210 static const char *format_lower[] = {
211 	NULL,		/* a */
212 	NULL,		/* b */
213 	NULL,		/* c */
214 	NULL,		/* d */
215 	NULL,		/* e */
216 	NULL,		/* f */
217 	NULL,		/* g */
218 	"host_short",	/* h */
219 	NULL,		/* i */
220 	NULL,		/* j */
221 	NULL,		/* k */
222 	NULL,		/* l */
223 	NULL,		/* m */
224 	NULL,		/* n */
225 	NULL,		/* o */
226 	NULL,		/* p */
227 	NULL,		/* q */
228 	NULL,		/* r */
229 	NULL,		/* s */
230 	NULL,		/* t */
231 	NULL,		/* u */
232 	NULL,		/* v */
233 	NULL,		/* w */
234 	NULL,		/* x */
235 	NULL,		/* y */
236 	NULL		/* z */
237 };
238 
239 /* Is logging enabled? */
240 static inline int
241 format_logging(struct format_tree *ft)
242 {
243 	return (log_get_level() != 0 || (ft->flags & FORMAT_VERBOSE));
244 }
245 
246 /* Log a message if verbose. */
247 static void printflike(3, 4)
248 format_log1(struct format_expand_state *es, const char *from, const char *fmt,
249     ...)
250 {
251 	struct format_tree	*ft = es->ft;
252 	va_list			 ap;
253 	char			*s;
254 	static const char	 spaces[] = "          ";
255 
256 	if (!format_logging(ft))
257 		return;
258 
259 	va_start(ap, fmt);
260 	xvasprintf(&s, fmt, ap);
261 	va_end(ap);
262 
263 	log_debug("%s: %s", from, s);
264 	if (ft->item != NULL && (ft->flags & FORMAT_VERBOSE))
265 		cmdq_print(ft->item, "#%.*s%s", es->loop, spaces, s);
266 
267 	free(s);
268 }
269 #define format_log(es, fmt, ...) format_log1(es, __func__, fmt, ##__VA_ARGS__)
270 
271 /* Copy expand state. */
272 static void
273 format_copy_state(struct format_expand_state *to,
274     struct format_expand_state *from, int flags)
275 {
276 	to->ft = from->ft;
277 	to->loop = from->loop;
278 	to->time = from->time;
279 	memcpy(&to->tm, &from->tm, sizeof to->tm);
280 	to->flags = from->flags|flags;
281 }
282 
283 /* Format job update callback. */
284 static void
285 format_job_update(struct job *job)
286 {
287 	struct format_job	*fj = job_get_data(job);
288 	struct evbuffer		*evb = job_get_event(job)->input;
289 	char			*line = NULL, *next;
290 	time_t			 t;
291 
292 	while ((next = evbuffer_readline(evb)) != NULL) {
293 		free(line);
294 		line = next;
295 	}
296 	if (line == NULL)
297 		return;
298 	fj->updated = 1;
299 
300 	free(fj->out);
301 	fj->out = line;
302 
303 	log_debug("%s: %p %s: %s", __func__, fj, fj->cmd, fj->out);
304 
305 	t = time(NULL);
306 	if (fj->status && fj->last != t) {
307 		if (fj->client != NULL)
308 			server_status_client(fj->client);
309 		fj->last = t;
310 	}
311 }
312 
313 /* Format job complete callback. */
314 static void
315 format_job_complete(struct job *job)
316 {
317 	struct format_job	*fj = job_get_data(job);
318 	struct evbuffer		*evb = job_get_event(job)->input;
319 	char			*line, *buf;
320 	size_t			 len;
321 
322 	fj->job = NULL;
323 
324 	buf = NULL;
325 	if ((line = evbuffer_readline(evb)) == NULL) {
326 		len = EVBUFFER_LENGTH(evb);
327 		buf = xmalloc(len + 1);
328 		if (len != 0)
329 			memcpy(buf, EVBUFFER_DATA(evb), len);
330 		buf[len] = '\0';
331 	} else
332 		buf = line;
333 
334 	log_debug("%s: %p %s: %s", __func__, fj, fj->cmd, buf);
335 
336 	if (*buf != '\0' || !fj->updated) {
337 		free(fj->out);
338 		fj->out = buf;
339 	} else
340 		free(buf);
341 
342 	if (fj->status) {
343 		if (fj->client != NULL)
344 			server_status_client(fj->client);
345 		fj->status = 0;
346 	}
347 }
348 
349 /* Find a job. */
350 static char *
351 format_job_get(struct format_expand_state *es, const char *cmd)
352 {
353 	struct format_tree		*ft = es->ft;
354 	struct format_job_tree		*jobs;
355 	struct format_job		 fj0, *fj;
356 	time_t				 t;
357 	char				*expanded;
358 	int				 force;
359 	struct format_expand_state	 next;
360 
361 	if (ft->client == NULL)
362 		jobs = &format_jobs;
363 	else if (ft->client->jobs != NULL)
364 		jobs = ft->client->jobs;
365 	else {
366 		jobs = ft->client->jobs = xmalloc(sizeof *ft->client->jobs);
367 		RB_INIT(jobs);
368 	}
369 
370 	fj0.tag = ft->tag;
371 	fj0.cmd = cmd;
372 	if ((fj = RB_FIND(format_job_tree, jobs, &fj0)) == NULL) {
373 		fj = xcalloc(1, sizeof *fj);
374 		fj->client = ft->client;
375 		fj->tag = ft->tag;
376 		fj->cmd = xstrdup(cmd);
377 
378 		RB_INSERT(format_job_tree, jobs, fj);
379 	}
380 
381 	format_copy_state(&next, es, FORMAT_EXPAND_NOJOBS);
382 	next.flags &= ~FORMAT_EXPAND_TIME;
383 
384 	expanded = format_expand1(&next, cmd);
385 	if (fj->expanded == NULL || strcmp(expanded, fj->expanded) != 0) {
386 		free((void *)fj->expanded);
387 		fj->expanded = xstrdup(expanded);
388 		force = 1;
389 	} else
390 		force = (ft->flags & FORMAT_FORCE);
391 
392 	t = time(NULL);
393 	if (force && fj->job != NULL)
394 	       job_free(fj->job);
395 	if (force || (fj->job == NULL && fj->last != t)) {
396 		fj->job = job_run(expanded, 0, NULL, NULL, NULL,
397 		    server_client_get_cwd(ft->client, NULL), format_job_update,
398 		    format_job_complete, NULL, fj, JOB_NOWAIT, -1, -1);
399 		if (fj->job == NULL) {
400 			free(fj->out);
401 			xasprintf(&fj->out, "<'%s' didn't start>", fj->cmd);
402 		}
403 		fj->last = t;
404 		fj->updated = 0;
405 	} else if (fj->job != NULL && (t - fj->last) > 1 && fj->out == NULL)
406 		xasprintf(&fj->out, "<'%s' not ready>", fj->cmd);
407 	free(expanded);
408 
409 	if (ft->flags & FORMAT_STATUS)
410 		fj->status = 1;
411 	if (fj->out == NULL)
412 		return (xstrdup(""));
413 	return (format_expand1(&next, fj->out));
414 }
415 
416 /* Remove old jobs. */
417 static void
418 format_job_tidy(struct format_job_tree *jobs, int force)
419 {
420 	struct format_job	*fj, *fj1;
421 	time_t			 now;
422 
423 	now = time(NULL);
424 	RB_FOREACH_SAFE(fj, format_job_tree, jobs, fj1) {
425 		if (!force && (fj->last > now || now - fj->last < 3600))
426 			continue;
427 		RB_REMOVE(format_job_tree, jobs, fj);
428 
429 		log_debug("%s: %s", __func__, fj->cmd);
430 
431 		if (fj->job != NULL)
432 			job_free(fj->job);
433 
434 		free((void *)fj->expanded);
435 		free((void *)fj->cmd);
436 		free(fj->out);
437 
438 		free(fj);
439 	}
440 }
441 
442 /* Tidy old jobs for all clients. */
443 void
444 format_tidy_jobs(void)
445 {
446 	struct client	*c;
447 
448 	format_job_tidy(&format_jobs, 0);
449 	TAILQ_FOREACH(c, &clients, entry) {
450 		if (c->jobs != NULL)
451 			format_job_tidy(c->jobs, 0);
452 	}
453 }
454 
455 /* Remove old jobs for client. */
456 void
457 format_lost_client(struct client *c)
458 {
459 	if (c->jobs != NULL)
460 		format_job_tidy(c->jobs, 1);
461 	free(c->jobs);
462 }
463 
464 /* Wrapper for asprintf. */
465 static char * printflike(1, 2)
466 format_printf(const char *fmt, ...)
467 {
468 	va_list	 ap;
469 	char	*s;
470 
471 	va_start(ap, fmt);
472 	xvasprintf(&s, fmt, ap);
473 	va_end(ap);
474 	return (s);
475 }
476 
477 /* Callback for host. */
478 static void *
479 format_cb_host(__unused struct format_tree *ft)
480 {
481 	char host[HOST_NAME_MAX + 1];
482 
483 	if (gethostname(host, sizeof host) != 0)
484 		return (xstrdup(""));
485 	return (xstrdup(host));
486 }
487 
488 /* Callback for host_short. */
489 static void *
490 format_cb_host_short(__unused struct format_tree *ft)
491 {
492 	char host[HOST_NAME_MAX + 1], *cp;
493 
494 	if (gethostname(host, sizeof host) != 0)
495 		return (xstrdup(""));
496 	if ((cp = strchr(host, '.')) != NULL)
497 		*cp = '\0';
498 	return (xstrdup(host));
499 }
500 
501 /* Callback for pid. */
502 static void *
503 format_cb_pid(__unused struct format_tree *ft)
504 {
505 	char	*value;
506 
507 	xasprintf(&value, "%ld", (long)getpid());
508 	return (value);
509 }
510 
511 /* Callback for session_attached_list. */
512 static void *
513 format_cb_session_attached_list(struct format_tree *ft)
514 {
515 	struct session	*s = ft->s;
516 	struct client	*loop;
517 	struct evbuffer	*buffer;
518 	int		 size;
519 	char		*value = NULL;
520 
521 	if (s == NULL)
522 		return (NULL);
523 
524 	buffer = evbuffer_new();
525 	if (buffer == NULL)
526 		fatalx("out of memory");
527 
528 	TAILQ_FOREACH(loop, &clients, entry) {
529 		if (loop->session == s) {
530 			if (EVBUFFER_LENGTH(buffer) > 0)
531 				evbuffer_add(buffer, ",", 1);
532 			evbuffer_add_printf(buffer, "%s", loop->name);
533 		}
534 	}
535 
536 	if ((size = EVBUFFER_LENGTH(buffer)) != 0)
537 		xasprintf(&value, "%.*s", size, EVBUFFER_DATA(buffer));
538 	evbuffer_free(buffer);
539 	return (value);
540 }
541 
542 /* Callback for session_alerts. */
543 static void *
544 format_cb_session_alerts(struct format_tree *ft)
545 {
546 	struct session	*s = ft->s;
547 	struct winlink	*wl;
548 	char		 alerts[1024], tmp[16];
549 
550 	if (s == NULL)
551 		return (NULL);
552 
553 	*alerts = '\0';
554 	RB_FOREACH(wl, winlinks, &s->windows) {
555 		if ((wl->flags & WINLINK_ALERTFLAGS) == 0)
556 			continue;
557 		xsnprintf(tmp, sizeof tmp, "%u", wl->idx);
558 
559 		if (*alerts != '\0')
560 			strlcat(alerts, ",", sizeof alerts);
561 		strlcat(alerts, tmp, sizeof alerts);
562 		if (wl->flags & WINLINK_ACTIVITY)
563 			strlcat(alerts, "#", sizeof alerts);
564 		if (wl->flags & WINLINK_BELL)
565 			strlcat(alerts, "!", sizeof alerts);
566 		if (wl->flags & WINLINK_SILENCE)
567 			strlcat(alerts, "~", sizeof alerts);
568 	}
569 	return (xstrdup(alerts));
570 }
571 
572 /* Callback for session_stack. */
573 static void *
574 format_cb_session_stack(struct format_tree *ft)
575 {
576 	struct session	*s = ft->s;
577 	struct winlink	*wl;
578 	char		 result[1024], tmp[16];
579 
580 	if (s == NULL)
581 		return (NULL);
582 
583 	xsnprintf(result, sizeof result, "%u", s->curw->idx);
584 	TAILQ_FOREACH(wl, &s->lastw, sentry) {
585 		xsnprintf(tmp, sizeof tmp, "%u", wl->idx);
586 
587 		if (*result != '\0')
588 			strlcat(result, ",", sizeof result);
589 		strlcat(result, tmp, sizeof result);
590 	}
591 	return (xstrdup(result));
592 }
593 
594 /* Callback for window_stack_index. */
595 static void *
596 format_cb_window_stack_index(struct format_tree *ft)
597 {
598 	struct session	*s;
599 	struct winlink	*wl;
600 	u_int		 idx;
601 	char		*value = NULL;
602 
603 	if (ft->wl == NULL)
604 		return (NULL);
605 	s = ft->wl->session;
606 
607 	idx = 0;
608 	TAILQ_FOREACH(wl, &s->lastw, sentry) {
609 		idx++;
610 		if (wl == ft->wl)
611 			break;
612 	}
613 	if (wl == NULL)
614 		return (xstrdup("0"));
615 	xasprintf(&value, "%u", idx);
616 	return (value);
617 }
618 
619 /* Callback for window_linked_sessions_list. */
620 static void *
621 format_cb_window_linked_sessions_list(struct format_tree *ft)
622 {
623 	struct window	*w;
624 	struct winlink	*wl;
625 	struct evbuffer	*buffer;
626 	int		 size;
627 	char		*value = NULL;
628 
629 	if (ft->wl == NULL)
630 		return (NULL);
631 	w = ft->wl->window;
632 
633 	buffer = evbuffer_new();
634 	if (buffer == NULL)
635 		fatalx("out of memory");
636 
637 	TAILQ_FOREACH(wl, &w->winlinks, wentry) {
638 		if (EVBUFFER_LENGTH(buffer) > 0)
639 			evbuffer_add(buffer, ",", 1);
640 		evbuffer_add_printf(buffer, "%s", wl->session->name);
641 	}
642 
643 	if ((size = EVBUFFER_LENGTH(buffer)) != 0)
644 		xasprintf(&value, "%.*s", size, EVBUFFER_DATA(buffer));
645 	evbuffer_free(buffer);
646 	return (value);
647 }
648 
649 /* Callback for window_active_sessions. */
650 static void *
651 format_cb_window_active_sessions(struct format_tree *ft)
652 {
653 	struct window	*w;
654 	struct winlink	*wl;
655 	u_int		 n = 0;
656 	char		*value;
657 
658 	if (ft->wl == NULL)
659 		return (NULL);
660 	w = ft->wl->window;
661 
662 	TAILQ_FOREACH(wl, &w->winlinks, wentry) {
663 		if (wl->session->curw == wl)
664 			n++;
665 	}
666 
667 	xasprintf(&value, "%u", n);
668 	return (value);
669 }
670 
671 /* Callback for window_active_sessions_list. */
672 static void *
673 format_cb_window_active_sessions_list(struct format_tree *ft)
674 {
675 	struct window	*w;
676 	struct winlink	*wl;
677 	struct evbuffer	*buffer;
678 	int		 size;
679 	char		*value = NULL;
680 
681 	if (ft->wl == NULL)
682 		return (NULL);
683 	w = ft->wl->window;
684 
685 	buffer = evbuffer_new();
686 	if (buffer == NULL)
687 		fatalx("out of memory");
688 
689 	TAILQ_FOREACH(wl, &w->winlinks, wentry) {
690 		if (wl->session->curw == wl) {
691 			if (EVBUFFER_LENGTH(buffer) > 0)
692 				evbuffer_add(buffer, ",", 1);
693 			evbuffer_add_printf(buffer, "%s", wl->session->name);
694 		}
695 	}
696 
697 	if ((size = EVBUFFER_LENGTH(buffer)) != 0)
698 		xasprintf(&value, "%.*s", size, EVBUFFER_DATA(buffer));
699 	evbuffer_free(buffer);
700 	return (value);
701 }
702 
703 /* Callback for window_active_clients. */
704 static void *
705 format_cb_window_active_clients(struct format_tree *ft)
706 {
707 	struct window	*w;
708 	struct client	*loop;
709 	struct session	*client_session;
710 	u_int		 n = 0;
711 	char		*value;
712 
713 	if (ft->wl == NULL)
714 		return (NULL);
715 	w = ft->wl->window;
716 
717 	TAILQ_FOREACH(loop, &clients, entry) {
718 		client_session = loop->session;
719 		if (client_session == NULL)
720 			continue;
721 
722 		if (w == client_session->curw->window)
723 			n++;
724 	}
725 
726 	xasprintf(&value, "%u", n);
727 	return (value);
728 }
729 
730 /* Callback for window_active_clients_list. */
731 static void *
732 format_cb_window_active_clients_list(struct format_tree *ft)
733 {
734 	struct window	*w;
735 	struct client	*loop;
736 	struct session	*client_session;
737 	struct evbuffer	*buffer;
738 	int		 size;
739 	char		*value = NULL;
740 
741 	if (ft->wl == NULL)
742 		return (NULL);
743 	w = ft->wl->window;
744 
745 	buffer = evbuffer_new();
746 	if (buffer == NULL)
747 		fatalx("out of memory");
748 
749 	TAILQ_FOREACH(loop, &clients, entry) {
750 		client_session = loop->session;
751 		if (client_session == NULL)
752 			continue;
753 
754 		if (w == client_session->curw->window) {
755 			if (EVBUFFER_LENGTH(buffer) > 0)
756 				evbuffer_add(buffer, ",", 1);
757 			evbuffer_add_printf(buffer, "%s", loop->name);
758 		}
759 	}
760 
761 	if ((size = EVBUFFER_LENGTH(buffer)) != 0)
762 		xasprintf(&value, "%.*s", size, EVBUFFER_DATA(buffer));
763 	evbuffer_free(buffer);
764 	return (value);
765 }
766 
767 /* Callback for window_layout. */
768 static void *
769 format_cb_window_layout(struct format_tree *ft)
770 {
771 	struct window	*w = ft->w;
772 
773 	if (w == NULL)
774 		return (NULL);
775 
776 	if (w->saved_layout_root != NULL)
777 		return (layout_dump(w->saved_layout_root));
778 	return (layout_dump(w->layout_root));
779 }
780 
781 /* Callback for window_visible_layout. */
782 static void *
783 format_cb_window_visible_layout(struct format_tree *ft)
784 {
785 	struct window	*w = ft->w;
786 
787 	if (w == NULL)
788 		return (NULL);
789 
790 	return (layout_dump(w->layout_root));
791 }
792 
793 /* Callback for pane_start_command. */
794 static void *
795 format_cb_start_command(struct format_tree *ft)
796 {
797 	struct window_pane	*wp = ft->wp;
798 
799 	if (wp == NULL)
800 		return (NULL);
801 
802 	return (cmd_stringify_argv(wp->argc, wp->argv));
803 }
804 
805 /* Callback for pane_start_path. */
806 static void *
807 format_cb_start_path(struct format_tree *ft)
808 {
809 	struct window_pane	*wp = ft->wp;
810 
811 	if (wp == NULL)
812 		return (NULL);
813 
814 	if (wp->cwd == NULL)
815 		return (xstrdup(""));
816 	return (xstrdup(wp->cwd));
817 }
818 
819 /* Callback for pane_current_command. */
820 static void *
821 format_cb_current_command(struct format_tree *ft)
822 {
823 	struct window_pane	*wp = ft->wp;
824 	char			*cmd, *value;
825 
826 	if (wp == NULL || wp->shell == NULL)
827 		return (NULL);
828 
829 	cmd = get_proc_name(wp->fd, wp->tty);
830 	if (cmd == NULL || *cmd == '\0') {
831 		free(cmd);
832 		cmd = cmd_stringify_argv(wp->argc, wp->argv);
833 		if (cmd == NULL || *cmd == '\0') {
834 			free(cmd);
835 			cmd = xstrdup(wp->shell);
836 		}
837 	}
838 	value = parse_window_name(cmd);
839 	free(cmd);
840 	return (value);
841 }
842 
843 /* Callback for pane_current_path. */
844 static void *
845 format_cb_current_path(struct format_tree *ft)
846 {
847 	struct window_pane	*wp = ft->wp;
848 	char			*cwd;
849 
850 	if (wp == NULL)
851 		return (NULL);
852 
853 	cwd = get_proc_cwd(wp->fd);
854 	if (cwd == NULL)
855 		return (NULL);
856 	return (xstrdup(cwd));
857 }
858 
859 /* Callback for history_bytes. */
860 static void *
861 format_cb_history_bytes(struct format_tree *ft)
862 {
863 	struct window_pane	*wp = ft->wp;
864 	struct grid		*gd;
865 	struct grid_line	*gl;
866 	size_t		         size = 0;
867 	u_int			 i;
868 	char			*value;
869 
870 	if (wp == NULL)
871 		return (NULL);
872 	gd = wp->base.grid;
873 
874 	for (i = 0; i < gd->hsize + gd->sy; i++) {
875 		gl = grid_get_line(gd, i);
876 		size += gl->cellsize * sizeof *gl->celldata;
877 		size += gl->extdsize * sizeof *gl->extddata;
878 	}
879 	size += (gd->hsize + gd->sy) * sizeof *gl;
880 
881 	xasprintf(&value, "%zu", size);
882 	return (value);
883 }
884 
885 /* Callback for history_all_bytes. */
886 static void *
887 format_cb_history_all_bytes(struct format_tree *ft)
888 {
889 	struct window_pane	*wp = ft->wp;
890 	struct grid		*gd;
891 	struct grid_line	*gl;
892 	u_int			 i, lines, cells = 0, extended_cells = 0;
893 	char			*value;
894 
895 	if (wp == NULL)
896 		return (NULL);
897 	gd = wp->base.grid;
898 
899 	lines = gd->hsize + gd->sy;
900 	for (i = 0; i < lines; i++) {
901 		gl = grid_get_line(gd, i);
902 		cells += gl->cellsize;
903 		extended_cells += gl->extdsize;
904 	}
905 
906 	xasprintf(&value, "%u,%zu,%u,%zu,%u,%zu", lines,
907 	    lines * sizeof *gl, cells, cells * sizeof *gl->celldata,
908 	    extended_cells, extended_cells * sizeof *gl->extddata);
909 	return (value);
910 }
911 
912 /* Callback for pane_tabs. */
913 static void *
914 format_cb_pane_tabs(struct format_tree *ft)
915 {
916 	struct window_pane	*wp = ft->wp;
917 	struct evbuffer		*buffer;
918 	u_int			 i;
919 	int			 size;
920 	char			*value = NULL;
921 
922 	if (wp == NULL)
923 		return (NULL);
924 
925 	buffer = evbuffer_new();
926 	if (buffer == NULL)
927 		fatalx("out of memory");
928 	for (i = 0; i < wp->base.grid->sx; i++) {
929 		if (!bit_test(wp->base.tabs, i))
930 			continue;
931 
932 		if (EVBUFFER_LENGTH(buffer) > 0)
933 			evbuffer_add(buffer, ",", 1);
934 		evbuffer_add_printf(buffer, "%u", i);
935 	}
936 	if ((size = EVBUFFER_LENGTH(buffer)) != 0)
937 		xasprintf(&value, "%.*s", size, EVBUFFER_DATA(buffer));
938 	evbuffer_free(buffer);
939 	return (value);
940 }
941 
942 /* Callback for pane_fg. */
943 static void *
944 format_cb_pane_fg(struct format_tree *ft)
945 {
946 	struct window_pane	*wp = ft->wp;
947 	struct grid_cell	 gc;
948 
949 	if (wp == NULL)
950 		return (NULL);
951 
952 	tty_default_colours(&gc, wp);
953 	return (xstrdup(colour_tostring(gc.fg)));
954 }
955 
956 /* Callback for pane_bg. */
957 static void *
958 format_cb_pane_bg(struct format_tree *ft)
959 {
960 	struct window_pane	*wp = ft->wp;
961 	struct grid_cell	 gc;
962 
963 	if (wp == NULL)
964 		return (NULL);
965 
966 	tty_default_colours(&gc, wp);
967 	return (xstrdup(colour_tostring(gc.bg)));
968 }
969 
970 /* Callback for session_group_list. */
971 static void *
972 format_cb_session_group_list(struct format_tree *ft)
973 {
974 	struct session		*s = ft->s;
975 	struct session_group	*sg;
976 	struct session		*loop;
977 	struct evbuffer		*buffer;
978 	int			 size;
979 	char			*value = NULL;
980 
981 	if (s == NULL)
982 		return (NULL);
983 	sg = session_group_contains(s);
984 	if (sg == NULL)
985 		return (NULL);
986 
987 	buffer = evbuffer_new();
988 	if (buffer == NULL)
989 		fatalx("out of memory");
990 
991 	TAILQ_FOREACH(loop, &sg->sessions, gentry) {
992 		if (EVBUFFER_LENGTH(buffer) > 0)
993 			evbuffer_add(buffer, ",", 1);
994 		evbuffer_add_printf(buffer, "%s", loop->name);
995 	}
996 
997 	if ((size = EVBUFFER_LENGTH(buffer)) != 0)
998 		xasprintf(&value, "%.*s", size, EVBUFFER_DATA(buffer));
999 	evbuffer_free(buffer);
1000 	return (value);
1001 }
1002 
1003 /* Callback for session_group_attached_list. */
1004 static void *
1005 format_cb_session_group_attached_list(struct format_tree *ft)
1006 {
1007 	struct session		*s = ft->s, *client_session, *session_loop;
1008 	struct session_group	*sg;
1009 	struct client		*loop;
1010 	struct evbuffer		*buffer;
1011 	int			 size;
1012 	char			*value = NULL;
1013 
1014 	if (s == NULL)
1015 		return (NULL);
1016 	sg = session_group_contains(s);
1017 	if (sg == NULL)
1018 		return (NULL);
1019 
1020 	buffer = evbuffer_new();
1021 	if (buffer == NULL)
1022 		fatalx("out of memory");
1023 
1024 	TAILQ_FOREACH(loop, &clients, entry) {
1025 		client_session = loop->session;
1026 		if (client_session == NULL)
1027 			continue;
1028 		TAILQ_FOREACH(session_loop, &sg->sessions, gentry) {
1029 			if (session_loop == client_session){
1030 				if (EVBUFFER_LENGTH(buffer) > 0)
1031 					evbuffer_add(buffer, ",", 1);
1032 				evbuffer_add_printf(buffer, "%s", loop->name);
1033 			}
1034 		}
1035 	}
1036 
1037 	if ((size = EVBUFFER_LENGTH(buffer)) != 0)
1038 		xasprintf(&value, "%.*s", size, EVBUFFER_DATA(buffer));
1039 	evbuffer_free(buffer);
1040 	return (value);
1041 }
1042 
1043 /* Callback for pane_in_mode. */
1044 static void *
1045 format_cb_pane_in_mode(struct format_tree *ft)
1046 {
1047 	struct window_pane		*wp = ft->wp;
1048 	u_int				 n = 0;
1049 	struct window_mode_entry	*wme;
1050 	char				*value;
1051 
1052 	if (wp == NULL)
1053 		return (NULL);
1054 
1055 	TAILQ_FOREACH(wme, &wp->modes, entry)
1056 		n++;
1057 	xasprintf(&value, "%u", n);
1058 	return (value);
1059 }
1060 
1061 /* Callback for pane_at_top. */
1062 static void *
1063 format_cb_pane_at_top(struct format_tree *ft)
1064 {
1065 	struct window_pane	*wp = ft->wp;
1066 	struct window		*w;
1067 	int			 status, flag;
1068 	char			*value;
1069 
1070 	if (wp == NULL)
1071 		return (NULL);
1072 	w = wp->window;
1073 
1074 	status = options_get_number(w->options, "pane-border-status");
1075 	if (status == PANE_STATUS_TOP)
1076 		flag = (wp->yoff == 1);
1077 	else
1078 		flag = (wp->yoff == 0);
1079 	xasprintf(&value, "%d", flag);
1080 	return (value);
1081 }
1082 
1083 /* Callback for pane_at_bottom. */
1084 static void *
1085 format_cb_pane_at_bottom(struct format_tree *ft)
1086 {
1087 	struct window_pane	*wp = ft->wp;
1088 	struct window		*w;
1089 	int			 status, flag;
1090 	char			*value;
1091 
1092 	if (wp == NULL)
1093 		return (NULL);
1094 	w = wp->window;
1095 
1096 	status = options_get_number(w->options, "pane-border-status");
1097 	if (status == PANE_STATUS_BOTTOM)
1098 		flag = (wp->yoff + wp->sy == w->sy - 1);
1099 	else
1100 		flag = (wp->yoff + wp->sy == w->sy);
1101 	xasprintf(&value, "%d", flag);
1102 	return (value);
1103 }
1104 
1105 /* Callback for cursor_character. */
1106 static void *
1107 format_cb_cursor_character(struct format_tree *ft)
1108 {
1109 	struct window_pane	*wp = ft->wp;
1110 	struct grid_cell	 gc;
1111 	char			*value = NULL;
1112 
1113 	if (wp == NULL)
1114 		return (NULL);
1115 
1116 	grid_view_get_cell(wp->base.grid, wp->base.cx, wp->base.cy, &gc);
1117 	if (~gc.flags & GRID_FLAG_PADDING)
1118 		xasprintf(&value, "%.*s", (int)gc.data.size, gc.data.data);
1119 	return (value);
1120 }
1121 
1122 /* Callback for mouse_word. */
1123 static void *
1124 format_cb_mouse_word(struct format_tree *ft)
1125 {
1126 	struct window_pane	*wp;
1127 	struct grid		*gd;
1128 	u_int			 x, y;
1129 	char			*s;
1130 
1131 	if (!ft->m.valid)
1132 		return (NULL);
1133 	wp = cmd_mouse_pane(&ft->m, NULL, NULL);
1134 	if (wp == NULL)
1135 		return (NULL);
1136 	if (cmd_mouse_at(wp, &ft->m, &x, &y, 0) != 0)
1137 		return (NULL);
1138 
1139 	if (!TAILQ_EMPTY(&wp->modes)) {
1140 		if (TAILQ_FIRST(&wp->modes)->mode == &window_copy_mode ||
1141 		    TAILQ_FIRST(&wp->modes)->mode == &window_view_mode)
1142 			return (s = window_copy_get_word(wp, x, y));
1143 		return (NULL);
1144 	}
1145 	gd = wp->base.grid;
1146 	return (format_grid_word(gd, x, gd->hsize + y));
1147 }
1148 
1149 /* Callback for mouse_hyperlink. */
1150 static void *
1151 format_cb_mouse_hyperlink(struct format_tree *ft)
1152 {
1153 	struct window_pane	*wp;
1154 	struct grid		*gd;
1155 	u_int			 x, y;
1156 
1157 	if (!ft->m.valid)
1158 		return (NULL);
1159 	wp = cmd_mouse_pane(&ft->m, NULL, NULL);
1160 	if (wp == NULL)
1161 		return (NULL);
1162 	if (cmd_mouse_at(wp, &ft->m, &x, &y, 0) != 0)
1163 		return (NULL);
1164 	gd = wp->base.grid;
1165 	return (format_grid_hyperlink(gd, x, gd->hsize + y, wp->screen));
1166 }
1167 
1168 /* Callback for mouse_line. */
1169 static void *
1170 format_cb_mouse_line(struct format_tree *ft)
1171 {
1172 	struct window_pane	*wp;
1173 	struct grid		*gd;
1174 	u_int			 x, y;
1175 
1176 	if (!ft->m.valid)
1177 		return (NULL);
1178 	wp = cmd_mouse_pane(&ft->m, NULL, NULL);
1179 	if (wp == NULL)
1180 		return (NULL);
1181 	if (cmd_mouse_at(wp, &ft->m, &x, &y, 0) != 0)
1182 		return (NULL);
1183 
1184 	if (!TAILQ_EMPTY(&wp->modes)) {
1185 		if (TAILQ_FIRST(&wp->modes)->mode == &window_copy_mode ||
1186 		    TAILQ_FIRST(&wp->modes)->mode == &window_view_mode)
1187 			return (window_copy_get_line(wp, y));
1188 		return (NULL);
1189 	}
1190 	gd = wp->base.grid;
1191 	return (format_grid_line(gd, gd->hsize + y));
1192 }
1193 
1194 /* Callback for alternate_on. */
1195 static void *
1196 format_cb_alternate_on(struct format_tree *ft)
1197 {
1198 	if (ft->wp != NULL) {
1199 		if (ft->wp->base.saved_grid != NULL)
1200 			return (xstrdup("1"));
1201 		return (xstrdup("0"));
1202 	}
1203 	return (NULL);
1204 }
1205 
1206 /* Callback for alternate_saved_x. */
1207 static void *
1208 format_cb_alternate_saved_x(struct format_tree *ft)
1209 {
1210 	if (ft->wp != NULL)
1211 		return (format_printf("%u", ft->wp->base.saved_cx));
1212 	return (NULL);
1213 }
1214 
1215 /* Callback for alternate_saved_y. */
1216 static void *
1217 format_cb_alternate_saved_y(struct format_tree *ft)
1218 {
1219 	if (ft->wp != NULL)
1220 		return (format_printf("%u", ft->wp->base.saved_cy));
1221 	return (NULL);
1222 }
1223 
1224 /* Callback for buffer_name. */
1225 static void *
1226 format_cb_buffer_name(struct format_tree *ft)
1227 {
1228 	if (ft->pb != NULL)
1229 		return (xstrdup(paste_buffer_name(ft->pb)));
1230 	return (NULL);
1231 }
1232 
1233 /* Callback for buffer_sample. */
1234 static void *
1235 format_cb_buffer_sample(struct format_tree *ft)
1236 {
1237 	if (ft->pb != NULL)
1238 		return (paste_make_sample(ft->pb));
1239 	return (NULL);
1240 }
1241 
1242 /* Callback for buffer_size. */
1243 static void *
1244 format_cb_buffer_size(struct format_tree *ft)
1245 {
1246 	size_t	size;
1247 
1248 	if (ft->pb != NULL) {
1249 		paste_buffer_data(ft->pb, &size);
1250 		return (format_printf("%zu", size));
1251 	}
1252 	return (NULL);
1253 }
1254 
1255 /* Callback for client_cell_height. */
1256 static void *
1257 format_cb_client_cell_height(struct format_tree *ft)
1258 {
1259 	if (ft->c != NULL && (ft->c->tty.flags & TTY_STARTED))
1260 		return (format_printf("%u", ft->c->tty.ypixel));
1261 	return (NULL);
1262 }
1263 
1264 /* Callback for client_cell_width. */
1265 static void *
1266 format_cb_client_cell_width(struct format_tree *ft)
1267 {
1268 	if (ft->c != NULL && (ft->c->tty.flags & TTY_STARTED))
1269 		return (format_printf("%u", ft->c->tty.xpixel));
1270 	return (NULL);
1271 }
1272 
1273 /* Callback for client_control_mode. */
1274 static void *
1275 format_cb_client_control_mode(struct format_tree *ft)
1276 {
1277 	if (ft->c != NULL) {
1278 		if (ft->c->flags & CLIENT_CONTROL)
1279 			return (xstrdup("1"));
1280 		return (xstrdup("0"));
1281 	}
1282 	return (NULL);
1283 }
1284 
1285 /* Callback for client_discarded. */
1286 static void *
1287 format_cb_client_discarded(struct format_tree *ft)
1288 {
1289 	if (ft->c != NULL)
1290 		return (format_printf("%zu", ft->c->discarded));
1291 	return (NULL);
1292 }
1293 
1294 /* Callback for client_flags. */
1295 static void *
1296 format_cb_client_flags(struct format_tree *ft)
1297 {
1298 	if (ft->c != NULL)
1299 		return (xstrdup(server_client_get_flags(ft->c)));
1300 	return (NULL);
1301 }
1302 
1303 /* Callback for client_height. */
1304 static void *
1305 format_cb_client_height(struct format_tree *ft)
1306 {
1307 	if (ft->c != NULL && (ft->c->tty.flags & TTY_STARTED))
1308 		return (format_printf("%u", ft->c->tty.sy));
1309 	return (NULL);
1310 }
1311 
1312 /* Callback for client_key_table. */
1313 static void *
1314 format_cb_client_key_table(struct format_tree *ft)
1315 {
1316 	if (ft->c != NULL)
1317 		return (xstrdup(ft->c->keytable->name));
1318 	return (NULL);
1319 }
1320 
1321 /* Callback for client_last_session. */
1322 static void *
1323 format_cb_client_last_session(struct format_tree *ft)
1324 {
1325 	if (ft->c != NULL &&
1326 	    ft->c->last_session != NULL &&
1327 	    session_alive(ft->c->last_session))
1328 		return (xstrdup(ft->c->last_session->name));
1329 	return (NULL);
1330 }
1331 
1332 /* Callback for client_name. */
1333 static void *
1334 format_cb_client_name(struct format_tree *ft)
1335 {
1336 	if (ft->c != NULL)
1337 		return (xstrdup(ft->c->name));
1338 	return (NULL);
1339 }
1340 
1341 /* Callback for client_pid. */
1342 static void *
1343 format_cb_client_pid(struct format_tree *ft)
1344 {
1345 	if (ft->c != NULL)
1346 		return (format_printf("%ld", (long)ft->c->pid));
1347 	return (NULL);
1348 }
1349 
1350 /* Callback for client_prefix. */
1351 static void *
1352 format_cb_client_prefix(struct format_tree *ft)
1353 {
1354 	const char	*name;
1355 
1356 	if (ft->c != NULL) {
1357 		name = server_client_get_key_table(ft->c);
1358 		if (strcmp(ft->c->keytable->name, name) == 0)
1359 			return (xstrdup("0"));
1360 		return (xstrdup("1"));
1361 	}
1362 	return (NULL);
1363 }
1364 
1365 /* Callback for client_readonly. */
1366 static void *
1367 format_cb_client_readonly(struct format_tree *ft)
1368 {
1369 	if (ft->c != NULL) {
1370 		if (ft->c->flags & CLIENT_READONLY)
1371 			return (xstrdup("1"));
1372 		return (xstrdup("0"));
1373 	}
1374 	return (NULL);
1375 }
1376 
1377 /* Callback for client_session. */
1378 static void *
1379 format_cb_client_session(struct format_tree *ft)
1380 {
1381 	if (ft->c != NULL && ft->c->session != NULL)
1382 		return (xstrdup(ft->c->session->name));
1383 	return (NULL);
1384 }
1385 
1386 /* Callback for client_termfeatures. */
1387 static void *
1388 format_cb_client_termfeatures(struct format_tree *ft)
1389 {
1390 	if (ft->c != NULL)
1391 		return (xstrdup(tty_get_features(ft->c->term_features)));
1392 	return (NULL);
1393 }
1394 
1395 /* Callback for client_termname. */
1396 static void *
1397 format_cb_client_termname(struct format_tree *ft)
1398 {
1399 	if (ft->c != NULL)
1400 		return (xstrdup(ft->c->term_name));
1401 	return (NULL);
1402 }
1403 
1404 /* Callback for client_termtype. */
1405 static void *
1406 format_cb_client_termtype(struct format_tree *ft)
1407 {
1408 	if (ft->c != NULL) {
1409 		if (ft->c->term_type == NULL)
1410 			return (xstrdup(""));
1411 		return (xstrdup(ft->c->term_type));
1412 	}
1413 	return (NULL);
1414 }
1415 
1416 /* Callback for client_tty. */
1417 static void *
1418 format_cb_client_tty(struct format_tree *ft)
1419 {
1420 	if (ft->c != NULL)
1421 		return (xstrdup(ft->c->ttyname));
1422 	return (NULL);
1423 }
1424 
1425 /* Callback for client_uid. */
1426 static void *
1427 format_cb_client_uid(struct format_tree *ft)
1428 {
1429 	uid_t	uid;
1430 
1431 	if (ft->c != NULL) {
1432 		uid = proc_get_peer_uid(ft->c->peer);
1433 		if (uid != (uid_t)-1)
1434 			return (format_printf("%ld", (long)uid));
1435 	}
1436 	return (NULL);
1437 }
1438 
1439 /* Callback for client_user. */
1440 static void *
1441 format_cb_client_user(struct format_tree *ft)
1442 {
1443 	uid_t		 uid;
1444 	struct passwd	*pw;
1445 
1446 	if (ft->c != NULL) {
1447 		uid = proc_get_peer_uid(ft->c->peer);
1448 		if (uid != (uid_t)-1 && (pw = getpwuid(uid)) != NULL)
1449 			return (xstrdup(pw->pw_name));
1450 	}
1451 	return (NULL);
1452 }
1453 
1454 /* Callback for client_utf8. */
1455 static void *
1456 format_cb_client_utf8(struct format_tree *ft)
1457 {
1458 	if (ft->c != NULL) {
1459 		if (ft->c->flags & CLIENT_UTF8)
1460 			return (xstrdup("1"));
1461 		return (xstrdup("0"));
1462 	}
1463 	return (NULL);
1464 }
1465 
1466 /* Callback for client_width. */
1467 static void *
1468 format_cb_client_width(struct format_tree *ft)
1469 {
1470 	if (ft->c != NULL)
1471 		return (format_printf("%u", ft->c->tty.sx));
1472 	return (NULL);
1473 }
1474 
1475 /* Callback for client_written. */
1476 static void *
1477 format_cb_client_written(struct format_tree *ft)
1478 {
1479 	if (ft->c != NULL)
1480 		return (format_printf("%zu", ft->c->written));
1481 	return (NULL);
1482 }
1483 
1484 /* Callback for config_files. */
1485 static void *
1486 format_cb_config_files(__unused struct format_tree *ft)
1487 {
1488 	char	*s = NULL;
1489 	size_t	 slen = 0;
1490 	u_int	 i;
1491 	size_t	 n;
1492 
1493 	for (i = 0; i < cfg_nfiles; i++) {
1494 		n = strlen(cfg_files[i]) + 1;
1495 		s = xrealloc(s, slen + n + 1);
1496 		slen += xsnprintf(s + slen, n + 1, "%s,", cfg_files[i]);
1497 	}
1498 	if (s == NULL)
1499 		return (xstrdup(""));
1500 	s[slen - 1] = '\0';
1501 	return (s);
1502 }
1503 
1504 /* Callback for cursor_flag. */
1505 static void *
1506 format_cb_cursor_flag(struct format_tree *ft)
1507 {
1508 	if (ft->wp != NULL) {
1509 		if (ft->wp->base.mode & MODE_CURSOR)
1510 			return (xstrdup("1"));
1511 		return (xstrdup("0"));
1512 	}
1513 	return (NULL);
1514 }
1515 
1516 /* Callback for cursor_x. */
1517 static void *
1518 format_cb_cursor_x(struct format_tree *ft)
1519 {
1520 	if (ft->wp != NULL)
1521 		return (format_printf("%u", ft->wp->base.cx));
1522 	return (NULL);
1523 }
1524 
1525 /* Callback for cursor_y. */
1526 static void *
1527 format_cb_cursor_y(struct format_tree *ft)
1528 {
1529 	if (ft->wp != NULL)
1530 		return (format_printf("%u", ft->wp->base.cy));
1531 	return (NULL);
1532 }
1533 
1534 /* Callback for history_limit. */
1535 static void *
1536 format_cb_history_limit(struct format_tree *ft)
1537 {
1538 	if (ft->wp != NULL)
1539 		return (format_printf("%u", ft->wp->base.grid->hlimit));
1540 	return (NULL);
1541 }
1542 
1543 /* Callback for history_size. */
1544 static void *
1545 format_cb_history_size(struct format_tree *ft)
1546 {
1547 	if (ft->wp != NULL)
1548 		return (format_printf("%u", ft->wp->base.grid->hsize));
1549 	return (NULL);
1550 }
1551 
1552 /* Callback for insert_flag. */
1553 static void *
1554 format_cb_insert_flag(struct format_tree *ft)
1555 {
1556 	if (ft->wp != NULL) {
1557 		if (ft->wp->base.mode & MODE_INSERT)
1558 			return (xstrdup("1"));
1559 		return (xstrdup("0"));
1560 	}
1561 	return (NULL);
1562 }
1563 
1564 /* Callback for keypad_cursor_flag. */
1565 static void *
1566 format_cb_keypad_cursor_flag(struct format_tree *ft)
1567 {
1568 	if (ft->wp != NULL) {
1569 		if (ft->wp->base.mode & MODE_KCURSOR)
1570 			return (xstrdup("1"));
1571 		return (xstrdup("0"));
1572 	}
1573 	return (NULL);
1574 }
1575 
1576 /* Callback for keypad_flag. */
1577 static void *
1578 format_cb_keypad_flag(struct format_tree *ft)
1579 {
1580 	if (ft->wp != NULL) {
1581 		if (ft->wp->base.mode & MODE_KKEYPAD)
1582 			return (xstrdup("1"));
1583 		return (xstrdup("0"));
1584 	}
1585 	return (NULL);
1586 }
1587 
1588 /* Callback for mouse_all_flag. */
1589 static void *
1590 format_cb_mouse_all_flag(struct format_tree *ft)
1591 {
1592 	if (ft->wp != NULL) {
1593 		if (ft->wp->base.mode & MODE_MOUSE_ALL)
1594 			return (xstrdup("1"));
1595 		return (xstrdup("0"));
1596 	}
1597 	return (NULL);
1598 }
1599 
1600 /* Callback for mouse_any_flag. */
1601 static void *
1602 format_cb_mouse_any_flag(struct format_tree *ft)
1603 {
1604 	if (ft->wp != NULL) {
1605 		if (ft->wp->base.mode & ALL_MOUSE_MODES)
1606 			return (xstrdup("1"));
1607 		return (xstrdup("0"));
1608 	}
1609 	return (NULL);
1610 }
1611 
1612 /* Callback for mouse_button_flag. */
1613 static void *
1614 format_cb_mouse_button_flag(struct format_tree *ft)
1615 {
1616 	if (ft->wp != NULL) {
1617 		if (ft->wp->base.mode & MODE_MOUSE_BUTTON)
1618 			return (xstrdup("1"));
1619 		return (xstrdup("0"));
1620 	}
1621 	return (NULL);
1622 }
1623 
1624 /* Callback for mouse_pane. */
1625 static void *
1626 format_cb_mouse_pane(struct format_tree *ft)
1627 {
1628 	struct window_pane	*wp;
1629 
1630 	if (ft->m.valid) {
1631 		wp = cmd_mouse_pane(&ft->m, NULL, NULL);
1632 		if (wp != NULL)
1633 			return (format_printf("%%%u", wp->id));
1634 		return (NULL);
1635 	}
1636 	return (NULL);
1637 }
1638 
1639 /* Callback for mouse_sgr_flag. */
1640 static void *
1641 format_cb_mouse_sgr_flag(struct format_tree *ft)
1642 {
1643 	if (ft->wp != NULL) {
1644 		if (ft->wp->base.mode & MODE_MOUSE_SGR)
1645 			return (xstrdup("1"));
1646 		return (xstrdup("0"));
1647 	}
1648 	return (NULL);
1649 }
1650 
1651 /* Callback for mouse_standard_flag. */
1652 static void *
1653 format_cb_mouse_standard_flag(struct format_tree *ft)
1654 {
1655 	if (ft->wp != NULL) {
1656 		if (ft->wp->base.mode & MODE_MOUSE_STANDARD)
1657 			return (xstrdup("1"));
1658 		return (xstrdup("0"));
1659 	}
1660 	return (NULL);
1661 }
1662 
1663 /* Callback for mouse_utf8_flag. */
1664 static void *
1665 format_cb_mouse_utf8_flag(struct format_tree *ft)
1666 {
1667 	if (ft->wp != NULL) {
1668 		if (ft->wp->base.mode & MODE_MOUSE_UTF8)
1669 			return (xstrdup("1"));
1670 		return (xstrdup("0"));
1671 	}
1672 	return (NULL);
1673 }
1674 
1675 /* Callback for mouse_x. */
1676 static void *
1677 format_cb_mouse_x(struct format_tree *ft)
1678 {
1679 	struct window_pane	*wp;
1680 	u_int			 x, y;
1681 
1682 	if (!ft->m.valid)
1683 		return (NULL);
1684 	wp = cmd_mouse_pane(&ft->m, NULL, NULL);
1685 	if (wp != NULL && cmd_mouse_at(wp, &ft->m, &x, &y, 0) == 0)
1686 		return (format_printf("%u", x));
1687 	if (ft->c != NULL && (ft->c->tty.flags & TTY_STARTED)) {
1688 		if (ft->m.statusat == 0 && ft->m.y < ft->m.statuslines)
1689 			return (format_printf("%u", ft->m.x));
1690 		if (ft->m.statusat > 0 && ft->m.y >= (u_int)ft->m.statusat)
1691 			return (format_printf("%u", ft->m.x));
1692 	}
1693 	return (NULL);
1694 }
1695 
1696 /* Callback for mouse_y. */
1697 static void *
1698 format_cb_mouse_y(struct format_tree *ft)
1699 {
1700 	struct window_pane	*wp;
1701 	u_int			 x, y;
1702 
1703 	if (!ft->m.valid)
1704 		return (NULL);
1705 	wp = cmd_mouse_pane(&ft->m, NULL, NULL);
1706 	if (wp != NULL && cmd_mouse_at(wp, &ft->m, &x, &y, 0) == 0)
1707 		return (format_printf("%u", y));
1708 	if (ft->c != NULL && (ft->c->tty.flags & TTY_STARTED)) {
1709 		if (ft->m.statusat == 0 && ft->m.y < ft->m.statuslines)
1710 			return (format_printf("%u", ft->m.y));
1711 		if (ft->m.statusat > 0 && ft->m.y >= (u_int)ft->m.statusat)
1712 			return (format_printf("%u", ft->m.y - ft->m.statusat));
1713 	}
1714 	return (NULL);
1715 }
1716 
1717 /* Callback for next_session_id. */
1718 static void *
1719 format_cb_next_session_id(__unused struct format_tree *ft)
1720 {
1721 	return (format_printf("$%u", next_session_id));
1722 }
1723 
1724 /* Callback for origin_flag. */
1725 static void *
1726 format_cb_origin_flag(struct format_tree *ft)
1727 {
1728 	if (ft->wp != NULL) {
1729 		if (ft->wp->base.mode & MODE_ORIGIN)
1730 			return (xstrdup("1"));
1731 		return (xstrdup("0"));
1732 	}
1733 	return (NULL);
1734 }
1735 
1736 /* Callback for pane_active. */
1737 static void *
1738 format_cb_pane_active(struct format_tree *ft)
1739 {
1740 	if (ft->wp != NULL) {
1741 		if (ft->wp == ft->wp->window->active)
1742 			return (xstrdup("1"));
1743 		return (xstrdup("0"));
1744 	}
1745 	return (NULL);
1746 }
1747 
1748 /* Callback for pane_at_left. */
1749 static void *
1750 format_cb_pane_at_left(struct format_tree *ft)
1751 {
1752 	if (ft->wp != NULL) {
1753 		if (ft->wp->xoff == 0)
1754 			return (xstrdup("1"));
1755 		return (xstrdup("0"));
1756 	}
1757 	return (NULL);
1758 }
1759 
1760 /* Callback for pane_at_right. */
1761 static void *
1762 format_cb_pane_at_right(struct format_tree *ft)
1763 {
1764 	if (ft->wp != NULL) {
1765 		if (ft->wp->xoff + ft->wp->sx == ft->wp->window->sx)
1766 			return (xstrdup("1"));
1767 		return (xstrdup("0"));
1768 	}
1769 	return (NULL);
1770 }
1771 
1772 /* Callback for pane_bottom. */
1773 static void *
1774 format_cb_pane_bottom(struct format_tree *ft)
1775 {
1776 	if (ft->wp != NULL)
1777 		return (format_printf("%u", ft->wp->yoff + ft->wp->sy - 1));
1778 	return (NULL);
1779 }
1780 
1781 /* Callback for pane_dead. */
1782 static void *
1783 format_cb_pane_dead(struct format_tree *ft)
1784 {
1785 	if (ft->wp != NULL) {
1786 		if (ft->wp->fd == -1)
1787 			return (xstrdup("1"));
1788 		return (xstrdup("0"));
1789 	}
1790 	return (NULL);
1791 }
1792 
1793 /* Callback for pane_dead_signal. */
1794 static void *
1795 format_cb_pane_dead_signal(struct format_tree *ft)
1796 {
1797 	struct window_pane	*wp = ft->wp;
1798 	const char		*name;
1799 
1800 	if (wp != NULL) {
1801 		if ((wp->flags & PANE_STATUSREADY) && WIFSIGNALED(wp->status)) {
1802 			name = sig2name(WTERMSIG(wp->status));
1803 			return (format_printf("%s", name));
1804 		}
1805 		return (NULL);
1806 	}
1807 	return (NULL);
1808 }
1809 
1810 /* Callback for pane_dead_status. */
1811 static void *
1812 format_cb_pane_dead_status(struct format_tree *ft)
1813 {
1814 	struct window_pane	*wp = ft->wp;
1815 
1816 	if (wp != NULL) {
1817 		if ((wp->flags & PANE_STATUSREADY) && WIFEXITED(wp->status))
1818 			return (format_printf("%d", WEXITSTATUS(wp->status)));
1819 		return (NULL);
1820 	}
1821 	return (NULL);
1822 }
1823 
1824 /* Callback for pane_dead_time. */
1825 static void *
1826 format_cb_pane_dead_time(struct format_tree *ft)
1827 {
1828 	struct window_pane	*wp = ft->wp;
1829 
1830 	if (wp != NULL) {
1831 		if (wp->flags & PANE_STATUSDRAWN)
1832 			return (&wp->dead_time);
1833 		return (NULL);
1834 	}
1835 	return (NULL);
1836 }
1837 
1838 /* Callback for pane_format. */
1839 static void *
1840 format_cb_pane_format(struct format_tree *ft)
1841 {
1842 	if (ft->type == FORMAT_TYPE_PANE)
1843 		return (xstrdup("1"));
1844 	return (xstrdup("0"));
1845 }
1846 
1847 /* Callback for pane_height. */
1848 static void *
1849 format_cb_pane_height(struct format_tree *ft)
1850 {
1851 	if (ft->wp != NULL)
1852 		return (format_printf("%u", ft->wp->sy));
1853 	return (NULL);
1854 }
1855 
1856 /* Callback for pane_id. */
1857 static void *
1858 format_cb_pane_id(struct format_tree *ft)
1859 {
1860 	if (ft->wp != NULL)
1861 		return (format_printf("%%%u", ft->wp->id));
1862 	return (NULL);
1863 }
1864 
1865 /* Callback for pane_index. */
1866 static void *
1867 format_cb_pane_index(struct format_tree *ft)
1868 {
1869 	u_int	idx;
1870 
1871 	if (ft->wp != NULL && window_pane_index(ft->wp, &idx) == 0)
1872 		return (format_printf("%u", idx));
1873 	return (NULL);
1874 }
1875 
1876 /* Callback for pane_input_off. */
1877 static void *
1878 format_cb_pane_input_off(struct format_tree *ft)
1879 {
1880 	if (ft->wp != NULL) {
1881 		if (ft->wp->flags & PANE_INPUTOFF)
1882 			return (xstrdup("1"));
1883 		return (xstrdup("0"));
1884 	}
1885 	return (NULL);
1886 }
1887 
1888 /* Callback for pane_unseen_changes. */
1889 static void *
1890 format_cb_pane_unseen_changes(struct format_tree *ft)
1891 {
1892 	if (ft->wp != NULL) {
1893 		if (ft->wp->flags & PANE_UNSEENCHANGES)
1894 			return (xstrdup("1"));
1895 		return (xstrdup("0"));
1896 	}
1897 	return (NULL);
1898 }
1899 
1900 /* Callback for pane_last. */
1901 static void *
1902 format_cb_pane_last(struct format_tree *ft)
1903 {
1904 	if (ft->wp != NULL) {
1905 		if (ft->wp == ft->wp->window->last)
1906 			return (xstrdup("1"));
1907 		return (xstrdup("0"));
1908 	}
1909 	return (NULL);
1910 }
1911 
1912 /* Callback for pane_left. */
1913 static void *
1914 format_cb_pane_left(struct format_tree *ft)
1915 {
1916 	if (ft->wp != NULL)
1917 		return (format_printf("%u", ft->wp->xoff));
1918 	return (NULL);
1919 }
1920 
1921 /* Callback for pane_marked. */
1922 static void *
1923 format_cb_pane_marked(struct format_tree *ft)
1924 {
1925 	if (ft->wp != NULL) {
1926 		if (server_check_marked() && marked_pane.wp == ft->wp)
1927 			return (xstrdup("1"));
1928 		return (xstrdup("0"));
1929 	}
1930 	return (NULL);
1931 }
1932 
1933 /* Callback for pane_marked_set. */
1934 static void *
1935 format_cb_pane_marked_set(struct format_tree *ft)
1936 {
1937 	if (ft->wp != NULL) {
1938 		if (server_check_marked())
1939 			return (xstrdup("1"));
1940 		return (xstrdup("0"));
1941 	}
1942 	return (NULL);
1943 }
1944 
1945 /* Callback for pane_mode. */
1946 static void *
1947 format_cb_pane_mode(struct format_tree *ft)
1948 {
1949 	struct window_mode_entry	*wme;
1950 
1951 	if (ft->wp != NULL) {
1952 		wme = TAILQ_FIRST(&ft->wp->modes);
1953 		if (wme != NULL)
1954 			return (xstrdup(wme->mode->name));
1955 		return (NULL);
1956 	}
1957 	return (NULL);
1958 }
1959 
1960 /* Callback for pane_path. */
1961 static void *
1962 format_cb_pane_path(struct format_tree *ft)
1963 {
1964 	if (ft->wp != NULL) {
1965 		if (ft->wp->base.path == NULL)
1966 			return (xstrdup(""));
1967 		return (xstrdup(ft->wp->base.path));
1968 	}
1969 	return (NULL);
1970 }
1971 
1972 /* Callback for pane_pid. */
1973 static void *
1974 format_cb_pane_pid(struct format_tree *ft)
1975 {
1976 	if (ft->wp != NULL)
1977 		return (format_printf("%ld", (long)ft->wp->pid));
1978 	return (NULL);
1979 }
1980 
1981 /* Callback for pane_pipe. */
1982 static void *
1983 format_cb_pane_pipe(struct format_tree *ft)
1984 {
1985 	if (ft->wp != NULL) {
1986 		if (ft->wp->pipe_fd != -1)
1987 			return (xstrdup("1"));
1988 		return (xstrdup("0"));
1989 	}
1990 	return (NULL);
1991 }
1992 
1993 /* Callback for pane_right. */
1994 static void *
1995 format_cb_pane_right(struct format_tree *ft)
1996 {
1997 	if (ft->wp != NULL)
1998 		return (format_printf("%u", ft->wp->xoff + ft->wp->sx - 1));
1999 	return (NULL);
2000 }
2001 
2002 /* Callback for pane_search_string. */
2003 static void *
2004 format_cb_pane_search_string(struct format_tree *ft)
2005 {
2006 	if (ft->wp != NULL) {
2007 		if (ft->wp->searchstr == NULL)
2008 			return (xstrdup(""));
2009 		return (xstrdup(ft->wp->searchstr));
2010 	}
2011 	return (NULL);
2012 }
2013 
2014 /* Callback for pane_synchronized. */
2015 static void *
2016 format_cb_pane_synchronized(struct format_tree *ft)
2017 {
2018 	if (ft->wp != NULL) {
2019 		if (options_get_number(ft->wp->options, "synchronize-panes"))
2020 			return (xstrdup("1"));
2021 		return (xstrdup("0"));
2022 	}
2023 	return (NULL);
2024 }
2025 
2026 /* Callback for pane_title. */
2027 static void *
2028 format_cb_pane_title(struct format_tree *ft)
2029 {
2030 	if (ft->wp != NULL)
2031 		return (xstrdup(ft->wp->base.title));
2032 	return (NULL);
2033 }
2034 
2035 /* Callback for pane_top. */
2036 static void *
2037 format_cb_pane_top(struct format_tree *ft)
2038 {
2039 	if (ft->wp != NULL)
2040 		return (format_printf("%u", ft->wp->yoff));
2041 	return (NULL);
2042 }
2043 
2044 /* Callback for pane_tty. */
2045 static void *
2046 format_cb_pane_tty(struct format_tree *ft)
2047 {
2048 	if (ft->wp != NULL)
2049 		return (xstrdup(ft->wp->tty));
2050 	return (NULL);
2051 }
2052 
2053 /* Callback for pane_width. */
2054 static void *
2055 format_cb_pane_width(struct format_tree *ft)
2056 {
2057 	if (ft->wp != NULL)
2058 		return (format_printf("%u", ft->wp->sx));
2059 	return (NULL);
2060 }
2061 
2062 /* Callback for scroll_region_lower. */
2063 static void *
2064 format_cb_scroll_region_lower(struct format_tree *ft)
2065 {
2066 	if (ft->wp != NULL)
2067 		return (format_printf("%u", ft->wp->base.rlower));
2068 	return (NULL);
2069 }
2070 
2071 /* Callback for scroll_region_upper. */
2072 static void *
2073 format_cb_scroll_region_upper(struct format_tree *ft)
2074 {
2075 	if (ft->wp != NULL)
2076 		return (format_printf("%u", ft->wp->base.rupper));
2077 	return (NULL);
2078 }
2079 
2080 /* Callback for server_sessions. */
2081 static void *
2082 format_cb_server_sessions(__unused struct format_tree *ft)
2083 {
2084 	struct session	*s;
2085 	u_int		 n = 0;
2086 
2087 	RB_FOREACH(s, sessions, &sessions)
2088 		n++;
2089 	return (format_printf("%u", n));
2090 }
2091 
2092 /* Callback for session_attached. */
2093 static void *
2094 format_cb_session_attached(struct format_tree *ft)
2095 {
2096 	if (ft->s != NULL)
2097 		return (format_printf("%u", ft->s->attached));
2098 	return (NULL);
2099 }
2100 
2101 /* Callback for session_format. */
2102 static void *
2103 format_cb_session_format(struct format_tree *ft)
2104 {
2105 	if (ft->type == FORMAT_TYPE_SESSION)
2106 		return (xstrdup("1"));
2107 	return (xstrdup("0"));
2108 }
2109 
2110 /* Callback for session_group. */
2111 static void *
2112 format_cb_session_group(struct format_tree *ft)
2113 {
2114 	struct session_group	*sg;
2115 
2116 	if (ft->s != NULL && (sg = session_group_contains(ft->s)) != NULL)
2117 		return (xstrdup(sg->name));
2118 	return (NULL);
2119 }
2120 
2121 /* Callback for session_group_attached. */
2122 static void *
2123 format_cb_session_group_attached(struct format_tree *ft)
2124 {
2125 	struct session_group	*sg;
2126 
2127 	if (ft->s != NULL && (sg = session_group_contains(ft->s)) != NULL)
2128 		return (format_printf("%u", session_group_attached_count (sg)));
2129 	return (NULL);
2130 }
2131 
2132 /* Callback for session_group_many_attached. */
2133 static void *
2134 format_cb_session_group_many_attached(struct format_tree *ft)
2135 {
2136 	struct session_group	*sg;
2137 
2138 	if (ft->s != NULL && (sg = session_group_contains(ft->s)) != NULL) {
2139 		if (session_group_attached_count (sg) > 1)
2140 			return (xstrdup("1"));
2141 		return (xstrdup("0"));
2142 	}
2143 	return (NULL);
2144 }
2145 
2146 /* Callback for session_group_size. */
2147 static void *
2148 format_cb_session_group_size(struct format_tree *ft)
2149 {
2150 	struct session_group	*sg;
2151 
2152 	if (ft->s != NULL && (sg = session_group_contains(ft->s)) != NULL)
2153 		return (format_printf("%u", session_group_count (sg)));
2154 	return (NULL);
2155 }
2156 
2157 /* Callback for session_grouped. */
2158 static void *
2159 format_cb_session_grouped(struct format_tree *ft)
2160 {
2161 	if (ft->s != NULL) {
2162 		if (session_group_contains(ft->s) != NULL)
2163 			return (xstrdup("1"));
2164 		return (xstrdup("0"));
2165 	}
2166 	return (NULL);
2167 }
2168 
2169 /* Callback for session_id. */
2170 static void *
2171 format_cb_session_id(struct format_tree *ft)
2172 {
2173 	if (ft->s != NULL)
2174 		return (format_printf("$%u", ft->s->id));
2175 	return (NULL);
2176 }
2177 
2178 /* Callback for session_many_attached. */
2179 static void *
2180 format_cb_session_many_attached(struct format_tree *ft)
2181 {
2182 	if (ft->s != NULL) {
2183 		if (ft->s->attached > 1)
2184 			return (xstrdup("1"));
2185 		return (xstrdup("0"));
2186 	}
2187 	return (NULL);
2188 }
2189 
2190 /* Callback for session_marked. */
2191 static void *
2192 format_cb_session_marked(struct format_tree *ft)
2193 {
2194 	if (ft->s != NULL) {
2195 		if (server_check_marked() && marked_pane.s == ft->s)
2196 			return (xstrdup("1"));
2197 		return (xstrdup("0"));
2198 	}
2199 	return (NULL);
2200 }
2201 
2202 /* Callback for session_name. */
2203 static void *
2204 format_cb_session_name(struct format_tree *ft)
2205 {
2206 	if (ft->s != NULL)
2207 		return (xstrdup(ft->s->name));
2208 	return (NULL);
2209 }
2210 
2211 /* Callback for session_path. */
2212 static void *
2213 format_cb_session_path(struct format_tree *ft)
2214 {
2215 	if (ft->s != NULL)
2216 		return (xstrdup(ft->s->cwd));
2217 	return (NULL);
2218 }
2219 
2220 /* Callback for session_windows. */
2221 static void *
2222 format_cb_session_windows(struct format_tree *ft)
2223 {
2224 	if (ft->s != NULL)
2225 		return (format_printf("%u", winlink_count(&ft->s->windows)));
2226 	return (NULL);
2227 }
2228 
2229 /* Callback for socket_path. */
2230 static void *
2231 format_cb_socket_path(__unused struct format_tree *ft)
2232 {
2233 	return (xstrdup(socket_path));
2234 }
2235 
2236 /* Callback for version. */
2237 static void *
2238 format_cb_version(__unused struct format_tree *ft)
2239 {
2240 	return (xstrdup(getversion()));
2241 }
2242 
2243 /* Callback for active_window_index. */
2244 static void *
2245 format_cb_active_window_index(struct format_tree *ft)
2246 {
2247 	if (ft->s != NULL)
2248 		return (format_printf("%u", ft->s->curw->idx));
2249 	return (NULL);
2250 }
2251 
2252 /* Callback for last_window_index. */
2253 static void *
2254 format_cb_last_window_index(struct format_tree *ft)
2255 {
2256 	struct winlink	*wl;
2257 
2258 	if (ft->s != NULL) {
2259 		wl = RB_MAX(winlinks, &ft->s->windows);
2260 		return (format_printf("%u", wl->idx));
2261 	}
2262 	return (NULL);
2263 }
2264 
2265 /* Callback for window_active. */
2266 static void *
2267 format_cb_window_active(struct format_tree *ft)
2268 {
2269 	if (ft->wl != NULL) {
2270 		if (ft->wl == ft->wl->session->curw)
2271 			return (xstrdup("1"));
2272 		return (xstrdup("0"));
2273 	}
2274 	return (NULL);
2275 }
2276 
2277 /* Callback for window_activity_flag. */
2278 static void *
2279 format_cb_window_activity_flag(struct format_tree *ft)
2280 {
2281 	if (ft->wl != NULL) {
2282 		if (ft->wl->flags & WINLINK_ACTIVITY)
2283 			return (xstrdup("1"));
2284 		return (xstrdup("0"));
2285 	}
2286 	return (NULL);
2287 }
2288 
2289 /* Callback for window_bell_flag. */
2290 static void *
2291 format_cb_window_bell_flag(struct format_tree *ft)
2292 {
2293 	if (ft->wl != NULL) {
2294 		if (ft->wl->flags & WINLINK_BELL)
2295 			return (xstrdup("1"));
2296 		return (xstrdup("0"));
2297 	}
2298 	return (NULL);
2299 }
2300 
2301 /* Callback for window_bigger. */
2302 static void *
2303 format_cb_window_bigger(struct format_tree *ft)
2304 {
2305 	u_int	ox, oy, sx, sy;
2306 
2307 	if (ft->c != NULL) {
2308 		if (tty_window_offset(&ft->c->tty, &ox, &oy, &sx, &sy))
2309 			return (xstrdup("1"));
2310 		return (xstrdup("0"));
2311 	}
2312 	return (NULL);
2313 }
2314 
2315 /* Callback for window_cell_height. */
2316 static void *
2317 format_cb_window_cell_height(struct format_tree *ft)
2318 {
2319 	if (ft->w != NULL)
2320 		return (format_printf("%u", ft->w->ypixel));
2321 	return (NULL);
2322 }
2323 
2324 /* Callback for window_cell_width. */
2325 static void *
2326 format_cb_window_cell_width(struct format_tree *ft)
2327 {
2328 	if (ft->w != NULL)
2329 		return (format_printf("%u", ft->w->xpixel));
2330 	return (NULL);
2331 }
2332 
2333 /* Callback for window_end_flag. */
2334 static void *
2335 format_cb_window_end_flag(struct format_tree *ft)
2336 {
2337 	if (ft->wl != NULL) {
2338 		if (ft->wl == RB_MAX(winlinks, &ft->wl->session->windows))
2339 			return (xstrdup("1"));
2340 		return (xstrdup("0"));
2341 	}
2342 	return (NULL);
2343 }
2344 
2345 /* Callback for window_flags. */
2346 static void *
2347 format_cb_window_flags(struct format_tree *ft)
2348 {
2349 	if (ft->wl != NULL)
2350 		return (xstrdup(window_printable_flags(ft->wl, 1)));
2351 	return (NULL);
2352 }
2353 
2354 /* Callback for window_format. */
2355 static void *
2356 format_cb_window_format(struct format_tree *ft)
2357 {
2358 	if (ft->type == FORMAT_TYPE_WINDOW)
2359 		return (xstrdup("1"));
2360 	return (xstrdup("0"));
2361 }
2362 
2363 /* Callback for window_height. */
2364 static void *
2365 format_cb_window_height(struct format_tree *ft)
2366 {
2367 	if (ft->w != NULL)
2368 		return (format_printf("%u", ft->w->sy));
2369 	return (NULL);
2370 }
2371 
2372 /* Callback for window_id. */
2373 static void *
2374 format_cb_window_id(struct format_tree *ft)
2375 {
2376 	if (ft->w != NULL)
2377 		return (format_printf("@%u", ft->w->id));
2378 	return (NULL);
2379 }
2380 
2381 /* Callback for window_index. */
2382 static void *
2383 format_cb_window_index(struct format_tree *ft)
2384 {
2385 	if (ft->wl != NULL)
2386 		return (format_printf("%d", ft->wl->idx));
2387 	return (NULL);
2388 }
2389 
2390 /* Callback for window_last_flag. */
2391 static void *
2392 format_cb_window_last_flag(struct format_tree *ft)
2393 {
2394 	if (ft->wl != NULL) {
2395 		if (ft->wl == TAILQ_FIRST(&ft->wl->session->lastw))
2396 			return (xstrdup("1"));
2397 		return (xstrdup("0"));
2398 	}
2399 	return (NULL);
2400 }
2401 
2402 /* Callback for window_linked. */
2403 static void *
2404 format_cb_window_linked(struct format_tree *ft)
2405 {
2406 	if (ft->wl != NULL) {
2407 		if (session_is_linked(ft->wl->session, ft->wl->window))
2408 			return (xstrdup("1"));
2409 		return (xstrdup("0"));
2410 	}
2411 	return (NULL);
2412 }
2413 
2414 /* Callback for window_linked_sessions. */
2415 static void *
2416 format_cb_window_linked_sessions(struct format_tree *ft)
2417 {
2418 	if (ft->wl != NULL)
2419 		return (format_printf("%u", ft->wl->window->references));
2420 	return (NULL);
2421 }
2422 
2423 /* Callback for window_marked_flag. */
2424 static void *
2425 format_cb_window_marked_flag(struct format_tree *ft)
2426 {
2427 	if (ft->wl != NULL) {
2428 		if (server_check_marked() && marked_pane.wl == ft->wl)
2429 			return (xstrdup("1"));
2430 		return (xstrdup("0"));
2431 	}
2432 	return (NULL);
2433 }
2434 
2435 /* Callback for window_name. */
2436 static void *
2437 format_cb_window_name(struct format_tree *ft)
2438 {
2439 	if (ft->w != NULL)
2440 		return (format_printf("%s", ft->w->name));
2441 	return (NULL);
2442 }
2443 
2444 /* Callback for window_offset_x. */
2445 static void *
2446 format_cb_window_offset_x(struct format_tree *ft)
2447 {
2448 	u_int	ox, oy, sx, sy;
2449 
2450 	if (ft->c != NULL) {
2451 		if (tty_window_offset(&ft->c->tty, &ox, &oy, &sx, &sy))
2452 			return (format_printf("%u", ox));
2453 		return (NULL);
2454 	}
2455 	return (NULL);
2456 }
2457 
2458 /* Callback for window_offset_y. */
2459 static void *
2460 format_cb_window_offset_y(struct format_tree *ft)
2461 {
2462 	u_int	ox, oy, sx, sy;
2463 
2464 	if (ft->c != NULL) {
2465 		if (tty_window_offset(&ft->c->tty, &ox, &oy, &sx, &sy))
2466 			return (format_printf("%u", oy));
2467 		return (NULL);
2468 	}
2469 	return (NULL);
2470 }
2471 
2472 /* Callback for window_panes. */
2473 static void *
2474 format_cb_window_panes(struct format_tree *ft)
2475 {
2476 	if (ft->w != NULL)
2477 		return (format_printf("%u", window_count_panes(ft->w)));
2478 	return (NULL);
2479 }
2480 
2481 /* Callback for window_raw_flags. */
2482 static void *
2483 format_cb_window_raw_flags(struct format_tree *ft)
2484 {
2485 	if (ft->wl != NULL)
2486 		return (xstrdup(window_printable_flags(ft->wl, 0)));
2487 	return (NULL);
2488 }
2489 
2490 /* Callback for window_silence_flag. */
2491 static void *
2492 format_cb_window_silence_flag(struct format_tree *ft)
2493 {
2494 	if (ft->wl != NULL) {
2495 		if (ft->wl->flags & WINLINK_SILENCE)
2496 			return (xstrdup("1"));
2497 		return (xstrdup("0"));
2498 	}
2499 	return (NULL);
2500 }
2501 
2502 /* Callback for window_start_flag. */
2503 static void *
2504 format_cb_window_start_flag(struct format_tree *ft)
2505 {
2506 	if (ft->wl != NULL) {
2507 		if (ft->wl == RB_MIN(winlinks, &ft->wl->session->windows))
2508 			return (xstrdup("1"));
2509 		return (xstrdup("0"));
2510 	}
2511 	return (NULL);
2512 }
2513 
2514 /* Callback for window_width. */
2515 static void *
2516 format_cb_window_width(struct format_tree *ft)
2517 {
2518 	if (ft->w != NULL)
2519 		return (format_printf("%u", ft->w->sx));
2520 	return (NULL);
2521 }
2522 
2523 /* Callback for window_zoomed_flag. */
2524 static void *
2525 format_cb_window_zoomed_flag(struct format_tree *ft)
2526 {
2527 	if (ft->w != NULL) {
2528 		if (ft->w->flags & WINDOW_ZOOMED)
2529 			return (xstrdup("1"));
2530 		return (xstrdup("0"));
2531 	}
2532 	return (NULL);
2533 }
2534 
2535 /* Callback for wrap_flag. */
2536 static void *
2537 format_cb_wrap_flag(struct format_tree *ft)
2538 {
2539 	if (ft->wp != NULL) {
2540 		if (ft->wp->base.mode & MODE_WRAP)
2541 			return (xstrdup("1"));
2542 		return (xstrdup("0"));
2543 	}
2544 	return (NULL);
2545 }
2546 
2547 /* Callback for buffer_created. */
2548 static void *
2549 format_cb_buffer_created(struct format_tree *ft)
2550 {
2551 	static struct timeval	 tv;
2552 
2553 	if (ft->pb != NULL) {
2554 		timerclear(&tv);
2555 		tv.tv_sec = paste_buffer_created(ft->pb);
2556 		return (&tv);
2557 	}
2558 	return (NULL);
2559 }
2560 
2561 /* Callback for client_activity. */
2562 static void *
2563 format_cb_client_activity(struct format_tree *ft)
2564 {
2565 	if (ft->c != NULL)
2566 		return (&ft->c->activity_time);
2567 	return (NULL);
2568 }
2569 
2570 /* Callback for client_created. */
2571 static void *
2572 format_cb_client_created(struct format_tree *ft)
2573 {
2574 	if (ft->c != NULL)
2575 		return (&ft->c->creation_time);
2576 	return (NULL);
2577 }
2578 
2579 /* Callback for session_activity. */
2580 static void *
2581 format_cb_session_activity(struct format_tree *ft)
2582 {
2583 	if (ft->s != NULL)
2584 		return (&ft->s->activity_time);
2585 	return (NULL);
2586 }
2587 
2588 /* Callback for session_created. */
2589 static void *
2590 format_cb_session_created(struct format_tree *ft)
2591 {
2592 	if (ft->s != NULL)
2593 		return (&ft->s->creation_time);
2594 	return (NULL);
2595 }
2596 
2597 /* Callback for session_last_attached. */
2598 static void *
2599 format_cb_session_last_attached(struct format_tree *ft)
2600 {
2601 	if (ft->s != NULL)
2602 		return (&ft->s->last_attached_time);
2603 	return (NULL);
2604 }
2605 
2606 /* Callback for start_time. */
2607 static void *
2608 format_cb_start_time(__unused struct format_tree *ft)
2609 {
2610 	return (&start_time);
2611 }
2612 
2613 /* Callback for window_activity. */
2614 static void *
2615 format_cb_window_activity(struct format_tree *ft)
2616 {
2617 	if (ft->w != NULL)
2618 		return (&ft->w->activity_time);
2619 	return (NULL);
2620 }
2621 
2622 /* Callback for buffer_mode_format, */
2623 static void *
2624 format_cb_buffer_mode_format(__unused struct format_tree *ft)
2625 {
2626 	return (xstrdup(window_buffer_mode.default_format));
2627 }
2628 
2629 /* Callback for client_mode_format, */
2630 static void *
2631 format_cb_client_mode_format(__unused struct format_tree *ft)
2632 {
2633 	return (xstrdup(window_client_mode.default_format));
2634 }
2635 
2636 /* Callback for tree_mode_format, */
2637 static void *
2638 format_cb_tree_mode_format(__unused struct format_tree *ft)
2639 {
2640 	return (xstrdup(window_tree_mode.default_format));
2641 }
2642 
2643 /* Callback for uid. */
2644 static void *
2645 format_cb_uid(__unused struct format_tree *ft)
2646 {
2647 	return (format_printf("%ld", (long)getuid()));
2648 }
2649 
2650 /* Callback for user. */
2651 static void *
2652 format_cb_user(__unused struct format_tree *ft)
2653 {
2654 	struct passwd	*pw;
2655 
2656 	if ((pw = getpwuid(getuid())) != NULL)
2657 		return (xstrdup(pw->pw_name));
2658 	return (NULL);
2659 }
2660 
2661 /* Format table type. */
2662 enum format_table_type {
2663 	FORMAT_TABLE_STRING,
2664 	FORMAT_TABLE_TIME
2665 };
2666 
2667 /* Format table entry. */
2668 struct format_table_entry {
2669 	const char		*key;
2670 	enum format_table_type	 type;
2671 	format_cb		 cb;
2672 };
2673 
2674 /*
2675  * Format table. Default format variables (that are almost always in the tree
2676  * and where the value is expanded by a callback in this file) are listed here.
2677  * Only variables which are added by the caller go into the tree.
2678  */
2679 static const struct format_table_entry format_table[] = {
2680 	{ "active_window_index", FORMAT_TABLE_STRING,
2681 	  format_cb_active_window_index
2682 	},
2683 	{ "alternate_on", FORMAT_TABLE_STRING,
2684 	  format_cb_alternate_on
2685 	},
2686 	{ "alternate_saved_x", FORMAT_TABLE_STRING,
2687 	  format_cb_alternate_saved_x
2688 	},
2689 	{ "alternate_saved_y", FORMAT_TABLE_STRING,
2690 	  format_cb_alternate_saved_y
2691 	},
2692 	{ "buffer_created", FORMAT_TABLE_TIME,
2693 	  format_cb_buffer_created
2694 	},
2695 	{ "buffer_mode_format", FORMAT_TABLE_STRING,
2696 	  format_cb_buffer_mode_format
2697 	},
2698 	{ "buffer_name", FORMAT_TABLE_STRING,
2699 	  format_cb_buffer_name
2700 	},
2701 	{ "buffer_sample", FORMAT_TABLE_STRING,
2702 	  format_cb_buffer_sample
2703 	},
2704 	{ "buffer_size", FORMAT_TABLE_STRING,
2705 	  format_cb_buffer_size
2706 	},
2707 	{ "client_activity", FORMAT_TABLE_TIME,
2708 	  format_cb_client_activity
2709 	},
2710 	{ "client_cell_height", FORMAT_TABLE_STRING,
2711 	  format_cb_client_cell_height
2712 	},
2713 	{ "client_cell_width", FORMAT_TABLE_STRING,
2714 	  format_cb_client_cell_width
2715 	},
2716 	{ "client_control_mode", FORMAT_TABLE_STRING,
2717 	  format_cb_client_control_mode
2718 	},
2719 	{ "client_created", FORMAT_TABLE_TIME,
2720 	  format_cb_client_created
2721 	},
2722 	{ "client_discarded", FORMAT_TABLE_STRING,
2723 	  format_cb_client_discarded
2724 	},
2725 	{ "client_flags", FORMAT_TABLE_STRING,
2726 	  format_cb_client_flags
2727 	},
2728 	{ "client_height", FORMAT_TABLE_STRING,
2729 	  format_cb_client_height
2730 	},
2731 	{ "client_key_table", FORMAT_TABLE_STRING,
2732 	  format_cb_client_key_table
2733 	},
2734 	{ "client_last_session", FORMAT_TABLE_STRING,
2735 	  format_cb_client_last_session
2736 	},
2737 	{ "client_mode_format", FORMAT_TABLE_STRING,
2738 	  format_cb_client_mode_format
2739 	},
2740 	{ "client_name", FORMAT_TABLE_STRING,
2741 	  format_cb_client_name
2742 	},
2743 	{ "client_pid", FORMAT_TABLE_STRING,
2744 	  format_cb_client_pid
2745 	},
2746 	{ "client_prefix", FORMAT_TABLE_STRING,
2747 	  format_cb_client_prefix
2748 	},
2749 	{ "client_readonly", FORMAT_TABLE_STRING,
2750 	  format_cb_client_readonly
2751 	},
2752 	{ "client_session", FORMAT_TABLE_STRING,
2753 	  format_cb_client_session
2754 	},
2755 	{ "client_termfeatures", FORMAT_TABLE_STRING,
2756 	  format_cb_client_termfeatures
2757 	},
2758 	{ "client_termname", FORMAT_TABLE_STRING,
2759 	  format_cb_client_termname
2760 	},
2761 	{ "client_termtype", FORMAT_TABLE_STRING,
2762 	  format_cb_client_termtype
2763 	},
2764 	{ "client_tty", FORMAT_TABLE_STRING,
2765 	  format_cb_client_tty
2766 	},
2767 	{ "client_uid", FORMAT_TABLE_STRING,
2768 	  format_cb_client_uid
2769 	},
2770 	{ "client_user", FORMAT_TABLE_STRING,
2771 	  format_cb_client_user
2772 	},
2773 	{ "client_utf8", FORMAT_TABLE_STRING,
2774 	  format_cb_client_utf8
2775 	},
2776 	{ "client_width", FORMAT_TABLE_STRING,
2777 	  format_cb_client_width
2778 	},
2779 	{ "client_written", FORMAT_TABLE_STRING,
2780 	  format_cb_client_written
2781 	},
2782 	{ "config_files", FORMAT_TABLE_STRING,
2783 	  format_cb_config_files
2784 	},
2785 	{ "cursor_character", FORMAT_TABLE_STRING,
2786 	  format_cb_cursor_character
2787 	},
2788 	{ "cursor_flag", FORMAT_TABLE_STRING,
2789 	  format_cb_cursor_flag
2790 	},
2791 	{ "cursor_x", FORMAT_TABLE_STRING,
2792 	  format_cb_cursor_x
2793 	},
2794 	{ "cursor_y", FORMAT_TABLE_STRING,
2795 	  format_cb_cursor_y
2796 	},
2797 	{ "history_all_bytes", FORMAT_TABLE_STRING,
2798 	  format_cb_history_all_bytes
2799 	},
2800 	{ "history_bytes", FORMAT_TABLE_STRING,
2801 	  format_cb_history_bytes
2802 	},
2803 	{ "history_limit", FORMAT_TABLE_STRING,
2804 	  format_cb_history_limit
2805 	},
2806 	{ "history_size", FORMAT_TABLE_STRING,
2807 	  format_cb_history_size
2808 	},
2809 	{ "host", FORMAT_TABLE_STRING,
2810 	  format_cb_host
2811 	},
2812 	{ "host_short", FORMAT_TABLE_STRING,
2813 	  format_cb_host_short
2814 	},
2815 	{ "insert_flag", FORMAT_TABLE_STRING,
2816 	  format_cb_insert_flag
2817 	},
2818 	{ "keypad_cursor_flag", FORMAT_TABLE_STRING,
2819 	  format_cb_keypad_cursor_flag
2820 	},
2821 	{ "keypad_flag", FORMAT_TABLE_STRING,
2822 	  format_cb_keypad_flag
2823 	},
2824 	{ "last_window_index", FORMAT_TABLE_STRING,
2825 	  format_cb_last_window_index
2826 	},
2827 	{ "mouse_all_flag", FORMAT_TABLE_STRING,
2828 	  format_cb_mouse_all_flag
2829 	},
2830 	{ "mouse_any_flag", FORMAT_TABLE_STRING,
2831 	  format_cb_mouse_any_flag
2832 	},
2833 	{ "mouse_button_flag", FORMAT_TABLE_STRING,
2834 	  format_cb_mouse_button_flag
2835 	},
2836 	{ "mouse_hyperlink", FORMAT_TABLE_STRING,
2837 	  format_cb_mouse_hyperlink
2838 	},
2839 	{ "mouse_line", FORMAT_TABLE_STRING,
2840 	  format_cb_mouse_line
2841 	},
2842 	{ "mouse_pane", FORMAT_TABLE_STRING,
2843 	  format_cb_mouse_pane
2844 	},
2845 	{ "mouse_sgr_flag", FORMAT_TABLE_STRING,
2846 	  format_cb_mouse_sgr_flag
2847 	},
2848 	{ "mouse_standard_flag", FORMAT_TABLE_STRING,
2849 	  format_cb_mouse_standard_flag
2850 	},
2851 	{ "mouse_utf8_flag", FORMAT_TABLE_STRING,
2852 	  format_cb_mouse_utf8_flag
2853 	},
2854 	{ "mouse_word", FORMAT_TABLE_STRING,
2855 	  format_cb_mouse_word
2856 	},
2857 	{ "mouse_x", FORMAT_TABLE_STRING,
2858 	  format_cb_mouse_x
2859 	},
2860 	{ "mouse_y", FORMAT_TABLE_STRING,
2861 	  format_cb_mouse_y
2862 	},
2863 	{ "next_session_id", FORMAT_TABLE_STRING,
2864 	  format_cb_next_session_id
2865 	},
2866 	{ "origin_flag", FORMAT_TABLE_STRING,
2867 	  format_cb_origin_flag
2868 	},
2869 	{ "pane_active", FORMAT_TABLE_STRING,
2870 	  format_cb_pane_active
2871 	},
2872 	{ "pane_at_bottom", FORMAT_TABLE_STRING,
2873 	  format_cb_pane_at_bottom
2874 	},
2875 	{ "pane_at_left", FORMAT_TABLE_STRING,
2876 	  format_cb_pane_at_left
2877 	},
2878 	{ "pane_at_right", FORMAT_TABLE_STRING,
2879 	  format_cb_pane_at_right
2880 	},
2881 	{ "pane_at_top", FORMAT_TABLE_STRING,
2882 	  format_cb_pane_at_top
2883 	},
2884 	{ "pane_bg", FORMAT_TABLE_STRING,
2885 	  format_cb_pane_bg
2886 	},
2887 	{ "pane_bottom", FORMAT_TABLE_STRING,
2888 	  format_cb_pane_bottom
2889 	},
2890 	{ "pane_current_command", FORMAT_TABLE_STRING,
2891 	  format_cb_current_command
2892 	},
2893 	{ "pane_current_path", FORMAT_TABLE_STRING,
2894 	  format_cb_current_path
2895 	},
2896 	{ "pane_dead", FORMAT_TABLE_STRING,
2897 	  format_cb_pane_dead
2898 	},
2899 	{ "pane_dead_signal", FORMAT_TABLE_STRING,
2900 	  format_cb_pane_dead_signal
2901 	},
2902 	{ "pane_dead_status", FORMAT_TABLE_STRING,
2903 	  format_cb_pane_dead_status
2904 	},
2905 	{ "pane_dead_time", FORMAT_TABLE_TIME,
2906 	  format_cb_pane_dead_time
2907 	},
2908 	{ "pane_fg", FORMAT_TABLE_STRING,
2909 	  format_cb_pane_fg
2910 	},
2911 	{ "pane_format", FORMAT_TABLE_STRING,
2912 	  format_cb_pane_format
2913 	},
2914 	{ "pane_height", FORMAT_TABLE_STRING,
2915 	  format_cb_pane_height
2916 	},
2917 	{ "pane_id", FORMAT_TABLE_STRING,
2918 	  format_cb_pane_id
2919 	},
2920 	{ "pane_in_mode", FORMAT_TABLE_STRING,
2921 	  format_cb_pane_in_mode
2922 	},
2923 	{ "pane_index", FORMAT_TABLE_STRING,
2924 	  format_cb_pane_index
2925 	},
2926 	{ "pane_input_off", FORMAT_TABLE_STRING,
2927 	  format_cb_pane_input_off
2928 	},
2929 	{ "pane_last", FORMAT_TABLE_STRING,
2930 	  format_cb_pane_last
2931 	},
2932 	{ "pane_left", FORMAT_TABLE_STRING,
2933 	  format_cb_pane_left
2934 	},
2935 	{ "pane_marked", FORMAT_TABLE_STRING,
2936 	  format_cb_pane_marked
2937 	},
2938 	{ "pane_marked_set", FORMAT_TABLE_STRING,
2939 	  format_cb_pane_marked_set
2940 	},
2941 	{ "pane_mode", FORMAT_TABLE_STRING,
2942 	  format_cb_pane_mode
2943 	},
2944 	{ "pane_path", FORMAT_TABLE_STRING,
2945 	  format_cb_pane_path
2946 	},
2947 	{ "pane_pid", FORMAT_TABLE_STRING,
2948 	  format_cb_pane_pid
2949 	},
2950 	{ "pane_pipe", FORMAT_TABLE_STRING,
2951 	  format_cb_pane_pipe
2952 	},
2953 	{ "pane_right", FORMAT_TABLE_STRING,
2954 	  format_cb_pane_right
2955 	},
2956 	{ "pane_search_string", FORMAT_TABLE_STRING,
2957 	  format_cb_pane_search_string
2958 	},
2959 	{ "pane_start_command", FORMAT_TABLE_STRING,
2960 	  format_cb_start_command
2961 	},
2962 	{ "pane_start_path", FORMAT_TABLE_STRING,
2963 	  format_cb_start_path
2964 	},
2965 	{ "pane_synchronized", FORMAT_TABLE_STRING,
2966 	  format_cb_pane_synchronized
2967 	},
2968 	{ "pane_tabs", FORMAT_TABLE_STRING,
2969 	  format_cb_pane_tabs
2970 	},
2971 	{ "pane_title", FORMAT_TABLE_STRING,
2972 	  format_cb_pane_title
2973 	},
2974 	{ "pane_top", FORMAT_TABLE_STRING,
2975 	  format_cb_pane_top
2976 	},
2977 	{ "pane_tty", FORMAT_TABLE_STRING,
2978 	  format_cb_pane_tty
2979 	},
2980 	{ "pane_unseen_changes", FORMAT_TABLE_STRING,
2981 	  format_cb_pane_unseen_changes
2982 	},
2983 	{ "pane_width", FORMAT_TABLE_STRING,
2984 	  format_cb_pane_width
2985 	},
2986 	{ "pid", FORMAT_TABLE_STRING,
2987 	  format_cb_pid
2988 	},
2989 	{ "scroll_region_lower", FORMAT_TABLE_STRING,
2990 	  format_cb_scroll_region_lower
2991 	},
2992 	{ "scroll_region_upper", FORMAT_TABLE_STRING,
2993 	  format_cb_scroll_region_upper
2994 	},
2995 	{ "server_sessions", FORMAT_TABLE_STRING,
2996 	  format_cb_server_sessions
2997 	},
2998 	{ "session_activity", FORMAT_TABLE_TIME,
2999 	  format_cb_session_activity
3000 	},
3001 	{ "session_alerts", FORMAT_TABLE_STRING,
3002 	  format_cb_session_alerts
3003 	},
3004 	{ "session_attached", FORMAT_TABLE_STRING,
3005 	  format_cb_session_attached
3006 	},
3007 	{ "session_attached_list", FORMAT_TABLE_STRING,
3008 	  format_cb_session_attached_list
3009 	},
3010 	{ "session_created", FORMAT_TABLE_TIME,
3011 	  format_cb_session_created
3012 	},
3013 	{ "session_format", FORMAT_TABLE_STRING,
3014 	  format_cb_session_format
3015 	},
3016 	{ "session_group", FORMAT_TABLE_STRING,
3017 	  format_cb_session_group
3018 	},
3019 	{ "session_group_attached", FORMAT_TABLE_STRING,
3020 	  format_cb_session_group_attached
3021 	},
3022 	{ "session_group_attached_list", FORMAT_TABLE_STRING,
3023 	  format_cb_session_group_attached_list
3024 	},
3025 	{ "session_group_list", FORMAT_TABLE_STRING,
3026 	  format_cb_session_group_list
3027 	},
3028 	{ "session_group_many_attached", FORMAT_TABLE_STRING,
3029 	  format_cb_session_group_many_attached
3030 	},
3031 	{ "session_group_size", FORMAT_TABLE_STRING,
3032 	  format_cb_session_group_size
3033 	},
3034 	{ "session_grouped", FORMAT_TABLE_STRING,
3035 	  format_cb_session_grouped
3036 	},
3037 	{ "session_id", FORMAT_TABLE_STRING,
3038 	  format_cb_session_id
3039 	},
3040 	{ "session_last_attached", FORMAT_TABLE_TIME,
3041 	  format_cb_session_last_attached
3042 	},
3043 	{ "session_many_attached", FORMAT_TABLE_STRING,
3044 	  format_cb_session_many_attached
3045 	},
3046 	{ "session_marked", FORMAT_TABLE_STRING,
3047 	  format_cb_session_marked,
3048 	},
3049 	{ "session_name", FORMAT_TABLE_STRING,
3050 	  format_cb_session_name
3051 	},
3052 	{ "session_path", FORMAT_TABLE_STRING,
3053 	  format_cb_session_path
3054 	},
3055 	{ "session_stack", FORMAT_TABLE_STRING,
3056 	  format_cb_session_stack
3057 	},
3058 	{ "session_windows", FORMAT_TABLE_STRING,
3059 	  format_cb_session_windows
3060 	},
3061 	{ "socket_path", FORMAT_TABLE_STRING,
3062 	  format_cb_socket_path
3063 	},
3064 	{ "start_time", FORMAT_TABLE_TIME,
3065 	  format_cb_start_time
3066 	},
3067 	{ "tree_mode_format", FORMAT_TABLE_STRING,
3068 	  format_cb_tree_mode_format
3069 	},
3070 	{ "uid", FORMAT_TABLE_STRING,
3071 	  format_cb_uid
3072 	},
3073 	{ "user", FORMAT_TABLE_STRING,
3074 	  format_cb_user
3075 	},
3076 	{ "version", FORMAT_TABLE_STRING,
3077 	  format_cb_version
3078 	},
3079 	{ "window_active", FORMAT_TABLE_STRING,
3080 	  format_cb_window_active
3081 	},
3082 	{ "window_active_clients", FORMAT_TABLE_STRING,
3083 	  format_cb_window_active_clients
3084 	},
3085 	{ "window_active_clients_list", FORMAT_TABLE_STRING,
3086 	  format_cb_window_active_clients_list
3087 	},
3088 	{ "window_active_sessions", FORMAT_TABLE_STRING,
3089 	  format_cb_window_active_sessions
3090 	},
3091 	{ "window_active_sessions_list", FORMAT_TABLE_STRING,
3092 	  format_cb_window_active_sessions_list
3093 	},
3094 	{ "window_activity", FORMAT_TABLE_TIME,
3095 	  format_cb_window_activity
3096 	},
3097 	{ "window_activity_flag", FORMAT_TABLE_STRING,
3098 	  format_cb_window_activity_flag
3099 	},
3100 	{ "window_bell_flag", FORMAT_TABLE_STRING,
3101 	  format_cb_window_bell_flag
3102 	},
3103 	{ "window_bigger", FORMAT_TABLE_STRING,
3104 	  format_cb_window_bigger
3105 	},
3106 	{ "window_cell_height", FORMAT_TABLE_STRING,
3107 	  format_cb_window_cell_height
3108 	},
3109 	{ "window_cell_width", FORMAT_TABLE_STRING,
3110 	  format_cb_window_cell_width
3111 	},
3112 	{ "window_end_flag", FORMAT_TABLE_STRING,
3113 	  format_cb_window_end_flag
3114 	},
3115 	{ "window_flags", FORMAT_TABLE_STRING,
3116 	  format_cb_window_flags
3117 	},
3118 	{ "window_format", FORMAT_TABLE_STRING,
3119 	  format_cb_window_format
3120 	},
3121 	{ "window_height", FORMAT_TABLE_STRING,
3122 	  format_cb_window_height
3123 	},
3124 	{ "window_id", FORMAT_TABLE_STRING,
3125 	  format_cb_window_id
3126 	},
3127 	{ "window_index", FORMAT_TABLE_STRING,
3128 	  format_cb_window_index
3129 	},
3130 	{ "window_last_flag", FORMAT_TABLE_STRING,
3131 	  format_cb_window_last_flag
3132 	},
3133 	{ "window_layout", FORMAT_TABLE_STRING,
3134 	  format_cb_window_layout
3135 	},
3136 	{ "window_linked", FORMAT_TABLE_STRING,
3137 	  format_cb_window_linked
3138 	},
3139 	{ "window_linked_sessions", FORMAT_TABLE_STRING,
3140 	  format_cb_window_linked_sessions
3141 	},
3142 	{ "window_linked_sessions_list", FORMAT_TABLE_STRING,
3143 	  format_cb_window_linked_sessions_list
3144 	},
3145 	{ "window_marked_flag", FORMAT_TABLE_STRING,
3146 	  format_cb_window_marked_flag
3147 	},
3148 	{ "window_name", FORMAT_TABLE_STRING,
3149 	  format_cb_window_name
3150 	},
3151 	{ "window_offset_x", FORMAT_TABLE_STRING,
3152 	  format_cb_window_offset_x
3153 	},
3154 	{ "window_offset_y", FORMAT_TABLE_STRING,
3155 	  format_cb_window_offset_y
3156 	},
3157 	{ "window_panes", FORMAT_TABLE_STRING,
3158 	  format_cb_window_panes
3159 	},
3160 	{ "window_raw_flags", FORMAT_TABLE_STRING,
3161 	  format_cb_window_raw_flags
3162 	},
3163 	{ "window_silence_flag", FORMAT_TABLE_STRING,
3164 	  format_cb_window_silence_flag
3165 	},
3166 	{ "window_stack_index", FORMAT_TABLE_STRING,
3167 	  format_cb_window_stack_index
3168 	},
3169 	{ "window_start_flag", FORMAT_TABLE_STRING,
3170 	  format_cb_window_start_flag
3171 	},
3172 	{ "window_visible_layout", FORMAT_TABLE_STRING,
3173 	  format_cb_window_visible_layout
3174 	},
3175 	{ "window_width", FORMAT_TABLE_STRING,
3176 	  format_cb_window_width
3177 	},
3178 	{ "window_zoomed_flag", FORMAT_TABLE_STRING,
3179 	  format_cb_window_zoomed_flag
3180 	},
3181 	{ "wrap_flag", FORMAT_TABLE_STRING,
3182 	  format_cb_wrap_flag
3183 	}
3184 };
3185 
3186 /* Compare format table entries. */
3187 static int
3188 format_table_compare(const void *key0, const void *entry0)
3189 {
3190 	const char			*key = key0;
3191 	const struct format_table_entry	*entry = entry0;
3192 
3193 	return (strcmp(key, entry->key));
3194 }
3195 
3196 /* Get a format callback. */
3197 static struct format_table_entry *
3198 format_table_get(const char *key)
3199 {
3200 	return (bsearch(key, format_table, nitems(format_table),
3201 	    sizeof *format_table, format_table_compare));
3202 }
3203 
3204 /* Merge one format tree into another. */
3205 void
3206 format_merge(struct format_tree *ft, struct format_tree *from)
3207 {
3208 	struct format_entry	*fe;
3209 
3210 	RB_FOREACH(fe, format_entry_tree, &from->tree) {
3211 		if (fe->value != NULL)
3212 			format_add(ft, fe->key, "%s", fe->value);
3213 	}
3214 }
3215 
3216 /* Get format pane. */
3217 struct window_pane *
3218 format_get_pane(struct format_tree *ft)
3219 {
3220 	return (ft->wp);
3221 }
3222 
3223 /* Add item bits to tree. */
3224 static void
3225 format_create_add_item(struct format_tree *ft, struct cmdq_item *item)
3226 {
3227 	struct key_event	*event = cmdq_get_event(item);
3228 	struct mouse_event	*m = &event->m;
3229 
3230 	cmdq_merge_formats(item, ft);
3231 	memcpy(&ft->m, m, sizeof ft->m);
3232 }
3233 
3234 /* Create a new tree. */
3235 struct format_tree *
3236 format_create(struct client *c, struct cmdq_item *item, int tag, int flags)
3237 {
3238 	struct format_tree	*ft;
3239 
3240 	ft = xcalloc(1, sizeof *ft);
3241 	RB_INIT(&ft->tree);
3242 
3243 	if (c != NULL) {
3244 		ft->client = c;
3245 		ft->client->references++;
3246 	}
3247 	ft->item = item;
3248 
3249 	ft->tag = tag;
3250 	ft->flags = flags;
3251 
3252 	if (item != NULL)
3253 		format_create_add_item(ft, item);
3254 
3255 	return (ft);
3256 }
3257 
3258 /* Free a tree. */
3259 void
3260 format_free(struct format_tree *ft)
3261 {
3262 	struct format_entry	*fe, *fe1;
3263 
3264 	RB_FOREACH_SAFE(fe, format_entry_tree, &ft->tree, fe1) {
3265 		RB_REMOVE(format_entry_tree, &ft->tree, fe);
3266 		free(fe->value);
3267 		free(fe->key);
3268 		free(fe);
3269 	}
3270 
3271 	if (ft->client != NULL)
3272 		server_client_unref(ft->client);
3273 	free(ft);
3274 }
3275 
3276 /* Log each format. */
3277 static void
3278 format_log_debug_cb(const char *key, const char *value, void *arg)
3279 {
3280 	const char	*prefix = arg;
3281 
3282 	log_debug("%s: %s=%s", prefix, key, value);
3283 }
3284 
3285 /* Log a format tree. */
3286 void
3287 format_log_debug(struct format_tree *ft, const char *prefix)
3288 {
3289 	format_each(ft, format_log_debug_cb, (void *)prefix);
3290 }
3291 
3292 /* Walk each format. */
3293 void
3294 format_each(struct format_tree *ft, void (*cb)(const char *, const char *,
3295     void *), void *arg)
3296 {
3297 	const struct format_table_entry	*fte;
3298 	struct format_entry		*fe;
3299 	u_int				 i;
3300 	char				 s[64];
3301 	void				*value;
3302 	struct timeval			*tv;
3303 
3304 	for (i = 0; i < nitems(format_table); i++) {
3305 		fte = &format_table[i];
3306 
3307 		value = fte->cb(ft);
3308 		if (value == NULL)
3309 			continue;
3310 		if (fte->type == FORMAT_TABLE_TIME) {
3311 			tv = value;
3312 			xsnprintf(s, sizeof s, "%lld", (long long)tv->tv_sec);
3313 			cb(fte->key, s, arg);
3314 		} else {
3315 			cb(fte->key, value, arg);
3316 			free(value);
3317 		}
3318 	}
3319 	RB_FOREACH(fe, format_entry_tree, &ft->tree) {
3320 		if (fe->time != 0) {
3321 			xsnprintf(s, sizeof s, "%lld", (long long)fe->time);
3322 			cb(fe->key, s, arg);
3323 		} else {
3324 			if (fe->value == NULL && fe->cb != NULL) {
3325 				fe->value = fe->cb(ft);
3326 				if (fe->value == NULL)
3327 					fe->value = xstrdup("");
3328 			}
3329 			cb(fe->key, fe->value, arg);
3330 		}
3331 	}
3332 }
3333 
3334 /* Add a key-value pair. */
3335 void
3336 format_add(struct format_tree *ft, const char *key, const char *fmt, ...)
3337 {
3338 	struct format_entry	*fe;
3339 	struct format_entry	*fe_now;
3340 	va_list			 ap;
3341 
3342 	fe = xmalloc(sizeof *fe);
3343 	fe->key = xstrdup(key);
3344 
3345 	fe_now = RB_INSERT(format_entry_tree, &ft->tree, fe);
3346 	if (fe_now != NULL) {
3347 		free(fe->key);
3348 		free(fe);
3349 		free(fe_now->value);
3350 		fe = fe_now;
3351 	}
3352 
3353 	fe->cb = NULL;
3354 	fe->time = 0;
3355 
3356 	va_start(ap, fmt);
3357 	xvasprintf(&fe->value, fmt, ap);
3358 	va_end(ap);
3359 }
3360 
3361 /* Add a key and time. */
3362 void
3363 format_add_tv(struct format_tree *ft, const char *key, struct timeval *tv)
3364 {
3365 	struct format_entry	*fe, *fe_now;
3366 
3367 	fe = xmalloc(sizeof *fe);
3368 	fe->key = xstrdup(key);
3369 
3370 	fe_now = RB_INSERT(format_entry_tree, &ft->tree, fe);
3371 	if (fe_now != NULL) {
3372 		free(fe->key);
3373 		free(fe);
3374 		free(fe_now->value);
3375 		fe = fe_now;
3376 	}
3377 
3378 	fe->cb = NULL;
3379 	fe->time = tv->tv_sec;
3380 
3381 	fe->value = NULL;
3382 }
3383 
3384 /* Add a key and function. */
3385 void
3386 format_add_cb(struct format_tree *ft, const char *key, format_cb cb)
3387 {
3388 	struct format_entry	*fe;
3389 	struct format_entry	*fe_now;
3390 
3391 	fe = xmalloc(sizeof *fe);
3392 	fe->key = xstrdup(key);
3393 
3394 	fe_now = RB_INSERT(format_entry_tree, &ft->tree, fe);
3395 	if (fe_now != NULL) {
3396 		free(fe->key);
3397 		free(fe);
3398 		free(fe_now->value);
3399 		fe = fe_now;
3400 	}
3401 
3402 	fe->cb = cb;
3403 	fe->time = 0;
3404 
3405 	fe->value = NULL;
3406 }
3407 
3408 /* Quote shell special characters in string. */
3409 static char *
3410 format_quote_shell(const char *s)
3411 {
3412 	const char	*cp;
3413 	char		*out, *at;
3414 
3415 	at = out = xmalloc(strlen(s) * 2 + 1);
3416 	for (cp = s; *cp != '\0'; cp++) {
3417 		if (strchr("|&;<>()$`\\\"'*?[# =%", *cp) != NULL)
3418 			*at++ = '\\';
3419 		*at++ = *cp;
3420 	}
3421 	*at = '\0';
3422 	return (out);
3423 }
3424 
3425 /* Quote #s in string. */
3426 static char *
3427 format_quote_style(const char *s)
3428 {
3429 	const char	*cp;
3430 	char		*out, *at;
3431 
3432 	at = out = xmalloc(strlen(s) * 2 + 1);
3433 	for (cp = s; *cp != '\0'; cp++) {
3434 		if (*cp == '#')
3435 			*at++ = '#';
3436 		*at++ = *cp;
3437 	}
3438 	*at = '\0';
3439 	return (out);
3440 }
3441 
3442 /* Make a prettier time. */
3443 char *
3444 format_pretty_time(time_t t, int seconds)
3445 {
3446 	struct tm       now_tm, tm;
3447 	time_t		now, age;
3448 	char		s[9];
3449 
3450 	time(&now);
3451 	if (now < t)
3452 		now = t;
3453 	age = now - t;
3454 
3455 	localtime_r(&now, &now_tm);
3456 	localtime_r(&t, &tm);
3457 
3458 	/* Last 24 hours. */
3459 	if (age < 24 * 3600) {
3460 		if (seconds)
3461 			strftime(s, sizeof s, "%H:%M:%S", &tm);
3462 		else
3463 			strftime(s, sizeof s, "%H:%M", &tm);
3464 		return (xstrdup(s));
3465 	}
3466 
3467 	/* This month or last 28 days. */
3468 	if ((tm.tm_year == now_tm.tm_year && tm.tm_mon == now_tm.tm_mon) ||
3469 	    age < 28 * 24 * 3600) {
3470 		strftime(s, sizeof s, "%a%d", &tm);
3471 		return (xstrdup(s));
3472 	}
3473 
3474 	/* Last 12 months. */
3475 	if ((tm.tm_year == now_tm.tm_year && tm.tm_mon < now_tm.tm_mon) ||
3476 	    (tm.tm_year == now_tm.tm_year - 1 && tm.tm_mon > now_tm.tm_mon)) {
3477 		strftime(s, sizeof s, "%d%b", &tm);
3478 		return (xstrdup(s));
3479 	}
3480 
3481 	/* Older than that. */
3482 	strftime(s, sizeof s, "%h%y", &tm);
3483 	return (xstrdup(s));
3484 }
3485 
3486 /* Find a format entry. */
3487 static char *
3488 format_find(struct format_tree *ft, const char *key, int modifiers,
3489     const char *time_format)
3490 {
3491 	struct format_table_entry	*fte;
3492 	void				*value;
3493 	struct format_entry		*fe, fe_find;
3494 	struct environ_entry		*envent;
3495 	struct options_entry		*o;
3496 	int				 idx;
3497 	char				*found = NULL, *saved, s[512];
3498 	const char			*errstr;
3499 	time_t				 t = 0;
3500 	struct tm			 tm;
3501 
3502 	o = options_parse_get(global_options, key, &idx, 0);
3503 	if (o == NULL && ft->wp != NULL)
3504 		o = options_parse_get(ft->wp->options, key, &idx, 0);
3505 	if (o == NULL && ft->w != NULL)
3506 		o = options_parse_get(ft->w->options, key, &idx, 0);
3507 	if (o == NULL)
3508 		o = options_parse_get(global_w_options, key, &idx, 0);
3509 	if (o == NULL && ft->s != NULL)
3510 		o = options_parse_get(ft->s->options, key, &idx, 0);
3511 	if (o == NULL)
3512 		o = options_parse_get(global_s_options, key, &idx, 0);
3513 	if (o != NULL) {
3514 		found = options_to_string(o, idx, 1);
3515 		goto found;
3516 	}
3517 
3518 	fte = format_table_get(key);
3519 	if (fte != NULL) {
3520 		value = fte->cb(ft);
3521 		if (fte->type == FORMAT_TABLE_TIME && value != NULL)
3522 			t = ((struct timeval *)value)->tv_sec;
3523 		else
3524 			found = value;
3525 		goto found;
3526 	}
3527 	fe_find.key = (char *)key;
3528 	fe = RB_FIND(format_entry_tree, &ft->tree, &fe_find);
3529 	if (fe != NULL) {
3530 		if (fe->time != 0) {
3531 			t = fe->time;
3532 			goto found;
3533 		}
3534 		if (fe->value == NULL && fe->cb != NULL) {
3535 			fe->value = fe->cb(ft);
3536 			if (fe->value == NULL)
3537 				fe->value = xstrdup("");
3538 		}
3539 		found = xstrdup(fe->value);
3540 		goto found;
3541 	}
3542 
3543 	if (~modifiers & FORMAT_TIMESTRING) {
3544 		envent = NULL;
3545 		if (ft->s != NULL)
3546 			envent = environ_find(ft->s->environ, key);
3547 		if (envent == NULL)
3548 			envent = environ_find(global_environ, key);
3549 		if (envent != NULL && envent->value != NULL) {
3550 			found = xstrdup(envent->value);
3551 			goto found;
3552 		}
3553 	}
3554 
3555 	return (NULL);
3556 
3557 found:
3558 	if (modifiers & FORMAT_TIMESTRING) {
3559 		if (t == 0 && found != NULL) {
3560 			t = strtonum(found, 0, INT64_MAX, &errstr);
3561 			if (errstr != NULL)
3562 				t = 0;
3563 			free(found);
3564 		}
3565 		if (t == 0)
3566 			return (NULL);
3567 		if (modifiers & FORMAT_PRETTY)
3568 			found = format_pretty_time(t, 0);
3569 		else {
3570 			if (time_format != NULL) {
3571 				localtime_r(&t, &tm);
3572 				strftime(s, sizeof s, time_format, &tm);
3573 			} else {
3574 				ctime_r(&t, s);
3575 				s[strcspn(s, "\n")] = '\0';
3576 			}
3577 			found = xstrdup(s);
3578 		}
3579 		return (found);
3580 	}
3581 
3582 	if (t != 0)
3583 		xasprintf(&found, "%lld", (long long)t);
3584 	else if (found == NULL)
3585 		return (NULL);
3586 	if (modifiers & FORMAT_BASENAME) {
3587 		saved = found;
3588 		found = xstrdup(basename(saved));
3589 		free(saved);
3590 	}
3591 	if (modifiers & FORMAT_DIRNAME) {
3592 		saved = found;
3593 		found = xstrdup(dirname(saved));
3594 		free(saved);
3595 	}
3596 	if (modifiers & FORMAT_QUOTE_SHELL) {
3597 		saved = found;
3598 		found = format_quote_shell(saved);
3599 		free(saved);
3600 	}
3601 	if (modifiers & FORMAT_QUOTE_STYLE) {
3602 		saved = found;
3603 		found = format_quote_style(saved);
3604 		free(saved);
3605 	}
3606 	return (found);
3607 }
3608 
3609 /* Unescape escaped characters. */
3610 static char *
3611 format_unescape(const char *s)
3612 {
3613 	char	*out, *cp;
3614 	int	 brackets = 0;
3615 
3616 	cp = out = xmalloc(strlen(s) + 1);
3617 	for (; *s != '\0'; s++) {
3618 		if (*s == '#' && s[1] == '{')
3619 			brackets++;
3620 		if (brackets == 0 &&
3621 		    *s == '#' &&
3622 		    strchr(",#{}:", s[1]) != NULL) {
3623 			*cp++ = *++s;
3624  			continue;
3625 		}
3626 		if (*s == '}')
3627 			brackets--;
3628 		*cp++ = *s;
3629 	}
3630 	*cp = '\0';
3631 	return (out);
3632 }
3633 
3634 /* Remove escaped characters. */
3635 static char *
3636 format_strip(const char *s)
3637 {
3638 	char	*out, *cp;
3639 	int	 brackets = 0;
3640 
3641 	cp = out = xmalloc(strlen(s) + 1);
3642 	for (; *s != '\0'; s++) {
3643 		if (*s == '#' && s[1] == '{')
3644 			brackets++;
3645 		if (*s == '#' && strchr(",#{}:", s[1]) != NULL) {
3646 			if (brackets != 0)
3647 				*cp++ = *s;
3648 			continue;
3649 		}
3650 		if (*s == '}')
3651 			brackets--;
3652 		*cp++ = *s;
3653 	}
3654 	*cp = '\0';
3655 	return (out);
3656 }
3657 
3658 /* Skip until end. */
3659 const char *
3660 format_skip(const char *s, const char *end)
3661 {
3662 	int	brackets = 0;
3663 
3664 	for (; *s != '\0'; s++) {
3665 		if (*s == '#' && s[1] == '{')
3666 			brackets++;
3667 		if (*s == '#' && strchr(",#{}:", s[1]) != NULL) {
3668 			s++;
3669 			continue;
3670 		}
3671 		if (*s == '}')
3672 			brackets--;
3673 		if (strchr(end, *s) != NULL && brackets == 0)
3674 			break;
3675 	}
3676 	if (*s == '\0')
3677 		return (NULL);
3678 	return (s);
3679 }
3680 
3681 /* Return left and right alternatives separated by commas. */
3682 static int
3683 format_choose(struct format_expand_state *es, const char *s, char **left,
3684     char **right, int expand)
3685 {
3686 	const char	*cp;
3687 	char		*left0, *right0;
3688 
3689 	cp = format_skip(s, ",");
3690 	if (cp == NULL)
3691 		return (-1);
3692 	left0 = xstrndup(s, cp - s);
3693 	right0 = xstrdup(cp + 1);
3694 
3695 	if (expand) {
3696 		*left = format_expand1(es, left0);
3697 		free(left0);
3698 		*right = format_expand1(es, right0);
3699 		free(right0);
3700 	} else {
3701 		*left = left0;
3702 		*right = right0;
3703 	}
3704 	return (0);
3705 }
3706 
3707 /* Is this true? */
3708 int
3709 format_true(const char *s)
3710 {
3711 	if (s != NULL && *s != '\0' && (s[0] != '0' || s[1] != '\0'))
3712 		return (1);
3713 	return (0);
3714 }
3715 
3716 /* Check if modifier end. */
3717 static int
3718 format_is_end(char c)
3719 {
3720 	return (c == ';' || c == ':');
3721 }
3722 
3723 /* Add to modifier list. */
3724 static void
3725 format_add_modifier(struct format_modifier **list, u_int *count,
3726     const char *c, size_t n, char **argv, int argc)
3727 {
3728 	struct format_modifier *fm;
3729 
3730 	*list = xreallocarray(*list, (*count) + 1, sizeof **list);
3731 	fm = &(*list)[(*count)++];
3732 
3733 	memcpy(fm->modifier, c, n);
3734 	fm->modifier[n] = '\0';
3735 	fm->size = n;
3736 
3737 	fm->argv = argv;
3738 	fm->argc = argc;
3739 }
3740 
3741 /* Free modifier list. */
3742 static void
3743 format_free_modifiers(struct format_modifier *list, u_int count)
3744 {
3745 	u_int	i;
3746 
3747 	for (i = 0; i < count; i++)
3748 		cmd_free_argv(list[i].argc, list[i].argv);
3749 	free(list);
3750 }
3751 
3752 /* Build modifier list. */
3753 static struct format_modifier *
3754 format_build_modifiers(struct format_expand_state *es, const char **s,
3755     u_int *count)
3756 {
3757 	const char		*cp = *s, *end;
3758 	struct format_modifier	*list = NULL;
3759 	char			 c, last[] = "X;:", **argv, *value;
3760 	int			 argc;
3761 
3762 	/*
3763 	 * Modifiers are a ; separated list of the forms:
3764 	 *      l,m,C,a,b,c,d,n,t,w,q,E,T,S,W,P,<,>
3765 	 *	=a
3766 	 *	=/a
3767 	 *      =/a/
3768 	 *	s/a/b/
3769 	 *	s/a/b
3770 	 *	||,&&,!=,==,<=,>=
3771 	 */
3772 
3773 	*count = 0;
3774 
3775 	while (*cp != '\0' && *cp != ':') {
3776 		/* Skip any separator character. */
3777 		if (*cp == ';')
3778 			cp++;
3779 
3780 		/* Check single character modifiers with no arguments. */
3781 		if (strchr("labcdnwETSWPL<>", cp[0]) != NULL &&
3782 		    format_is_end(cp[1])) {
3783 			format_add_modifier(&list, count, cp, 1, NULL, 0);
3784 			cp++;
3785 			continue;
3786 		}
3787 
3788 		/* Then try double character with no arguments. */
3789 		if ((memcmp("||", cp, 2) == 0 ||
3790 		    memcmp("&&", cp, 2) == 0 ||
3791 		    memcmp("!=", cp, 2) == 0 ||
3792 		    memcmp("==", cp, 2) == 0 ||
3793 		    memcmp("<=", cp, 2) == 0 ||
3794 		    memcmp(">=", cp, 2) == 0) &&
3795 		    format_is_end(cp[2])) {
3796 			format_add_modifier(&list, count, cp, 2, NULL, 0);
3797 			cp += 2;
3798 			continue;
3799 		}
3800 
3801 		/* Now try single character with arguments. */
3802 		if (strchr("mCNst=peq", cp[0]) == NULL)
3803 			break;
3804 		c = cp[0];
3805 
3806 		/* No arguments provided. */
3807 		if (format_is_end(cp[1])) {
3808 			format_add_modifier(&list, count, cp, 1, NULL, 0);
3809 			cp++;
3810 			continue;
3811 		}
3812 		argv = NULL;
3813 		argc = 0;
3814 
3815 		/* Single argument with no wrapper character. */
3816 		if (!ispunct(cp[1]) || cp[1] == '-') {
3817 			end = format_skip(cp + 1, ":;");
3818 			if (end == NULL)
3819 				break;
3820 
3821 			argv = xcalloc(1, sizeof *argv);
3822 			value = xstrndup(cp + 1, end - (cp + 1));
3823 			argv[0] = format_expand1(es, value);
3824 			free(value);
3825 			argc = 1;
3826 
3827 			format_add_modifier(&list, count, &c, 1, argv, argc);
3828 			cp = end;
3829 			continue;
3830 		}
3831 
3832 		/* Multiple arguments with a wrapper character. */
3833 		last[0] = cp[1];
3834 		cp++;
3835 		do {
3836 			if (cp[0] == last[0] && format_is_end(cp[1])) {
3837 				cp++;
3838 				break;
3839 			}
3840 			end = format_skip(cp + 1, last);
3841 			if (end == NULL)
3842 				break;
3843 			cp++;
3844 
3845 			argv = xreallocarray(argv, argc + 1, sizeof *argv);
3846 			value = xstrndup(cp, end - cp);
3847 			argv[argc++] = format_expand1(es, value);
3848 			free(value);
3849 
3850 			cp = end;
3851 		} while (!format_is_end(cp[0]));
3852 		format_add_modifier(&list, count, &c, 1, argv, argc);
3853 	}
3854 	if (*cp != ':') {
3855 		format_free_modifiers(list, *count);
3856 		*count = 0;
3857 		return (NULL);
3858 	}
3859 	*s = cp + 1;
3860 	return (list);
3861 }
3862 
3863 /* Match against an fnmatch(3) pattern or regular expression. */
3864 static char *
3865 format_match(struct format_modifier *fm, const char *pattern, const char *text)
3866 {
3867 	const char	*s = "";
3868 	regex_t		 r;
3869 	int		 flags = 0;
3870 
3871 	if (fm->argc >= 1)
3872 		s = fm->argv[0];
3873 	if (strchr(s, 'r') == NULL) {
3874 		if (strchr(s, 'i') != NULL)
3875 			flags |= FNM_CASEFOLD;
3876 		if (fnmatch(pattern, text, flags) != 0)
3877 			return (xstrdup("0"));
3878 	} else {
3879 		flags = REG_EXTENDED|REG_NOSUB;
3880 		if (strchr(s, 'i') != NULL)
3881 			flags |= REG_ICASE;
3882 		if (regcomp(&r, pattern, flags) != 0)
3883 			return (xstrdup("0"));
3884 		if (regexec(&r, text, 0, NULL, 0) != 0) {
3885 			regfree(&r);
3886 			return (xstrdup("0"));
3887 		}
3888 		regfree(&r);
3889 	}
3890 	return (xstrdup("1"));
3891 }
3892 
3893 /* Perform substitution in string. */
3894 static char *
3895 format_sub(struct format_modifier *fm, const char *text, const char *pattern,
3896     const char *with)
3897 {
3898 	char	*value;
3899 	int	 flags = REG_EXTENDED;
3900 
3901 	if (fm->argc >= 3 && strchr(fm->argv[2], 'i') != NULL)
3902 		flags |= REG_ICASE;
3903 	value = regsub(pattern, with, text, flags);
3904 	if (value == NULL)
3905 		return (xstrdup(text));
3906 	return (value);
3907 }
3908 
3909 /* Search inside pane. */
3910 static char *
3911 format_search(struct format_modifier *fm, struct window_pane *wp, const char *s)
3912 {
3913 	int	 ignore = 0, regex = 0;
3914 	char	*value;
3915 
3916 	if (fm->argc >= 1) {
3917 		if (strchr(fm->argv[0], 'i') != NULL)
3918 			ignore = 1;
3919 		if (strchr(fm->argv[0], 'r') != NULL)
3920 			regex = 1;
3921 	}
3922 	xasprintf(&value, "%u", window_pane_search(wp, s, regex, ignore));
3923 	return (value);
3924 }
3925 
3926 /* Does session name exist? */
3927 static char *
3928 format_session_name(struct format_expand_state *es, const char *fmt)
3929 {
3930 	char		*name;
3931 	struct session	*s;
3932 
3933 	name = format_expand1(es, fmt);
3934 	RB_FOREACH(s, sessions, &sessions) {
3935 		if (strcmp(s->name, name) == 0) {
3936 			free(name);
3937 			return (xstrdup("1"));
3938 		}
3939 	}
3940 	free(name);
3941 	return (xstrdup("0"));
3942 }
3943 
3944 /* Loop over sessions. */
3945 static char *
3946 format_loop_sessions(struct format_expand_state *es, const char *fmt)
3947 {
3948 	struct format_tree		*ft = es->ft;
3949 	struct client			*c = ft->client;
3950 	struct cmdq_item		*item = ft->item;
3951 	struct format_tree		*nft;
3952 	struct format_expand_state	 next;
3953 	char				*expanded, *value;
3954 	size_t				 valuelen;
3955 	struct session			*s;
3956 
3957 	value = xcalloc(1, 1);
3958 	valuelen = 1;
3959 
3960 	RB_FOREACH(s, sessions, &sessions) {
3961 		format_log(es, "session loop: $%u", s->id);
3962 		nft = format_create(c, item, FORMAT_NONE, ft->flags);
3963 		format_defaults(nft, ft->c, s, NULL, NULL);
3964 		format_copy_state(&next, es, 0);
3965 		next.ft = nft;
3966 		expanded = format_expand1(&next, fmt);
3967 		format_free(next.ft);
3968 
3969 		valuelen += strlen(expanded);
3970 		value = xrealloc(value, valuelen);
3971 
3972 		strlcat(value, expanded, valuelen);
3973 		free(expanded);
3974 	}
3975 
3976 	return (value);
3977 }
3978 
3979 /* Does window name exist? */
3980 static char *
3981 format_window_name(struct format_expand_state *es, const char *fmt)
3982 {
3983 	struct format_tree	*ft = es->ft;
3984 	char			*name;
3985 	struct winlink		*wl;
3986 
3987 	if (ft->s == NULL) {
3988 		format_log(es, "window name but no session");
3989 		return (NULL);
3990 	}
3991 
3992 	name = format_expand1(es, fmt);
3993 	RB_FOREACH(wl, winlinks, &ft->s->windows) {
3994 		if (strcmp(wl->window->name, name) == 0) {
3995 			free(name);
3996 			return (xstrdup("1"));
3997 		}
3998 	}
3999 	free(name);
4000 	return (xstrdup("0"));
4001 }
4002 
4003 /* Loop over windows. */
4004 static char *
4005 format_loop_windows(struct format_expand_state *es, const char *fmt)
4006 {
4007 	struct format_tree		*ft = es->ft;
4008 	struct client			*c = ft->client;
4009 	struct cmdq_item		*item = ft->item;
4010 	struct format_tree		*nft;
4011 	struct format_expand_state	 next;
4012 	char				*all, *active, *use, *expanded, *value;
4013 	size_t				 valuelen;
4014 	struct winlink			*wl;
4015 	struct window			*w;
4016 
4017 	if (ft->s == NULL) {
4018 		format_log(es, "window loop but no session");
4019 		return (NULL);
4020 	}
4021 
4022 	if (format_choose(es, fmt, &all, &active, 0) != 0) {
4023 		all = xstrdup(fmt);
4024 		active = NULL;
4025 	}
4026 
4027 	value = xcalloc(1, 1);
4028 	valuelen = 1;
4029 
4030 	RB_FOREACH(wl, winlinks, &ft->s->windows) {
4031 		w = wl->window;
4032 		format_log(es, "window loop: %u @%u", wl->idx, w->id);
4033 		if (active != NULL && wl == ft->s->curw)
4034 			use = active;
4035 		else
4036 			use = all;
4037 		nft = format_create(c, item, FORMAT_WINDOW|w->id, ft->flags);
4038 		format_defaults(nft, ft->c, ft->s, wl, NULL);
4039 		format_copy_state(&next, es, 0);
4040 		next.ft = nft;
4041 		expanded = format_expand1(&next, use);
4042 		format_free(nft);
4043 
4044 		valuelen += strlen(expanded);
4045 		value = xrealloc(value, valuelen);
4046 
4047 		strlcat(value, expanded, valuelen);
4048 		free(expanded);
4049 	}
4050 
4051 	free(active);
4052 	free(all);
4053 
4054 	return (value);
4055 }
4056 
4057 /* Loop over panes. */
4058 static char *
4059 format_loop_panes(struct format_expand_state *es, const char *fmt)
4060 {
4061 	struct format_tree		*ft = es->ft;
4062 	struct client			*c = ft->client;
4063 	struct cmdq_item		*item = ft->item;
4064 	struct format_tree		*nft;
4065 	struct format_expand_state	 next;
4066 	char				*all, *active, *use, *expanded, *value;
4067 	size_t				 valuelen;
4068 	struct window_pane		*wp;
4069 
4070 	if (ft->w == NULL) {
4071 		format_log(es, "pane loop but no window");
4072 		return (NULL);
4073 	}
4074 
4075 	if (format_choose(es, fmt, &all, &active, 0) != 0) {
4076 		all = xstrdup(fmt);
4077 		active = NULL;
4078 	}
4079 
4080 	value = xcalloc(1, 1);
4081 	valuelen = 1;
4082 
4083 	TAILQ_FOREACH(wp, &ft->w->panes, entry) {
4084 		format_log(es, "pane loop: %%%u", wp->id);
4085 		if (active != NULL && wp == ft->w->active)
4086 			use = active;
4087 		else
4088 			use = all;
4089 		nft = format_create(c, item, FORMAT_PANE|wp->id, ft->flags);
4090 		format_defaults(nft, ft->c, ft->s, ft->wl, wp);
4091 		format_copy_state(&next, es, 0);
4092 		next.ft = nft;
4093 		expanded = format_expand1(&next, use);
4094 		format_free(nft);
4095 
4096 		valuelen += strlen(expanded);
4097 		value = xrealloc(value, valuelen);
4098 
4099 		strlcat(value, expanded, valuelen);
4100 		free(expanded);
4101 	}
4102 
4103 	free(active);
4104 	free(all);
4105 
4106 	return (value);
4107 }
4108 
4109 /* Loop over clients. */
4110 static char *
4111 format_loop_clients(struct format_expand_state *es, const char *fmt)
4112 {
4113 	struct format_tree		*ft = es->ft;
4114 	struct client			*c = ft->client;
4115 	struct cmdq_item		*item = ft->item;
4116 	struct format_tree		*nft;
4117 	struct format_expand_state	 next;
4118 	char				*expanded, *value;
4119 	size_t				 valuelen;
4120 
4121 	value = xcalloc(1, 1);
4122 	valuelen = 1;
4123 
4124 	TAILQ_FOREACH(c, &clients, entry) {
4125 		format_log(es, "client loop: %s", c->name);
4126 		nft = format_create(c, item, 0, ft->flags);
4127 		format_defaults(nft, c, ft->s, ft->wl, ft->wp);
4128 		format_copy_state(&next, es, 0);
4129 		next.ft = nft;
4130 		expanded = format_expand1(&next, fmt);
4131 		format_free(nft);
4132 
4133 		valuelen += strlen(expanded);
4134 		value = xrealloc(value, valuelen);
4135 
4136 		strlcat(value, expanded, valuelen);
4137 		free(expanded);
4138 	}
4139 
4140 	return (value);
4141 }
4142 
4143 static char *
4144 format_replace_expression(struct format_modifier *mexp,
4145     struct format_expand_state *es, const char *copy)
4146 {
4147 	int			 argc = mexp->argc;
4148 	const char		*errstr;
4149 	char			*endch, *value, *left = NULL, *right = NULL;
4150 	int			 use_fp = 0;
4151 	u_int			 prec = 0;
4152 	double			 mleft, mright, result;
4153 	enum { ADD,
4154 	       SUBTRACT,
4155 	       MULTIPLY,
4156 	       DIVIDE,
4157 	       MODULUS,
4158 	       EQUAL,
4159 	       NOT_EQUAL,
4160 	       GREATER_THAN,
4161 	       GREATER_THAN_EQUAL,
4162 	       LESS_THAN,
4163 	       LESS_THAN_EQUAL } operator;
4164 
4165 	if (strcmp(mexp->argv[0], "+") == 0)
4166 		operator = ADD;
4167 	else if (strcmp(mexp->argv[0], "-") == 0)
4168 		operator = SUBTRACT;
4169 	else if (strcmp(mexp->argv[0], "*") == 0)
4170 		operator = MULTIPLY;
4171 	else if (strcmp(mexp->argv[0], "/") == 0)
4172 		operator = DIVIDE;
4173 	else if (strcmp(mexp->argv[0], "%") == 0 ||
4174 	    strcmp(mexp->argv[0], "m") == 0)
4175 		operator = MODULUS;
4176 	else if (strcmp(mexp->argv[0], "==") == 0)
4177 		operator = EQUAL;
4178 	else if (strcmp(mexp->argv[0], "!=") == 0)
4179 		operator = NOT_EQUAL;
4180 	else if (strcmp(mexp->argv[0], ">") == 0)
4181 		operator = GREATER_THAN;
4182 	else if (strcmp(mexp->argv[0], "<") == 0)
4183 		operator = LESS_THAN;
4184 	else if (strcmp(mexp->argv[0], ">=") == 0)
4185 		operator = GREATER_THAN_EQUAL;
4186 	else if (strcmp(mexp->argv[0], "<=") == 0)
4187 		operator = LESS_THAN_EQUAL;
4188 	else {
4189 		format_log(es, "expression has no valid operator: '%s'",
4190 		    mexp->argv[0]);
4191 		goto fail;
4192 	}
4193 
4194 	/* The second argument may be flags. */
4195 	if (argc >= 2 && strchr(mexp->argv[1], 'f') != NULL) {
4196 		use_fp = 1;
4197 		prec = 2;
4198 	}
4199 
4200 	/* The third argument may be precision. */
4201 	if (argc >= 3) {
4202 		prec = strtonum(mexp->argv[2], INT_MIN, INT_MAX, &errstr);
4203 		if (errstr != NULL) {
4204 			format_log(es, "expression precision %s: %s", errstr,
4205 			    mexp->argv[2]);
4206 			goto fail;
4207 		}
4208 	}
4209 
4210 	if (format_choose(es, copy, &left, &right, 1) != 0) {
4211 		format_log(es, "expression syntax error");
4212 		goto fail;
4213 	}
4214 
4215 	mleft = strtod(left, &endch);
4216 	if (*endch != '\0') {
4217 		format_log(es, "expression left side is invalid: %s", left);
4218 		goto fail;
4219 	}
4220 
4221 	mright = strtod(right, &endch);
4222 	if (*endch != '\0') {
4223 		format_log(es, "expression right side is invalid: %s", right);
4224 		goto fail;
4225 	}
4226 
4227 	if (!use_fp) {
4228 		mleft = (long long)mleft;
4229 		mright = (long long)mright;
4230 	}
4231 	format_log(es, "expression left side is: %.*f", prec, mleft);
4232 	format_log(es, "expression right side is: %.*f", prec, mright);
4233 
4234 	switch (operator) {
4235 	case ADD:
4236 		result = mleft + mright;
4237 		break;
4238 	case SUBTRACT:
4239 		result = mleft - mright;
4240 		break;
4241 	case MULTIPLY:
4242 		result = mleft * mright;
4243 		break;
4244 	case DIVIDE:
4245 		result = mleft / mright;
4246 		break;
4247 	case MODULUS:
4248 		result = fmod(mleft, mright);
4249 		break;
4250 	case EQUAL:
4251 		result = fabs(mleft - mright) < 1e-9;
4252 		break;
4253 	case NOT_EQUAL:
4254 		result = fabs(mleft - mright) > 1e-9;
4255 		break;
4256 	case GREATER_THAN:
4257 		result = (mleft > mright);
4258 		break;
4259 	case GREATER_THAN_EQUAL:
4260 		result = (mleft >= mright);
4261 		break;
4262 	case LESS_THAN:
4263 		result = (mleft < mright);
4264 		break;
4265 	case LESS_THAN_EQUAL:
4266 		result = (mleft <= mright);
4267 		break;
4268 	}
4269 	if (use_fp)
4270 		xasprintf(&value, "%.*f", prec, result);
4271 	else
4272 		xasprintf(&value, "%.*f", prec, (double)(long long)result);
4273 	format_log(es, "expression result is %s", value);
4274 
4275 	free(right);
4276 	free(left);
4277 	return (value);
4278 
4279 fail:
4280 	free(right);
4281 	free(left);
4282 	return (NULL);
4283 }
4284 
4285 /* Replace a key. */
4286 static int
4287 format_replace(struct format_expand_state *es, const char *key, size_t keylen,
4288     char **buf, size_t *len, size_t *off)
4289 {
4290 	struct format_tree		 *ft = es->ft;
4291 	struct window_pane		 *wp = ft->wp;
4292 	const char			 *errstr, *copy, *cp, *marker = NULL;
4293 	const char			 *time_format = NULL;
4294 	char				 *copy0, *condition, *found, *new;
4295 	char				 *value, *left, *right;
4296 	size_t				  valuelen;
4297 	int				  modifiers = 0, limit = 0, width = 0;
4298 	int				  j, c;
4299 	struct format_modifier		 *list, *cmp = NULL, *search = NULL;
4300 	struct format_modifier		**sub = NULL, *mexp = NULL, *fm;
4301 	u_int				  i, count, nsub = 0;
4302 	struct format_expand_state	  next;
4303 
4304 	/* Make a copy of the key. */
4305 	copy = copy0 = xstrndup(key, keylen);
4306 
4307 	/* Process modifier list. */
4308 	list = format_build_modifiers(es, &copy, &count);
4309 	for (i = 0; i < count; i++) {
4310 		fm = &list[i];
4311 		if (format_logging(ft)) {
4312 			format_log(es, "modifier %u is %s", i, fm->modifier);
4313 			for (j = 0; j < fm->argc; j++) {
4314 				format_log(es, "modifier %u argument %d: %s", i,
4315 				    j, fm->argv[j]);
4316 			}
4317 		}
4318 		if (fm->size == 1) {
4319 			switch (fm->modifier[0]) {
4320 			case 'm':
4321 			case '<':
4322 			case '>':
4323 				cmp = fm;
4324 				break;
4325 			case 'C':
4326 				search = fm;
4327 				break;
4328 			case 's':
4329 				if (fm->argc < 2)
4330 					break;
4331 				sub = xreallocarray(sub, nsub + 1, sizeof *sub);
4332 				sub[nsub++] = fm;
4333 				break;
4334 			case '=':
4335 				if (fm->argc < 1)
4336 					break;
4337 				limit = strtonum(fm->argv[0], INT_MIN, INT_MAX,
4338 				    &errstr);
4339 				if (errstr != NULL)
4340 					limit = 0;
4341 				if (fm->argc >= 2 && fm->argv[1] != NULL)
4342 					marker = fm->argv[1];
4343 				break;
4344 			case 'p':
4345 				if (fm->argc < 1)
4346 					break;
4347 				width = strtonum(fm->argv[0], INT_MIN, INT_MAX,
4348 				    &errstr);
4349 				if (errstr != NULL)
4350 					width = 0;
4351 				break;
4352 			case 'w':
4353 				modifiers |= FORMAT_WIDTH;
4354 				break;
4355 			case 'e':
4356 				if (fm->argc < 1 || fm->argc > 3)
4357 					break;
4358 				mexp = fm;
4359 				break;
4360 			case 'l':
4361 				modifiers |= FORMAT_LITERAL;
4362 				break;
4363 			case 'a':
4364 				modifiers |= FORMAT_CHARACTER;
4365 				break;
4366 			case 'b':
4367 				modifiers |= FORMAT_BASENAME;
4368 				break;
4369 			case 'c':
4370 				modifiers |= FORMAT_COLOUR;
4371 				break;
4372 			case 'd':
4373 				modifiers |= FORMAT_DIRNAME;
4374 				break;
4375 			case 'n':
4376 				modifiers |= FORMAT_LENGTH;
4377 				break;
4378 			case 't':
4379 				modifiers |= FORMAT_TIMESTRING;
4380 				if (fm->argc < 1)
4381 					break;
4382 				if (strchr(fm->argv[0], 'p') != NULL)
4383 					modifiers |= FORMAT_PRETTY;
4384 				else if (fm->argc >= 2 &&
4385 				    strchr(fm->argv[0], 'f') != NULL)
4386 					time_format = format_strip(fm->argv[1]);
4387 				break;
4388 			case 'q':
4389 				if (fm->argc < 1)
4390 					modifiers |= FORMAT_QUOTE_SHELL;
4391 				else if (strchr(fm->argv[0], 'e') != NULL ||
4392 				    strchr(fm->argv[0], 'h') != NULL)
4393 					modifiers |= FORMAT_QUOTE_STYLE;
4394 				break;
4395 			case 'E':
4396 				modifiers |= FORMAT_EXPAND;
4397 				break;
4398 			case 'T':
4399 				modifiers |= FORMAT_EXPANDTIME;
4400 				break;
4401 			case 'N':
4402 				if (fm->argc < 1 ||
4403 				    strchr(fm->argv[0], 'w') != NULL)
4404 					modifiers |= FORMAT_WINDOW_NAME;
4405 				else if (strchr(fm->argv[0], 's') != NULL)
4406 					modifiers |= FORMAT_SESSION_NAME;
4407 				break;
4408 			case 'S':
4409 				modifiers |= FORMAT_SESSIONS;
4410 				break;
4411 			case 'W':
4412 				modifiers |= FORMAT_WINDOWS;
4413 				break;
4414 			case 'P':
4415 				modifiers |= FORMAT_PANES;
4416 				break;
4417 			case 'L':
4418 				modifiers |= FORMAT_CLIENTS;
4419 				break;
4420 			}
4421 		} else if (fm->size == 2) {
4422 			if (strcmp(fm->modifier, "||") == 0 ||
4423 			    strcmp(fm->modifier, "&&") == 0 ||
4424 			    strcmp(fm->modifier, "==") == 0 ||
4425 			    strcmp(fm->modifier, "!=") == 0 ||
4426 			    strcmp(fm->modifier, ">=") == 0 ||
4427 			    strcmp(fm->modifier, "<=") == 0)
4428 				cmp = fm;
4429 		}
4430 	}
4431 
4432 	/* Is this a literal string? */
4433 	if (modifiers & FORMAT_LITERAL) {
4434 		format_log(es, "literal string is '%s'", copy);
4435 		value = format_unescape(copy);
4436 		goto done;
4437 	}
4438 
4439 	/* Is this a character? */
4440 	if (modifiers & FORMAT_CHARACTER) {
4441 		new = format_expand1(es, copy);
4442 		c = strtonum(new, 32, 126, &errstr);
4443 		if (errstr != NULL)
4444 			value = xstrdup("");
4445 		else
4446 			xasprintf(&value, "%c", c);
4447 		free(new);
4448 		goto done;
4449 	}
4450 
4451 	/* Is this a colour? */
4452 	if (modifiers & FORMAT_COLOUR) {
4453 		new = format_expand1(es, copy);
4454 		c = colour_fromstring(new);
4455 		if (c == -1 || (c = colour_force_rgb(c)) == -1)
4456 			value = xstrdup("");
4457 		else
4458 			xasprintf(&value, "%06x", c & 0xffffff);
4459 		free(new);
4460 		goto done;
4461 	}
4462 
4463 	/* Is this a loop, comparison or condition? */
4464 	if (modifiers & FORMAT_SESSIONS) {
4465 		value = format_loop_sessions(es, copy);
4466 		if (value == NULL)
4467 			goto fail;
4468 	} else if (modifiers & FORMAT_WINDOWS) {
4469 		value = format_loop_windows(es, copy);
4470 		if (value == NULL)
4471 			goto fail;
4472 	} else if (modifiers & FORMAT_PANES) {
4473 		value = format_loop_panes(es, copy);
4474 		if (value == NULL)
4475 			goto fail;
4476 	} else if (modifiers & FORMAT_CLIENTS) {
4477 		value = format_loop_clients(es, copy);
4478 		if (value == NULL)
4479 			goto fail;
4480 	} else if (modifiers & FORMAT_WINDOW_NAME) {
4481 		value = format_window_name(es, copy);
4482 		if (value == NULL)
4483 			goto fail;
4484 	} else if (modifiers & FORMAT_SESSION_NAME) {
4485 		value = format_session_name(es, copy);
4486 		if (value == NULL)
4487 			goto fail;
4488 	} else if (search != NULL) {
4489 		/* Search in pane. */
4490 		new = format_expand1(es, copy);
4491 		if (wp == NULL) {
4492 			format_log(es, "search '%s' but no pane", new);
4493 			value = xstrdup("0");
4494 		} else {
4495 			format_log(es, "search '%s' pane %%%u", new, wp->id);
4496 			value = format_search(search, wp, new);
4497 		}
4498 		free(new);
4499 	} else if (cmp != NULL) {
4500 		/* Comparison of left and right. */
4501 		if (format_choose(es, copy, &left, &right, 1) != 0) {
4502 			format_log(es, "compare %s syntax error: %s",
4503 			    cmp->modifier, copy);
4504 			goto fail;
4505 		}
4506 		format_log(es, "compare %s left is: %s", cmp->modifier, left);
4507 		format_log(es, "compare %s right is: %s", cmp->modifier, right);
4508 
4509 		if (strcmp(cmp->modifier, "||") == 0) {
4510 			if (format_true(left) || format_true(right))
4511 				value = xstrdup("1");
4512 			else
4513 				value = xstrdup("0");
4514 		} else if (strcmp(cmp->modifier, "&&") == 0) {
4515 			if (format_true(left) && format_true(right))
4516 				value = xstrdup("1");
4517 			else
4518 				value = xstrdup("0");
4519 		} else if (strcmp(cmp->modifier, "==") == 0) {
4520 			if (strcmp(left, right) == 0)
4521 				value = xstrdup("1");
4522 			else
4523 				value = xstrdup("0");
4524 		} else if (strcmp(cmp->modifier, "!=") == 0) {
4525 			if (strcmp(left, right) != 0)
4526 				value = xstrdup("1");
4527 			else
4528 				value = xstrdup("0");
4529 		} else if (strcmp(cmp->modifier, "<") == 0) {
4530 			if (strcmp(left, right) < 0)
4531 				value = xstrdup("1");
4532 			else
4533 				value = xstrdup("0");
4534 		} else if (strcmp(cmp->modifier, ">") == 0) {
4535 			if (strcmp(left, right) > 0)
4536 				value = xstrdup("1");
4537 			else
4538 				value = xstrdup("0");
4539 		} else if (strcmp(cmp->modifier, "<=") == 0) {
4540 			if (strcmp(left, right) <= 0)
4541 				value = xstrdup("1");
4542 			else
4543 				value = xstrdup("0");
4544 		} else if (strcmp(cmp->modifier, ">=") == 0) {
4545 			if (strcmp(left, right) >= 0)
4546 				value = xstrdup("1");
4547 			else
4548 				value = xstrdup("0");
4549 		} else if (strcmp(cmp->modifier, "m") == 0)
4550 			value = format_match(cmp, left, right);
4551 
4552 		free(right);
4553 		free(left);
4554 	} else if (*copy == '?') {
4555 		/* Conditional: check first and choose second or third. */
4556 		cp = format_skip(copy + 1, ",");
4557 		if (cp == NULL) {
4558 			format_log(es, "condition syntax error: %s", copy + 1);
4559 			goto fail;
4560 		}
4561 		condition = xstrndup(copy + 1, cp - (copy + 1));
4562 		format_log(es, "condition is: %s", condition);
4563 
4564 		found = format_find(ft, condition, modifiers, time_format);
4565 		if (found == NULL) {
4566 			/*
4567 			 * If the condition not found, try to expand it. If
4568 			 * the expansion doesn't have any effect, then assume
4569 			 * false.
4570 			 */
4571 			found = format_expand1(es, condition);
4572 			if (strcmp(found, condition) == 0) {
4573 				free(found);
4574 				found = xstrdup("");
4575 				format_log(es,
4576 				    "condition '%s' not found; assuming false",
4577 				    condition);
4578 			}
4579 		} else {
4580 			format_log(es, "condition '%s' found: %s", condition,
4581 			    found);
4582 		}
4583 
4584 		if (format_choose(es, cp + 1, &left, &right, 0) != 0) {
4585 			format_log(es, "condition '%s' syntax error: %s",
4586 			    condition, cp + 1);
4587 			free(found);
4588 			goto fail;
4589 		}
4590 		if (format_true(found)) {
4591 			format_log(es, "condition '%s' is true", condition);
4592 			value = format_expand1(es, left);
4593 		} else {
4594 			format_log(es, "condition '%s' is false", condition);
4595 			value = format_expand1(es, right);
4596 		}
4597 		free(right);
4598 		free(left);
4599 
4600 		free(condition);
4601 		free(found);
4602 	} else if (mexp != NULL) {
4603 		value = format_replace_expression(mexp, es, copy);
4604 		if (value == NULL)
4605 			value = xstrdup("");
4606 	} else {
4607 		if (strstr(copy, "#{") != 0) {
4608 			format_log(es, "expanding inner format '%s'", copy);
4609 			value = format_expand1(es, copy);
4610 		} else {
4611 			value = format_find(ft, copy, modifiers, time_format);
4612 			if (value == NULL) {
4613 				format_log(es, "format '%s' not found", copy);
4614 				value = xstrdup("");
4615 			} else {
4616 				format_log(es, "format '%s' found: %s", copy,
4617 				    value);
4618 			}
4619 		}
4620 	}
4621 
4622 done:
4623 	/* Expand again if required. */
4624 	if (modifiers & FORMAT_EXPAND) {
4625 		new = format_expand1(es, value);
4626 		free(value);
4627 		value = new;
4628 	} else if (modifiers & FORMAT_EXPANDTIME) {
4629 		format_copy_state(&next, es, FORMAT_EXPAND_TIME);
4630 		new = format_expand1(&next, value);
4631 		free(value);
4632 		value = new;
4633 	}
4634 
4635 	/* Perform substitution if any. */
4636 	for (i = 0; i < nsub; i++) {
4637 		left = format_expand1(es, sub[i]->argv[0]);
4638 		right = format_expand1(es, sub[i]->argv[1]);
4639 		new = format_sub(sub[i], value, left, right);
4640 		format_log(es, "substitute '%s' to '%s': %s", left, right, new);
4641 		free(value);
4642 		value = new;
4643 		free(right);
4644 		free(left);
4645 	}
4646 
4647 	/* Truncate the value if needed. */
4648 	if (limit > 0) {
4649 		new = format_trim_left(value, limit);
4650 		if (marker != NULL && strcmp(new, value) != 0) {
4651 			free(value);
4652 			xasprintf(&value, "%s%s", new, marker);
4653 		} else {
4654 			free(value);
4655 			value = new;
4656 		}
4657 		format_log(es, "applied length limit %d: %s", limit, value);
4658 	} else if (limit < 0) {
4659 		new = format_trim_right(value, -limit);
4660 		if (marker != NULL && strcmp(new, value) != 0) {
4661 			free(value);
4662 			xasprintf(&value, "%s%s", marker, new);
4663 		} else {
4664 			free(value);
4665 			value = new;
4666 		}
4667 		format_log(es, "applied length limit %d: %s", limit, value);
4668 	}
4669 
4670 	/* Pad the value if needed. */
4671 	if (width > 0) {
4672 		new = utf8_padcstr(value, width);
4673 		free(value);
4674 		value = new;
4675 		format_log(es, "applied padding width %d: %s", width, value);
4676 	} else if (width < 0) {
4677 		new = utf8_rpadcstr(value, -width);
4678 		free(value);
4679 		value = new;
4680 		format_log(es, "applied padding width %d: %s", width, value);
4681 	}
4682 
4683 	/* Replace with the length or width if needed. */
4684 	if (modifiers & FORMAT_LENGTH) {
4685 		xasprintf(&new, "%zu", strlen(value));
4686 		free(value);
4687 		value = new;
4688 		format_log(es, "replacing with length: %s", new);
4689 	}
4690 	if (modifiers & FORMAT_WIDTH) {
4691 		xasprintf(&new, "%u", format_width(value));
4692 		free(value);
4693 		value = new;
4694 		format_log(es, "replacing with width: %s", new);
4695 	}
4696 
4697 	/* Expand the buffer and copy in the value. */
4698 	valuelen = strlen(value);
4699 	while (*len - *off < valuelen + 1) {
4700 		*buf = xreallocarray(*buf, 2, *len);
4701 		*len *= 2;
4702 	}
4703 	memcpy(*buf + *off, value, valuelen);
4704 	*off += valuelen;
4705 
4706 	format_log(es, "replaced '%s' with '%s'", copy0, value);
4707 	free(value);
4708 
4709 	free(sub);
4710 	format_free_modifiers(list, count);
4711 	free(copy0);
4712 	return (0);
4713 
4714 fail:
4715 	format_log(es, "failed %s", copy0);
4716 
4717 	free(sub);
4718 	format_free_modifiers(list, count);
4719 	free(copy0);
4720 	return (-1);
4721 }
4722 
4723 /* Expand keys in a template. */
4724 static char *
4725 format_expand1(struct format_expand_state *es, const char *fmt)
4726 {
4727 	struct format_tree	*ft = es->ft;
4728 	char			*buf, *out, *name;
4729 	const char		*ptr, *s, *style_end = NULL;
4730 	size_t			 off, len, n, outlen;
4731 	int     		 ch, brackets;
4732 	char			 expanded[8192];
4733 
4734 	if (fmt == NULL || *fmt == '\0')
4735 		return (xstrdup(""));
4736 
4737 	if (es->loop == FORMAT_LOOP_LIMIT) {
4738 		format_log(es, "reached loop limit (%u)", FORMAT_LOOP_LIMIT);
4739 		return (xstrdup(""));
4740 	}
4741 	es->loop++;
4742 
4743 	format_log(es, "expanding format: %s", fmt);
4744 
4745 	if ((es->flags & FORMAT_EXPAND_TIME) && strchr(fmt, '%') != NULL) {
4746 		if (es->time == 0) {
4747 			es->time = time(NULL);
4748 			localtime_r(&es->time, &es->tm);
4749 		}
4750 		if (strftime(expanded, sizeof expanded, fmt, &es->tm) == 0) {
4751 			format_log(es, "format is too long");
4752 			return (xstrdup(""));
4753 		}
4754 		if (format_logging(ft) && strcmp(expanded, fmt) != 0)
4755 			format_log(es, "after time expanded: %s", expanded);
4756 		fmt = expanded;
4757 	}
4758 
4759 	len = 64;
4760 	buf = xmalloc(len);
4761 	off = 0;
4762 
4763 	while (*fmt != '\0') {
4764 		if (*fmt != '#') {
4765 			while (len - off < 2) {
4766 				buf = xreallocarray(buf, 2, len);
4767 				len *= 2;
4768 			}
4769 			buf[off++] = *fmt++;
4770 			continue;
4771 		}
4772 		fmt++;
4773 
4774 		ch = (u_char)*fmt++;
4775 		switch (ch) {
4776 		case '(':
4777 			brackets = 1;
4778 			for (ptr = fmt; *ptr != '\0'; ptr++) {
4779 				if (*ptr == '(')
4780 					brackets++;
4781 				if (*ptr == ')' && --brackets == 0)
4782 					break;
4783 			}
4784 			if (*ptr != ')' || brackets != 0)
4785 				break;
4786 			n = ptr - fmt;
4787 
4788 			name = xstrndup(fmt, n);
4789 			format_log(es, "found #(): %s", name);
4790 
4791 			if ((ft->flags & FORMAT_NOJOBS) ||
4792 			    (es->flags & FORMAT_EXPAND_NOJOBS)) {
4793 				out = xstrdup("");
4794 				format_log(es, "#() is disabled");
4795 			} else {
4796 				out = format_job_get(es, name);
4797 				format_log(es, "#() result: %s", out);
4798 			}
4799 			free(name);
4800 
4801 			outlen = strlen(out);
4802 			while (len - off < outlen + 1) {
4803 				buf = xreallocarray(buf, 2, len);
4804 				len *= 2;
4805 			}
4806 			memcpy(buf + off, out, outlen);
4807 			off += outlen;
4808 
4809 			free(out);
4810 
4811 			fmt += n + 1;
4812 			continue;
4813 		case '{':
4814 			ptr = format_skip((char *)fmt - 2, "}");
4815 			if (ptr == NULL)
4816 				break;
4817 			n = ptr - fmt;
4818 
4819 			format_log(es, "found #{}: %.*s", (int)n, fmt);
4820 			if (format_replace(es, fmt, n, &buf, &len, &off) != 0)
4821 				break;
4822 			fmt += n + 1;
4823 			continue;
4824 		case '[':
4825 		case '#':
4826 			/*
4827 			 * If ##[ (with two or more #s), then it is a style and
4828 			 * can be left for format_draw to handle.
4829 			 */
4830 			ptr = fmt - (ch == '[');
4831 			n = 2 - (ch == '[');
4832 			while (*ptr == '#') {
4833 				ptr++;
4834 				n++;
4835 			}
4836 			if (*ptr == '[') {
4837 				style_end = format_skip(fmt - 2, "]");
4838 				format_log(es, "found #*%zu[", n);
4839 				while (len - off < n + 2) {
4840 					buf = xreallocarray(buf, 2, len);
4841 					len *= 2;
4842 				}
4843 				memcpy(buf + off, fmt - 2, n + 1);
4844 				off += n + 1;
4845 				fmt = ptr + 1;
4846 				continue;
4847 			}
4848 			/* FALLTHROUGH */
4849 		case '}':
4850 		case ',':
4851 			format_log(es, "found #%c", ch);
4852 			while (len - off < 2) {
4853 				buf = xreallocarray(buf, 2, len);
4854 				len *= 2;
4855 			}
4856 			buf[off++] = ch;
4857 			continue;
4858 		default:
4859 			s = NULL;
4860 			if (fmt > style_end) { /* skip inside #[] */
4861 				if (ch >= 'A' && ch <= 'Z')
4862 					s = format_upper[ch - 'A'];
4863 				else if (ch >= 'a' && ch <= 'z')
4864 					s = format_lower[ch - 'a'];
4865 			}
4866 			if (s == NULL) {
4867 				while (len - off < 3) {
4868 					buf = xreallocarray(buf, 2, len);
4869 					len *= 2;
4870 				}
4871 				buf[off++] = '#';
4872 				buf[off++] = ch;
4873 				continue;
4874 			}
4875 			n = strlen(s);
4876 			format_log(es, "found #%c: %s", ch, s);
4877 			if (format_replace(es, s, n, &buf, &len, &off) != 0)
4878 				break;
4879 			continue;
4880 		}
4881 
4882 		break;
4883 	}
4884 	buf[off] = '\0';
4885 
4886 	format_log(es, "result is: %s", buf);
4887 	es->loop--;
4888 
4889 	return (buf);
4890 }
4891 
4892 /* Expand keys in a template, passing through strftime first. */
4893 char *
4894 format_expand_time(struct format_tree *ft, const char *fmt)
4895 {
4896 	struct format_expand_state	es;
4897 
4898 	memset(&es, 0, sizeof es);
4899 	es.ft = ft;
4900 	es.flags = FORMAT_EXPAND_TIME;
4901 	return (format_expand1(&es, fmt));
4902 }
4903 
4904 /* Expand keys in a template. */
4905 char *
4906 format_expand(struct format_tree *ft, const char *fmt)
4907 {
4908 	struct format_expand_state	es;
4909 
4910 	memset(&es, 0, sizeof es);
4911 	es.ft = ft;
4912 	es.flags = 0;
4913 	return (format_expand1(&es, fmt));
4914 }
4915 
4916 /* Expand a single string. */
4917 char *
4918 format_single(struct cmdq_item *item, const char *fmt, struct client *c,
4919     struct session *s, struct winlink *wl, struct window_pane *wp)
4920 {
4921 	struct format_tree	*ft;
4922 	char			*expanded;
4923 
4924 	ft = format_create_defaults(item, c, s, wl, wp);
4925 	expanded = format_expand(ft, fmt);
4926 	format_free(ft);
4927 	return (expanded);
4928 }
4929 
4930 /* Expand a single string using state. */
4931 char *
4932 format_single_from_state(struct cmdq_item *item, const char *fmt,
4933     struct client *c, struct cmd_find_state *fs)
4934 {
4935 	return (format_single(item, fmt, c, fs->s, fs->wl, fs->wp));
4936 }
4937 
4938 /* Expand a single string using target. */
4939 char *
4940 format_single_from_target(struct cmdq_item *item, const char *fmt)
4941 {
4942 	struct client	*tc = cmdq_get_target_client(item);
4943 
4944 	return (format_single_from_state(item, fmt, tc, cmdq_get_target(item)));
4945 }
4946 
4947 /* Create and add defaults. */
4948 struct format_tree *
4949 format_create_defaults(struct cmdq_item *item, struct client *c,
4950     struct session *s, struct winlink *wl, struct window_pane *wp)
4951 {
4952 	struct format_tree	*ft;
4953 
4954 	if (item != NULL)
4955 		ft = format_create(cmdq_get_client(item), item, FORMAT_NONE, 0);
4956 	else
4957 		ft = format_create(NULL, item, FORMAT_NONE, 0);
4958 	format_defaults(ft, c, s, wl, wp);
4959 	return (ft);
4960 }
4961 
4962 /* Create and add defaults using state. */
4963 struct format_tree *
4964 format_create_from_state(struct cmdq_item *item, struct client *c,
4965     struct cmd_find_state *fs)
4966 {
4967 	return (format_create_defaults(item, c, fs->s, fs->wl, fs->wp));
4968 }
4969 
4970 /* Create and add defaults using target. */
4971 struct format_tree *
4972 format_create_from_target(struct cmdq_item *item)
4973 {
4974 	struct client	*tc = cmdq_get_target_client(item);
4975 
4976 	return (format_create_from_state(item, tc, cmdq_get_target(item)));
4977 }
4978 
4979 /* Set defaults for any of arguments that are not NULL. */
4980 void
4981 format_defaults(struct format_tree *ft, struct client *c, struct session *s,
4982     struct winlink *wl, struct window_pane *wp)
4983 {
4984 	struct paste_buffer	*pb;
4985 
4986 	if (c != NULL && c->name != NULL)
4987 		log_debug("%s: c=%s", __func__, c->name);
4988 	else
4989 		log_debug("%s: c=none", __func__);
4990 	if (s != NULL)
4991 		log_debug("%s: s=$%u", __func__, s->id);
4992 	else
4993 		log_debug("%s: s=none", __func__);
4994 	if (wl != NULL)
4995 		log_debug("%s: wl=%u", __func__, wl->idx);
4996 	else
4997 		log_debug("%s: wl=none", __func__);
4998 	if (wp != NULL)
4999 		log_debug("%s: wp=%%%u", __func__, wp->id);
5000 	else
5001 		log_debug("%s: wp=none", __func__);
5002 
5003 	if (c != NULL && s != NULL && c->session != s)
5004 		log_debug("%s: session does not match", __func__);
5005 
5006 	if (wp != NULL)
5007 		ft->type = FORMAT_TYPE_PANE;
5008 	else if (wl != NULL)
5009 		ft->type = FORMAT_TYPE_WINDOW;
5010 	else if (s != NULL)
5011 		ft->type = FORMAT_TYPE_SESSION;
5012 	else
5013 		ft->type = FORMAT_TYPE_UNKNOWN;
5014 
5015 	if (s == NULL && c != NULL)
5016 		s = c->session;
5017 	if (wl == NULL && s != NULL)
5018 		wl = s->curw;
5019 	if (wp == NULL && wl != NULL)
5020 		wp = wl->window->active;
5021 
5022 	if (c != NULL)
5023 		format_defaults_client(ft, c);
5024 	if (s != NULL)
5025 		format_defaults_session(ft, s);
5026 	if (wl != NULL)
5027 		format_defaults_winlink(ft, wl);
5028 	if (wp != NULL)
5029 		format_defaults_pane(ft, wp);
5030 
5031 	pb = paste_get_top(NULL);
5032 	if (pb != NULL)
5033 		format_defaults_paste_buffer(ft, pb);
5034 }
5035 
5036 /* Set default format keys for a session. */
5037 static void
5038 format_defaults_session(struct format_tree *ft, struct session *s)
5039 {
5040 	ft->s = s;
5041 }
5042 
5043 /* Set default format keys for a client. */
5044 static void
5045 format_defaults_client(struct format_tree *ft, struct client *c)
5046 {
5047 	if (ft->s == NULL)
5048 		ft->s = c->session;
5049 	ft->c = c;
5050 }
5051 
5052 /* Set default format keys for a window. */
5053 void
5054 format_defaults_window(struct format_tree *ft, struct window *w)
5055 {
5056 	ft->w = w;
5057 }
5058 
5059 /* Set default format keys for a winlink. */
5060 static void
5061 format_defaults_winlink(struct format_tree *ft, struct winlink *wl)
5062 {
5063 	if (ft->w == NULL)
5064 		format_defaults_window(ft, wl->window);
5065 	ft->wl = wl;
5066 }
5067 
5068 /* Set default format keys for a window pane. */
5069 void
5070 format_defaults_pane(struct format_tree *ft, struct window_pane *wp)
5071 {
5072 	struct window_mode_entry	*wme;
5073 
5074 	if (ft->w == NULL)
5075 		format_defaults_window(ft, wp->window);
5076 	ft->wp = wp;
5077 
5078 	wme = TAILQ_FIRST(&wp->modes);
5079 	if (wme != NULL && wme->mode->formats != NULL)
5080 		wme->mode->formats(wme, ft);
5081 }
5082 
5083 /* Set default format keys for paste buffer. */
5084 void
5085 format_defaults_paste_buffer(struct format_tree *ft, struct paste_buffer *pb)
5086 {
5087 	ft->pb = pb;
5088 }
5089 
5090 /* Return word at given coordinates. Caller frees. */
5091 char *
5092 format_grid_word(struct grid *gd, u_int x, u_int y)
5093 {
5094 	const struct grid_line	*gl;
5095 	struct grid_cell	 gc;
5096 	const char		*ws;
5097 	struct utf8_data	*ud = NULL;
5098 	u_int			 end;
5099 	size_t			 size = 0;
5100 	int			 found = 0;
5101 	char			*s = NULL;
5102 
5103 	ws = options_get_string(global_s_options, "word-separators");
5104 
5105 	for (;;) {
5106 		grid_get_cell(gd, x, y, &gc);
5107 		if (gc.flags & GRID_FLAG_PADDING)
5108 			break;
5109 		if (utf8_cstrhas(ws, &gc.data) ||
5110 		    (gc.data.size == 1 && *gc.data.data == ' ')) {
5111 			found = 1;
5112 			break;
5113 		}
5114 
5115 		if (x == 0) {
5116 			if (y == 0)
5117 				break;
5118 			gl = grid_peek_line(gd, y - 1);
5119 			if (~gl->flags & GRID_LINE_WRAPPED)
5120 				break;
5121 			y--;
5122 			x = grid_line_length(gd, y);
5123 			if (x == 0)
5124 				break;
5125 		}
5126 		x--;
5127 	}
5128 	for (;;) {
5129 		if (found) {
5130 			end = grid_line_length(gd, y);
5131 			if (end == 0 || x == end - 1) {
5132 				if (y == gd->hsize + gd->sy - 1)
5133 					break;
5134 				gl = grid_peek_line(gd, y);
5135 				if (~gl->flags & GRID_LINE_WRAPPED)
5136 					break;
5137 				y++;
5138 				x = 0;
5139 			} else
5140 				x++;
5141 		}
5142 		found = 1;
5143 
5144 		grid_get_cell(gd, x, y, &gc);
5145 		if (gc.flags & GRID_FLAG_PADDING)
5146 			break;
5147 		if (utf8_cstrhas(ws, &gc.data) ||
5148 		    (gc.data.size == 1 && *gc.data.data == ' '))
5149 			break;
5150 
5151 		ud = xreallocarray(ud, size + 2, sizeof *ud);
5152 		memcpy(&ud[size++], &gc.data, sizeof *ud);
5153 	}
5154 	if (size != 0) {
5155 		ud[size].size = 0;
5156 		s = utf8_tocstr(ud);
5157 		free(ud);
5158 	}
5159 	return (s);
5160 }
5161 
5162 /* Return line at given coordinates. Caller frees. */
5163 char *
5164 format_grid_line(struct grid *gd, u_int y)
5165 {
5166 	struct grid_cell	 gc;
5167 	struct utf8_data	*ud = NULL;
5168 	u_int			 x;
5169 	size_t			 size = 0;
5170 	char			*s = NULL;
5171 
5172 	for (x = 0; x < grid_line_length(gd, y); x++) {
5173 		grid_get_cell(gd, x, y, &gc);
5174 		if (gc.flags & GRID_FLAG_PADDING)
5175 			break;
5176 
5177 		ud = xreallocarray(ud, size + 2, sizeof *ud);
5178 		memcpy(&ud[size++], &gc.data, sizeof *ud);
5179 	}
5180 	if (size != 0) {
5181 		ud[size].size = 0;
5182 		s = utf8_tocstr(ud);
5183 		free(ud);
5184 	}
5185 	return (s);
5186 }
5187 
5188 /* Return hyperlink at given coordinates. Caller frees. */
5189 char *
5190 format_grid_hyperlink(struct grid *gd, u_int x, u_int y, struct screen* s)
5191 {
5192 	const char		*uri;
5193 	struct grid_cell	 gc;
5194 
5195 	grid_get_cell(gd, x, y, &gc);
5196 	if (gc.flags & GRID_FLAG_PADDING)
5197 		return (NULL);
5198 	if (s->hyperlinks == NULL || gc.link == 0)
5199 		return (NULL);
5200 	if (!hyperlinks_get(s->hyperlinks, gc.link, &uri, NULL, NULL))
5201 		return (NULL);
5202 	return (xstrdup(uri));
5203 }
5204