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