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>
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 loop up the real type when
31 * the user sets an option or its value needs to be shown.
34 /* Choice option type lists. */
35 const char *options_table_mode_keys_list
[] = {
38 const char *options_table_mode_mouse_list
[] = {
39 "off", "on", "copy-mode", NULL
41 const char *options_table_clock_mode_style_list
[] = {
44 const char *options_table_status_keys_list
[] = {
47 const char *options_table_status_justify_list
[] = {
48 "left", "centre", "right", NULL
50 const char *options_table_status_position_list
[] = {
53 const char *options_table_bell_action_list
[] = {
54 "none", "any", "current", NULL
58 const struct options_table_entry server_options_table
[] = {
59 { .name
= "buffer-limit",
60 .type
= OPTIONS_TABLE_NUMBER
,
66 { .name
= "escape-time",
67 .type
= OPTIONS_TABLE_NUMBER
,
73 { .name
= "exit-unattached",
74 .type
= OPTIONS_TABLE_FLAG
,
78 { .name
= "focus-events",
79 .type
= OPTIONS_TABLE_FLAG
,
84 .type
= OPTIONS_TABLE_FLAG
,
85 .default_num
= 0 /* overridden in main() */
88 { .name
= "set-clipboard",
89 .type
= OPTIONS_TABLE_FLAG
,
96 /* Session options. */
97 const struct options_table_entry session_options_table
[] = {
98 { .name
= "assume-paste-time",
99 .type
= OPTIONS_TABLE_NUMBER
,
105 { .name
= "base-index",
106 .type
= OPTIONS_TABLE_NUMBER
,
112 { .name
= "bell-action",
113 .type
= OPTIONS_TABLE_CHOICE
,
114 .choices
= options_table_bell_action_list
,
115 .default_num
= BELL_ANY
118 { .name
= "bell-on-alert",
119 .type
= OPTIONS_TABLE_FLAG
,
123 { .name
= "default-command",
124 .type
= OPTIONS_TABLE_STRING
,
128 { .name
= "default-shell",
129 .type
= OPTIONS_TABLE_STRING
,
130 .default_str
= _PATH_BSHELL
133 { .name
= "default-terminal",
134 .type
= OPTIONS_TABLE_STRING
,
135 .default_str
= "screen"
138 { .name
= "destroy-unattached",
139 .type
= OPTIONS_TABLE_FLAG
,
143 { .name
= "detach-on-destroy",
144 .type
= OPTIONS_TABLE_FLAG
,
148 { .name
= "display-panes-active-colour",
149 .type
= OPTIONS_TABLE_COLOUR
,
153 { .name
= "display-panes-colour",
154 .type
= OPTIONS_TABLE_COLOUR
,
158 { .name
= "display-panes-time",
159 .type
= OPTIONS_TABLE_NUMBER
,
165 { .name
= "display-time",
166 .type
= OPTIONS_TABLE_NUMBER
,
172 { .name
= "history-limit",
173 .type
= OPTIONS_TABLE_NUMBER
,
179 { .name
= "lock-after-time",
180 .type
= OPTIONS_TABLE_NUMBER
,
186 { .name
= "lock-command",
187 .type
= OPTIONS_TABLE_STRING
,
188 .default_str
= "lock -np"
191 { .name
= "lock-server",
192 .type
= OPTIONS_TABLE_FLAG
,
196 { .name
= "message-attr",
197 .type
= OPTIONS_TABLE_ATTRIBUTES
,
199 .style
= "message-style"
202 { .name
= "message-bg",
203 .type
= OPTIONS_TABLE_COLOUR
,
205 .style
= "message-style"
208 { .name
= "message-command-attr",
209 .type
= OPTIONS_TABLE_ATTRIBUTES
,
211 .style
= "message-command-style"
214 { .name
= "message-command-bg",
215 .type
= OPTIONS_TABLE_COLOUR
,
217 .style
= "message-command-style"
220 { .name
= "message-command-fg",
221 .type
= OPTIONS_TABLE_COLOUR
,
223 .style
= "message-command-style"
226 { .name
= "message-command-style",
227 .type
= OPTIONS_TABLE_STYLE
,
228 .default_str
= "bg=black,fg=yellow"
231 { .name
= "message-fg",
232 .type
= OPTIONS_TABLE_COLOUR
,
234 .style
= "message-style"
237 { .name
= "message-limit",
238 .type
= OPTIONS_TABLE_NUMBER
,
244 { .name
= "message-style",
245 .type
= OPTIONS_TABLE_STYLE
,
246 .default_str
= "bg=yellow,fg=black"
249 { .name
= "mouse-resize-pane",
250 .type
= OPTIONS_TABLE_FLAG
,
254 { .name
= "mouse-select-pane",
255 .type
= OPTIONS_TABLE_FLAG
,
259 { .name
= "mouse-select-window",
260 .type
= OPTIONS_TABLE_FLAG
,
264 { .name
= "mouse-utf8",
265 .type
= OPTIONS_TABLE_FLAG
,
269 { .name
= "pane-active-border-bg",
270 .type
= OPTIONS_TABLE_COLOUR
,
272 .style
= "pane-active-border-style"
275 { .name
= "pane-active-border-fg",
276 .type
= OPTIONS_TABLE_COLOUR
,
278 .style
= "pane-active-border-style"
281 { .name
= "pane-active-border-style",
282 .type
= OPTIONS_TABLE_STYLE
,
283 .default_str
= "fg=green"
286 { .name
= "pane-border-bg",
287 .type
= OPTIONS_TABLE_COLOUR
,
289 .style
= "pane-border-style"
292 { .name
= "pane-border-fg",
293 .type
= OPTIONS_TABLE_COLOUR
,
295 .style
= "pane-border-style"
298 { .name
= "pane-border-style",
299 .type
= OPTIONS_TABLE_STYLE
,
300 .default_str
= "default"
304 .type
= OPTIONS_TABLE_KEY
,
305 .default_num
= '\002',
309 .type
= OPTIONS_TABLE_KEY
,
310 .default_num
= KEYC_NONE
,
313 { .name
= "renumber-windows",
314 .type
= OPTIONS_TABLE_FLAG
,
318 { .name
= "repeat-time",
319 .type
= OPTIONS_TABLE_NUMBER
,
325 { .name
= "set-remain-on-exit",
326 .type
= OPTIONS_TABLE_FLAG
,
330 { .name
= "set-titles",
331 .type
= OPTIONS_TABLE_FLAG
,
335 { .name
= "set-titles-string",
336 .type
= OPTIONS_TABLE_STRING
,
337 .default_str
= "#S:#I:#W - \"#T\""
341 .type
= OPTIONS_TABLE_FLAG
,
345 { .name
= "status-attr",
346 .type
= OPTIONS_TABLE_ATTRIBUTES
,
348 .style
= "status-style"
351 { .name
= "status-bg",
352 .type
= OPTIONS_TABLE_COLOUR
,
354 .style
= "status-style"
357 { .name
= "status-fg",
358 .type
= OPTIONS_TABLE_COLOUR
,
360 .style
= "status-style"
363 { .name
= "status-interval",
364 .type
= OPTIONS_TABLE_NUMBER
,
370 { .name
= "status-justify",
371 .type
= OPTIONS_TABLE_CHOICE
,
372 .choices
= options_table_status_justify_list
,
376 { .name
= "status-keys",
377 .type
= OPTIONS_TABLE_CHOICE
,
378 .choices
= options_table_status_keys_list
,
379 .default_num
= MODEKEY_EMACS
382 { .name
= "status-left",
383 .type
= OPTIONS_TABLE_STRING
,
384 .default_str
= "[#S]"
387 { .name
= "status-left-attr",
388 .type
= OPTIONS_TABLE_ATTRIBUTES
,
390 .style
= "status-left-style"
393 { .name
= "status-left-bg",
394 .type
= OPTIONS_TABLE_COLOUR
,
396 .style
= "status-left-style"
399 { .name
= "status-left-fg",
400 .type
= OPTIONS_TABLE_COLOUR
,
402 .style
= "status-left-style"
405 { .name
= "status-left-length",
406 .type
= OPTIONS_TABLE_NUMBER
,
412 { .name
= "status-left-style",
413 .type
= OPTIONS_TABLE_STYLE
,
414 .default_str
= "default"
417 { .name
= "status-position",
418 .type
= OPTIONS_TABLE_CHOICE
,
419 .choices
= options_table_status_position_list
,
423 { .name
= "status-right",
424 .type
= OPTIONS_TABLE_STRING
,
425 .default_str
= "\"#{=22:pane_title}\" %H:%M %d-%b-%y"
428 { .name
= "status-right-attr",
429 .type
= OPTIONS_TABLE_ATTRIBUTES
,
431 .style
= "status-right-style"
434 { .name
= "status-right-bg",
435 .type
= OPTIONS_TABLE_COLOUR
,
437 .style
= "status-right-style"
440 { .name
= "status-right-fg",
441 .type
= OPTIONS_TABLE_COLOUR
,
443 .style
= "status-right-style"
446 { .name
= "status-right-length",
447 .type
= OPTIONS_TABLE_NUMBER
,
453 { .name
= "status-right-style",
454 .type
= OPTIONS_TABLE_STYLE
,
455 .default_str
= "default"
458 { .name
= "status-style",
459 .type
= OPTIONS_TABLE_STYLE
,
460 .default_str
= "bg=green,fg=black"
463 { .name
= "status-utf8",
464 .type
= OPTIONS_TABLE_FLAG
,
465 .default_num
= 0 /* overridden in main() */
468 { .name
= "terminal-overrides",
469 .type
= OPTIONS_TABLE_STRING
,
470 .default_str
= "*256col*:colors=256"
471 ",xterm*:XT:Ms=\\E]52;%p1%s;%p2%s\\007"
472 ":Cs=\\E]12;%p1%s\\007:Cr=\\E]112\\007"
473 ":Ss=\\E[%p1%d q:Se=\\E[2 q,screen*:XT"
476 { .name
= "update-environment",
477 .type
= OPTIONS_TABLE_STRING
,
478 .default_str
= "DISPLAY SSH_ASKPASS SSH_AUTH_SOCK SSH_AGENT_PID "
479 "SSH_CONNECTION WINDOWID XAUTHORITY"
483 { .name
= "visual-activity",
484 .type
= OPTIONS_TABLE_FLAG
,
488 { .name
= "visual-bell",
489 .type
= OPTIONS_TABLE_FLAG
,
493 { .name
= "visual-content",
494 .type
= OPTIONS_TABLE_FLAG
,
498 { .name
= "visual-silence",
499 .type
= OPTIONS_TABLE_FLAG
,
503 { .name
= "word-separators",
504 .type
= OPTIONS_TABLE_STRING
,
505 .default_str
= " -_@"
511 /* Window options. */
512 const struct options_table_entry window_options_table
[] = {
513 { .name
= "aggressive-resize",
514 .type
= OPTIONS_TABLE_FLAG
,
518 { .name
= "allow-rename",
519 .type
= OPTIONS_TABLE_FLAG
,
523 { .name
= "alternate-screen",
524 .type
= OPTIONS_TABLE_FLAG
,
528 { .name
= "automatic-rename",
529 .type
= OPTIONS_TABLE_FLAG
,
533 { .name
= "automatic-rename-format",
534 .type
= OPTIONS_TABLE_STRING
,
535 .default_str
= "#{?pane_in_mode,[tmux],#{pane_current_command}}#{?pane_dead,[dead],}"
538 { .name
= "c0-change-trigger",
539 .type
= OPTIONS_TABLE_NUMBER
,
545 { .name
= "c0-change-interval",
546 .type
= OPTIONS_TABLE_NUMBER
,
552 { .name
= "clock-mode-colour",
553 .type
= OPTIONS_TABLE_COLOUR
,
557 { .name
= "clock-mode-style",
558 .type
= OPTIONS_TABLE_CHOICE
,
559 .choices
= options_table_clock_mode_style_list
,
563 { .name
= "force-height",
564 .type
= OPTIONS_TABLE_NUMBER
,
570 { .name
= "force-width",
571 .type
= OPTIONS_TABLE_NUMBER
,
577 { .name
= "main-pane-height",
578 .type
= OPTIONS_TABLE_NUMBER
,
584 { .name
= "main-pane-width",
585 .type
= OPTIONS_TABLE_NUMBER
,
591 { .name
= "mode-attr",
592 .type
= OPTIONS_TABLE_ATTRIBUTES
,
594 .style
= "mode-style"
598 .type
= OPTIONS_TABLE_COLOUR
,
600 .style
= "mode-style"
604 .type
= OPTIONS_TABLE_COLOUR
,
606 .style
= "mode-style"
609 { .name
= "mode-keys",
610 .type
= OPTIONS_TABLE_CHOICE
,
611 .choices
= options_table_mode_keys_list
,
612 .default_num
= MODEKEY_EMACS
615 { .name
= "mode-mouse",
616 .type
= OPTIONS_TABLE_CHOICE
,
617 .choices
= options_table_mode_mouse_list
,
621 { .name
= "mode-style",
622 .type
= OPTIONS_TABLE_STYLE
,
623 .default_str
= "bg=yellow,fg=black"
626 { .name
= "monitor-activity",
627 .type
= OPTIONS_TABLE_FLAG
,
631 { .name
= "monitor-content",
632 .type
= OPTIONS_TABLE_STRING
,
636 { .name
= "monitor-silence",
637 .type
= OPTIONS_TABLE_NUMBER
,
643 { .name
= "other-pane-height",
644 .type
= OPTIONS_TABLE_NUMBER
,
650 { .name
= "other-pane-width",
651 .type
= OPTIONS_TABLE_NUMBER
,
657 { .name
= "pane-base-index",
658 .type
= OPTIONS_TABLE_NUMBER
,
660 .maximum
= USHRT_MAX
,
664 { .name
= "remain-on-exit",
665 .type
= OPTIONS_TABLE_FLAG
,
669 { .name
= "synchronize-panes",
670 .type
= OPTIONS_TABLE_FLAG
,
675 .type
= OPTIONS_TABLE_FLAG
,
676 .default_num
= 0 /* overridden in main() */
679 { .name
= "window-status-activity-attr",
680 .type
= OPTIONS_TABLE_ATTRIBUTES
,
681 .default_num
= GRID_ATTR_REVERSE
,
682 .style
= "window-status-activity-style"
685 { .name
= "window-status-activity-bg",
686 .type
= OPTIONS_TABLE_COLOUR
,
688 .style
= "window-status-activity-style"
691 { .name
= "window-status-activity-fg",
692 .type
= OPTIONS_TABLE_COLOUR
,
694 .style
= "window-status-activity-style"
697 { .name
= "window-status-activity-style",
698 .type
= OPTIONS_TABLE_STYLE
,
699 .default_str
= "reverse"
702 { .name
= "window-status-attr",
703 .type
= OPTIONS_TABLE_ATTRIBUTES
,
705 .style
= "window-status-style"
708 { .name
= "window-status-bell-attr",
709 .type
= OPTIONS_TABLE_ATTRIBUTES
,
710 .default_num
= GRID_ATTR_REVERSE
,
711 .style
= "window-status-bell-style"
714 { .name
= "window-status-bell-bg",
715 .type
= OPTIONS_TABLE_COLOUR
,
717 .style
= "window-status-bell-style"
720 { .name
= "window-status-bell-fg",
721 .type
= OPTIONS_TABLE_COLOUR
,
723 .style
= "window-status-bell-style"
726 { .name
= "window-status-bell-style",
727 .type
= OPTIONS_TABLE_STYLE
,
728 .default_str
= "reverse"
731 { .name
= "window-status-bg",
732 .type
= OPTIONS_TABLE_COLOUR
,
734 .style
= "window-status-style"
737 { .name
= "window-status-content-attr",
738 .type
= OPTIONS_TABLE_ATTRIBUTES
,
739 .default_num
= GRID_ATTR_REVERSE
,
740 .style
= "window-status-content-style"
743 { .name
= "window-status-content-bg",
744 .type
= OPTIONS_TABLE_COLOUR
,
746 .style
= "window-status-content-style"
749 { .name
= "window-status-content-fg",
750 .type
= OPTIONS_TABLE_COLOUR
,
752 .style
= "window-status-content-style"
755 { .name
= "window-status-content-style",
756 .type
= OPTIONS_TABLE_STYLE
,
757 .default_str
= "reverse"
760 { .name
= "window-status-current-attr",
761 .type
= OPTIONS_TABLE_ATTRIBUTES
,
763 .style
= "window-status-current-style"
766 { .name
= "window-status-current-bg",
767 .type
= OPTIONS_TABLE_COLOUR
,
769 .style
= "window-status-current-style"
772 { .name
= "window-status-current-fg",
773 .type
= OPTIONS_TABLE_COLOUR
,
775 .style
= "window-status-current-style"
778 { .name
= "window-status-current-format",
779 .type
= OPTIONS_TABLE_STRING
,
780 .default_str
= "#I:#W#F"
783 { .name
= "window-status-current-style",
784 .type
= OPTIONS_TABLE_STYLE
,
785 .default_str
= "default"
788 { .name
= "window-status-fg",
789 .type
= OPTIONS_TABLE_COLOUR
,
791 .style
= "window-status-style"
794 { .name
= "window-status-format",
795 .type
= OPTIONS_TABLE_STRING
,
796 .default_str
= "#I:#W#F"
799 { .name
= "window-status-last-attr",
800 .type
= OPTIONS_TABLE_ATTRIBUTES
,
802 .style
= "window-status-last-style"
805 { .name
= "window-status-last-bg",
806 .type
= OPTIONS_TABLE_COLOUR
,
808 .style
= "window-status-last-style"
811 { .name
= "window-status-last-fg",
812 .type
= OPTIONS_TABLE_COLOUR
,
814 .style
= "window-status-last-style"
817 { .name
= "window-status-last-style",
818 .type
= OPTIONS_TABLE_STYLE
,
819 .default_str
= "default"
822 { .name
= "window-status-separator",
823 .type
= OPTIONS_TABLE_STRING
,
827 { .name
= "window-status-style",
828 .type
= OPTIONS_TABLE_STYLE
,
829 .default_str
= "default"
832 { .name
= "wrap-search",
833 .type
= OPTIONS_TABLE_FLAG
,
837 { .name
= "xterm-keys",
838 .type
= OPTIONS_TABLE_FLAG
,
845 /* Populate an options tree from a table. */
847 options_table_populate_tree(
848 const struct options_table_entry
*table
, struct options
*oo
)
850 const struct options_table_entry
*oe
;
852 for (oe
= table
; oe
->name
!= NULL
; oe
++) {
854 case OPTIONS_TABLE_STRING
:
855 options_set_string(oo
, oe
->name
, "%s", oe
->default_str
);
857 case OPTIONS_TABLE_STYLE
:
858 options_set_style(oo
, oe
->name
, oe
->default_str
, 0);
861 options_set_number(oo
, oe
->name
, oe
->default_num
);
867 /* Print an option using its type from the table. */
869 options_table_print_entry(const struct options_table_entry
*oe
,
870 struct options_entry
*o
, int no_quotes
)
872 static char out
[BUFSIZ
];
877 case OPTIONS_TABLE_STRING
:
879 xsnprintf(out
, sizeof out
, "%s", o
->str
);
881 xsnprintf(out
, sizeof out
, "\"%s\"", o
->str
);
883 case OPTIONS_TABLE_NUMBER
:
884 xsnprintf(out
, sizeof out
, "%lld", o
->num
);
886 case OPTIONS_TABLE_KEY
:
887 xsnprintf(out
, sizeof out
, "%s",
888 key_string_lookup_key(o
->num
));
890 case OPTIONS_TABLE_COLOUR
:
891 s
= colour_tostring(o
->num
);
892 xsnprintf(out
, sizeof out
, "%s", s
);
894 case OPTIONS_TABLE_ATTRIBUTES
:
895 s
= attributes_tostring(o
->num
);
896 xsnprintf(out
, sizeof out
, "%s", s
);
898 case OPTIONS_TABLE_FLAG
:
900 strlcpy(out
, "on", sizeof out
);
902 strlcpy(out
, "off", sizeof out
);
904 case OPTIONS_TABLE_CHOICE
:
905 s
= oe
->choices
[o
->num
];
906 xsnprintf(out
, sizeof out
, "%s", s
);
908 case OPTIONS_TABLE_STYLE
:
909 s
= style_tostring(&o
->style
);
910 xsnprintf(out
, sizeof out
, "%s", s
);
916 /* Find an option. */
919 const char *optstr
, const struct options_table_entry
**table
,
920 const struct options_table_entry
**oe
)
922 static const struct options_table_entry
*tables
[] = {
923 server_options_table
,
924 window_options_table
,
925 session_options_table
927 const struct options_table_entry
*oe_loop
;
930 for (i
= 0; i
< nitems(tables
); i
++) {
931 for (oe_loop
= tables
[i
]; oe_loop
->name
!= NULL
; oe_loop
++) {
932 if (strncmp(oe_loop
->name
, optstr
, strlen(optstr
)) != 0)
935 /* If already found, ambiguous. */
941 /* Bail now if an exact match. */
942 if (strcmp((*oe
)->name
, optstr
) == 0)