xref: /netbsd-src/external/bsd/tmux/dist/options-table.c (revision 946379e7b37692fc43f68eb0d1c10daa0a7f3b6c)
1 /* $OpenBSD$ */
2 
3 /*
4  * Copyright (c) 2011 Nicholas Marriott <nicm@users.sourceforge.net>
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 
21 #include <string.h>
22 
23 #include "tmux.h"
24 
25 /*
26  * This file has a tables with all the server, session and window
27  * options. These tables are the master copy of the options with their real
28  * (user-visible) types, range limits and default values. At start these are
29  * copied into the runtime global options trees (which only has number and
30  * string types). These tables are then used to look up the real type when the
31  * user sets an option or its value needs to be shown.
32  */
33 
34 /* Choice option type lists. */
35 const char *options_table_mode_keys_list[] = {
36 	"emacs", "vi", NULL
37 };
38 const char *options_table_clock_mode_style_list[] = {
39 	"12", "24", NULL
40 };
41 const char *options_table_status_keys_list[] = {
42 	"emacs", "vi", NULL
43 };
44 const char *options_table_status_justify_list[] = {
45 	"left", "centre", "right", NULL
46 };
47 const char *options_table_status_position_list[] = {
48 	"top", "bottom", NULL
49 };
50 const char *options_table_bell_action_list[] = {
51 	"none", "any", "current", "other", NULL
52 };
53 
54 /* Server options. */
55 const struct options_table_entry server_options_table[] = {
56 	{ .name = "buffer-limit",
57 	  .type = OPTIONS_TABLE_NUMBER,
58 	  .minimum = 1,
59 	  .maximum = INT_MAX,
60 	  .default_num = 20
61 	},
62 
63 	{ .name = "default-terminal",
64 	  .type = OPTIONS_TABLE_STRING,
65 	  .default_str = "screen"
66 	},
67 
68 	{ .name = "escape-time",
69 	  .type = OPTIONS_TABLE_NUMBER,
70 	  .minimum = 0,
71 	  .maximum = INT_MAX,
72 	  .default_num = 500
73 	},
74 
75 	{ .name = "exit-unattached",
76 	  .type = OPTIONS_TABLE_FLAG,
77 	  .default_num = 0
78 	},
79 
80 	{ .name = "focus-events",
81 	  .type = OPTIONS_TABLE_FLAG,
82 	  .default_num = 0
83 	},
84 
85 	{ .name = "history-file",
86 	  .type = OPTIONS_TABLE_STRING,
87 	  .default_str = NULL
88 	},
89 
90 	{ .name = "message-limit",
91 	  .type = OPTIONS_TABLE_NUMBER,
92 	  .minimum = 0,
93 	  .maximum = INT_MAX,
94 	  .default_num = 100
95 	},
96 
97 	{ .name = "quiet",
98 	  .type = OPTIONS_TABLE_FLAG,
99 	  .default_num = 0
100 	},
101 
102 	{ .name = "set-clipboard",
103 	  .type = OPTIONS_TABLE_FLAG,
104 	  .default_num = 1
105 	},
106 
107 	{ .name = "terminal-overrides",
108 	  .type = OPTIONS_TABLE_STRING,
109 	  .default_str = "xterm*:XT:Ms=\\E]52;%p1%s;%p2%s\\007"
110 	                 ":Cs=\\E]12;%p1%s\\007:Cr=\\E]112\\007"
111 			 ":Ss=\\E[%p1%d q:Se=\\E[2 q,screen*:XT"
112 	},
113 
114 	{ .name = NULL }
115 };
116 
117 /* Session options. */
118 const struct options_table_entry session_options_table[] = {
119 	{ .name = "assume-paste-time",
120 	  .type = OPTIONS_TABLE_NUMBER,
121 	  .minimum = 0,
122 	  .maximum = INT_MAX,
123 	  .default_num = 1,
124 	},
125 
126 	{ .name = "base-index",
127 	  .type = OPTIONS_TABLE_NUMBER,
128 	  .minimum = 0,
129 	  .maximum = INT_MAX,
130 	  .default_num = 0
131 	},
132 
133 	{ .name = "bell-action",
134 	  .type = OPTIONS_TABLE_CHOICE,
135 	  .choices = options_table_bell_action_list,
136 	  .default_num = BELL_ANY
137 	},
138 
139 	{ .name = "bell-on-alert",
140 	  .type = OPTIONS_TABLE_FLAG,
141 	  .default_num = 0
142 	},
143 
144 	{ .name = "default-command",
145 	  .type = OPTIONS_TABLE_STRING,
146 	  .default_str = ""
147 	},
148 
149 	{ .name = "default-shell",
150 	  .type = OPTIONS_TABLE_STRING,
151 	  .default_str = _PATH_BSHELL
152 	},
153 
154 	{ .name = "destroy-unattached",
155 	  .type = OPTIONS_TABLE_FLAG,
156 	  .default_num = 0
157 	},
158 
159 	{ .name = "detach-on-destroy",
160 	  .type = OPTIONS_TABLE_FLAG,
161 	  .default_num = 1
162 	},
163 
164 	{ .name = "display-panes-active-colour",
165 	  .type = OPTIONS_TABLE_COLOUR,
166 	  .default_num = 1
167 	},
168 
169 	{ .name = "display-panes-colour",
170 	  .type = OPTIONS_TABLE_COLOUR,
171 	  .default_num = 4
172 	},
173 
174 	{ .name = "display-panes-time",
175 	  .type = OPTIONS_TABLE_NUMBER,
176 	  .minimum = 1,
177 	  .maximum = INT_MAX,
178 	  .default_num = 1000
179 	},
180 
181 	{ .name = "display-time",
182 	  .type = OPTIONS_TABLE_NUMBER,
183 	  .minimum = 1,
184 	  .maximum = INT_MAX,
185 	  .default_num = 750
186 	},
187 
188 	{ .name = "history-limit",
189 	  .type = OPTIONS_TABLE_NUMBER,
190 	  .minimum = 0,
191 	  .maximum = INT_MAX,
192 	  .default_num = 2000
193 	},
194 
195 	{ .name = "lock-after-time",
196 	  .type = OPTIONS_TABLE_NUMBER,
197 	  .minimum = 0,
198 	  .maximum = INT_MAX,
199 	  .default_num = 0
200 	},
201 
202 	{ .name = "lock-command",
203 	  .type = OPTIONS_TABLE_STRING,
204 	  .default_str = "lock -np"
205 	},
206 
207 	{ .name = "message-attr",
208 	  .type = OPTIONS_TABLE_ATTRIBUTES,
209 	  .default_num = 0,
210 	  .style = "message-style"
211 	},
212 
213 	{ .name = "message-bg",
214 	  .type = OPTIONS_TABLE_COLOUR,
215 	  .default_num = 3,
216 	  .style = "message-style"
217 	},
218 
219 	{ .name = "message-command-attr",
220 	  .type = OPTIONS_TABLE_ATTRIBUTES,
221 	  .default_num = 0,
222 	  .style = "message-command-style"
223 	},
224 
225 	{ .name = "message-command-bg",
226 	  .type = OPTIONS_TABLE_COLOUR,
227 	  .default_num = 0,
228 	  .style = "message-command-style"
229 	},
230 
231 	{ .name = "message-command-fg",
232 	  .type = OPTIONS_TABLE_COLOUR,
233 	  .default_num = 3,
234 	  .style = "message-command-style"
235 	},
236 
237 	{ .name = "message-command-style",
238 	  .type = OPTIONS_TABLE_STYLE,
239 	  .default_str = "bg=black,fg=yellow"
240 	},
241 
242 	{ .name = "message-fg",
243 	  .type = OPTIONS_TABLE_COLOUR,
244 	  .default_num = 0,
245 	  .style = "message-style"
246 	},
247 
248 	{ .name = "message-style",
249 	  .type = OPTIONS_TABLE_STYLE,
250 	  .default_str = "bg=yellow,fg=black"
251 	},
252 
253 	{ .name = "mouse",
254 	  .type = OPTIONS_TABLE_FLAG,
255 	  .default_num = 0
256 	},
257 
258 	{ .name = "mouse-utf8",
259 	  .type = OPTIONS_TABLE_FLAG,
260 	  .default_num = 0
261 	},
262 
263 	{ .name = "prefix",
264 	  .type = OPTIONS_TABLE_KEY,
265 	  .default_num = '\002',
266 	},
267 
268 	{ .name = "prefix2",
269 	  .type = OPTIONS_TABLE_KEY,
270 	  .default_num = KEYC_NONE,
271 	},
272 
273 	{ .name = "renumber-windows",
274 	  .type = OPTIONS_TABLE_FLAG,
275 	  .default_num = 0
276 	},
277 
278 	{ .name = "repeat-time",
279 	  .type = OPTIONS_TABLE_NUMBER,
280 	  .minimum = 0,
281 	  .maximum = SHRT_MAX,
282 	  .default_num = 500
283 	},
284 
285 	{ .name = "set-remain-on-exit",
286 	  .type = OPTIONS_TABLE_FLAG,
287 	  .default_num = 0
288 	},
289 
290 	{ .name = "set-titles",
291 	  .type = OPTIONS_TABLE_FLAG,
292 	  .default_num = 0
293 	},
294 
295 	{ .name = "set-titles-string",
296 	  .type = OPTIONS_TABLE_STRING,
297 	  .default_str = "#S:#I:#W - \"#T\" #{session_alerts}"
298 	},
299 
300 	{ .name = "status",
301 	  .type = OPTIONS_TABLE_FLAG,
302 	  .default_num = 1
303 	},
304 
305 	{ .name = "status-attr",
306 	  .type = OPTIONS_TABLE_ATTRIBUTES,
307 	  .default_num = 0,
308 	  .style = "status-style"
309 	},
310 
311 	{ .name = "status-bg",
312 	  .type = OPTIONS_TABLE_COLOUR,
313 	  .default_num = 2,
314 	  .style = "status-style"
315 	},
316 
317 	{ .name = "status-fg",
318 	  .type = OPTIONS_TABLE_COLOUR,
319 	  .default_num = 0,
320 	  .style = "status-style"
321 	},
322 
323 	{ .name = "status-interval",
324 	  .type = OPTIONS_TABLE_NUMBER,
325 	  .minimum = 0,
326 	  .maximum = INT_MAX,
327 	  .default_num = 15
328 	},
329 
330 	{ .name = "status-justify",
331 	  .type = OPTIONS_TABLE_CHOICE,
332 	  .choices = options_table_status_justify_list,
333 	  .default_num = 0
334 	},
335 
336 	{ .name = "status-keys",
337 	  .type = OPTIONS_TABLE_CHOICE,
338 	  .choices = options_table_status_keys_list,
339 	  .default_num = MODEKEY_EMACS
340 	},
341 
342 	{ .name = "status-left",
343 	  .type = OPTIONS_TABLE_STRING,
344 	  .default_str = "[#S] "
345 	},
346 
347 	{ .name = "status-left-attr",
348 	  .type = OPTIONS_TABLE_ATTRIBUTES,
349 	  .default_num = 0,
350 	  .style = "status-left-style"
351 	},
352 
353 	{ .name = "status-left-bg",
354 	  .type = OPTIONS_TABLE_COLOUR,
355 	  .default_num = 8,
356 	  .style = "status-left-style"
357 	},
358 
359 	{ .name = "status-left-fg",
360 	  .type = OPTIONS_TABLE_COLOUR,
361 	  .default_num = 8,
362 	  .style = "status-left-style"
363 	},
364 
365 	{ .name = "status-left-length",
366 	  .type = OPTIONS_TABLE_NUMBER,
367 	  .minimum = 0,
368 	  .maximum = SHRT_MAX,
369 	  .default_num = 10
370 	},
371 
372 	{ .name = "status-left-style",
373 	  .type = OPTIONS_TABLE_STYLE,
374 	  .default_str = "default"
375 	},
376 
377 	{ .name = "status-position",
378 	  .type = OPTIONS_TABLE_CHOICE,
379 	  .choices = options_table_status_position_list,
380 	  .default_num = 1
381 	},
382 
383 	{ .name = "status-right",
384 	  .type = OPTIONS_TABLE_STRING,
385 	  .default_str = " \"#{=21:pane_title}\" %H:%M %d-%b-%y"
386 	},
387 
388 	{ .name = "status-right-attr",
389 	  .type = OPTIONS_TABLE_ATTRIBUTES,
390 	  .default_num = 0,
391 	  .style = "status-right-style"
392 	},
393 
394 	{ .name = "status-right-bg",
395 	  .type = OPTIONS_TABLE_COLOUR,
396 	  .default_num = 8,
397 	  .style = "status-right-style"
398 	},
399 
400 	{ .name = "status-right-fg",
401 	  .type = OPTIONS_TABLE_COLOUR,
402 	  .default_num = 8,
403 	  .style = "status-right-style"
404 	},
405 
406 	{ .name = "status-right-length",
407 	  .type = OPTIONS_TABLE_NUMBER,
408 	  .minimum = 0,
409 	  .maximum = SHRT_MAX,
410 	  .default_num = 40
411 	},
412 
413 	{ .name = "status-right-style",
414 	  .type = OPTIONS_TABLE_STYLE,
415 	  .default_str = "default"
416 	},
417 
418 	{ .name = "status-style",
419 	  .type = OPTIONS_TABLE_STYLE,
420 	  .default_str = "bg=green,fg=black"
421 	},
422 
423 	{ .name = "status-utf8",
424 	  .type = OPTIONS_TABLE_FLAG,
425 	  .default_num = 0 /* overridden in main() */
426 	},
427 
428 	{ .name = "update-environment",
429 	  .type = OPTIONS_TABLE_STRING,
430 	  .default_str = "DISPLAY SSH_ASKPASS SSH_AUTH_SOCK SSH_AGENT_PID "
431 	                 "SSH_CONNECTION WINDOWID XAUTHORITY"
432 
433 	},
434 
435 	{ .name = "visual-activity",
436 	  .type = OPTIONS_TABLE_FLAG,
437 	  .default_num = 0
438 	},
439 
440 	{ .name = "visual-bell",
441 	  .type = OPTIONS_TABLE_FLAG,
442 	  .default_num = 0
443 	},
444 
445 	{ .name = "visual-silence",
446 	  .type = OPTIONS_TABLE_FLAG,
447 	  .default_num = 0
448 	},
449 
450 	{ .name = "word-separators",
451 	  .type = OPTIONS_TABLE_STRING,
452 	  .default_str = " -_@"
453 	},
454 
455 	{ .name = NULL }
456 };
457 
458 /* Window options. */
459 const struct options_table_entry window_options_table[] = {
460 	{ .name = "aggressive-resize",
461 	  .type = OPTIONS_TABLE_FLAG,
462 	  .default_num = 0
463 	},
464 
465 	{ .name = "allow-rename",
466 	  .type = OPTIONS_TABLE_FLAG,
467 	  .default_num = 1
468 	},
469 
470 	{ .name = "alternate-screen",
471 	  .type = OPTIONS_TABLE_FLAG,
472 	  .default_num = 1
473 	},
474 
475 	{ .name = "automatic-rename",
476 	  .type = OPTIONS_TABLE_FLAG,
477 	  .default_num = 1
478 	},
479 
480 	{ .name = "automatic-rename-format",
481 	  .type = OPTIONS_TABLE_STRING,
482 	  .default_str = "#{?pane_in_mode,[tmux],#{pane_current_command}}"
483 	                 "#{?pane_dead,[dead],}"
484 	},
485 
486 	{ .name = "clock-mode-colour",
487 	  .type = OPTIONS_TABLE_COLOUR,
488 	  .default_num = 4
489 	},
490 
491 	{ .name = "clock-mode-style",
492 	  .type = OPTIONS_TABLE_CHOICE,
493 	  .choices = options_table_clock_mode_style_list,
494 	  .default_num = 1
495 	},
496 
497 	{ .name = "force-height",
498 	  .type = OPTIONS_TABLE_NUMBER,
499 	  .minimum = 0,
500 	  .maximum = INT_MAX,
501 	  .default_num = 0
502 	},
503 
504 	{ .name = "force-width",
505 	  .type = OPTIONS_TABLE_NUMBER,
506 	  .minimum = 0,
507 	  .maximum = INT_MAX,
508 	  .default_num = 0
509 	},
510 
511 	{ .name = "main-pane-height",
512 	  .type = OPTIONS_TABLE_NUMBER,
513 	  .minimum = 1,
514 	  .maximum = INT_MAX,
515 	  .default_num = 24
516 	},
517 
518 	{ .name = "main-pane-width",
519 	  .type = OPTIONS_TABLE_NUMBER,
520 	  .minimum = 1,
521 	  .maximum = INT_MAX,
522 	  .default_num = 80
523 	},
524 
525 	{ .name = "mode-attr",
526 	  .type = OPTIONS_TABLE_ATTRIBUTES,
527 	  .default_num = 0,
528 	  .style = "mode-style"
529 	},
530 
531 	{ .name = "mode-bg",
532 	  .type = OPTIONS_TABLE_COLOUR,
533 	  .default_num = 3,
534 	  .style = "mode-style"
535 	},
536 
537 	{ .name = "mode-fg",
538 	  .type = OPTIONS_TABLE_COLOUR,
539 	  .default_num = 0,
540 	  .style = "mode-style"
541 	},
542 
543 	{ .name = "mode-keys",
544 	  .type = OPTIONS_TABLE_CHOICE,
545 	  .choices = options_table_mode_keys_list,
546 	  .default_num = MODEKEY_EMACS
547 	},
548 
549 	{ .name = "mode-style",
550 	  .type = OPTIONS_TABLE_STYLE,
551 	  .default_str = "bg=yellow,fg=black"
552 	},
553 
554 	{ .name = "monitor-activity",
555 	  .type = OPTIONS_TABLE_FLAG,
556 	  .default_num = 0
557 	},
558 
559 	{ .name = "monitor-silence",
560 	  .type = OPTIONS_TABLE_NUMBER,
561 	  .minimum = 0,
562 	  .maximum = INT_MAX,
563 	  .default_num = 0
564 	},
565 
566 	{ .name = "other-pane-height",
567 	  .type = OPTIONS_TABLE_NUMBER,
568 	  .minimum = 0,
569 	  .maximum = INT_MAX,
570 	  .default_num = 0
571 	},
572 
573 	{ .name = "other-pane-width",
574 	  .type = OPTIONS_TABLE_NUMBER,
575 	  .minimum = 0,
576 	  .maximum = INT_MAX,
577 	  .default_num = 0
578 	},
579 
580 	{ .name = "pane-active-border-bg",
581 	  .type = OPTIONS_TABLE_COLOUR,
582 	  .default_num = 8,
583 	  .style = "pane-active-border-style"
584 	},
585 
586 	{ .name = "pane-active-border-fg",
587 	  .type = OPTIONS_TABLE_COLOUR,
588 	  .default_num = 2,
589 	  .style = "pane-active-border-style"
590 	},
591 
592 	{ .name = "pane-active-border-style",
593 	  .type = OPTIONS_TABLE_STYLE,
594 	  .default_str = "fg=green"
595 	},
596 
597 	{ .name = "pane-base-index",
598 	  .type = OPTIONS_TABLE_NUMBER,
599 	  .minimum = 0,
600 	  .maximum = USHRT_MAX,
601 	  .default_num = 0
602 	},
603 
604 	{ .name = "pane-border-bg",
605 	  .type = OPTIONS_TABLE_COLOUR,
606 	  .default_num = 8,
607 	  .style = "pane-border-style"
608 	},
609 
610 	{ .name = "pane-border-fg",
611 	  .type = OPTIONS_TABLE_COLOUR,
612 	  .default_num = 8,
613 	  .style = "pane-border-style"
614 	},
615 
616 	{ .name = "pane-border-style",
617 	  .type = OPTIONS_TABLE_STYLE,
618 	  .default_str = "default"
619 	},
620 
621 	{ .name = "remain-on-exit",
622 	  .type = OPTIONS_TABLE_FLAG,
623 	  .default_num = 0
624 	},
625 
626 	{ .name = "synchronize-panes",
627 	  .type = OPTIONS_TABLE_FLAG,
628 	  .default_num = 0
629 	},
630 
631 	{ .name = "utf8",
632 	  .type = OPTIONS_TABLE_FLAG,
633 	  .default_num = 0 /* overridden in main() */
634 	},
635 
636 	{ .name = "window-active-style",
637 	  .type = OPTIONS_TABLE_STYLE,
638 	  .default_str = "default"
639 	},
640 
641 	{ .name = "window-style",
642 	  .type = OPTIONS_TABLE_STYLE,
643 	  .default_str = "default"
644 	},
645 
646 	{ .name = "window-status-activity-attr",
647 	  .type = OPTIONS_TABLE_ATTRIBUTES,
648 	  .default_num = GRID_ATTR_REVERSE,
649 	  .style = "window-status-activity-style"
650 	},
651 
652 	{ .name = "window-status-activity-bg",
653 	  .type = OPTIONS_TABLE_COLOUR,
654 	  .default_num = 8,
655 	  .style = "window-status-activity-style"
656 	},
657 
658 	{ .name = "window-status-activity-fg",
659 	  .type = OPTIONS_TABLE_COLOUR,
660 	  .default_num = 8,
661 	  .style = "window-status-activity-style"
662 	},
663 
664 	{ .name = "window-status-activity-style",
665 	  .type = OPTIONS_TABLE_STYLE,
666 	  .default_str = "reverse"
667 	},
668 
669 	{ .name = "window-status-attr",
670 	  .type = OPTIONS_TABLE_ATTRIBUTES,
671 	  .default_num = 0,
672 	  .style = "window-status-style"
673 	},
674 
675 	{ .name = "window-status-bell-attr",
676 	  .type = OPTIONS_TABLE_ATTRIBUTES,
677 	  .default_num = GRID_ATTR_REVERSE,
678 	  .style = "window-status-bell-style"
679 	},
680 
681 	{ .name = "window-status-bell-bg",
682 	  .type = OPTIONS_TABLE_COLOUR,
683 	  .default_num = 8,
684 	  .style = "window-status-bell-style"
685 	},
686 
687 	{ .name = "window-status-bell-fg",
688 	  .type = OPTIONS_TABLE_COLOUR,
689 	  .default_num = 8,
690 	  .style = "window-status-bell-style"
691 	},
692 
693 	{ .name = "window-status-bell-style",
694 	  .type = OPTIONS_TABLE_STYLE,
695 	  .default_str = "reverse"
696 	},
697 
698 	{ .name = "window-status-bg",
699 	  .type = OPTIONS_TABLE_COLOUR,
700 	  .default_num = 8,
701 	  .style = "window-status-style"
702 	},
703 
704 	{ .name = "window-status-current-attr",
705 	  .type = OPTIONS_TABLE_ATTRIBUTES,
706 	  .default_num = 0,
707 	  .style = "window-status-current-style"
708 	},
709 
710 	{ .name = "window-status-current-bg",
711 	  .type = OPTIONS_TABLE_COLOUR,
712 	  .default_num = 8,
713 	  .style = "window-status-current-style"
714 	},
715 
716 	{ .name = "window-status-current-fg",
717 	  .type = OPTIONS_TABLE_COLOUR,
718 	  .default_num = 8,
719 	  .style = "window-status-current-style"
720 	},
721 
722 	{ .name = "window-status-current-format",
723 	  .type = OPTIONS_TABLE_STRING,
724 	  .default_str = "#I:#W#{?window_flags,#{window_flags}, }"
725 	},
726 
727 	{ .name = "window-status-current-style",
728 	  .type = OPTIONS_TABLE_STYLE,
729 	  .default_str = "default"
730 	},
731 
732 	{ .name = "window-status-fg",
733 	  .type = OPTIONS_TABLE_COLOUR,
734 	  .default_num = 8,
735 	  .style = "window-status-style"
736 	},
737 
738 	{ .name = "window-status-format",
739 	  .type = OPTIONS_TABLE_STRING,
740 	  .default_str = "#I:#W#{?window_flags,#{window_flags}, }"
741 	},
742 
743 	{ .name = "window-status-last-attr",
744 	  .type = OPTIONS_TABLE_ATTRIBUTES,
745 	  .default_num = 0,
746 	  .style = "window-status-last-style"
747 	},
748 
749 	{ .name = "window-status-last-bg",
750 	  .type = OPTIONS_TABLE_COLOUR,
751 	  .default_num = 8,
752 	  .style = "window-status-last-style"
753 	},
754 
755 	{ .name = "window-status-last-fg",
756 	  .type = OPTIONS_TABLE_COLOUR,
757 	  .default_num = 8,
758 	  .style = "window-status-last-style"
759 	},
760 
761 	{ .name = "window-status-last-style",
762 	  .type = OPTIONS_TABLE_STYLE,
763 	  .default_str = "default"
764 	},
765 
766 	{ .name = "window-status-separator",
767 	  .type = OPTIONS_TABLE_STRING,
768 	  .default_str = " "
769 	},
770 
771 	{ .name = "window-status-style",
772 	  .type = OPTIONS_TABLE_STYLE,
773 	  .default_str = "default"
774 	},
775 
776 	{ .name = "wrap-search",
777 	  .type = OPTIONS_TABLE_FLAG,
778 	  .default_num = 1
779 	},
780 
781 	{ .name = "xterm-keys",
782 	  .type = OPTIONS_TABLE_FLAG,
783 	  .default_num = 0
784 	},
785 
786 	{ .name = NULL }
787 };
788 
789 /* Populate an options tree from a table. */
790 void
791 options_table_populate_tree(
792     const struct options_table_entry *table, struct options *oo)
793 {
794 	const struct options_table_entry	*oe;
795 
796 	for (oe = table; oe->name != NULL; oe++) {
797 		switch (oe->type) {
798 		case OPTIONS_TABLE_STRING:
799 			options_set_string(oo, oe->name, "%s", oe->default_str);
800 			break;
801 		case OPTIONS_TABLE_STYLE:
802 			options_set_style(oo, oe->name, oe->default_str, 0);
803 			break;
804 		default:
805 			options_set_number(oo, oe->name, oe->default_num);
806 			break;
807 		}
808 	}
809 }
810 
811 /* Print an option using its type from the table. */
812 const char *
813 options_table_print_entry(const struct options_table_entry *oe,
814     struct options_entry *o, int no_quotes)
815 {
816 	static char	 out[BUFSIZ];
817 	const char	*s;
818 
819 	*out = '\0';
820 	switch (oe->type) {
821 	case OPTIONS_TABLE_STRING:
822 		if (no_quotes)
823 			xsnprintf(out, sizeof out, "%s", o->str);
824 		else
825 			xsnprintf(out, sizeof out, "\"%s\"", o->str);
826 		break;
827 	case OPTIONS_TABLE_NUMBER:
828 		xsnprintf(out, sizeof out, "%lld", o->num);
829 		break;
830 	case OPTIONS_TABLE_KEY:
831 		xsnprintf(out, sizeof out, "%s",
832 		    key_string_lookup_key(o->num));
833 		break;
834 	case OPTIONS_TABLE_COLOUR:
835 		s = colour_tostring(o->num);
836 		xsnprintf(out, sizeof out, "%s", s);
837 		break;
838 	case OPTIONS_TABLE_ATTRIBUTES:
839 		s = attributes_tostring(o->num);
840 		xsnprintf(out, sizeof out, "%s", s);
841 		break;
842 	case OPTIONS_TABLE_FLAG:
843 		if (o->num)
844 			strlcpy(out, "on", sizeof out);
845 		else
846 			strlcpy(out, "off", sizeof out);
847 		break;
848 	case OPTIONS_TABLE_CHOICE:
849 		s = oe->choices[o->num];
850 		xsnprintf(out, sizeof out, "%s", s);
851 		break;
852 	case OPTIONS_TABLE_STYLE:
853 		s = style_tostring(&o->style);
854 		xsnprintf(out, sizeof out, "%s", s);
855 		break;
856 	}
857 	return (out);
858 }
859 
860 /* Find an option. */
861 int
862 options_table_find(
863     const char *optstr, const struct options_table_entry **table,
864     const struct options_table_entry **oe)
865 {
866 	static const struct options_table_entry	*tables[] = {
867 		server_options_table,
868 		window_options_table,
869 		session_options_table
870 	};
871 	const struct options_table_entry	*oe_loop;
872 	u_int					 i;
873 
874 	for (i = 0; i < nitems(tables); i++) {
875 		for (oe_loop = tables[i]; oe_loop->name != NULL; oe_loop++) {
876 			if (strncmp(oe_loop->name, optstr, strlen(optstr)) != 0)
877 				continue;
878 
879 			/* If already found, ambiguous. */
880 			if (*oe != NULL)
881 				return (-1);
882 			*oe = oe_loop;
883 			*table = tables[i];
884 
885 			/* Bail now if an exact match. */
886 			if (strcmp((*oe)->name, optstr) == 0)
887 				break;
888 		}
889 	}
890 	return (0);
891 }
892