4 * Copyright (c) 2011 Nicholas Marriott <nicm@users.sourceforge.net>
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.
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.
19 #include <sys/types.h>
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 loop up the real type when
32 * the user sets an option or its value needs to be shown.
35 /* Choice option type lists. */
36 const char *options_table_mode_keys_list
[] = {
39 const char *options_table_mode_mouse_list
[] = {
40 "off", "on", "copy-mode", NULL
42 const char *options_table_clock_mode_style_list
[] = {
45 const char *options_table_status_keys_list
[] = {
48 const char *options_table_status_justify_list
[] = {
49 "left", "centre", "right", NULL
51 const char *options_table_status_position_list
[] = {
54 const char *options_table_bell_action_list
[] = {
55 "none", "any", "current", NULL
59 const struct options_table_entry server_options_table
[] = {
60 { .name
= "buffer-limit",
61 .type
= OPTIONS_TABLE_NUMBER
,
67 { .name
= "escape-time",
68 .type
= OPTIONS_TABLE_NUMBER
,
74 { .name
= "exit-unattached",
75 .type
= OPTIONS_TABLE_FLAG
,
80 .type
= OPTIONS_TABLE_FLAG
,
81 .default_num
= 0 /* overridden in main() */
84 { .name
= "set-clipboard",
85 .type
= OPTIONS_TABLE_FLAG
,
92 /* Session options. */
93 const struct options_table_entry session_options_table
[] = {
94 { .name
= "base-index",
95 .type
= OPTIONS_TABLE_NUMBER
,
101 { .name
= "bell-action",
102 .type
= OPTIONS_TABLE_CHOICE
,
103 .choices
= options_table_bell_action_list
,
104 .default_num
= BELL_ANY
107 { .name
= "bell-on-alert",
108 .type
= OPTIONS_TABLE_FLAG
,
112 { .name
= "default-command",
113 .type
= OPTIONS_TABLE_STRING
,
117 { .name
= "default-path",
118 .type
= OPTIONS_TABLE_STRING
,
122 { .name
= "default-shell",
123 .type
= OPTIONS_TABLE_STRING
,
124 .default_str
= _PATH_BSHELL
127 { .name
= "default-terminal",
128 .type
= OPTIONS_TABLE_STRING
,
129 .default_str
= "screen"
132 { .name
= "destroy-unattached",
133 .type
= OPTIONS_TABLE_FLAG
,
137 { .name
= "detach-on-destroy",
138 .type
= OPTIONS_TABLE_FLAG
,
142 { .name
= "display-panes-active-colour",
143 .type
= OPTIONS_TABLE_COLOUR
,
147 { .name
= "display-panes-colour",
148 .type
= OPTIONS_TABLE_COLOUR
,
152 { .name
= "display-panes-time",
153 .type
= OPTIONS_TABLE_NUMBER
,
159 { .name
= "display-time",
160 .type
= OPTIONS_TABLE_NUMBER
,
166 { .name
= "history-limit",
167 .type
= OPTIONS_TABLE_NUMBER
,
173 { .name
= "lock-after-time",
174 .type
= OPTIONS_TABLE_NUMBER
,
180 { .name
= "lock-command",
181 .type
= OPTIONS_TABLE_STRING
,
182 .default_str
= "lock -np"
185 { .name
= "lock-server",
186 .type
= OPTIONS_TABLE_FLAG
,
190 { .name
= "message-attr",
191 .type
= OPTIONS_TABLE_ATTRIBUTES
,
195 { .name
= "message-bg",
196 .type
= OPTIONS_TABLE_COLOUR
,
200 { .name
= "message-command-attr",
201 .type
= OPTIONS_TABLE_ATTRIBUTES
,
205 { .name
= "message-command-bg",
206 .type
= OPTIONS_TABLE_COLOUR
,
210 { .name
= "message-command-fg",
211 .type
= OPTIONS_TABLE_COLOUR
,
215 { .name
= "message-fg",
216 .type
= OPTIONS_TABLE_COLOUR
,
220 { .name
= "message-limit",
221 .type
= OPTIONS_TABLE_NUMBER
,
227 { .name
= "mouse-resize-pane",
228 .type
= OPTIONS_TABLE_FLAG
,
232 { .name
= "mouse-select-pane",
233 .type
= OPTIONS_TABLE_FLAG
,
237 { .name
= "mouse-select-window",
238 .type
= OPTIONS_TABLE_FLAG
,
242 { .name
= "mouse-utf8",
243 .type
= OPTIONS_TABLE_FLAG
,
247 { .name
= "pane-active-border-bg",
248 .type
= OPTIONS_TABLE_COLOUR
,
252 { .name
= "pane-active-border-fg",
253 .type
= OPTIONS_TABLE_COLOUR
,
257 { .name
= "pane-border-bg",
258 .type
= OPTIONS_TABLE_COLOUR
,
262 { .name
= "pane-border-fg",
263 .type
= OPTIONS_TABLE_COLOUR
,
268 .type
= OPTIONS_TABLE_KEY
,
269 .default_num
= '\002',
273 .type
= OPTIONS_TABLE_KEY
,
274 .default_num
= KEYC_NONE
,
277 { .name
= "repeat-time",
278 .type
= OPTIONS_TABLE_NUMBER
,
284 { .name
= "set-remain-on-exit",
285 .type
= OPTIONS_TABLE_FLAG
,
289 { .name
= "set-titles",
290 .type
= OPTIONS_TABLE_FLAG
,
294 { .name
= "set-titles-string",
295 .type
= OPTIONS_TABLE_STRING
,
296 .default_str
= "#S:#I:#W - \"#T\""
300 .type
= OPTIONS_TABLE_FLAG
,
304 { .name
= "status-attr",
305 .type
= OPTIONS_TABLE_ATTRIBUTES
,
309 { .name
= "status-bg",
310 .type
= OPTIONS_TABLE_COLOUR
,
314 { .name
= "status-fg",
315 .type
= OPTIONS_TABLE_COLOUR
,
319 { .name
= "status-interval",
320 .type
= OPTIONS_TABLE_NUMBER
,
326 { .name
= "status-justify",
327 .type
= OPTIONS_TABLE_CHOICE
,
328 .choices
= options_table_status_justify_list
,
332 { .name
= "status-keys",
333 .type
= OPTIONS_TABLE_CHOICE
,
334 .choices
= options_table_status_keys_list
,
335 .default_num
= MODEKEY_EMACS
338 { .name
= "status-left",
339 .type
= OPTIONS_TABLE_STRING
,
340 .default_str
= "[#S]"
343 { .name
= "status-left-attr",
344 .type
= OPTIONS_TABLE_ATTRIBUTES
,
348 { .name
= "status-left-bg",
349 .type
= OPTIONS_TABLE_COLOUR
,
353 { .name
= "status-left-fg",
354 .type
= OPTIONS_TABLE_COLOUR
,
358 { .name
= "status-left-length",
359 .type
= OPTIONS_TABLE_NUMBER
,
365 { .name
= "status-position",
366 .type
= OPTIONS_TABLE_CHOICE
,
367 .choices
= options_table_status_position_list
,
371 { .name
= "status-right",
372 .type
= OPTIONS_TABLE_STRING
,
373 .default_str
= "\"#22T\" %H:%M %d-%b-%y"
376 { .name
= "status-right-attr",
377 .type
= OPTIONS_TABLE_ATTRIBUTES
,
381 { .name
= "status-right-bg",
382 .type
= OPTIONS_TABLE_COLOUR
,
386 { .name
= "status-right-fg",
387 .type
= OPTIONS_TABLE_COLOUR
,
391 { .name
= "status-right-length",
392 .type
= OPTIONS_TABLE_NUMBER
,
398 { .name
= "status-utf8",
399 .type
= OPTIONS_TABLE_FLAG
,
400 .default_num
= 0 /* overridden in main() */
403 { .name
= "terminal-overrides",
404 .type
= OPTIONS_TABLE_STRING
,
405 .default_str
= "*88col*:colors=88,*256col*:colors=256"
406 ",xterm*:XT:Ms=\\E]52;%p1%s;%p2%s\\007"
407 ":Cc=\\E]12;%p1%s\\007:Cr=\\E]112\\007"
408 ":Cs=\\E[%p1%d q:Csr=\\E[2 q,screen*:XT"
411 { .name
= "update-environment",
412 .type
= OPTIONS_TABLE_STRING
,
413 .default_str
= "DISPLAY SSH_ASKPASS SSH_AUTH_SOCK SSH_AGENT_PID "
414 "SSH_CONNECTION WINDOWID XAUTHORITY"
418 { .name
= "visual-activity",
419 .type
= OPTIONS_TABLE_FLAG
,
423 { .name
= "visual-bell",
424 .type
= OPTIONS_TABLE_FLAG
,
428 { .name
= "visual-content",
429 .type
= OPTIONS_TABLE_FLAG
,
433 { .name
= "visual-silence",
434 .type
= OPTIONS_TABLE_FLAG
,
438 { .name
= "word-separators",
439 .type
= OPTIONS_TABLE_STRING
,
440 .default_str
= " -_@"
446 /* Window options. */
447 const struct options_table_entry window_options_table
[] = {
448 { .name
= "aggressive-resize",
449 .type
= OPTIONS_TABLE_FLAG
,
453 { .name
= "allow-rename",
454 .type
= OPTIONS_TABLE_FLAG
,
458 { .name
= "alternate-screen",
459 .type
= OPTIONS_TABLE_FLAG
,
463 { .name
= "automatic-rename",
464 .type
= OPTIONS_TABLE_FLAG
,
469 { .name
= "c0-change-trigger",
470 .type
= OPTIONS_TABLE_NUMBER
,
476 { .name
= "c0-change-interval",
477 .type
= OPTIONS_TABLE_NUMBER
,
483 { .name
= "clock-mode-colour",
484 .type
= OPTIONS_TABLE_COLOUR
,
488 { .name
= "clock-mode-style",
489 .type
= OPTIONS_TABLE_CHOICE
,
490 .choices
= options_table_clock_mode_style_list
,
494 { .name
= "force-height",
495 .type
= OPTIONS_TABLE_NUMBER
,
501 { .name
= "force-width",
502 .type
= OPTIONS_TABLE_NUMBER
,
508 { .name
= "layout-history-limit",
509 .type
= OPTIONS_TABLE_NUMBER
,
511 .maximum
= USHRT_MAX
,
515 { .name
= "main-pane-height",
516 .type
= OPTIONS_TABLE_NUMBER
,
522 { .name
= "main-pane-width",
523 .type
= OPTIONS_TABLE_NUMBER
,
529 { .name
= "mode-attr",
530 .type
= OPTIONS_TABLE_ATTRIBUTES
,
535 .type
= OPTIONS_TABLE_COLOUR
,
540 .type
= OPTIONS_TABLE_COLOUR
,
544 { .name
= "mode-keys",
545 .type
= OPTIONS_TABLE_CHOICE
,
546 .choices
= options_table_mode_keys_list
,
547 .default_num
= MODEKEY_EMACS
550 { .name
= "mode-mouse",
551 .type
= OPTIONS_TABLE_CHOICE
,
552 .choices
= options_table_mode_mouse_list
,
556 { .name
= "monitor-activity",
557 .type
= OPTIONS_TABLE_FLAG
,
561 { .name
= "monitor-content",
562 .type
= OPTIONS_TABLE_STRING
,
566 { .name
= "monitor-silence",
567 .type
= OPTIONS_TABLE_NUMBER
,
573 { .name
= "other-pane-height",
574 .type
= OPTIONS_TABLE_NUMBER
,
580 { .name
= "other-pane-width",
581 .type
= OPTIONS_TABLE_NUMBER
,
587 { .name
= "pane-base-index",
588 .type
= OPTIONS_TABLE_NUMBER
,
590 .maximum
= USHRT_MAX
,
594 { .name
= "remain-on-exit",
595 .type
= OPTIONS_TABLE_FLAG
,
599 { .name
= "synchronize-panes",
600 .type
= OPTIONS_TABLE_FLAG
,
605 .type
= OPTIONS_TABLE_FLAG
,
606 .default_num
= 0 /* overridden in main() */
609 { .name
= "window-status-activity-attr",
610 .type
= OPTIONS_TABLE_ATTRIBUTES
,
611 .default_num
= GRID_ATTR_REVERSE
614 { .name
= "window-status-activity-bg",
615 .type
= OPTIONS_TABLE_COLOUR
,
619 { .name
= "window-status-activity-fg",
620 .type
= OPTIONS_TABLE_COLOUR
,
624 { .name
= "window-status-bell-attr",
625 .type
= OPTIONS_TABLE_ATTRIBUTES
,
626 .default_num
= GRID_ATTR_REVERSE
629 { .name
= "window-status-bell-bg",
630 .type
= OPTIONS_TABLE_COLOUR
,
634 { .name
= "window-status-bell-fg",
635 .type
= OPTIONS_TABLE_COLOUR
,
639 { .name
= "window-status-content-attr",
640 .type
= OPTIONS_TABLE_ATTRIBUTES
,
641 .default_num
= GRID_ATTR_REVERSE
644 { .name
= "window-status-content-bg",
645 .type
= OPTIONS_TABLE_COLOUR
,
649 { .name
= "window-status-content-fg",
650 .type
= OPTIONS_TABLE_COLOUR
,
654 { .name
= "window-status-attr",
655 .type
= OPTIONS_TABLE_ATTRIBUTES
,
659 { .name
= "window-status-bg",
660 .type
= OPTIONS_TABLE_COLOUR
,
664 { .name
= "window-status-current-attr",
665 .type
= OPTIONS_TABLE_ATTRIBUTES
,
669 { .name
= "window-status-current-bg",
670 .type
= OPTIONS_TABLE_COLOUR
,
674 { .name
= "window-status-current-fg",
675 .type
= OPTIONS_TABLE_COLOUR
,
679 { .name
= "window-status-current-format",
680 .type
= OPTIONS_TABLE_STRING
,
681 .default_str
= "#I:#W#F"
684 { .name
= "window-status-fg",
685 .type
= OPTIONS_TABLE_COLOUR
,
689 { .name
= "window-status-format",
690 .type
= OPTIONS_TABLE_STRING
,
691 .default_str
= "#I:#W#F"
694 { .name
= "window-status-separator",
695 .type
= OPTIONS_TABLE_STRING
,
699 { .name
= "wrap-search",
700 .type
= OPTIONS_TABLE_FLAG
,
704 { .name
= "xterm-keys",
705 .type
= OPTIONS_TABLE_FLAG
,
712 /* Populate an options tree from a table. */
714 options_table_populate_tree(
715 const struct options_table_entry
*table
, struct options
*oo
)
717 const struct options_table_entry
*oe
;
719 for (oe
= table
; oe
->name
!= NULL
; oe
++) {
720 if (oe
->default_str
!= NULL
)
721 options_set_string(oo
, oe
->name
, "%s", oe
->default_str
);
723 options_set_number(oo
, oe
->name
, oe
->default_num
);
727 /* Print an option using its type from the table. */
729 options_table_print_entry(
730 const struct options_table_entry
*oe
, struct options_entry
*o
)
732 static char out
[BUFSIZ
];
737 case OPTIONS_TABLE_STRING
:
738 xsnprintf(out
, sizeof out
, "\"%s\"", o
->str
);
740 case OPTIONS_TABLE_NUMBER
:
741 xsnprintf(out
, sizeof out
, "%lld", o
->num
);
743 case OPTIONS_TABLE_KEY
:
744 xsnprintf(out
, sizeof out
, "%s", key_string_lookup_key(o
->num
));
746 case OPTIONS_TABLE_COLOUR
:
747 s
= colour_tostring(o
->num
);
748 xsnprintf(out
, sizeof out
, "%s", s
);
750 case OPTIONS_TABLE_ATTRIBUTES
:
751 s
= attributes_tostring(o
->num
);
752 xsnprintf(out
, sizeof out
, "%s", s
);
754 case OPTIONS_TABLE_FLAG
:
756 strlcpy(out
, "on", sizeof out
);
758 strlcpy(out
, "off", sizeof out
);
760 case OPTIONS_TABLE_CHOICE
:
761 s
= oe
->choices
[o
->num
];
762 xsnprintf(out
, sizeof out
, "%s", s
);
768 /* Find an option. */
771 const char *optstr
, const struct options_table_entry
**table
,
772 const struct options_table_entry
**oe
)
774 static const struct options_table_entry
*tables
[] = {
775 server_options_table
,
776 window_options_table
,
777 session_options_table
779 const struct options_table_entry
*oe_loop
;
782 for (i
= 0; i
< nitems(tables
); i
++) {
783 for (oe_loop
= tables
[i
]; oe_loop
->name
!= NULL
; oe_loop
++) {
784 if (strncmp(oe_loop
->name
, optstr
, strlen(optstr
)) != 0)
787 /* If already found, ambiguous. */
793 /* Bail now if an exact match. */
794 if (strcmp((*oe
)->name
, optstr
) == 0)