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
,
79 { .name
= "focus-events",
80 .type
= OPTIONS_TABLE_FLAG
,
85 .type
= OPTIONS_TABLE_FLAG
,
86 .default_num
= 0 /* overridden in main() */
89 { .name
= "set-clipboard",
90 .type
= OPTIONS_TABLE_FLAG
,
94 { .name
= "terminal-overrides",
95 .type
= OPTIONS_TABLE_STRING
,
96 .default_str
= "*256col*:colors=256"
97 ",xterm*:XT:Ms=\\E]52;%p1%s;%p2%s\\007"
98 ":Cs=\\E]12;%p1%s\\007:Cr=\\E]112\\007"
99 ":Ss=\\E[%p1%d q:Se=\\E[2 q,screen*:XT"
105 /* Session options. */
106 const struct options_table_entry session_options_table
[] = {
107 { .name
= "assume-paste-time",
108 .type
= OPTIONS_TABLE_NUMBER
,
114 { .name
= "base-index",
115 .type
= OPTIONS_TABLE_NUMBER
,
121 { .name
= "bell-action",
122 .type
= OPTIONS_TABLE_CHOICE
,
123 .choices
= options_table_bell_action_list
,
124 .default_num
= BELL_ANY
127 { .name
= "bell-on-alert",
128 .type
= OPTIONS_TABLE_FLAG
,
132 { .name
= "default-command",
133 .type
= OPTIONS_TABLE_STRING
,
137 { .name
= "default-shell",
138 .type
= OPTIONS_TABLE_STRING
,
139 .default_str
= _PATH_BSHELL
142 { .name
= "default-terminal",
143 .type
= OPTIONS_TABLE_STRING
,
144 .default_str
= "screen"
147 { .name
= "destroy-unattached",
148 .type
= OPTIONS_TABLE_FLAG
,
152 { .name
= "detach-on-destroy",
153 .type
= OPTIONS_TABLE_FLAG
,
157 { .name
= "display-panes-active-colour",
158 .type
= OPTIONS_TABLE_COLOUR
,
162 { .name
= "display-panes-colour",
163 .type
= OPTIONS_TABLE_COLOUR
,
167 { .name
= "display-panes-time",
168 .type
= OPTIONS_TABLE_NUMBER
,
174 { .name
= "display-time",
175 .type
= OPTIONS_TABLE_NUMBER
,
181 { .name
= "history-limit",
182 .type
= OPTIONS_TABLE_NUMBER
,
188 { .name
= "lock-after-time",
189 .type
= OPTIONS_TABLE_NUMBER
,
195 { .name
= "lock-command",
196 .type
= OPTIONS_TABLE_STRING
,
197 .default_str
= "lock -np"
200 { .name
= "lock-server",
201 .type
= OPTIONS_TABLE_FLAG
,
205 { .name
= "message-attr",
206 .type
= OPTIONS_TABLE_ATTRIBUTES
,
208 .style
= "message-style"
211 { .name
= "message-bg",
212 .type
= OPTIONS_TABLE_COLOUR
,
214 .style
= "message-style"
217 { .name
= "message-command-attr",
218 .type
= OPTIONS_TABLE_ATTRIBUTES
,
220 .style
= "message-command-style"
223 { .name
= "message-command-bg",
224 .type
= OPTIONS_TABLE_COLOUR
,
226 .style
= "message-command-style"
229 { .name
= "message-command-fg",
230 .type
= OPTIONS_TABLE_COLOUR
,
232 .style
= "message-command-style"
235 { .name
= "message-command-style",
236 .type
= OPTIONS_TABLE_STYLE
,
237 .default_str
= "bg=black,fg=yellow"
240 { .name
= "message-fg",
241 .type
= OPTIONS_TABLE_COLOUR
,
243 .style
= "message-style"
246 { .name
= "message-limit",
247 .type
= OPTIONS_TABLE_NUMBER
,
253 { .name
= "message-style",
254 .type
= OPTIONS_TABLE_STYLE
,
255 .default_str
= "bg=yellow,fg=black"
258 { .name
= "mouse-resize-pane",
259 .type
= OPTIONS_TABLE_FLAG
,
263 { .name
= "mouse-select-pane",
264 .type
= OPTIONS_TABLE_FLAG
,
268 { .name
= "mouse-select-window",
269 .type
= OPTIONS_TABLE_FLAG
,
273 { .name
= "mouse-utf8",
274 .type
= OPTIONS_TABLE_FLAG
,
278 { .name
= "pane-active-border-bg",
279 .type
= OPTIONS_TABLE_COLOUR
,
281 .style
= "pane-active-border-style"
284 { .name
= "pane-active-border-fg",
285 .type
= OPTIONS_TABLE_COLOUR
,
287 .style
= "pane-active-border-style"
290 { .name
= "pane-active-border-style",
291 .type
= OPTIONS_TABLE_STYLE
,
292 .default_str
= "fg=green"
295 { .name
= "pane-border-bg",
296 .type
= OPTIONS_TABLE_COLOUR
,
298 .style
= "pane-border-style"
301 { .name
= "pane-border-fg",
302 .type
= OPTIONS_TABLE_COLOUR
,
304 .style
= "pane-border-style"
307 { .name
= "pane-border-style",
308 .type
= OPTIONS_TABLE_STYLE
,
309 .default_str
= "default"
313 .type
= OPTIONS_TABLE_KEY
,
314 .default_num
= '\002',
318 .type
= OPTIONS_TABLE_KEY
,
319 .default_num
= KEYC_NONE
,
322 { .name
= "renumber-windows",
323 .type
= OPTIONS_TABLE_FLAG
,
327 { .name
= "repeat-time",
328 .type
= OPTIONS_TABLE_NUMBER
,
334 { .name
= "set-remain-on-exit",
335 .type
= OPTIONS_TABLE_FLAG
,
339 { .name
= "set-titles",
340 .type
= OPTIONS_TABLE_FLAG
,
344 { .name
= "set-titles-string",
345 .type
= OPTIONS_TABLE_STRING
,
346 .default_str
= "#S:#I:#W - \"#T\""
350 .type
= OPTIONS_TABLE_FLAG
,
354 { .name
= "status-attr",
355 .type
= OPTIONS_TABLE_ATTRIBUTES
,
357 .style
= "status-style"
360 { .name
= "status-bg",
361 .type
= OPTIONS_TABLE_COLOUR
,
363 .style
= "status-style"
366 { .name
= "status-fg",
367 .type
= OPTIONS_TABLE_COLOUR
,
369 .style
= "status-style"
372 { .name
= "status-interval",
373 .type
= OPTIONS_TABLE_NUMBER
,
379 { .name
= "status-justify",
380 .type
= OPTIONS_TABLE_CHOICE
,
381 .choices
= options_table_status_justify_list
,
385 { .name
= "status-keys",
386 .type
= OPTIONS_TABLE_CHOICE
,
387 .choices
= options_table_status_keys_list
,
388 .default_num
= MODEKEY_EMACS
391 { .name
= "status-left",
392 .type
= OPTIONS_TABLE_STRING
,
393 .default_str
= "[#S]"
396 { .name
= "status-left-attr",
397 .type
= OPTIONS_TABLE_ATTRIBUTES
,
399 .style
= "status-left-style"
402 { .name
= "status-left-bg",
403 .type
= OPTIONS_TABLE_COLOUR
,
405 .style
= "status-left-style"
408 { .name
= "status-left-fg",
409 .type
= OPTIONS_TABLE_COLOUR
,
411 .style
= "status-left-style"
414 { .name
= "status-left-length",
415 .type
= OPTIONS_TABLE_NUMBER
,
421 { .name
= "status-left-style",
422 .type
= OPTIONS_TABLE_STYLE
,
423 .default_str
= "default"
426 { .name
= "status-position",
427 .type
= OPTIONS_TABLE_CHOICE
,
428 .choices
= options_table_status_position_list
,
432 { .name
= "status-right",
433 .type
= OPTIONS_TABLE_STRING
,
434 .default_str
= "\"#{=22:pane_title}\" %H:%M %d-%b-%y"
437 { .name
= "status-right-attr",
438 .type
= OPTIONS_TABLE_ATTRIBUTES
,
440 .style
= "status-right-style"
443 { .name
= "status-right-bg",
444 .type
= OPTIONS_TABLE_COLOUR
,
446 .style
= "status-right-style"
449 { .name
= "status-right-fg",
450 .type
= OPTIONS_TABLE_COLOUR
,
452 .style
= "status-right-style"
455 { .name
= "status-right-length",
456 .type
= OPTIONS_TABLE_NUMBER
,
462 { .name
= "status-right-style",
463 .type
= OPTIONS_TABLE_STYLE
,
464 .default_str
= "default"
467 { .name
= "status-style",
468 .type
= OPTIONS_TABLE_STYLE
,
469 .default_str
= "bg=green,fg=black"
472 { .name
= "status-utf8",
473 .type
= OPTIONS_TABLE_FLAG
,
474 .default_num
= 0 /* overridden in main() */
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"
484 { .name
= "visual-activity",
485 .type
= OPTIONS_TABLE_FLAG
,
489 { .name
= "visual-bell",
490 .type
= OPTIONS_TABLE_FLAG
,
494 { .name
= "visual-content",
495 .type
= OPTIONS_TABLE_FLAG
,
499 { .name
= "visual-silence",
500 .type
= OPTIONS_TABLE_FLAG
,
504 { .name
= "word-separators",
505 .type
= OPTIONS_TABLE_STRING
,
506 .default_str
= " -_@"
512 /* Window options. */
513 const struct options_table_entry window_options_table
[] = {
514 { .name
= "aggressive-resize",
515 .type
= OPTIONS_TABLE_FLAG
,
519 { .name
= "allow-rename",
520 .type
= OPTIONS_TABLE_FLAG
,
524 { .name
= "alternate-screen",
525 .type
= OPTIONS_TABLE_FLAG
,
529 { .name
= "automatic-rename",
530 .type
= OPTIONS_TABLE_FLAG
,
534 { .name
= "automatic-rename-format",
535 .type
= OPTIONS_TABLE_STRING
,
536 .default_str
= "#{?pane_in_mode,[tmux],#{pane_current_command}}#{?pane_dead,[dead],}"
539 { .name
= "c0-change-trigger",
540 .type
= OPTIONS_TABLE_NUMBER
,
546 { .name
= "c0-change-interval",
547 .type
= OPTIONS_TABLE_NUMBER
,
553 { .name
= "clock-mode-colour",
554 .type
= OPTIONS_TABLE_COLOUR
,
558 { .name
= "clock-mode-style",
559 .type
= OPTIONS_TABLE_CHOICE
,
560 .choices
= options_table_clock_mode_style_list
,
564 { .name
= "force-height",
565 .type
= OPTIONS_TABLE_NUMBER
,
571 { .name
= "force-width",
572 .type
= OPTIONS_TABLE_NUMBER
,
578 { .name
= "main-pane-height",
579 .type
= OPTIONS_TABLE_NUMBER
,
585 { .name
= "main-pane-width",
586 .type
= OPTIONS_TABLE_NUMBER
,
592 { .name
= "mode-attr",
593 .type
= OPTIONS_TABLE_ATTRIBUTES
,
595 .style
= "mode-style"
599 .type
= OPTIONS_TABLE_COLOUR
,
601 .style
= "mode-style"
605 .type
= OPTIONS_TABLE_COLOUR
,
607 .style
= "mode-style"
610 { .name
= "mode-keys",
611 .type
= OPTIONS_TABLE_CHOICE
,
612 .choices
= options_table_mode_keys_list
,
613 .default_num
= MODEKEY_EMACS
616 { .name
= "mode-mouse",
617 .type
= OPTIONS_TABLE_CHOICE
,
618 .choices
= options_table_mode_mouse_list
,
622 { .name
= "mode-style",
623 .type
= OPTIONS_TABLE_STYLE
,
624 .default_str
= "bg=yellow,fg=black"
627 { .name
= "monitor-activity",
628 .type
= OPTIONS_TABLE_FLAG
,
632 { .name
= "monitor-content",
633 .type
= OPTIONS_TABLE_STRING
,
637 { .name
= "monitor-silence",
638 .type
= OPTIONS_TABLE_NUMBER
,
644 { .name
= "other-pane-height",
645 .type
= OPTIONS_TABLE_NUMBER
,
651 { .name
= "other-pane-width",
652 .type
= OPTIONS_TABLE_NUMBER
,
658 { .name
= "pane-base-index",
659 .type
= OPTIONS_TABLE_NUMBER
,
661 .maximum
= USHRT_MAX
,
665 { .name
= "remain-on-exit",
666 .type
= OPTIONS_TABLE_FLAG
,
670 { .name
= "synchronize-panes",
671 .type
= OPTIONS_TABLE_FLAG
,
676 .type
= OPTIONS_TABLE_FLAG
,
677 .default_num
= 0 /* overridden in main() */
680 { .name
= "window-status-activity-attr",
681 .type
= OPTIONS_TABLE_ATTRIBUTES
,
682 .default_num
= GRID_ATTR_REVERSE
,
683 .style
= "window-status-activity-style"
686 { .name
= "window-status-activity-bg",
687 .type
= OPTIONS_TABLE_COLOUR
,
689 .style
= "window-status-activity-style"
692 { .name
= "window-status-activity-fg",
693 .type
= OPTIONS_TABLE_COLOUR
,
695 .style
= "window-status-activity-style"
698 { .name
= "window-status-activity-style",
699 .type
= OPTIONS_TABLE_STYLE
,
700 .default_str
= "reverse"
703 { .name
= "window-status-attr",
704 .type
= OPTIONS_TABLE_ATTRIBUTES
,
706 .style
= "window-status-style"
709 { .name
= "window-status-bell-attr",
710 .type
= OPTIONS_TABLE_ATTRIBUTES
,
711 .default_num
= GRID_ATTR_REVERSE
,
712 .style
= "window-status-bell-style"
715 { .name
= "window-status-bell-bg",
716 .type
= OPTIONS_TABLE_COLOUR
,
718 .style
= "window-status-bell-style"
721 { .name
= "window-status-bell-fg",
722 .type
= OPTIONS_TABLE_COLOUR
,
724 .style
= "window-status-bell-style"
727 { .name
= "window-status-bell-style",
728 .type
= OPTIONS_TABLE_STYLE
,
729 .default_str
= "reverse"
732 { .name
= "window-status-bg",
733 .type
= OPTIONS_TABLE_COLOUR
,
735 .style
= "window-status-style"
738 { .name
= "window-status-content-attr",
739 .type
= OPTIONS_TABLE_ATTRIBUTES
,
740 .default_num
= GRID_ATTR_REVERSE
,
741 .style
= "window-status-content-style"
744 { .name
= "window-status-content-bg",
745 .type
= OPTIONS_TABLE_COLOUR
,
747 .style
= "window-status-content-style"
750 { .name
= "window-status-content-fg",
751 .type
= OPTIONS_TABLE_COLOUR
,
753 .style
= "window-status-content-style"
756 { .name
= "window-status-content-style",
757 .type
= OPTIONS_TABLE_STYLE
,
758 .default_str
= "reverse"
761 { .name
= "window-status-current-attr",
762 .type
= OPTIONS_TABLE_ATTRIBUTES
,
764 .style
= "window-status-current-style"
767 { .name
= "window-status-current-bg",
768 .type
= OPTIONS_TABLE_COLOUR
,
770 .style
= "window-status-current-style"
773 { .name
= "window-status-current-fg",
774 .type
= OPTIONS_TABLE_COLOUR
,
776 .style
= "window-status-current-style"
779 { .name
= "window-status-current-format",
780 .type
= OPTIONS_TABLE_STRING
,
781 .default_str
= "#I:#W#F"
784 { .name
= "window-status-current-style",
785 .type
= OPTIONS_TABLE_STYLE
,
786 .default_str
= "default"
789 { .name
= "window-status-fg",
790 .type
= OPTIONS_TABLE_COLOUR
,
792 .style
= "window-status-style"
795 { .name
= "window-status-format",
796 .type
= OPTIONS_TABLE_STRING
,
797 .default_str
= "#I:#W#F"
800 { .name
= "window-status-last-attr",
801 .type
= OPTIONS_TABLE_ATTRIBUTES
,
803 .style
= "window-status-last-style"
806 { .name
= "window-status-last-bg",
807 .type
= OPTIONS_TABLE_COLOUR
,
809 .style
= "window-status-last-style"
812 { .name
= "window-status-last-fg",
813 .type
= OPTIONS_TABLE_COLOUR
,
815 .style
= "window-status-last-style"
818 { .name
= "window-status-last-style",
819 .type
= OPTIONS_TABLE_STYLE
,
820 .default_str
= "default"
823 { .name
= "window-status-separator",
824 .type
= OPTIONS_TABLE_STRING
,
828 { .name
= "window-status-style",
829 .type
= OPTIONS_TABLE_STYLE
,
830 .default_str
= "default"
833 { .name
= "wrap-search",
834 .type
= OPTIONS_TABLE_FLAG
,
838 { .name
= "xterm-keys",
839 .type
= OPTIONS_TABLE_FLAG
,
846 /* Populate an options tree from a table. */
848 options_table_populate_tree(
849 const struct options_table_entry
*table
, struct options
*oo
)
851 const struct options_table_entry
*oe
;
853 for (oe
= table
; oe
->name
!= NULL
; oe
++) {
855 case OPTIONS_TABLE_STRING
:
856 options_set_string(oo
, oe
->name
, "%s", oe
->default_str
);
858 case OPTIONS_TABLE_STYLE
:
859 options_set_style(oo
, oe
->name
, oe
->default_str
, 0);
862 options_set_number(oo
, oe
->name
, oe
->default_num
);
868 /* Print an option using its type from the table. */
870 options_table_print_entry(const struct options_table_entry
*oe
,
871 struct options_entry
*o
, int no_quotes
)
873 static char out
[BUFSIZ
];
878 case OPTIONS_TABLE_STRING
:
880 xsnprintf(out
, sizeof out
, "%s", o
->str
);
882 xsnprintf(out
, sizeof out
, "\"%s\"", o
->str
);
884 case OPTIONS_TABLE_NUMBER
:
885 xsnprintf(out
, sizeof out
, "%lld", o
->num
);
887 case OPTIONS_TABLE_KEY
:
888 xsnprintf(out
, sizeof out
, "%s",
889 key_string_lookup_key(o
->num
));
891 case OPTIONS_TABLE_COLOUR
:
892 s
= colour_tostring(o
->num
);
893 xsnprintf(out
, sizeof out
, "%s", s
);
895 case OPTIONS_TABLE_ATTRIBUTES
:
896 s
= attributes_tostring(o
->num
);
897 xsnprintf(out
, sizeof out
, "%s", s
);
899 case OPTIONS_TABLE_FLAG
:
901 strlcpy(out
, "on", sizeof out
);
903 strlcpy(out
, "off", sizeof out
);
905 case OPTIONS_TABLE_CHOICE
:
906 s
= oe
->choices
[o
->num
];
907 xsnprintf(out
, sizeof out
, "%s", s
);
909 case OPTIONS_TABLE_STYLE
:
910 s
= style_tostring(&o
->style
);
911 xsnprintf(out
, sizeof out
, "%s", s
);
917 /* Find an option. */
920 const char *optstr
, const struct options_table_entry
**table
,
921 const struct options_table_entry
**oe
)
923 static const struct options_table_entry
*tables
[] = {
924 server_options_table
,
925 window_options_table
,
926 session_options_table
928 const struct options_table_entry
*oe_loop
;
931 for (i
= 0; i
< nitems(tables
); i
++) {
932 for (oe_loop
= tables
[i
]; oe_loop
->name
!= NULL
; oe_loop
++) {
933 if (strncmp(oe_loop
->name
, optstr
, strlen(optstr
)) != 0)
936 /* If already found, ambiguous. */
942 /* Bail now if an exact match. */
943 if (strcmp((*oe
)->name
, optstr
) == 0)