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