xref: /openbsd-src/usr.bin/tmux/format.c (revision 6ca44032e7be0d795b9f13c99fbce059e942c15d)
1 /* $OpenBSD: format.c,v 1.312 2023/03/27 08:47:57 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 session_attached. */
2081 static void *
2082 format_cb_session_attached(struct format_tree *ft)
2083 {
2084 	if (ft->s != NULL)
2085 		return (format_printf("%u", ft->s->attached));
2086 	return (NULL);
2087 }
2088 
2089 /* Callback for session_format. */
2090 static void *
2091 format_cb_session_format(struct format_tree *ft)
2092 {
2093 	if (ft->type == FORMAT_TYPE_SESSION)
2094 		return (xstrdup("1"));
2095 	return (xstrdup("0"));
2096 }
2097 
2098 /* Callback for session_group. */
2099 static void *
2100 format_cb_session_group(struct format_tree *ft)
2101 {
2102 	struct session_group	*sg;
2103 
2104 	if (ft->s != NULL && (sg = session_group_contains(ft->s)) != NULL)
2105 		return (xstrdup(sg->name));
2106 	return (NULL);
2107 }
2108 
2109 /* Callback for session_group_attached. */
2110 static void *
2111 format_cb_session_group_attached(struct format_tree *ft)
2112 {
2113 	struct session_group	*sg;
2114 
2115 	if (ft->s != NULL && (sg = session_group_contains(ft->s)) != NULL)
2116 		return (format_printf("%u", session_group_attached_count (sg)));
2117 	return (NULL);
2118 }
2119 
2120 /* Callback for session_group_many_attached. */
2121 static void *
2122 format_cb_session_group_many_attached(struct format_tree *ft)
2123 {
2124 	struct session_group	*sg;
2125 
2126 	if (ft->s != NULL && (sg = session_group_contains(ft->s)) != NULL) {
2127 		if (session_group_attached_count (sg) > 1)
2128 			return (xstrdup("1"));
2129 		return (xstrdup("0"));
2130 	}
2131 	return (NULL);
2132 }
2133 
2134 /* Callback for session_group_size. */
2135 static void *
2136 format_cb_session_group_size(struct format_tree *ft)
2137 {
2138 	struct session_group	*sg;
2139 
2140 	if (ft->s != NULL && (sg = session_group_contains(ft->s)) != NULL)
2141 		return (format_printf("%u", session_group_count (sg)));
2142 	return (NULL);
2143 }
2144 
2145 /* Callback for session_grouped. */
2146 static void *
2147 format_cb_session_grouped(struct format_tree *ft)
2148 {
2149 	if (ft->s != NULL) {
2150 		if (session_group_contains(ft->s) != NULL)
2151 			return (xstrdup("1"));
2152 		return (xstrdup("0"));
2153 	}
2154 	return (NULL);
2155 }
2156 
2157 /* Callback for session_id. */
2158 static void *
2159 format_cb_session_id(struct format_tree *ft)
2160 {
2161 	if (ft->s != NULL)
2162 		return (format_printf("$%u", ft->s->id));
2163 	return (NULL);
2164 }
2165 
2166 /* Callback for session_many_attached. */
2167 static void *
2168 format_cb_session_many_attached(struct format_tree *ft)
2169 {
2170 	if (ft->s != NULL) {
2171 		if (ft->s->attached > 1)
2172 			return (xstrdup("1"));
2173 		return (xstrdup("0"));
2174 	}
2175 	return (NULL);
2176 }
2177 
2178 /* Callback for session_marked. */
2179 static void *
2180 format_cb_session_marked(struct format_tree *ft)
2181 {
2182 	if (ft->s != NULL) {
2183 		if (server_check_marked() && marked_pane.s == ft->s)
2184 			return (xstrdup("1"));
2185 		return (xstrdup("0"));
2186 	}
2187 	return (NULL);
2188 }
2189 
2190 /* Callback for session_name. */
2191 static void *
2192 format_cb_session_name(struct format_tree *ft)
2193 {
2194 	if (ft->s != NULL)
2195 		return (xstrdup(ft->s->name));
2196 	return (NULL);
2197 }
2198 
2199 /* Callback for session_path. */
2200 static void *
2201 format_cb_session_path(struct format_tree *ft)
2202 {
2203 	if (ft->s != NULL)
2204 		return (xstrdup(ft->s->cwd));
2205 	return (NULL);
2206 }
2207 
2208 /* Callback for session_windows. */
2209 static void *
2210 format_cb_session_windows(struct format_tree *ft)
2211 {
2212 	if (ft->s != NULL)
2213 		return (format_printf("%u", winlink_count(&ft->s->windows)));
2214 	return (NULL);
2215 }
2216 
2217 /* Callback for socket_path. */
2218 static void *
2219 format_cb_socket_path(__unused struct format_tree *ft)
2220 {
2221 	return (xstrdup(socket_path));
2222 }
2223 
2224 /* Callback for version. */
2225 static void *
2226 format_cb_version(__unused struct format_tree *ft)
2227 {
2228 	return (xstrdup(getversion()));
2229 }
2230 
2231 /* Callback for active_window_index. */
2232 static void *
2233 format_cb_active_window_index(struct format_tree *ft)
2234 {
2235 	if (ft->s != NULL)
2236 		return (format_printf("%u", ft->s->curw->idx));
2237 	return (NULL);
2238 }
2239 
2240 /* Callback for last_window_index. */
2241 static void *
2242 format_cb_last_window_index(struct format_tree *ft)
2243 {
2244 	struct winlink	*wl;
2245 
2246 	if (ft->s != NULL) {
2247 		wl = RB_MAX(winlinks, &ft->s->windows);
2248 		return (format_printf("%u", wl->idx));
2249 	}
2250 	return (NULL);
2251 }
2252 
2253 /* Callback for window_active. */
2254 static void *
2255 format_cb_window_active(struct format_tree *ft)
2256 {
2257 	if (ft->wl != NULL) {
2258 		if (ft->wl == ft->wl->session->curw)
2259 			return (xstrdup("1"));
2260 		return (xstrdup("0"));
2261 	}
2262 	return (NULL);
2263 }
2264 
2265 /* Callback for window_activity_flag. */
2266 static void *
2267 format_cb_window_activity_flag(struct format_tree *ft)
2268 {
2269 	if (ft->wl != NULL) {
2270 		if (ft->wl->flags & WINLINK_ACTIVITY)
2271 			return (xstrdup("1"));
2272 		return (xstrdup("0"));
2273 	}
2274 	return (NULL);
2275 }
2276 
2277 /* Callback for window_bell_flag. */
2278 static void *
2279 format_cb_window_bell_flag(struct format_tree *ft)
2280 {
2281 	if (ft->wl != NULL) {
2282 		if (ft->wl->flags & WINLINK_BELL)
2283 			return (xstrdup("1"));
2284 		return (xstrdup("0"));
2285 	}
2286 	return (NULL);
2287 }
2288 
2289 /* Callback for window_bigger. */
2290 static void *
2291 format_cb_window_bigger(struct format_tree *ft)
2292 {
2293 	u_int	ox, oy, sx, sy;
2294 
2295 	if (ft->c != NULL) {
2296 		if (tty_window_offset(&ft->c->tty, &ox, &oy, &sx, &sy))
2297 			return (xstrdup("1"));
2298 		return (xstrdup("0"));
2299 	}
2300 	return (NULL);
2301 }
2302 
2303 /* Callback for window_cell_height. */
2304 static void *
2305 format_cb_window_cell_height(struct format_tree *ft)
2306 {
2307 	if (ft->w != NULL)
2308 		return (format_printf("%u", ft->w->ypixel));
2309 	return (NULL);
2310 }
2311 
2312 /* Callback for window_cell_width. */
2313 static void *
2314 format_cb_window_cell_width(struct format_tree *ft)
2315 {
2316 	if (ft->w != NULL)
2317 		return (format_printf("%u", ft->w->xpixel));
2318 	return (NULL);
2319 }
2320 
2321 /* Callback for window_end_flag. */
2322 static void *
2323 format_cb_window_end_flag(struct format_tree *ft)
2324 {
2325 	if (ft->wl != NULL) {
2326 		if (ft->wl == RB_MAX(winlinks, &ft->wl->session->windows))
2327 			return (xstrdup("1"));
2328 		return (xstrdup("0"));
2329 	}
2330 	return (NULL);
2331 }
2332 
2333 /* Callback for window_flags. */
2334 static void *
2335 format_cb_window_flags(struct format_tree *ft)
2336 {
2337 	if (ft->wl != NULL)
2338 		return (xstrdup(window_printable_flags(ft->wl, 1)));
2339 	return (NULL);
2340 }
2341 
2342 /* Callback for window_format. */
2343 static void *
2344 format_cb_window_format(struct format_tree *ft)
2345 {
2346 	if (ft->type == FORMAT_TYPE_WINDOW)
2347 		return (xstrdup("1"));
2348 	return (xstrdup("0"));
2349 }
2350 
2351 /* Callback for window_height. */
2352 static void *
2353 format_cb_window_height(struct format_tree *ft)
2354 {
2355 	if (ft->w != NULL)
2356 		return (format_printf("%u", ft->w->sy));
2357 	return (NULL);
2358 }
2359 
2360 /* Callback for window_id. */
2361 static void *
2362 format_cb_window_id(struct format_tree *ft)
2363 {
2364 	if (ft->w != NULL)
2365 		return (format_printf("@%u", ft->w->id));
2366 	return (NULL);
2367 }
2368 
2369 /* Callback for window_index. */
2370 static void *
2371 format_cb_window_index(struct format_tree *ft)
2372 {
2373 	if (ft->wl != NULL)
2374 		return (format_printf("%d", ft->wl->idx));
2375 	return (NULL);
2376 }
2377 
2378 /* Callback for window_last_flag. */
2379 static void *
2380 format_cb_window_last_flag(struct format_tree *ft)
2381 {
2382 	if (ft->wl != NULL) {
2383 		if (ft->wl == TAILQ_FIRST(&ft->wl->session->lastw))
2384 			return (xstrdup("1"));
2385 		return (xstrdup("0"));
2386 	}
2387 	return (NULL);
2388 }
2389 
2390 /* Callback for window_linked. */
2391 static void *
2392 format_cb_window_linked(struct format_tree *ft)
2393 {
2394 	if (ft->wl != NULL) {
2395 		if (session_is_linked(ft->wl->session, ft->wl->window))
2396 			return (xstrdup("1"));
2397 		return (xstrdup("0"));
2398 	}
2399 	return (NULL);
2400 }
2401 
2402 /* Callback for window_linked_sessions. */
2403 static void *
2404 format_cb_window_linked_sessions(struct format_tree *ft)
2405 {
2406 	if (ft->wl != NULL)
2407 		return (format_printf("%u", ft->wl->window->references));
2408 	return (NULL);
2409 }
2410 
2411 /* Callback for window_marked_flag. */
2412 static void *
2413 format_cb_window_marked_flag(struct format_tree *ft)
2414 {
2415 	if (ft->wl != NULL) {
2416 		if (server_check_marked() && marked_pane.wl == ft->wl)
2417 			return (xstrdup("1"));
2418 		return (xstrdup("0"));
2419 	}
2420 	return (NULL);
2421 }
2422 
2423 /* Callback for window_name. */
2424 static void *
2425 format_cb_window_name(struct format_tree *ft)
2426 {
2427 	if (ft->w != NULL)
2428 		return (format_printf("%s", ft->w->name));
2429 	return (NULL);
2430 }
2431 
2432 /* Callback for window_offset_x. */
2433 static void *
2434 format_cb_window_offset_x(struct format_tree *ft)
2435 {
2436 	u_int	ox, oy, sx, sy;
2437 
2438 	if (ft->c != NULL) {
2439 		if (tty_window_offset(&ft->c->tty, &ox, &oy, &sx, &sy))
2440 			return (format_printf("%u", ox));
2441 		return (NULL);
2442 	}
2443 	return (NULL);
2444 }
2445 
2446 /* Callback for window_offset_y. */
2447 static void *
2448 format_cb_window_offset_y(struct format_tree *ft)
2449 {
2450 	u_int	ox, oy, sx, sy;
2451 
2452 	if (ft->c != NULL) {
2453 		if (tty_window_offset(&ft->c->tty, &ox, &oy, &sx, &sy))
2454 			return (format_printf("%u", oy));
2455 		return (NULL);
2456 	}
2457 	return (NULL);
2458 }
2459 
2460 /* Callback for window_panes. */
2461 static void *
2462 format_cb_window_panes(struct format_tree *ft)
2463 {
2464 	if (ft->w != NULL)
2465 		return (format_printf("%u", window_count_panes(ft->w)));
2466 	return (NULL);
2467 }
2468 
2469 /* Callback for window_raw_flags. */
2470 static void *
2471 format_cb_window_raw_flags(struct format_tree *ft)
2472 {
2473 	if (ft->wl != NULL)
2474 		return (xstrdup(window_printable_flags(ft->wl, 0)));
2475 	return (NULL);
2476 }
2477 
2478 /* Callback for window_silence_flag. */
2479 static void *
2480 format_cb_window_silence_flag(struct format_tree *ft)
2481 {
2482 	if (ft->wl != NULL) {
2483 		if (ft->wl->flags & WINLINK_SILENCE)
2484 			return (xstrdup("1"));
2485 		return (xstrdup("0"));
2486 	}
2487 	return (NULL);
2488 }
2489 
2490 /* Callback for window_start_flag. */
2491 static void *
2492 format_cb_window_start_flag(struct format_tree *ft)
2493 {
2494 	if (ft->wl != NULL) {
2495 		if (ft->wl == RB_MIN(winlinks, &ft->wl->session->windows))
2496 			return (xstrdup("1"));
2497 		return (xstrdup("0"));
2498 	}
2499 	return (NULL);
2500 }
2501 
2502 /* Callback for window_width. */
2503 static void *
2504 format_cb_window_width(struct format_tree *ft)
2505 {
2506 	if (ft->w != NULL)
2507 		return (format_printf("%u", ft->w->sx));
2508 	return (NULL);
2509 }
2510 
2511 /* Callback for window_zoomed_flag. */
2512 static void *
2513 format_cb_window_zoomed_flag(struct format_tree *ft)
2514 {
2515 	if (ft->w != NULL) {
2516 		if (ft->w->flags & WINDOW_ZOOMED)
2517 			return (xstrdup("1"));
2518 		return (xstrdup("0"));
2519 	}
2520 	return (NULL);
2521 }
2522 
2523 /* Callback for wrap_flag. */
2524 static void *
2525 format_cb_wrap_flag(struct format_tree *ft)
2526 {
2527 	if (ft->wp != NULL) {
2528 		if (ft->wp->base.mode & MODE_WRAP)
2529 			return (xstrdup("1"));
2530 		return (xstrdup("0"));
2531 	}
2532 	return (NULL);
2533 }
2534 
2535 /* Callback for buffer_created. */
2536 static void *
2537 format_cb_buffer_created(struct format_tree *ft)
2538 {
2539 	static struct timeval	 tv;
2540 
2541 	if (ft->pb != NULL) {
2542 		timerclear(&tv);
2543 		tv.tv_sec = paste_buffer_created(ft->pb);
2544 		return (&tv);
2545 	}
2546 	return (NULL);
2547 }
2548 
2549 /* Callback for client_activity. */
2550 static void *
2551 format_cb_client_activity(struct format_tree *ft)
2552 {
2553 	if (ft->c != NULL)
2554 		return (&ft->c->activity_time);
2555 	return (NULL);
2556 }
2557 
2558 /* Callback for client_created. */
2559 static void *
2560 format_cb_client_created(struct format_tree *ft)
2561 {
2562 	if (ft->c != NULL)
2563 		return (&ft->c->creation_time);
2564 	return (NULL);
2565 }
2566 
2567 /* Callback for session_activity. */
2568 static void *
2569 format_cb_session_activity(struct format_tree *ft)
2570 {
2571 	if (ft->s != NULL)
2572 		return (&ft->s->activity_time);
2573 	return (NULL);
2574 }
2575 
2576 /* Callback for session_created. */
2577 static void *
2578 format_cb_session_created(struct format_tree *ft)
2579 {
2580 	if (ft->s != NULL)
2581 		return (&ft->s->creation_time);
2582 	return (NULL);
2583 }
2584 
2585 /* Callback for session_last_attached. */
2586 static void *
2587 format_cb_session_last_attached(struct format_tree *ft)
2588 {
2589 	if (ft->s != NULL)
2590 		return (&ft->s->last_attached_time);
2591 	return (NULL);
2592 }
2593 
2594 /* Callback for start_time. */
2595 static void *
2596 format_cb_start_time(__unused struct format_tree *ft)
2597 {
2598 	return (&start_time);
2599 }
2600 
2601 /* Callback for window_activity. */
2602 static void *
2603 format_cb_window_activity(struct format_tree *ft)
2604 {
2605 	if (ft->w != NULL)
2606 		return (&ft->w->activity_time);
2607 	return (NULL);
2608 }
2609 
2610 /* Callback for buffer_mode_format, */
2611 static void *
2612 format_cb_buffer_mode_format(__unused struct format_tree *ft)
2613 {
2614 	return (xstrdup(window_buffer_mode.default_format));
2615 }
2616 
2617 /* Callback for client_mode_format, */
2618 static void *
2619 format_cb_client_mode_format(__unused struct format_tree *ft)
2620 {
2621 	return (xstrdup(window_client_mode.default_format));
2622 }
2623 
2624 /* Callback for tree_mode_format, */
2625 static void *
2626 format_cb_tree_mode_format(__unused struct format_tree *ft)
2627 {
2628 	return (xstrdup(window_tree_mode.default_format));
2629 }
2630 
2631 /* Callback for uid. */
2632 static void *
2633 format_cb_uid(__unused struct format_tree *ft)
2634 {
2635 	return (format_printf("%ld", (long)getuid()));
2636 }
2637 
2638 /* Callback for user. */
2639 static void *
2640 format_cb_user(__unused struct format_tree *ft)
2641 {
2642 	struct passwd	*pw;
2643 
2644 	if ((pw = getpwuid(getuid())) != NULL)
2645 		return (xstrdup(pw->pw_name));
2646 	return (NULL);
2647 }
2648 
2649 /* Format table type. */
2650 enum format_table_type {
2651 	FORMAT_TABLE_STRING,
2652 	FORMAT_TABLE_TIME
2653 };
2654 
2655 /* Format table entry. */
2656 struct format_table_entry {
2657 	const char		*key;
2658 	enum format_table_type	 type;
2659 	format_cb		 cb;
2660 };
2661 
2662 /*
2663  * Format table. Default format variables (that are almost always in the tree
2664  * and where the value is expanded by a callback in this file) are listed here.
2665  * Only variables which are added by the caller go into the tree.
2666  */
2667 static const struct format_table_entry format_table[] = {
2668 	{ "active_window_index", FORMAT_TABLE_STRING,
2669 	  format_cb_active_window_index
2670 	},
2671 	{ "alternate_on", FORMAT_TABLE_STRING,
2672 	  format_cb_alternate_on
2673 	},
2674 	{ "alternate_saved_x", FORMAT_TABLE_STRING,
2675 	  format_cb_alternate_saved_x
2676 	},
2677 	{ "alternate_saved_y", FORMAT_TABLE_STRING,
2678 	  format_cb_alternate_saved_y
2679 	},
2680 	{ "buffer_created", FORMAT_TABLE_TIME,
2681 	  format_cb_buffer_created
2682 	},
2683 	{ "buffer_mode_format", FORMAT_TABLE_STRING,
2684 	  format_cb_buffer_mode_format
2685 	},
2686 	{ "buffer_name", FORMAT_TABLE_STRING,
2687 	  format_cb_buffer_name
2688 	},
2689 	{ "buffer_sample", FORMAT_TABLE_STRING,
2690 	  format_cb_buffer_sample
2691 	},
2692 	{ "buffer_size", FORMAT_TABLE_STRING,
2693 	  format_cb_buffer_size
2694 	},
2695 	{ "client_activity", FORMAT_TABLE_TIME,
2696 	  format_cb_client_activity
2697 	},
2698 	{ "client_cell_height", FORMAT_TABLE_STRING,
2699 	  format_cb_client_cell_height
2700 	},
2701 	{ "client_cell_width", FORMAT_TABLE_STRING,
2702 	  format_cb_client_cell_width
2703 	},
2704 	{ "client_control_mode", FORMAT_TABLE_STRING,
2705 	  format_cb_client_control_mode
2706 	},
2707 	{ "client_created", FORMAT_TABLE_TIME,
2708 	  format_cb_client_created
2709 	},
2710 	{ "client_discarded", FORMAT_TABLE_STRING,
2711 	  format_cb_client_discarded
2712 	},
2713 	{ "client_flags", FORMAT_TABLE_STRING,
2714 	  format_cb_client_flags
2715 	},
2716 	{ "client_height", FORMAT_TABLE_STRING,
2717 	  format_cb_client_height
2718 	},
2719 	{ "client_key_table", FORMAT_TABLE_STRING,
2720 	  format_cb_client_key_table
2721 	},
2722 	{ "client_last_session", FORMAT_TABLE_STRING,
2723 	  format_cb_client_last_session
2724 	},
2725 	{ "client_mode_format", FORMAT_TABLE_STRING,
2726 	  format_cb_client_mode_format
2727 	},
2728 	{ "client_name", FORMAT_TABLE_STRING,
2729 	  format_cb_client_name
2730 	},
2731 	{ "client_pid", FORMAT_TABLE_STRING,
2732 	  format_cb_client_pid
2733 	},
2734 	{ "client_prefix", FORMAT_TABLE_STRING,
2735 	  format_cb_client_prefix
2736 	},
2737 	{ "client_readonly", FORMAT_TABLE_STRING,
2738 	  format_cb_client_readonly
2739 	},
2740 	{ "client_session", FORMAT_TABLE_STRING,
2741 	  format_cb_client_session
2742 	},
2743 	{ "client_termfeatures", FORMAT_TABLE_STRING,
2744 	  format_cb_client_termfeatures
2745 	},
2746 	{ "client_termname", FORMAT_TABLE_STRING,
2747 	  format_cb_client_termname
2748 	},
2749 	{ "client_termtype", FORMAT_TABLE_STRING,
2750 	  format_cb_client_termtype
2751 	},
2752 	{ "client_tty", FORMAT_TABLE_STRING,
2753 	  format_cb_client_tty
2754 	},
2755 	{ "client_uid", FORMAT_TABLE_STRING,
2756 	  format_cb_client_uid
2757 	},
2758 	{ "client_user", FORMAT_TABLE_STRING,
2759 	  format_cb_client_user
2760 	},
2761 	{ "client_utf8", FORMAT_TABLE_STRING,
2762 	  format_cb_client_utf8
2763 	},
2764 	{ "client_width", FORMAT_TABLE_STRING,
2765 	  format_cb_client_width
2766 	},
2767 	{ "client_written", FORMAT_TABLE_STRING,
2768 	  format_cb_client_written
2769 	},
2770 	{ "config_files", FORMAT_TABLE_STRING,
2771 	  format_cb_config_files
2772 	},
2773 	{ "cursor_character", FORMAT_TABLE_STRING,
2774 	  format_cb_cursor_character
2775 	},
2776 	{ "cursor_flag", FORMAT_TABLE_STRING,
2777 	  format_cb_cursor_flag
2778 	},
2779 	{ "cursor_x", FORMAT_TABLE_STRING,
2780 	  format_cb_cursor_x
2781 	},
2782 	{ "cursor_y", FORMAT_TABLE_STRING,
2783 	  format_cb_cursor_y
2784 	},
2785 	{ "history_all_bytes", FORMAT_TABLE_STRING,
2786 	  format_cb_history_all_bytes
2787 	},
2788 	{ "history_bytes", FORMAT_TABLE_STRING,
2789 	  format_cb_history_bytes
2790 	},
2791 	{ "history_limit", FORMAT_TABLE_STRING,
2792 	  format_cb_history_limit
2793 	},
2794 	{ "history_size", FORMAT_TABLE_STRING,
2795 	  format_cb_history_size
2796 	},
2797 	{ "host", FORMAT_TABLE_STRING,
2798 	  format_cb_host
2799 	},
2800 	{ "host_short", FORMAT_TABLE_STRING,
2801 	  format_cb_host_short
2802 	},
2803 	{ "insert_flag", FORMAT_TABLE_STRING,
2804 	  format_cb_insert_flag
2805 	},
2806 	{ "keypad_cursor_flag", FORMAT_TABLE_STRING,
2807 	  format_cb_keypad_cursor_flag
2808 	},
2809 	{ "keypad_flag", FORMAT_TABLE_STRING,
2810 	  format_cb_keypad_flag
2811 	},
2812 	{ "last_window_index", FORMAT_TABLE_STRING,
2813 	  format_cb_last_window_index
2814 	},
2815 	{ "mouse_all_flag", FORMAT_TABLE_STRING,
2816 	  format_cb_mouse_all_flag
2817 	},
2818 	{ "mouse_any_flag", FORMAT_TABLE_STRING,
2819 	  format_cb_mouse_any_flag
2820 	},
2821 	{ "mouse_button_flag", FORMAT_TABLE_STRING,
2822 	  format_cb_mouse_button_flag
2823 	},
2824 	{ "mouse_hyperlink", FORMAT_TABLE_STRING,
2825 	  format_cb_mouse_hyperlink
2826 	},
2827 	{ "mouse_line", FORMAT_TABLE_STRING,
2828 	  format_cb_mouse_line
2829 	},
2830 	{ "mouse_pane", FORMAT_TABLE_STRING,
2831 	  format_cb_mouse_pane
2832 	},
2833 	{ "mouse_sgr_flag", FORMAT_TABLE_STRING,
2834 	  format_cb_mouse_sgr_flag
2835 	},
2836 	{ "mouse_standard_flag", FORMAT_TABLE_STRING,
2837 	  format_cb_mouse_standard_flag
2838 	},
2839 	{ "mouse_utf8_flag", FORMAT_TABLE_STRING,
2840 	  format_cb_mouse_utf8_flag
2841 	},
2842 	{ "mouse_word", FORMAT_TABLE_STRING,
2843 	  format_cb_mouse_word
2844 	},
2845 	{ "mouse_x", FORMAT_TABLE_STRING,
2846 	  format_cb_mouse_x
2847 	},
2848 	{ "mouse_y", FORMAT_TABLE_STRING,
2849 	  format_cb_mouse_y
2850 	},
2851 	{ "next_session_id", FORMAT_TABLE_STRING,
2852 	  format_cb_next_session_id
2853 	},
2854 	{ "origin_flag", FORMAT_TABLE_STRING,
2855 	  format_cb_origin_flag
2856 	},
2857 	{ "pane_active", FORMAT_TABLE_STRING,
2858 	  format_cb_pane_active
2859 	},
2860 	{ "pane_at_bottom", FORMAT_TABLE_STRING,
2861 	  format_cb_pane_at_bottom
2862 	},
2863 	{ "pane_at_left", FORMAT_TABLE_STRING,
2864 	  format_cb_pane_at_left
2865 	},
2866 	{ "pane_at_right", FORMAT_TABLE_STRING,
2867 	  format_cb_pane_at_right
2868 	},
2869 	{ "pane_at_top", FORMAT_TABLE_STRING,
2870 	  format_cb_pane_at_top
2871 	},
2872 	{ "pane_bg", FORMAT_TABLE_STRING,
2873 	  format_cb_pane_bg
2874 	},
2875 	{ "pane_bottom", FORMAT_TABLE_STRING,
2876 	  format_cb_pane_bottom
2877 	},
2878 	{ "pane_current_command", FORMAT_TABLE_STRING,
2879 	  format_cb_current_command
2880 	},
2881 	{ "pane_current_path", FORMAT_TABLE_STRING,
2882 	  format_cb_current_path
2883 	},
2884 	{ "pane_dead", FORMAT_TABLE_STRING,
2885 	  format_cb_pane_dead
2886 	},
2887 	{ "pane_dead_signal", FORMAT_TABLE_STRING,
2888 	  format_cb_pane_dead_signal
2889 	},
2890 	{ "pane_dead_status", FORMAT_TABLE_STRING,
2891 	  format_cb_pane_dead_status
2892 	},
2893 	{ "pane_dead_time", FORMAT_TABLE_TIME,
2894 	  format_cb_pane_dead_time
2895 	},
2896 	{ "pane_fg", FORMAT_TABLE_STRING,
2897 	  format_cb_pane_fg
2898 	},
2899 	{ "pane_format", FORMAT_TABLE_STRING,
2900 	  format_cb_pane_format
2901 	},
2902 	{ "pane_height", FORMAT_TABLE_STRING,
2903 	  format_cb_pane_height
2904 	},
2905 	{ "pane_id", FORMAT_TABLE_STRING,
2906 	  format_cb_pane_id
2907 	},
2908 	{ "pane_in_mode", FORMAT_TABLE_STRING,
2909 	  format_cb_pane_in_mode
2910 	},
2911 	{ "pane_index", FORMAT_TABLE_STRING,
2912 	  format_cb_pane_index
2913 	},
2914 	{ "pane_input_off", FORMAT_TABLE_STRING,
2915 	  format_cb_pane_input_off
2916 	},
2917 	{ "pane_last", FORMAT_TABLE_STRING,
2918 	  format_cb_pane_last
2919 	},
2920 	{ "pane_left", FORMAT_TABLE_STRING,
2921 	  format_cb_pane_left
2922 	},
2923 	{ "pane_marked", FORMAT_TABLE_STRING,
2924 	  format_cb_pane_marked
2925 	},
2926 	{ "pane_marked_set", FORMAT_TABLE_STRING,
2927 	  format_cb_pane_marked_set
2928 	},
2929 	{ "pane_mode", FORMAT_TABLE_STRING,
2930 	  format_cb_pane_mode
2931 	},
2932 	{ "pane_path", FORMAT_TABLE_STRING,
2933 	  format_cb_pane_path
2934 	},
2935 	{ "pane_pid", FORMAT_TABLE_STRING,
2936 	  format_cb_pane_pid
2937 	},
2938 	{ "pane_pipe", FORMAT_TABLE_STRING,
2939 	  format_cb_pane_pipe
2940 	},
2941 	{ "pane_right", FORMAT_TABLE_STRING,
2942 	  format_cb_pane_right
2943 	},
2944 	{ "pane_search_string", FORMAT_TABLE_STRING,
2945 	  format_cb_pane_search_string
2946 	},
2947 	{ "pane_start_command", FORMAT_TABLE_STRING,
2948 	  format_cb_start_command
2949 	},
2950 	{ "pane_start_path", FORMAT_TABLE_STRING,
2951 	  format_cb_start_path
2952 	},
2953 	{ "pane_synchronized", FORMAT_TABLE_STRING,
2954 	  format_cb_pane_synchronized
2955 	},
2956 	{ "pane_tabs", FORMAT_TABLE_STRING,
2957 	  format_cb_pane_tabs
2958 	},
2959 	{ "pane_title", FORMAT_TABLE_STRING,
2960 	  format_cb_pane_title
2961 	},
2962 	{ "pane_top", FORMAT_TABLE_STRING,
2963 	  format_cb_pane_top
2964 	},
2965 	{ "pane_tty", FORMAT_TABLE_STRING,
2966 	  format_cb_pane_tty
2967 	},
2968 	{ "pane_unseen_changes", FORMAT_TABLE_STRING,
2969 	  format_cb_pane_unseen_changes
2970 	},
2971 	{ "pane_width", FORMAT_TABLE_STRING,
2972 	  format_cb_pane_width
2973 	},
2974 	{ "pid", FORMAT_TABLE_STRING,
2975 	  format_cb_pid
2976 	},
2977 	{ "scroll_region_lower", FORMAT_TABLE_STRING,
2978 	  format_cb_scroll_region_lower
2979 	},
2980 	{ "scroll_region_upper", FORMAT_TABLE_STRING,
2981 	  format_cb_scroll_region_upper
2982 	},
2983 	{ "session_activity", FORMAT_TABLE_TIME,
2984 	  format_cb_session_activity
2985 	},
2986 	{ "session_alerts", FORMAT_TABLE_STRING,
2987 	  format_cb_session_alerts
2988 	},
2989 	{ "session_attached", FORMAT_TABLE_STRING,
2990 	  format_cb_session_attached
2991 	},
2992 	{ "session_attached_list", FORMAT_TABLE_STRING,
2993 	  format_cb_session_attached_list
2994 	},
2995 	{ "session_created", FORMAT_TABLE_TIME,
2996 	  format_cb_session_created
2997 	},
2998 	{ "session_format", FORMAT_TABLE_STRING,
2999 	  format_cb_session_format
3000 	},
3001 	{ "session_group", FORMAT_TABLE_STRING,
3002 	  format_cb_session_group
3003 	},
3004 	{ "session_group_attached", FORMAT_TABLE_STRING,
3005 	  format_cb_session_group_attached
3006 	},
3007 	{ "session_group_attached_list", FORMAT_TABLE_STRING,
3008 	  format_cb_session_group_attached_list
3009 	},
3010 	{ "session_group_list", FORMAT_TABLE_STRING,
3011 	  format_cb_session_group_list
3012 	},
3013 	{ "session_group_many_attached", FORMAT_TABLE_STRING,
3014 	  format_cb_session_group_many_attached
3015 	},
3016 	{ "session_group_size", FORMAT_TABLE_STRING,
3017 	  format_cb_session_group_size
3018 	},
3019 	{ "session_grouped", FORMAT_TABLE_STRING,
3020 	  format_cb_session_grouped
3021 	},
3022 	{ "session_id", FORMAT_TABLE_STRING,
3023 	  format_cb_session_id
3024 	},
3025 	{ "session_last_attached", FORMAT_TABLE_TIME,
3026 	  format_cb_session_last_attached
3027 	},
3028 	{ "session_many_attached", FORMAT_TABLE_STRING,
3029 	  format_cb_session_many_attached
3030 	},
3031 	{ "session_marked", FORMAT_TABLE_STRING,
3032 	  format_cb_session_marked,
3033 	},
3034 	{ "session_name", FORMAT_TABLE_STRING,
3035 	  format_cb_session_name
3036 	},
3037 	{ "session_path", FORMAT_TABLE_STRING,
3038 	  format_cb_session_path
3039 	},
3040 	{ "session_stack", FORMAT_TABLE_STRING,
3041 	  format_cb_session_stack
3042 	},
3043 	{ "session_windows", FORMAT_TABLE_STRING,
3044 	  format_cb_session_windows
3045 	},
3046 	{ "socket_path", FORMAT_TABLE_STRING,
3047 	  format_cb_socket_path
3048 	},
3049 	{ "start_time", FORMAT_TABLE_TIME,
3050 	  format_cb_start_time
3051 	},
3052 	{ "tree_mode_format", FORMAT_TABLE_STRING,
3053 	  format_cb_tree_mode_format
3054 	},
3055 	{ "uid", FORMAT_TABLE_STRING,
3056 	  format_cb_uid
3057 	},
3058 	{ "user", FORMAT_TABLE_STRING,
3059 	  format_cb_user
3060 	},
3061 	{ "version", FORMAT_TABLE_STRING,
3062 	  format_cb_version
3063 	},
3064 	{ "window_active", FORMAT_TABLE_STRING,
3065 	  format_cb_window_active
3066 	},
3067 	{ "window_active_clients", FORMAT_TABLE_STRING,
3068 	  format_cb_window_active_clients
3069 	},
3070 	{ "window_active_clients_list", FORMAT_TABLE_STRING,
3071 	  format_cb_window_active_clients_list
3072 	},
3073 	{ "window_active_sessions", FORMAT_TABLE_STRING,
3074 	  format_cb_window_active_sessions
3075 	},
3076 	{ "window_active_sessions_list", FORMAT_TABLE_STRING,
3077 	  format_cb_window_active_sessions_list
3078 	},
3079 	{ "window_activity", FORMAT_TABLE_TIME,
3080 	  format_cb_window_activity
3081 	},
3082 	{ "window_activity_flag", FORMAT_TABLE_STRING,
3083 	  format_cb_window_activity_flag
3084 	},
3085 	{ "window_bell_flag", FORMAT_TABLE_STRING,
3086 	  format_cb_window_bell_flag
3087 	},
3088 	{ "window_bigger", FORMAT_TABLE_STRING,
3089 	  format_cb_window_bigger
3090 	},
3091 	{ "window_cell_height", FORMAT_TABLE_STRING,
3092 	  format_cb_window_cell_height
3093 	},
3094 	{ "window_cell_width", FORMAT_TABLE_STRING,
3095 	  format_cb_window_cell_width
3096 	},
3097 	{ "window_end_flag", FORMAT_TABLE_STRING,
3098 	  format_cb_window_end_flag
3099 	},
3100 	{ "window_flags", FORMAT_TABLE_STRING,
3101 	  format_cb_window_flags
3102 	},
3103 	{ "window_format", FORMAT_TABLE_STRING,
3104 	  format_cb_window_format
3105 	},
3106 	{ "window_height", FORMAT_TABLE_STRING,
3107 	  format_cb_window_height
3108 	},
3109 	{ "window_id", FORMAT_TABLE_STRING,
3110 	  format_cb_window_id
3111 	},
3112 	{ "window_index", FORMAT_TABLE_STRING,
3113 	  format_cb_window_index
3114 	},
3115 	{ "window_last_flag", FORMAT_TABLE_STRING,
3116 	  format_cb_window_last_flag
3117 	},
3118 	{ "window_layout", FORMAT_TABLE_STRING,
3119 	  format_cb_window_layout
3120 	},
3121 	{ "window_linked", FORMAT_TABLE_STRING,
3122 	  format_cb_window_linked
3123 	},
3124 	{ "window_linked_sessions", FORMAT_TABLE_STRING,
3125 	  format_cb_window_linked_sessions
3126 	},
3127 	{ "window_linked_sessions_list", FORMAT_TABLE_STRING,
3128 	  format_cb_window_linked_sessions_list
3129 	},
3130 	{ "window_marked_flag", FORMAT_TABLE_STRING,
3131 	  format_cb_window_marked_flag
3132 	},
3133 	{ "window_name", FORMAT_TABLE_STRING,
3134 	  format_cb_window_name
3135 	},
3136 	{ "window_offset_x", FORMAT_TABLE_STRING,
3137 	  format_cb_window_offset_x
3138 	},
3139 	{ "window_offset_y", FORMAT_TABLE_STRING,
3140 	  format_cb_window_offset_y
3141 	},
3142 	{ "window_panes", FORMAT_TABLE_STRING,
3143 	  format_cb_window_panes
3144 	},
3145 	{ "window_raw_flags", FORMAT_TABLE_STRING,
3146 	  format_cb_window_raw_flags
3147 	},
3148 	{ "window_silence_flag", FORMAT_TABLE_STRING,
3149 	  format_cb_window_silence_flag
3150 	},
3151 	{ "window_stack_index", FORMAT_TABLE_STRING,
3152 	  format_cb_window_stack_index
3153 	},
3154 	{ "window_start_flag", FORMAT_TABLE_STRING,
3155 	  format_cb_window_start_flag
3156 	},
3157 	{ "window_visible_layout", FORMAT_TABLE_STRING,
3158 	  format_cb_window_visible_layout
3159 	},
3160 	{ "window_width", FORMAT_TABLE_STRING,
3161 	  format_cb_window_width
3162 	},
3163 	{ "window_zoomed_flag", FORMAT_TABLE_STRING,
3164 	  format_cb_window_zoomed_flag
3165 	},
3166 	{ "wrap_flag", FORMAT_TABLE_STRING,
3167 	  format_cb_wrap_flag
3168 	}
3169 };
3170 
3171 /* Compare format table entries. */
3172 static int
3173 format_table_compare(const void *key0, const void *entry0)
3174 {
3175 	const char			*key = key0;
3176 	const struct format_table_entry	*entry = entry0;
3177 
3178 	return (strcmp(key, entry->key));
3179 }
3180 
3181 /* Get a format callback. */
3182 static struct format_table_entry *
3183 format_table_get(const char *key)
3184 {
3185 	return (bsearch(key, format_table, nitems(format_table),
3186 	    sizeof *format_table, format_table_compare));
3187 }
3188 
3189 /* Merge one format tree into another. */
3190 void
3191 format_merge(struct format_tree *ft, struct format_tree *from)
3192 {
3193 	struct format_entry	*fe;
3194 
3195 	RB_FOREACH(fe, format_entry_tree, &from->tree) {
3196 		if (fe->value != NULL)
3197 			format_add(ft, fe->key, "%s", fe->value);
3198 	}
3199 }
3200 
3201 /* Get format pane. */
3202 struct window_pane *
3203 format_get_pane(struct format_tree *ft)
3204 {
3205 	return (ft->wp);
3206 }
3207 
3208 /* Add item bits to tree. */
3209 static void
3210 format_create_add_item(struct format_tree *ft, struct cmdq_item *item)
3211 {
3212 	struct key_event	*event = cmdq_get_event(item);
3213 	struct mouse_event	*m = &event->m;
3214 
3215 	cmdq_merge_formats(item, ft);
3216 	memcpy(&ft->m, m, sizeof ft->m);
3217 }
3218 
3219 /* Create a new tree. */
3220 struct format_tree *
3221 format_create(struct client *c, struct cmdq_item *item, int tag, int flags)
3222 {
3223 	struct format_tree	*ft;
3224 
3225 	ft = xcalloc(1, sizeof *ft);
3226 	RB_INIT(&ft->tree);
3227 
3228 	if (c != NULL) {
3229 		ft->client = c;
3230 		ft->client->references++;
3231 	}
3232 	ft->item = item;
3233 
3234 	ft->tag = tag;
3235 	ft->flags = flags;
3236 
3237 	if (item != NULL)
3238 		format_create_add_item(ft, item);
3239 
3240 	return (ft);
3241 }
3242 
3243 /* Free a tree. */
3244 void
3245 format_free(struct format_tree *ft)
3246 {
3247 	struct format_entry	*fe, *fe1;
3248 
3249 	RB_FOREACH_SAFE(fe, format_entry_tree, &ft->tree, fe1) {
3250 		RB_REMOVE(format_entry_tree, &ft->tree, fe);
3251 		free(fe->value);
3252 		free(fe->key);
3253 		free(fe);
3254 	}
3255 
3256 	if (ft->client != NULL)
3257 		server_client_unref(ft->client);
3258 	free(ft);
3259 }
3260 
3261 /* Log each format. */
3262 static void
3263 format_log_debug_cb(const char *key, const char *value, void *arg)
3264 {
3265 	const char	*prefix = arg;
3266 
3267 	log_debug("%s: %s=%s", prefix, key, value);
3268 }
3269 
3270 /* Log a format tree. */
3271 void
3272 format_log_debug(struct format_tree *ft, const char *prefix)
3273 {
3274 	format_each(ft, format_log_debug_cb, (void *)prefix);
3275 }
3276 
3277 /* Walk each format. */
3278 void
3279 format_each(struct format_tree *ft, void (*cb)(const char *, const char *,
3280     void *), void *arg)
3281 {
3282 	const struct format_table_entry	*fte;
3283 	struct format_entry		*fe;
3284 	u_int				 i;
3285 	char				 s[64];
3286 	void				*value;
3287 	struct timeval			*tv;
3288 
3289 	for (i = 0; i < nitems(format_table); i++) {
3290 		fte = &format_table[i];
3291 
3292 		value = fte->cb(ft);
3293 		if (value == NULL)
3294 			continue;
3295 		if (fte->type == FORMAT_TABLE_TIME) {
3296 			tv = value;
3297 			xsnprintf(s, sizeof s, "%lld", (long long)tv->tv_sec);
3298 			cb(fte->key, s, arg);
3299 		} else {
3300 			cb(fte->key, value, arg);
3301 			free(value);
3302 		}
3303 	}
3304 	RB_FOREACH(fe, format_entry_tree, &ft->tree) {
3305 		if (fe->time != 0) {
3306 			xsnprintf(s, sizeof s, "%lld", (long long)fe->time);
3307 			cb(fe->key, s, arg);
3308 		} else {
3309 			if (fe->value == NULL && fe->cb != NULL) {
3310 				fe->value = fe->cb(ft);
3311 				if (fe->value == NULL)
3312 					fe->value = xstrdup("");
3313 			}
3314 			cb(fe->key, fe->value, arg);
3315 		}
3316 	}
3317 }
3318 
3319 /* Add a key-value pair. */
3320 void
3321 format_add(struct format_tree *ft, const char *key, const char *fmt, ...)
3322 {
3323 	struct format_entry	*fe;
3324 	struct format_entry	*fe_now;
3325 	va_list			 ap;
3326 
3327 	fe = xmalloc(sizeof *fe);
3328 	fe->key = xstrdup(key);
3329 
3330 	fe_now = RB_INSERT(format_entry_tree, &ft->tree, fe);
3331 	if (fe_now != NULL) {
3332 		free(fe->key);
3333 		free(fe);
3334 		free(fe_now->value);
3335 		fe = fe_now;
3336 	}
3337 
3338 	fe->cb = NULL;
3339 	fe->time = 0;
3340 
3341 	va_start(ap, fmt);
3342 	xvasprintf(&fe->value, fmt, ap);
3343 	va_end(ap);
3344 }
3345 
3346 /* Add a key and time. */
3347 void
3348 format_add_tv(struct format_tree *ft, const char *key, struct timeval *tv)
3349 {
3350 	struct format_entry	*fe, *fe_now;
3351 
3352 	fe = xmalloc(sizeof *fe);
3353 	fe->key = xstrdup(key);
3354 
3355 	fe_now = RB_INSERT(format_entry_tree, &ft->tree, fe);
3356 	if (fe_now != NULL) {
3357 		free(fe->key);
3358 		free(fe);
3359 		free(fe_now->value);
3360 		fe = fe_now;
3361 	}
3362 
3363 	fe->cb = NULL;
3364 	fe->time = tv->tv_sec;
3365 
3366 	fe->value = NULL;
3367 }
3368 
3369 /* Add a key and function. */
3370 void
3371 format_add_cb(struct format_tree *ft, const char *key, format_cb cb)
3372 {
3373 	struct format_entry	*fe;
3374 	struct format_entry	*fe_now;
3375 
3376 	fe = xmalloc(sizeof *fe);
3377 	fe->key = xstrdup(key);
3378 
3379 	fe_now = RB_INSERT(format_entry_tree, &ft->tree, fe);
3380 	if (fe_now != NULL) {
3381 		free(fe->key);
3382 		free(fe);
3383 		free(fe_now->value);
3384 		fe = fe_now;
3385 	}
3386 
3387 	fe->cb = cb;
3388 	fe->time = 0;
3389 
3390 	fe->value = NULL;
3391 }
3392 
3393 /* Quote shell special characters in string. */
3394 static char *
3395 format_quote_shell(const char *s)
3396 {
3397 	const char	*cp;
3398 	char		*out, *at;
3399 
3400 	at = out = xmalloc(strlen(s) * 2 + 1);
3401 	for (cp = s; *cp != '\0'; cp++) {
3402 		if (strchr("|&;<>()$`\\\"'*?[# =%", *cp) != NULL)
3403 			*at++ = '\\';
3404 		*at++ = *cp;
3405 	}
3406 	*at = '\0';
3407 	return (out);
3408 }
3409 
3410 /* Quote #s in string. */
3411 static char *
3412 format_quote_style(const char *s)
3413 {
3414 	const char	*cp;
3415 	char		*out, *at;
3416 
3417 	at = out = xmalloc(strlen(s) * 2 + 1);
3418 	for (cp = s; *cp != '\0'; cp++) {
3419 		if (*cp == '#')
3420 			*at++ = '#';
3421 		*at++ = *cp;
3422 	}
3423 	*at = '\0';
3424 	return (out);
3425 }
3426 
3427 /* Make a prettier time. */
3428 char *
3429 format_pretty_time(time_t t, int seconds)
3430 {
3431 	struct tm       now_tm, tm;
3432 	time_t		now, age;
3433 	char		s[9];
3434 
3435 	time(&now);
3436 	if (now < t)
3437 		now = t;
3438 	age = now - t;
3439 
3440 	localtime_r(&now, &now_tm);
3441 	localtime_r(&t, &tm);
3442 
3443 	/* Last 24 hours. */
3444 	if (age < 24 * 3600) {
3445 		if (seconds)
3446 			strftime(s, sizeof s, "%H:%M:%S", &tm);
3447 		else
3448 			strftime(s, sizeof s, "%H:%M", &tm);
3449 		return (xstrdup(s));
3450 	}
3451 
3452 	/* This month or last 28 days. */
3453 	if ((tm.tm_year == now_tm.tm_year && tm.tm_mon == now_tm.tm_mon) ||
3454 	    age < 28 * 24 * 3600) {
3455 		strftime(s, sizeof s, "%a%d", &tm);
3456 		return (xstrdup(s));
3457 	}
3458 
3459 	/* Last 12 months. */
3460 	if ((tm.tm_year == now_tm.tm_year && tm.tm_mon < now_tm.tm_mon) ||
3461 	    (tm.tm_year == now_tm.tm_year - 1 && tm.tm_mon > now_tm.tm_mon)) {
3462 		strftime(s, sizeof s, "%d%b", &tm);
3463 		return (xstrdup(s));
3464 	}
3465 
3466 	/* Older than that. */
3467 	strftime(s, sizeof s, "%h%y", &tm);
3468 	return (xstrdup(s));
3469 }
3470 
3471 /* Find a format entry. */
3472 static char *
3473 format_find(struct format_tree *ft, const char *key, int modifiers,
3474     const char *time_format)
3475 {
3476 	struct format_table_entry	*fte;
3477 	void				*value;
3478 	struct format_entry		*fe, fe_find;
3479 	struct environ_entry		*envent;
3480 	struct options_entry		*o;
3481 	int				 idx;
3482 	char				*found = NULL, *saved, s[512];
3483 	const char			*errstr;
3484 	time_t				 t = 0;
3485 	struct tm			 tm;
3486 
3487 	o = options_parse_get(global_options, key, &idx, 0);
3488 	if (o == NULL && ft->wp != NULL)
3489 		o = options_parse_get(ft->wp->options, key, &idx, 0);
3490 	if (o == NULL && ft->w != NULL)
3491 		o = options_parse_get(ft->w->options, key, &idx, 0);
3492 	if (o == NULL)
3493 		o = options_parse_get(global_w_options, key, &idx, 0);
3494 	if (o == NULL && ft->s != NULL)
3495 		o = options_parse_get(ft->s->options, key, &idx, 0);
3496 	if (o == NULL)
3497 		o = options_parse_get(global_s_options, key, &idx, 0);
3498 	if (o != NULL) {
3499 		found = options_to_string(o, idx, 1);
3500 		goto found;
3501 	}
3502 
3503 	fte = format_table_get(key);
3504 	if (fte != NULL) {
3505 		value = fte->cb(ft);
3506 		if (fte->type == FORMAT_TABLE_TIME && value != NULL)
3507 			t = ((struct timeval *)value)->tv_sec;
3508 		else
3509 			found = value;
3510 		goto found;
3511 	}
3512 	fe_find.key = (char *)key;
3513 	fe = RB_FIND(format_entry_tree, &ft->tree, &fe_find);
3514 	if (fe != NULL) {
3515 		if (fe->time != 0) {
3516 			t = fe->time;
3517 			goto found;
3518 		}
3519 		if (fe->value == NULL && fe->cb != NULL) {
3520 			fe->value = fe->cb(ft);
3521 			if (fe->value == NULL)
3522 				fe->value = xstrdup("");
3523 		}
3524 		found = xstrdup(fe->value);
3525 		goto found;
3526 	}
3527 
3528 	if (~modifiers & FORMAT_TIMESTRING) {
3529 		envent = NULL;
3530 		if (ft->s != NULL)
3531 			envent = environ_find(ft->s->environ, key);
3532 		if (envent == NULL)
3533 			envent = environ_find(global_environ, key);
3534 		if (envent != NULL && envent->value != NULL) {
3535 			found = xstrdup(envent->value);
3536 			goto found;
3537 		}
3538 	}
3539 
3540 	return (NULL);
3541 
3542 found:
3543 	if (modifiers & FORMAT_TIMESTRING) {
3544 		if (t == 0 && found != NULL) {
3545 			t = strtonum(found, 0, INT64_MAX, &errstr);
3546 			if (errstr != NULL)
3547 				t = 0;
3548 			free(found);
3549 		}
3550 		if (t == 0)
3551 			return (NULL);
3552 		if (modifiers & FORMAT_PRETTY)
3553 			found = format_pretty_time(t, 0);
3554 		else {
3555 			if (time_format != NULL) {
3556 				localtime_r(&t, &tm);
3557 				strftime(s, sizeof s, time_format, &tm);
3558 			} else {
3559 				ctime_r(&t, s);
3560 				s[strcspn(s, "\n")] = '\0';
3561 			}
3562 			found = xstrdup(s);
3563 		}
3564 		return (found);
3565 	}
3566 
3567 	if (t != 0)
3568 		xasprintf(&found, "%lld", (long long)t);
3569 	else if (found == NULL)
3570 		return (NULL);
3571 	if (modifiers & FORMAT_BASENAME) {
3572 		saved = found;
3573 		found = xstrdup(basename(saved));
3574 		free(saved);
3575 	}
3576 	if (modifiers & FORMAT_DIRNAME) {
3577 		saved = found;
3578 		found = xstrdup(dirname(saved));
3579 		free(saved);
3580 	}
3581 	if (modifiers & FORMAT_QUOTE_SHELL) {
3582 		saved = found;
3583 		found = format_quote_shell(saved);
3584 		free(saved);
3585 	}
3586 	if (modifiers & FORMAT_QUOTE_STYLE) {
3587 		saved = found;
3588 		found = format_quote_style(saved);
3589 		free(saved);
3590 	}
3591 	return (found);
3592 }
3593 
3594 /* Unescape escaped characters. */
3595 static char *
3596 format_unescape(const char *s)
3597 {
3598 	char	*out, *cp;
3599 	int	 brackets = 0;
3600 
3601 	cp = out = xmalloc(strlen(s) + 1);
3602 	for (; *s != '\0'; s++) {
3603 		if (*s == '#' && s[1] == '{')
3604 			brackets++;
3605 		if (brackets == 0 &&
3606 		    *s == '#' &&
3607 		    strchr(",#{}:", s[1]) != NULL) {
3608 			*cp++ = *++s;
3609  			continue;
3610 		}
3611 		if (*s == '}')
3612 			brackets--;
3613 		*cp++ = *s;
3614 	}
3615 	*cp = '\0';
3616 	return (out);
3617 }
3618 
3619 /* Remove escaped characters. */
3620 static char *
3621 format_strip(const char *s)
3622 {
3623 	char	*out, *cp;
3624 	int	 brackets = 0;
3625 
3626 	cp = out = xmalloc(strlen(s) + 1);
3627 	for (; *s != '\0'; s++) {
3628 		if (*s == '#' && s[1] == '{')
3629 			brackets++;
3630 		if (*s == '#' && strchr(",#{}:", s[1]) != NULL) {
3631 			if (brackets != 0)
3632 				*cp++ = *s;
3633 			continue;
3634 		}
3635 		if (*s == '}')
3636 			brackets--;
3637 		*cp++ = *s;
3638 	}
3639 	*cp = '\0';
3640 	return (out);
3641 }
3642 
3643 /* Skip until end. */
3644 const char *
3645 format_skip(const char *s, const char *end)
3646 {
3647 	int	brackets = 0;
3648 
3649 	for (; *s != '\0'; s++) {
3650 		if (*s == '#' && s[1] == '{')
3651 			brackets++;
3652 		if (*s == '#' && strchr(",#{}:", s[1]) != NULL) {
3653 			s++;
3654 			continue;
3655 		}
3656 		if (*s == '}')
3657 			brackets--;
3658 		if (strchr(end, *s) != NULL && brackets == 0)
3659 			break;
3660 	}
3661 	if (*s == '\0')
3662 		return (NULL);
3663 	return (s);
3664 }
3665 
3666 /* Return left and right alternatives separated by commas. */
3667 static int
3668 format_choose(struct format_expand_state *es, const char *s, char **left,
3669     char **right, int expand)
3670 {
3671 	const char	*cp;
3672 	char		*left0, *right0;
3673 
3674 	cp = format_skip(s, ",");
3675 	if (cp == NULL)
3676 		return (-1);
3677 	left0 = xstrndup(s, cp - s);
3678 	right0 = xstrdup(cp + 1);
3679 
3680 	if (expand) {
3681 		*left = format_expand1(es, left0);
3682 		free(left0);
3683 		*right = format_expand1(es, right0);
3684 		free(right0);
3685 	} else {
3686 		*left = left0;
3687 		*right = right0;
3688 	}
3689 	return (0);
3690 }
3691 
3692 /* Is this true? */
3693 int
3694 format_true(const char *s)
3695 {
3696 	if (s != NULL && *s != '\0' && (s[0] != '0' || s[1] != '\0'))
3697 		return (1);
3698 	return (0);
3699 }
3700 
3701 /* Check if modifier end. */
3702 static int
3703 format_is_end(char c)
3704 {
3705 	return (c == ';' || c == ':');
3706 }
3707 
3708 /* Add to modifier list. */
3709 static void
3710 format_add_modifier(struct format_modifier **list, u_int *count,
3711     const char *c, size_t n, char **argv, int argc)
3712 {
3713 	struct format_modifier *fm;
3714 
3715 	*list = xreallocarray(*list, (*count) + 1, sizeof **list);
3716 	fm = &(*list)[(*count)++];
3717 
3718 	memcpy(fm->modifier, c, n);
3719 	fm->modifier[n] = '\0';
3720 	fm->size = n;
3721 
3722 	fm->argv = argv;
3723 	fm->argc = argc;
3724 }
3725 
3726 /* Free modifier list. */
3727 static void
3728 format_free_modifiers(struct format_modifier *list, u_int count)
3729 {
3730 	u_int	i;
3731 
3732 	for (i = 0; i < count; i++)
3733 		cmd_free_argv(list[i].argc, list[i].argv);
3734 	free(list);
3735 }
3736 
3737 /* Build modifier list. */
3738 static struct format_modifier *
3739 format_build_modifiers(struct format_expand_state *es, const char **s,
3740     u_int *count)
3741 {
3742 	const char		*cp = *s, *end;
3743 	struct format_modifier	*list = NULL;
3744 	char			 c, last[] = "X;:", **argv, *value;
3745 	int			 argc;
3746 
3747 	/*
3748 	 * Modifiers are a ; separated list of the forms:
3749 	 *      l,m,C,a,b,c,d,n,t,w,q,E,T,S,W,P,<,>
3750 	 *	=a
3751 	 *	=/a
3752 	 *      =/a/
3753 	 *	s/a/b/
3754 	 *	s/a/b
3755 	 *	||,&&,!=,==,<=,>=
3756 	 */
3757 
3758 	*count = 0;
3759 
3760 	while (*cp != '\0' && *cp != ':') {
3761 		/* Skip any separator character. */
3762 		if (*cp == ';')
3763 			cp++;
3764 
3765 		/* Check single character modifiers with no arguments. */
3766 		if (strchr("labcdnwETSWPL<>", cp[0]) != NULL &&
3767 		    format_is_end(cp[1])) {
3768 			format_add_modifier(&list, count, cp, 1, NULL, 0);
3769 			cp++;
3770 			continue;
3771 		}
3772 
3773 		/* Then try double character with no arguments. */
3774 		if ((memcmp("||", cp, 2) == 0 ||
3775 		    memcmp("&&", cp, 2) == 0 ||
3776 		    memcmp("!=", cp, 2) == 0 ||
3777 		    memcmp("==", cp, 2) == 0 ||
3778 		    memcmp("<=", cp, 2) == 0 ||
3779 		    memcmp(">=", cp, 2) == 0) &&
3780 		    format_is_end(cp[2])) {
3781 			format_add_modifier(&list, count, cp, 2, NULL, 0);
3782 			cp += 2;
3783 			continue;
3784 		}
3785 
3786 		/* Now try single character with arguments. */
3787 		if (strchr("mCNst=peq", cp[0]) == NULL)
3788 			break;
3789 		c = cp[0];
3790 
3791 		/* No arguments provided. */
3792 		if (format_is_end(cp[1])) {
3793 			format_add_modifier(&list, count, cp, 1, NULL, 0);
3794 			cp++;
3795 			continue;
3796 		}
3797 		argv = NULL;
3798 		argc = 0;
3799 
3800 		/* Single argument with no wrapper character. */
3801 		if (!ispunct(cp[1]) || cp[1] == '-') {
3802 			end = format_skip(cp + 1, ":;");
3803 			if (end == NULL)
3804 				break;
3805 
3806 			argv = xcalloc(1, sizeof *argv);
3807 			value = xstrndup(cp + 1, end - (cp + 1));
3808 			argv[0] = format_expand1(es, value);
3809 			free(value);
3810 			argc = 1;
3811 
3812 			format_add_modifier(&list, count, &c, 1, argv, argc);
3813 			cp = end;
3814 			continue;
3815 		}
3816 
3817 		/* Multiple arguments with a wrapper character. */
3818 		last[0] = cp[1];
3819 		cp++;
3820 		do {
3821 			if (cp[0] == last[0] && format_is_end(cp[1])) {
3822 				cp++;
3823 				break;
3824 			}
3825 			end = format_skip(cp + 1, last);
3826 			if (end == NULL)
3827 				break;
3828 			cp++;
3829 
3830 			argv = xreallocarray(argv, argc + 1, sizeof *argv);
3831 			value = xstrndup(cp, end - cp);
3832 			argv[argc++] = format_expand1(es, value);
3833 			free(value);
3834 
3835 			cp = end;
3836 		} while (!format_is_end(cp[0]));
3837 		format_add_modifier(&list, count, &c, 1, argv, argc);
3838 	}
3839 	if (*cp != ':') {
3840 		format_free_modifiers(list, *count);
3841 		*count = 0;
3842 		return (NULL);
3843 	}
3844 	*s = cp + 1;
3845 	return (list);
3846 }
3847 
3848 /* Match against an fnmatch(3) pattern or regular expression. */
3849 static char *
3850 format_match(struct format_modifier *fm, const char *pattern, const char *text)
3851 {
3852 	const char	*s = "";
3853 	regex_t		 r;
3854 	int		 flags = 0;
3855 
3856 	if (fm->argc >= 1)
3857 		s = fm->argv[0];
3858 	if (strchr(s, 'r') == NULL) {
3859 		if (strchr(s, 'i') != NULL)
3860 			flags |= FNM_CASEFOLD;
3861 		if (fnmatch(pattern, text, flags) != 0)
3862 			return (xstrdup("0"));
3863 	} else {
3864 		flags = REG_EXTENDED|REG_NOSUB;
3865 		if (strchr(s, 'i') != NULL)
3866 			flags |= REG_ICASE;
3867 		if (regcomp(&r, pattern, flags) != 0)
3868 			return (xstrdup("0"));
3869 		if (regexec(&r, text, 0, NULL, 0) != 0) {
3870 			regfree(&r);
3871 			return (xstrdup("0"));
3872 		}
3873 		regfree(&r);
3874 	}
3875 	return (xstrdup("1"));
3876 }
3877 
3878 /* Perform substitution in string. */
3879 static char *
3880 format_sub(struct format_modifier *fm, const char *text, const char *pattern,
3881     const char *with)
3882 {
3883 	char	*value;
3884 	int	 flags = REG_EXTENDED;
3885 
3886 	if (fm->argc >= 3 && strchr(fm->argv[2], 'i') != NULL)
3887 		flags |= REG_ICASE;
3888 	value = regsub(pattern, with, text, flags);
3889 	if (value == NULL)
3890 		return (xstrdup(text));
3891 	return (value);
3892 }
3893 
3894 /* Search inside pane. */
3895 static char *
3896 format_search(struct format_modifier *fm, struct window_pane *wp, const char *s)
3897 {
3898 	int	 ignore = 0, regex = 0;
3899 	char	*value;
3900 
3901 	if (fm->argc >= 1) {
3902 		if (strchr(fm->argv[0], 'i') != NULL)
3903 			ignore = 1;
3904 		if (strchr(fm->argv[0], 'r') != NULL)
3905 			regex = 1;
3906 	}
3907 	xasprintf(&value, "%u", window_pane_search(wp, s, regex, ignore));
3908 	return (value);
3909 }
3910 
3911 /* Does session name exist? */
3912 static char *
3913 format_session_name(struct format_expand_state *es, const char *fmt)
3914 {
3915 	char		*name;
3916 	struct session	*s;
3917 
3918 	name = format_expand1(es, fmt);
3919 	RB_FOREACH(s, sessions, &sessions) {
3920 		if (strcmp(s->name, name) == 0) {
3921 			free(name);
3922 			return (xstrdup("1"));
3923 		}
3924 	}
3925 	free(name);
3926 	return (xstrdup("0"));
3927 }
3928 
3929 /* Loop over sessions. */
3930 static char *
3931 format_loop_sessions(struct format_expand_state *es, const char *fmt)
3932 {
3933 	struct format_tree		*ft = es->ft;
3934 	struct client			*c = ft->client;
3935 	struct cmdq_item		*item = ft->item;
3936 	struct format_tree		*nft;
3937 	struct format_expand_state	 next;
3938 	char				*expanded, *value;
3939 	size_t				 valuelen;
3940 	struct session			*s;
3941 
3942 	value = xcalloc(1, 1);
3943 	valuelen = 1;
3944 
3945 	RB_FOREACH(s, sessions, &sessions) {
3946 		format_log(es, "session loop: $%u", s->id);
3947 		nft = format_create(c, item, FORMAT_NONE, ft->flags);
3948 		format_defaults(nft, ft->c, s, NULL, NULL);
3949 		format_copy_state(&next, es, 0);
3950 		next.ft = nft;
3951 		expanded = format_expand1(&next, fmt);
3952 		format_free(next.ft);
3953 
3954 		valuelen += strlen(expanded);
3955 		value = xrealloc(value, valuelen);
3956 
3957 		strlcat(value, expanded, valuelen);
3958 		free(expanded);
3959 	}
3960 
3961 	return (value);
3962 }
3963 
3964 /* Does window name exist? */
3965 static char *
3966 format_window_name(struct format_expand_state *es, const char *fmt)
3967 {
3968 	struct format_tree	*ft = es->ft;
3969 	char			*name;
3970 	struct winlink		*wl;
3971 
3972 	if (ft->s == NULL) {
3973 		format_log(es, "window name but no session");
3974 		return (NULL);
3975 	}
3976 
3977 	name = format_expand1(es, fmt);
3978 	RB_FOREACH(wl, winlinks, &ft->s->windows) {
3979 		if (strcmp(wl->window->name, name) == 0) {
3980 			free(name);
3981 			return (xstrdup("1"));
3982 		}
3983 	}
3984 	free(name);
3985 	return (xstrdup("0"));
3986 }
3987 
3988 /* Loop over windows. */
3989 static char *
3990 format_loop_windows(struct format_expand_state *es, const char *fmt)
3991 {
3992 	struct format_tree		*ft = es->ft;
3993 	struct client			*c = ft->client;
3994 	struct cmdq_item		*item = ft->item;
3995 	struct format_tree		*nft;
3996 	struct format_expand_state	 next;
3997 	char				*all, *active, *use, *expanded, *value;
3998 	size_t				 valuelen;
3999 	struct winlink			*wl;
4000 	struct window			*w;
4001 
4002 	if (ft->s == NULL) {
4003 		format_log(es, "window loop but no session");
4004 		return (NULL);
4005 	}
4006 
4007 	if (format_choose(es, fmt, &all, &active, 0) != 0) {
4008 		all = xstrdup(fmt);
4009 		active = NULL;
4010 	}
4011 
4012 	value = xcalloc(1, 1);
4013 	valuelen = 1;
4014 
4015 	RB_FOREACH(wl, winlinks, &ft->s->windows) {
4016 		w = wl->window;
4017 		format_log(es, "window loop: %u @%u", wl->idx, w->id);
4018 		if (active != NULL && wl == ft->s->curw)
4019 			use = active;
4020 		else
4021 			use = all;
4022 		nft = format_create(c, item, FORMAT_WINDOW|w->id, ft->flags);
4023 		format_defaults(nft, ft->c, ft->s, wl, NULL);
4024 		format_copy_state(&next, es, 0);
4025 		next.ft = nft;
4026 		expanded = format_expand1(&next, use);
4027 		format_free(nft);
4028 
4029 		valuelen += strlen(expanded);
4030 		value = xrealloc(value, valuelen);
4031 
4032 		strlcat(value, expanded, valuelen);
4033 		free(expanded);
4034 	}
4035 
4036 	free(active);
4037 	free(all);
4038 
4039 	return (value);
4040 }
4041 
4042 /* Loop over panes. */
4043 static char *
4044 format_loop_panes(struct format_expand_state *es, const char *fmt)
4045 {
4046 	struct format_tree		*ft = es->ft;
4047 	struct client			*c = ft->client;
4048 	struct cmdq_item		*item = ft->item;
4049 	struct format_tree		*nft;
4050 	struct format_expand_state	 next;
4051 	char				*all, *active, *use, *expanded, *value;
4052 	size_t				 valuelen;
4053 	struct window_pane		*wp;
4054 
4055 	if (ft->w == NULL) {
4056 		format_log(es, "pane loop but no window");
4057 		return (NULL);
4058 	}
4059 
4060 	if (format_choose(es, fmt, &all, &active, 0) != 0) {
4061 		all = xstrdup(fmt);
4062 		active = NULL;
4063 	}
4064 
4065 	value = xcalloc(1, 1);
4066 	valuelen = 1;
4067 
4068 	TAILQ_FOREACH(wp, &ft->w->panes, entry) {
4069 		format_log(es, "pane loop: %%%u", wp->id);
4070 		if (active != NULL && wp == ft->w->active)
4071 			use = active;
4072 		else
4073 			use = all;
4074 		nft = format_create(c, item, FORMAT_PANE|wp->id, ft->flags);
4075 		format_defaults(nft, ft->c, ft->s, ft->wl, wp);
4076 		format_copy_state(&next, es, 0);
4077 		next.ft = nft;
4078 		expanded = format_expand1(&next, use);
4079 		format_free(nft);
4080 
4081 		valuelen += strlen(expanded);
4082 		value = xrealloc(value, valuelen);
4083 
4084 		strlcat(value, expanded, valuelen);
4085 		free(expanded);
4086 	}
4087 
4088 	free(active);
4089 	free(all);
4090 
4091 	return (value);
4092 }
4093 
4094 /* Loop over clients. */
4095 static char *
4096 format_loop_clients(struct format_expand_state *es, const char *fmt)
4097 {
4098 	struct format_tree		*ft = es->ft;
4099 	struct client			*c = ft->client;
4100 	struct cmdq_item		*item = ft->item;
4101 	struct format_tree		*nft;
4102 	struct format_expand_state	 next;
4103 	char				*expanded, *value;
4104 	size_t				 valuelen;
4105 
4106 	value = xcalloc(1, 1);
4107 	valuelen = 1;
4108 
4109 	TAILQ_FOREACH(c, &clients, entry) {
4110 		format_log(es, "client loop: %s", c->name);
4111 		nft = format_create(c, item, 0, ft->flags);
4112 		format_defaults(nft, c, ft->s, ft->wl, ft->wp);
4113 		format_copy_state(&next, es, 0);
4114 		next.ft = nft;
4115 		expanded = format_expand1(&next, fmt);
4116 		format_free(nft);
4117 
4118 		valuelen += strlen(expanded);
4119 		value = xrealloc(value, valuelen);
4120 
4121 		strlcat(value, expanded, valuelen);
4122 		free(expanded);
4123 	}
4124 
4125 	return (value);
4126 }
4127 
4128 static char *
4129 format_replace_expression(struct format_modifier *mexp,
4130     struct format_expand_state *es, const char *copy)
4131 {
4132 	int			 argc = mexp->argc;
4133 	const char		*errstr;
4134 	char			*endch, *value, *left = NULL, *right = NULL;
4135 	int			 use_fp = 0;
4136 	u_int			 prec = 0;
4137 	double			 mleft, mright, result;
4138 	enum { ADD,
4139 	       SUBTRACT,
4140 	       MULTIPLY,
4141 	       DIVIDE,
4142 	       MODULUS,
4143 	       EQUAL,
4144 	       NOT_EQUAL,
4145 	       GREATER_THAN,
4146 	       GREATER_THAN_EQUAL,
4147 	       LESS_THAN,
4148 	       LESS_THAN_EQUAL } operator;
4149 
4150 	if (strcmp(mexp->argv[0], "+") == 0)
4151 		operator = ADD;
4152 	else if (strcmp(mexp->argv[0], "-") == 0)
4153 		operator = SUBTRACT;
4154 	else if (strcmp(mexp->argv[0], "*") == 0)
4155 		operator = MULTIPLY;
4156 	else if (strcmp(mexp->argv[0], "/") == 0)
4157 		operator = DIVIDE;
4158 	else if (strcmp(mexp->argv[0], "%") == 0 ||
4159 	    strcmp(mexp->argv[0], "m") == 0)
4160 		operator = MODULUS;
4161 	else if (strcmp(mexp->argv[0], "==") == 0)
4162 		operator = EQUAL;
4163 	else if (strcmp(mexp->argv[0], "!=") == 0)
4164 		operator = NOT_EQUAL;
4165 	else if (strcmp(mexp->argv[0], ">") == 0)
4166 		operator = GREATER_THAN;
4167 	else if (strcmp(mexp->argv[0], "<") == 0)
4168 		operator = LESS_THAN;
4169 	else if (strcmp(mexp->argv[0], ">=") == 0)
4170 		operator = GREATER_THAN_EQUAL;
4171 	else if (strcmp(mexp->argv[0], "<=") == 0)
4172 		operator = LESS_THAN_EQUAL;
4173 	else {
4174 		format_log(es, "expression has no valid operator: '%s'",
4175 		    mexp->argv[0]);
4176 		goto fail;
4177 	}
4178 
4179 	/* The second argument may be flags. */
4180 	if (argc >= 2 && strchr(mexp->argv[1], 'f') != NULL) {
4181 		use_fp = 1;
4182 		prec = 2;
4183 	}
4184 
4185 	/* The third argument may be precision. */
4186 	if (argc >= 3) {
4187 		prec = strtonum(mexp->argv[2], INT_MIN, INT_MAX, &errstr);
4188 		if (errstr != NULL) {
4189 			format_log(es, "expression precision %s: %s", errstr,
4190 			    mexp->argv[2]);
4191 			goto fail;
4192 		}
4193 	}
4194 
4195 	if (format_choose(es, copy, &left, &right, 1) != 0) {
4196 		format_log(es, "expression syntax error");
4197 		goto fail;
4198 	}
4199 
4200 	mleft = strtod(left, &endch);
4201 	if (*endch != '\0') {
4202 		format_log(es, "expression left side is invalid: %s", left);
4203 		goto fail;
4204 	}
4205 
4206 	mright = strtod(right, &endch);
4207 	if (*endch != '\0') {
4208 		format_log(es, "expression right side is invalid: %s", right);
4209 		goto fail;
4210 	}
4211 
4212 	if (!use_fp) {
4213 		mleft = (long long)mleft;
4214 		mright = (long long)mright;
4215 	}
4216 	format_log(es, "expression left side is: %.*f", prec, mleft);
4217 	format_log(es, "expression right side is: %.*f", prec, mright);
4218 
4219 	switch (operator) {
4220 	case ADD:
4221 		result = mleft + mright;
4222 		break;
4223 	case SUBTRACT:
4224 		result = mleft - mright;
4225 		break;
4226 	case MULTIPLY:
4227 		result = mleft * mright;
4228 		break;
4229 	case DIVIDE:
4230 		result = mleft / mright;
4231 		break;
4232 	case MODULUS:
4233 		result = fmod(mleft, mright);
4234 		break;
4235 	case EQUAL:
4236 		result = fabs(mleft - mright) < 1e-9;
4237 		break;
4238 	case NOT_EQUAL:
4239 		result = fabs(mleft - mright) > 1e-9;
4240 		break;
4241 	case GREATER_THAN:
4242 		result = (mleft > mright);
4243 		break;
4244 	case GREATER_THAN_EQUAL:
4245 		result = (mleft >= mright);
4246 		break;
4247 	case LESS_THAN:
4248 		result = (mleft < mright);
4249 		break;
4250 	case LESS_THAN_EQUAL:
4251 		result = (mleft <= mright);
4252 		break;
4253 	}
4254 	if (use_fp)
4255 		xasprintf(&value, "%.*f", prec, result);
4256 	else
4257 		xasprintf(&value, "%.*f", prec, (double)(long long)result);
4258 	format_log(es, "expression result is %s", value);
4259 
4260 	free(right);
4261 	free(left);
4262 	return (value);
4263 
4264 fail:
4265 	free(right);
4266 	free(left);
4267 	return (NULL);
4268 }
4269 
4270 /* Replace a key. */
4271 static int
4272 format_replace(struct format_expand_state *es, const char *key, size_t keylen,
4273     char **buf, size_t *len, size_t *off)
4274 {
4275 	struct format_tree		 *ft = es->ft;
4276 	struct window_pane		 *wp = ft->wp;
4277 	const char			 *errstr, *copy, *cp, *marker = NULL;
4278 	const char			 *time_format = NULL;
4279 	char				 *copy0, *condition, *found, *new;
4280 	char				 *value, *left, *right;
4281 	size_t				  valuelen;
4282 	int				  modifiers = 0, limit = 0, width = 0;
4283 	int				  j, c;
4284 	struct format_modifier		 *list, *cmp = NULL, *search = NULL;
4285 	struct format_modifier		**sub = NULL, *mexp = NULL, *fm;
4286 	u_int				  i, count, nsub = 0;
4287 	struct format_expand_state	  next;
4288 
4289 	/* Make a copy of the key. */
4290 	copy = copy0 = xstrndup(key, keylen);
4291 
4292 	/* Process modifier list. */
4293 	list = format_build_modifiers(es, &copy, &count);
4294 	for (i = 0; i < count; i++) {
4295 		fm = &list[i];
4296 		if (format_logging(ft)) {
4297 			format_log(es, "modifier %u is %s", i, fm->modifier);
4298 			for (j = 0; j < fm->argc; j++) {
4299 				format_log(es, "modifier %u argument %d: %s", i,
4300 				    j, fm->argv[j]);
4301 			}
4302 		}
4303 		if (fm->size == 1) {
4304 			switch (fm->modifier[0]) {
4305 			case 'm':
4306 			case '<':
4307 			case '>':
4308 				cmp = fm;
4309 				break;
4310 			case 'C':
4311 				search = fm;
4312 				break;
4313 			case 's':
4314 				if (fm->argc < 2)
4315 					break;
4316 				sub = xreallocarray(sub, nsub + 1, sizeof *sub);
4317 				sub[nsub++] = fm;
4318 				break;
4319 			case '=':
4320 				if (fm->argc < 1)
4321 					break;
4322 				limit = strtonum(fm->argv[0], INT_MIN, INT_MAX,
4323 				    &errstr);
4324 				if (errstr != NULL)
4325 					limit = 0;
4326 				if (fm->argc >= 2 && fm->argv[1] != NULL)
4327 					marker = fm->argv[1];
4328 				break;
4329 			case 'p':
4330 				if (fm->argc < 1)
4331 					break;
4332 				width = strtonum(fm->argv[0], INT_MIN, INT_MAX,
4333 				    &errstr);
4334 				if (errstr != NULL)
4335 					width = 0;
4336 				break;
4337 			case 'w':
4338 				modifiers |= FORMAT_WIDTH;
4339 				break;
4340 			case 'e':
4341 				if (fm->argc < 1 || fm->argc > 3)
4342 					break;
4343 				mexp = fm;
4344 				break;
4345 			case 'l':
4346 				modifiers |= FORMAT_LITERAL;
4347 				break;
4348 			case 'a':
4349 				modifiers |= FORMAT_CHARACTER;
4350 				break;
4351 			case 'b':
4352 				modifiers |= FORMAT_BASENAME;
4353 				break;
4354 			case 'c':
4355 				modifiers |= FORMAT_COLOUR;
4356 				break;
4357 			case 'd':
4358 				modifiers |= FORMAT_DIRNAME;
4359 				break;
4360 			case 'n':
4361 				modifiers |= FORMAT_LENGTH;
4362 				break;
4363 			case 't':
4364 				modifiers |= FORMAT_TIMESTRING;
4365 				if (fm->argc < 1)
4366 					break;
4367 				if (strchr(fm->argv[0], 'p') != NULL)
4368 					modifiers |= FORMAT_PRETTY;
4369 				else if (fm->argc >= 2 &&
4370 				    strchr(fm->argv[0], 'f') != NULL)
4371 					time_format = format_strip(fm->argv[1]);
4372 				break;
4373 			case 'q':
4374 				if (fm->argc < 1)
4375 					modifiers |= FORMAT_QUOTE_SHELL;
4376 				else if (strchr(fm->argv[0], 'e') != NULL ||
4377 				    strchr(fm->argv[0], 'h') != NULL)
4378 					modifiers |= FORMAT_QUOTE_STYLE;
4379 				break;
4380 			case 'E':
4381 				modifiers |= FORMAT_EXPAND;
4382 				break;
4383 			case 'T':
4384 				modifiers |= FORMAT_EXPANDTIME;
4385 				break;
4386 			case 'N':
4387 				if (fm->argc < 1 ||
4388 				    strchr(fm->argv[0], 'w') != NULL)
4389 					modifiers |= FORMAT_WINDOW_NAME;
4390 				else if (strchr(fm->argv[0], 's') != NULL)
4391 					modifiers |= FORMAT_SESSION_NAME;
4392 				break;
4393 			case 'S':
4394 				modifiers |= FORMAT_SESSIONS;
4395 				break;
4396 			case 'W':
4397 				modifiers |= FORMAT_WINDOWS;
4398 				break;
4399 			case 'P':
4400 				modifiers |= FORMAT_PANES;
4401 				break;
4402 			case 'L':
4403 				modifiers |= FORMAT_CLIENTS;
4404 				break;
4405 			}
4406 		} else if (fm->size == 2) {
4407 			if (strcmp(fm->modifier, "||") == 0 ||
4408 			    strcmp(fm->modifier, "&&") == 0 ||
4409 			    strcmp(fm->modifier, "==") == 0 ||
4410 			    strcmp(fm->modifier, "!=") == 0 ||
4411 			    strcmp(fm->modifier, ">=") == 0 ||
4412 			    strcmp(fm->modifier, "<=") == 0)
4413 				cmp = fm;
4414 		}
4415 	}
4416 
4417 	/* Is this a literal string? */
4418 	if (modifiers & FORMAT_LITERAL) {
4419 		format_log(es, "literal string is '%s'", copy);
4420 		value = format_unescape(copy);
4421 		goto done;
4422 	}
4423 
4424 	/* Is this a character? */
4425 	if (modifiers & FORMAT_CHARACTER) {
4426 		new = format_expand1(es, copy);
4427 		c = strtonum(new, 32, 126, &errstr);
4428 		if (errstr != NULL)
4429 			value = xstrdup("");
4430 		else
4431 			xasprintf(&value, "%c", c);
4432 		free(new);
4433 		goto done;
4434 	}
4435 
4436 	/* Is this a colour? */
4437 	if (modifiers & FORMAT_COLOUR) {
4438 		new = format_expand1(es, copy);
4439 		c = colour_fromstring(new);
4440 		if (c == -1 || (c = colour_force_rgb(c)) == -1)
4441 			value = xstrdup("");
4442 		else
4443 			xasprintf(&value, "%06x", c & 0xffffff);
4444 		free(new);
4445 		goto done;
4446 	}
4447 
4448 	/* Is this a loop, comparison or condition? */
4449 	if (modifiers & FORMAT_SESSIONS) {
4450 		value = format_loop_sessions(es, copy);
4451 		if (value == NULL)
4452 			goto fail;
4453 	} else if (modifiers & FORMAT_WINDOWS) {
4454 		value = format_loop_windows(es, copy);
4455 		if (value == NULL)
4456 			goto fail;
4457 	} else if (modifiers & FORMAT_PANES) {
4458 		value = format_loop_panes(es, copy);
4459 		if (value == NULL)
4460 			goto fail;
4461 	} else if (modifiers & FORMAT_CLIENTS) {
4462 		value = format_loop_clients(es, copy);
4463 		if (value == NULL)
4464 			goto fail;
4465 	} else if (modifiers & FORMAT_WINDOW_NAME) {
4466 		value = format_window_name(es, copy);
4467 		if (value == NULL)
4468 			goto fail;
4469 	} else if (modifiers & FORMAT_SESSION_NAME) {
4470 		value = format_session_name(es, copy);
4471 		if (value == NULL)
4472 			goto fail;
4473 	} else if (search != NULL) {
4474 		/* Search in pane. */
4475 		new = format_expand1(es, copy);
4476 		if (wp == NULL) {
4477 			format_log(es, "search '%s' but no pane", new);
4478 			value = xstrdup("0");
4479 		} else {
4480 			format_log(es, "search '%s' pane %%%u", new, wp->id);
4481 			value = format_search(search, wp, new);
4482 		}
4483 		free(new);
4484 	} else if (cmp != NULL) {
4485 		/* Comparison of left and right. */
4486 		if (format_choose(es, copy, &left, &right, 1) != 0) {
4487 			format_log(es, "compare %s syntax error: %s",
4488 			    cmp->modifier, copy);
4489 			goto fail;
4490 		}
4491 		format_log(es, "compare %s left is: %s", cmp->modifier, left);
4492 		format_log(es, "compare %s right is: %s", cmp->modifier, right);
4493 
4494 		if (strcmp(cmp->modifier, "||") == 0) {
4495 			if (format_true(left) || format_true(right))
4496 				value = xstrdup("1");
4497 			else
4498 				value = xstrdup("0");
4499 		} else if (strcmp(cmp->modifier, "&&") == 0) {
4500 			if (format_true(left) && format_true(right))
4501 				value = xstrdup("1");
4502 			else
4503 				value = xstrdup("0");
4504 		} else if (strcmp(cmp->modifier, "==") == 0) {
4505 			if (strcmp(left, right) == 0)
4506 				value = xstrdup("1");
4507 			else
4508 				value = xstrdup("0");
4509 		} else if (strcmp(cmp->modifier, "!=") == 0) {
4510 			if (strcmp(left, right) != 0)
4511 				value = xstrdup("1");
4512 			else
4513 				value = xstrdup("0");
4514 		} else if (strcmp(cmp->modifier, "<") == 0) {
4515 			if (strcmp(left, right) < 0)
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, "m") == 0)
4535 			value = format_match(cmp, left, right);
4536 
4537 		free(right);
4538 		free(left);
4539 	} else if (*copy == '?') {
4540 		/* Conditional: check first and choose second or third. */
4541 		cp = format_skip(copy + 1, ",");
4542 		if (cp == NULL) {
4543 			format_log(es, "condition syntax error: %s", copy + 1);
4544 			goto fail;
4545 		}
4546 		condition = xstrndup(copy + 1, cp - (copy + 1));
4547 		format_log(es, "condition is: %s", condition);
4548 
4549 		found = format_find(ft, condition, modifiers, time_format);
4550 		if (found == NULL) {
4551 			/*
4552 			 * If the condition not found, try to expand it. If
4553 			 * the expansion doesn't have any effect, then assume
4554 			 * false.
4555 			 */
4556 			found = format_expand1(es, condition);
4557 			if (strcmp(found, condition) == 0) {
4558 				free(found);
4559 				found = xstrdup("");
4560 				format_log(es,
4561 				    "condition '%s' not found; assuming false",
4562 				    condition);
4563 			}
4564 		} else {
4565 			format_log(es, "condition '%s' found: %s", condition,
4566 			    found);
4567 		}
4568 
4569 		if (format_choose(es, cp + 1, &left, &right, 0) != 0) {
4570 			format_log(es, "condition '%s' syntax error: %s",
4571 			    condition, cp + 1);
4572 			free(found);
4573 			goto fail;
4574 		}
4575 		if (format_true(found)) {
4576 			format_log(es, "condition '%s' is true", condition);
4577 			value = format_expand1(es, left);
4578 		} else {
4579 			format_log(es, "condition '%s' is false", condition);
4580 			value = format_expand1(es, right);
4581 		}
4582 		free(right);
4583 		free(left);
4584 
4585 		free(condition);
4586 		free(found);
4587 	} else if (mexp != NULL) {
4588 		value = format_replace_expression(mexp, es, copy);
4589 		if (value == NULL)
4590 			value = xstrdup("");
4591 	} else {
4592 		if (strstr(copy, "#{") != 0) {
4593 			format_log(es, "expanding inner format '%s'", copy);
4594 			value = format_expand1(es, copy);
4595 		} else {
4596 			value = format_find(ft, copy, modifiers, time_format);
4597 			if (value == NULL) {
4598 				format_log(es, "format '%s' not found", copy);
4599 				value = xstrdup("");
4600 			} else {
4601 				format_log(es, "format '%s' found: %s", copy,
4602 				    value);
4603 			}
4604 		}
4605 	}
4606 
4607 done:
4608 	/* Expand again if required. */
4609 	if (modifiers & FORMAT_EXPAND) {
4610 		new = format_expand1(es, value);
4611 		free(value);
4612 		value = new;
4613 	} else if (modifiers & FORMAT_EXPANDTIME) {
4614 		format_copy_state(&next, es, FORMAT_EXPAND_TIME);
4615 		new = format_expand1(&next, value);
4616 		free(value);
4617 		value = new;
4618 	}
4619 
4620 	/* Perform substitution if any. */
4621 	for (i = 0; i < nsub; i++) {
4622 		left = format_expand1(es, sub[i]->argv[0]);
4623 		right = format_expand1(es, sub[i]->argv[1]);
4624 		new = format_sub(sub[i], value, left, right);
4625 		format_log(es, "substitute '%s' to '%s': %s", left, right, new);
4626 		free(value);
4627 		value = new;
4628 		free(right);
4629 		free(left);
4630 	}
4631 
4632 	/* Truncate the value if needed. */
4633 	if (limit > 0) {
4634 		new = format_trim_left(value, limit);
4635 		if (marker != NULL && strcmp(new, value) != 0) {
4636 			free(value);
4637 			xasprintf(&value, "%s%s", new, marker);
4638 		} else {
4639 			free(value);
4640 			value = new;
4641 		}
4642 		format_log(es, "applied length limit %d: %s", limit, value);
4643 	} else if (limit < 0) {
4644 		new = format_trim_right(value, -limit);
4645 		if (marker != NULL && strcmp(new, value) != 0) {
4646 			free(value);
4647 			xasprintf(&value, "%s%s", marker, new);
4648 		} else {
4649 			free(value);
4650 			value = new;
4651 		}
4652 		format_log(es, "applied length limit %d: %s", limit, value);
4653 	}
4654 
4655 	/* Pad the value if needed. */
4656 	if (width > 0) {
4657 		new = utf8_padcstr(value, width);
4658 		free(value);
4659 		value = new;
4660 		format_log(es, "applied padding width %d: %s", width, value);
4661 	} else if (width < 0) {
4662 		new = utf8_rpadcstr(value, -width);
4663 		free(value);
4664 		value = new;
4665 		format_log(es, "applied padding width %d: %s", width, value);
4666 	}
4667 
4668 	/* Replace with the length or width if needed. */
4669 	if (modifiers & FORMAT_LENGTH) {
4670 		xasprintf(&new, "%zu", strlen(value));
4671 		free(value);
4672 		value = new;
4673 		format_log(es, "replacing with length: %s", new);
4674 	}
4675 	if (modifiers & FORMAT_WIDTH) {
4676 		xasprintf(&new, "%u", format_width(value));
4677 		free(value);
4678 		value = new;
4679 		format_log(es, "replacing with width: %s", new);
4680 	}
4681 
4682 	/* Expand the buffer and copy in the value. */
4683 	valuelen = strlen(value);
4684 	while (*len - *off < valuelen + 1) {
4685 		*buf = xreallocarray(*buf, 2, *len);
4686 		*len *= 2;
4687 	}
4688 	memcpy(*buf + *off, value, valuelen);
4689 	*off += valuelen;
4690 
4691 	format_log(es, "replaced '%s' with '%s'", copy0, value);
4692 	free(value);
4693 
4694 	free(sub);
4695 	format_free_modifiers(list, count);
4696 	free(copy0);
4697 	return (0);
4698 
4699 fail:
4700 	format_log(es, "failed %s", copy0);
4701 
4702 	free(sub);
4703 	format_free_modifiers(list, count);
4704 	free(copy0);
4705 	return (-1);
4706 }
4707 
4708 /* Expand keys in a template. */
4709 static char *
4710 format_expand1(struct format_expand_state *es, const char *fmt)
4711 {
4712 	struct format_tree	*ft = es->ft;
4713 	char			*buf, *out, *name;
4714 	const char		*ptr, *s, *style_end = NULL;
4715 	size_t			 off, len, n, outlen;
4716 	int     		 ch, brackets;
4717 	char			 expanded[8192];
4718 
4719 	if (fmt == NULL || *fmt == '\0')
4720 		return (xstrdup(""));
4721 
4722 	if (es->loop == FORMAT_LOOP_LIMIT) {
4723 		format_log(es, "reached loop limit (%u)", FORMAT_LOOP_LIMIT);
4724 		return (xstrdup(""));
4725 	}
4726 	es->loop++;
4727 
4728 	format_log(es, "expanding format: %s", fmt);
4729 
4730 	if ((es->flags & FORMAT_EXPAND_TIME) && strchr(fmt, '%') != NULL) {
4731 		if (es->time == 0) {
4732 			es->time = time(NULL);
4733 			localtime_r(&es->time, &es->tm);
4734 		}
4735 		if (strftime(expanded, sizeof expanded, fmt, &es->tm) == 0) {
4736 			format_log(es, "format is too long");
4737 			return (xstrdup(""));
4738 		}
4739 		if (format_logging(ft) && strcmp(expanded, fmt) != 0)
4740 			format_log(es, "after time expanded: %s", expanded);
4741 		fmt = expanded;
4742 	}
4743 
4744 	len = 64;
4745 	buf = xmalloc(len);
4746 	off = 0;
4747 
4748 	while (*fmt != '\0') {
4749 		if (*fmt != '#') {
4750 			while (len - off < 2) {
4751 				buf = xreallocarray(buf, 2, len);
4752 				len *= 2;
4753 			}
4754 			buf[off++] = *fmt++;
4755 			continue;
4756 		}
4757 		fmt++;
4758 
4759 		ch = (u_char)*fmt++;
4760 		switch (ch) {
4761 		case '(':
4762 			brackets = 1;
4763 			for (ptr = fmt; *ptr != '\0'; ptr++) {
4764 				if (*ptr == '(')
4765 					brackets++;
4766 				if (*ptr == ')' && --brackets == 0)
4767 					break;
4768 			}
4769 			if (*ptr != ')' || brackets != 0)
4770 				break;
4771 			n = ptr - fmt;
4772 
4773 			name = xstrndup(fmt, n);
4774 			format_log(es, "found #(): %s", name);
4775 
4776 			if ((ft->flags & FORMAT_NOJOBS) ||
4777 			    (es->flags & FORMAT_EXPAND_NOJOBS)) {
4778 				out = xstrdup("");
4779 				format_log(es, "#() is disabled");
4780 			} else {
4781 				out = format_job_get(es, name);
4782 				format_log(es, "#() result: %s", out);
4783 			}
4784 			free(name);
4785 
4786 			outlen = strlen(out);
4787 			while (len - off < outlen + 1) {
4788 				buf = xreallocarray(buf, 2, len);
4789 				len *= 2;
4790 			}
4791 			memcpy(buf + off, out, outlen);
4792 			off += outlen;
4793 
4794 			free(out);
4795 
4796 			fmt += n + 1;
4797 			continue;
4798 		case '{':
4799 			ptr = format_skip((char *)fmt - 2, "}");
4800 			if (ptr == NULL)
4801 				break;
4802 			n = ptr - fmt;
4803 
4804 			format_log(es, "found #{}: %.*s", (int)n, fmt);
4805 			if (format_replace(es, fmt, n, &buf, &len, &off) != 0)
4806 				break;
4807 			fmt += n + 1;
4808 			continue;
4809 		case '[':
4810 		case '#':
4811 			/*
4812 			 * If ##[ (with two or more #s), then it is a style and
4813 			 * can be left for format_draw to handle.
4814 			 */
4815 			ptr = fmt - (ch == '[');
4816 			n = 2 - (ch == '[');
4817 			while (*ptr == '#') {
4818 				ptr++;
4819 				n++;
4820 			}
4821 			if (*ptr == '[') {
4822 				style_end = format_skip(fmt - 2, "]");
4823 				format_log(es, "found #*%zu[", n);
4824 				while (len - off < n + 2) {
4825 					buf = xreallocarray(buf, 2, len);
4826 					len *= 2;
4827 				}
4828 				memcpy(buf + off, fmt - 2, n + 1);
4829 				off += n + 1;
4830 				fmt = ptr + 1;
4831 				continue;
4832 			}
4833 			/* FALLTHROUGH */
4834 		case '}':
4835 		case ',':
4836 			format_log(es, "found #%c", ch);
4837 			while (len - off < 2) {
4838 				buf = xreallocarray(buf, 2, len);
4839 				len *= 2;
4840 			}
4841 			buf[off++] = ch;
4842 			continue;
4843 		default:
4844 			s = NULL;
4845 			if (fmt > style_end) { /* skip inside #[] */
4846 				if (ch >= 'A' && ch <= 'Z')
4847 					s = format_upper[ch - 'A'];
4848 				else if (ch >= 'a' && ch <= 'z')
4849 					s = format_lower[ch - 'a'];
4850 			}
4851 			if (s == NULL) {
4852 				while (len - off < 3) {
4853 					buf = xreallocarray(buf, 2, len);
4854 					len *= 2;
4855 				}
4856 				buf[off++] = '#';
4857 				buf[off++] = ch;
4858 				continue;
4859 			}
4860 			n = strlen(s);
4861 			format_log(es, "found #%c: %s", ch, s);
4862 			if (format_replace(es, s, n, &buf, &len, &off) != 0)
4863 				break;
4864 			continue;
4865 		}
4866 
4867 		break;
4868 	}
4869 	buf[off] = '\0';
4870 
4871 	format_log(es, "result is: %s", buf);
4872 	es->loop--;
4873 
4874 	return (buf);
4875 }
4876 
4877 /* Expand keys in a template, passing through strftime first. */
4878 char *
4879 format_expand_time(struct format_tree *ft, const char *fmt)
4880 {
4881 	struct format_expand_state	es;
4882 
4883 	memset(&es, 0, sizeof es);
4884 	es.ft = ft;
4885 	es.flags = FORMAT_EXPAND_TIME;
4886 	return (format_expand1(&es, fmt));
4887 }
4888 
4889 /* Expand keys in a template. */
4890 char *
4891 format_expand(struct format_tree *ft, const char *fmt)
4892 {
4893 	struct format_expand_state	es;
4894 
4895 	memset(&es, 0, sizeof es);
4896 	es.ft = ft;
4897 	es.flags = 0;
4898 	return (format_expand1(&es, fmt));
4899 }
4900 
4901 /* Expand a single string. */
4902 char *
4903 format_single(struct cmdq_item *item, const char *fmt, struct client *c,
4904     struct session *s, struct winlink *wl, struct window_pane *wp)
4905 {
4906 	struct format_tree	*ft;
4907 	char			*expanded;
4908 
4909 	ft = format_create_defaults(item, c, s, wl, wp);
4910 	expanded = format_expand(ft, fmt);
4911 	format_free(ft);
4912 	return (expanded);
4913 }
4914 
4915 /* Expand a single string using state. */
4916 char *
4917 format_single_from_state(struct cmdq_item *item, const char *fmt,
4918     struct client *c, struct cmd_find_state *fs)
4919 {
4920 	return (format_single(item, fmt, c, fs->s, fs->wl, fs->wp));
4921 }
4922 
4923 /* Expand a single string using target. */
4924 char *
4925 format_single_from_target(struct cmdq_item *item, const char *fmt)
4926 {
4927 	struct client	*tc = cmdq_get_target_client(item);
4928 
4929 	return (format_single_from_state(item, fmt, tc, cmdq_get_target(item)));
4930 }
4931 
4932 /* Create and add defaults. */
4933 struct format_tree *
4934 format_create_defaults(struct cmdq_item *item, struct client *c,
4935     struct session *s, struct winlink *wl, struct window_pane *wp)
4936 {
4937 	struct format_tree	*ft;
4938 
4939 	if (item != NULL)
4940 		ft = format_create(cmdq_get_client(item), item, FORMAT_NONE, 0);
4941 	else
4942 		ft = format_create(NULL, item, FORMAT_NONE, 0);
4943 	format_defaults(ft, c, s, wl, wp);
4944 	return (ft);
4945 }
4946 
4947 /* Create and add defaults using state. */
4948 struct format_tree *
4949 format_create_from_state(struct cmdq_item *item, struct client *c,
4950     struct cmd_find_state *fs)
4951 {
4952 	return (format_create_defaults(item, c, fs->s, fs->wl, fs->wp));
4953 }
4954 
4955 /* Create and add defaults using target. */
4956 struct format_tree *
4957 format_create_from_target(struct cmdq_item *item)
4958 {
4959 	struct client	*tc = cmdq_get_target_client(item);
4960 
4961 	return (format_create_from_state(item, tc, cmdq_get_target(item)));
4962 }
4963 
4964 /* Set defaults for any of arguments that are not NULL. */
4965 void
4966 format_defaults(struct format_tree *ft, struct client *c, struct session *s,
4967     struct winlink *wl, struct window_pane *wp)
4968 {
4969 	struct paste_buffer	*pb;
4970 
4971 	if (c != NULL && c->name != NULL)
4972 		log_debug("%s: c=%s", __func__, c->name);
4973 	else
4974 		log_debug("%s: c=none", __func__);
4975 	if (s != NULL)
4976 		log_debug("%s: s=$%u", __func__, s->id);
4977 	else
4978 		log_debug("%s: s=none", __func__);
4979 	if (wl != NULL)
4980 		log_debug("%s: wl=%u", __func__, wl->idx);
4981 	else
4982 		log_debug("%s: wl=none", __func__);
4983 	if (wp != NULL)
4984 		log_debug("%s: wp=%%%u", __func__, wp->id);
4985 	else
4986 		log_debug("%s: wp=none", __func__);
4987 
4988 	if (c != NULL && s != NULL && c->session != s)
4989 		log_debug("%s: session does not match", __func__);
4990 
4991 	if (wp != NULL)
4992 		ft->type = FORMAT_TYPE_PANE;
4993 	else if (wl != NULL)
4994 		ft->type = FORMAT_TYPE_WINDOW;
4995 	else if (s != NULL)
4996 		ft->type = FORMAT_TYPE_SESSION;
4997 	else
4998 		ft->type = FORMAT_TYPE_UNKNOWN;
4999 
5000 	if (s == NULL && c != NULL)
5001 		s = c->session;
5002 	if (wl == NULL && s != NULL)
5003 		wl = s->curw;
5004 	if (wp == NULL && wl != NULL)
5005 		wp = wl->window->active;
5006 
5007 	if (c != NULL)
5008 		format_defaults_client(ft, c);
5009 	if (s != NULL)
5010 		format_defaults_session(ft, s);
5011 	if (wl != NULL)
5012 		format_defaults_winlink(ft, wl);
5013 	if (wp != NULL)
5014 		format_defaults_pane(ft, wp);
5015 
5016 	pb = paste_get_top(NULL);
5017 	if (pb != NULL)
5018 		format_defaults_paste_buffer(ft, pb);
5019 }
5020 
5021 /* Set default format keys for a session. */
5022 static void
5023 format_defaults_session(struct format_tree *ft, struct session *s)
5024 {
5025 	ft->s = s;
5026 }
5027 
5028 /* Set default format keys for a client. */
5029 static void
5030 format_defaults_client(struct format_tree *ft, struct client *c)
5031 {
5032 	if (ft->s == NULL)
5033 		ft->s = c->session;
5034 	ft->c = c;
5035 }
5036 
5037 /* Set default format keys for a window. */
5038 void
5039 format_defaults_window(struct format_tree *ft, struct window *w)
5040 {
5041 	ft->w = w;
5042 }
5043 
5044 /* Set default format keys for a winlink. */
5045 static void
5046 format_defaults_winlink(struct format_tree *ft, struct winlink *wl)
5047 {
5048 	if (ft->w == NULL)
5049 		format_defaults_window(ft, wl->window);
5050 	ft->wl = wl;
5051 }
5052 
5053 /* Set default format keys for a window pane. */
5054 void
5055 format_defaults_pane(struct format_tree *ft, struct window_pane *wp)
5056 {
5057 	struct window_mode_entry	*wme;
5058 
5059 	if (ft->w == NULL)
5060 		format_defaults_window(ft, wp->window);
5061 	ft->wp = wp;
5062 
5063 	wme = TAILQ_FIRST(&wp->modes);
5064 	if (wme != NULL && wme->mode->formats != NULL)
5065 		wme->mode->formats(wme, ft);
5066 }
5067 
5068 /* Set default format keys for paste buffer. */
5069 void
5070 format_defaults_paste_buffer(struct format_tree *ft, struct paste_buffer *pb)
5071 {
5072 	ft->pb = pb;
5073 }
5074 
5075 /* Return word at given coordinates. Caller frees. */
5076 char *
5077 format_grid_word(struct grid *gd, u_int x, u_int y)
5078 {
5079 	const struct grid_line	*gl;
5080 	struct grid_cell	 gc;
5081 	const char		*ws;
5082 	struct utf8_data	*ud = NULL;
5083 	u_int			 end;
5084 	size_t			 size = 0;
5085 	int			 found = 0;
5086 	char			*s = NULL;
5087 
5088 	ws = options_get_string(global_s_options, "word-separators");
5089 
5090 	for (;;) {
5091 		grid_get_cell(gd, x, y, &gc);
5092 		if (gc.flags & GRID_FLAG_PADDING)
5093 			break;
5094 		if (utf8_cstrhas(ws, &gc.data) ||
5095 		    (gc.data.size == 1 && *gc.data.data == ' ')) {
5096 			found = 1;
5097 			break;
5098 		}
5099 
5100 		if (x == 0) {
5101 			if (y == 0)
5102 				break;
5103 			gl = grid_peek_line(gd, y - 1);
5104 			if (~gl->flags & GRID_LINE_WRAPPED)
5105 				break;
5106 			y--;
5107 			x = grid_line_length(gd, y);
5108 			if (x == 0)
5109 				break;
5110 		}
5111 		x--;
5112 	}
5113 	for (;;) {
5114 		if (found) {
5115 			end = grid_line_length(gd, y);
5116 			if (end == 0 || x == end - 1) {
5117 				if (y == gd->hsize + gd->sy - 1)
5118 					break;
5119 				gl = grid_peek_line(gd, y);
5120 				if (~gl->flags & GRID_LINE_WRAPPED)
5121 					break;
5122 				y++;
5123 				x = 0;
5124 			} else
5125 				x++;
5126 		}
5127 		found = 1;
5128 
5129 		grid_get_cell(gd, x, y, &gc);
5130 		if (gc.flags & GRID_FLAG_PADDING)
5131 			break;
5132 		if (utf8_cstrhas(ws, &gc.data) ||
5133 		    (gc.data.size == 1 && *gc.data.data == ' '))
5134 			break;
5135 
5136 		ud = xreallocarray(ud, size + 2, sizeof *ud);
5137 		memcpy(&ud[size++], &gc.data, sizeof *ud);
5138 	}
5139 	if (size != 0) {
5140 		ud[size].size = 0;
5141 		s = utf8_tocstr(ud);
5142 		free(ud);
5143 	}
5144 	return (s);
5145 }
5146 
5147 /* Return line at given coordinates. Caller frees. */
5148 char *
5149 format_grid_line(struct grid *gd, u_int y)
5150 {
5151 	struct grid_cell	 gc;
5152 	struct utf8_data	*ud = NULL;
5153 	u_int			 x;
5154 	size_t			 size = 0;
5155 	char			*s = NULL;
5156 
5157 	for (x = 0; x < grid_line_length(gd, y); x++) {
5158 		grid_get_cell(gd, x, y, &gc);
5159 		if (gc.flags & GRID_FLAG_PADDING)
5160 			break;
5161 
5162 		ud = xreallocarray(ud, size + 2, sizeof *ud);
5163 		memcpy(&ud[size++], &gc.data, sizeof *ud);
5164 	}
5165 	if (size != 0) {
5166 		ud[size].size = 0;
5167 		s = utf8_tocstr(ud);
5168 		free(ud);
5169 	}
5170 	return (s);
5171 }
5172 
5173 /* Return hyperlink at given coordinates. Caller frees. */
5174 char *
5175 format_grid_hyperlink(struct grid *gd, u_int x, u_int y, struct screen* s)
5176 {
5177 	const char		*uri;
5178 	struct grid_cell	 gc;
5179 
5180 	grid_get_cell(gd, x, y, &gc);
5181 	if (gc.flags & GRID_FLAG_PADDING)
5182 		return (NULL);
5183 	if (s->hyperlinks == NULL || gc.link == 0)
5184 		return (NULL);
5185 	if (!hyperlinks_get(s->hyperlinks, gc.link, &uri, NULL, NULL))
5186 		return (NULL);
5187 	return (xstrdup(uri));
5188 }
5189