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
,
97 /* Session options. */
98 const struct options_table_entry session_options_table
[] = {
99 { .name
= "assume-paste-time",
100 .type
= OPTIONS_TABLE_NUMBER
,
106 { .name
= "base-index",
107 .type
= OPTIONS_TABLE_NUMBER
,
113 { .name
= "bell-action",
114 .type
= OPTIONS_TABLE_CHOICE
,
115 .choices
= options_table_bell_action_list
,
116 .default_num
= BELL_ANY
119 { .name
= "bell-on-alert",
120 .type
= OPTIONS_TABLE_FLAG
,
124 { .name
= "default-command",
125 .type
= OPTIONS_TABLE_STRING
,
129 { .name
= "default-path",
130 .type
= OPTIONS_TABLE_STRING
,
134 { .name
= "default-shell",
135 .type
= OPTIONS_TABLE_STRING
,
136 .default_str
= _PATH_BSHELL
139 { .name
= "default-terminal",
140 .type
= OPTIONS_TABLE_STRING
,
141 .default_str
= "screen"
144 { .name
= "destroy-unattached",
145 .type
= OPTIONS_TABLE_FLAG
,
149 { .name
= "detach-on-destroy",
150 .type
= OPTIONS_TABLE_FLAG
,
154 { .name
= "display-panes-active-colour",
155 .type
= OPTIONS_TABLE_COLOUR
,
159 { .name
= "display-panes-colour",
160 .type
= OPTIONS_TABLE_COLOUR
,
164 { .name
= "display-panes-time",
165 .type
= OPTIONS_TABLE_NUMBER
,
171 { .name
= "display-time",
172 .type
= OPTIONS_TABLE_NUMBER
,
178 { .name
= "history-limit",
179 .type
= OPTIONS_TABLE_NUMBER
,
185 { .name
= "lock-after-time",
186 .type
= OPTIONS_TABLE_NUMBER
,
192 { .name
= "lock-command",
193 .type
= OPTIONS_TABLE_STRING
,
194 .default_str
= "lock -np"
197 { .name
= "lock-server",
198 .type
= OPTIONS_TABLE_FLAG
,
202 { .name
= "message-attr",
203 .type
= OPTIONS_TABLE_ATTRIBUTES
,
207 { .name
= "message-bg",
208 .type
= OPTIONS_TABLE_COLOUR
,
212 { .name
= "message-command-attr",
213 .type
= OPTIONS_TABLE_ATTRIBUTES
,
217 { .name
= "message-command-bg",
218 .type
= OPTIONS_TABLE_COLOUR
,
222 { .name
= "message-command-fg",
223 .type
= OPTIONS_TABLE_COLOUR
,
227 { .name
= "message-fg",
228 .type
= OPTIONS_TABLE_COLOUR
,
232 { .name
= "message-limit",
233 .type
= OPTIONS_TABLE_NUMBER
,
239 { .name
= "mouse-resize-pane",
240 .type
= OPTIONS_TABLE_FLAG
,
244 { .name
= "mouse-select-pane",
245 .type
= OPTIONS_TABLE_FLAG
,
249 { .name
= "mouse-select-window",
250 .type
= OPTIONS_TABLE_FLAG
,
254 { .name
= "mouse-utf8",
255 .type
= OPTIONS_TABLE_FLAG
,
259 { .name
= "pane-active-border-bg",
260 .type
= OPTIONS_TABLE_COLOUR
,
264 { .name
= "pane-active-border-fg",
265 .type
= OPTIONS_TABLE_COLOUR
,
269 { .name
= "pane-border-bg",
270 .type
= OPTIONS_TABLE_COLOUR
,
274 { .name
= "pane-border-fg",
275 .type
= OPTIONS_TABLE_COLOUR
,
280 .type
= OPTIONS_TABLE_KEY
,
281 .default_num
= '\002',
285 .type
= OPTIONS_TABLE_KEY
,
286 .default_num
= KEYC_NONE
,
289 { .name
= "renumber-windows",
290 .type
= OPTIONS_TABLE_FLAG
,
294 { .name
= "repeat-time",
295 .type
= OPTIONS_TABLE_NUMBER
,
301 { .name
= "set-remain-on-exit",
302 .type
= OPTIONS_TABLE_FLAG
,
306 { .name
= "set-titles",
307 .type
= OPTIONS_TABLE_FLAG
,
311 { .name
= "set-titles-string",
312 .type
= OPTIONS_TABLE_STRING
,
313 .default_str
= "#S:#I:#W - \"#T\""
317 .type
= OPTIONS_TABLE_FLAG
,
321 { .name
= "status-attr",
322 .type
= OPTIONS_TABLE_ATTRIBUTES
,
326 { .name
= "status-bg",
327 .type
= OPTIONS_TABLE_COLOUR
,
331 { .name
= "status-fg",
332 .type
= OPTIONS_TABLE_COLOUR
,
336 { .name
= "status-interval",
337 .type
= OPTIONS_TABLE_NUMBER
,
343 { .name
= "status-justify",
344 .type
= OPTIONS_TABLE_CHOICE
,
345 .choices
= options_table_status_justify_list
,
349 { .name
= "status-keys",
350 .type
= OPTIONS_TABLE_CHOICE
,
351 .choices
= options_table_status_keys_list
,
352 .default_num
= MODEKEY_EMACS
355 { .name
= "status-left",
356 .type
= OPTIONS_TABLE_STRING
,
357 .default_str
= "[#S]"
360 { .name
= "status-left-attr",
361 .type
= OPTIONS_TABLE_ATTRIBUTES
,
365 { .name
= "status-left-bg",
366 .type
= OPTIONS_TABLE_COLOUR
,
370 { .name
= "status-left-fg",
371 .type
= OPTIONS_TABLE_COLOUR
,
375 { .name
= "status-left-length",
376 .type
= OPTIONS_TABLE_NUMBER
,
382 { .name
= "status-position",
383 .type
= OPTIONS_TABLE_CHOICE
,
384 .choices
= options_table_status_position_list
,
388 { .name
= "status-right",
389 .type
= OPTIONS_TABLE_STRING
,
390 .default_str
= "\"#{=22:pane_title}\" %H:%M %d-%b-%y"
393 { .name
= "status-right-attr",
394 .type
= OPTIONS_TABLE_ATTRIBUTES
,
398 { .name
= "status-right-bg",
399 .type
= OPTIONS_TABLE_COLOUR
,
403 { .name
= "status-right-fg",
404 .type
= OPTIONS_TABLE_COLOUR
,
408 { .name
= "status-right-length",
409 .type
= OPTIONS_TABLE_NUMBER
,
415 { .name
= "status-utf8",
416 .type
= OPTIONS_TABLE_FLAG
,
417 .default_num
= 0 /* overridden in main() */
420 { .name
= "terminal-overrides",
421 .type
= OPTIONS_TABLE_STRING
,
422 .default_str
= "*256col*:colors=256"
423 ",xterm*:XT:Ms=\\E]52;%p1%s;%p2%s\\007"
424 ":Cs=\\E]12;%p1%s\\007:Cr=\\E]112\\007"
425 ":Ss=\\E[%p1%d q:Se=\\E[2 q,screen*:XT"
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"
435 { .name
= "visual-activity",
436 .type
= OPTIONS_TABLE_FLAG
,
440 { .name
= "visual-bell",
441 .type
= OPTIONS_TABLE_FLAG
,
445 { .name
= "visual-content",
446 .type
= OPTIONS_TABLE_FLAG
,
450 { .name
= "visual-silence",
451 .type
= OPTIONS_TABLE_FLAG
,
455 { .name
= "word-separators",
456 .type
= OPTIONS_TABLE_STRING
,
457 .default_str
= " -_@"
463 /* Window options. */
464 const struct options_table_entry window_options_table
[] = {
465 { .name
= "aggressive-resize",
466 .type
= OPTIONS_TABLE_FLAG
,
470 { .name
= "allow-rename",
471 .type
= OPTIONS_TABLE_FLAG
,
475 { .name
= "alternate-screen",
476 .type
= OPTIONS_TABLE_FLAG
,
480 { .name
= "automatic-rename",
481 .type
= OPTIONS_TABLE_FLAG
,
485 { .name
= "automatic-rename-format",
486 .type
= OPTIONS_TABLE_STRING
,
487 .default_str
= "#{?pane_in_mode,[tmux],#{pane_current_command}}#{?pane_dead,[dead],}"
490 { .name
= "c0-change-trigger",
491 .type
= OPTIONS_TABLE_NUMBER
,
497 { .name
= "c0-change-interval",
498 .type
= OPTIONS_TABLE_NUMBER
,
504 { .name
= "clock-mode-colour",
505 .type
= OPTIONS_TABLE_COLOUR
,
509 { .name
= "clock-mode-style",
510 .type
= OPTIONS_TABLE_CHOICE
,
511 .choices
= options_table_clock_mode_style_list
,
515 { .name
= "force-height",
516 .type
= OPTIONS_TABLE_NUMBER
,
522 { .name
= "force-width",
523 .type
= OPTIONS_TABLE_NUMBER
,
529 { .name
= "main-pane-height",
530 .type
= OPTIONS_TABLE_NUMBER
,
536 { .name
= "main-pane-width",
537 .type
= OPTIONS_TABLE_NUMBER
,
543 { .name
= "mode-attr",
544 .type
= OPTIONS_TABLE_ATTRIBUTES
,
549 .type
= OPTIONS_TABLE_COLOUR
,
554 .type
= OPTIONS_TABLE_COLOUR
,
558 { .name
= "mode-keys",
559 .type
= OPTIONS_TABLE_CHOICE
,
560 .choices
= options_table_mode_keys_list
,
561 .default_num
= MODEKEY_EMACS
564 { .name
= "mode-mouse",
565 .type
= OPTIONS_TABLE_CHOICE
,
566 .choices
= options_table_mode_mouse_list
,
570 { .name
= "monitor-activity",
571 .type
= OPTIONS_TABLE_FLAG
,
575 { .name
= "monitor-content",
576 .type
= OPTIONS_TABLE_STRING
,
580 { .name
= "monitor-silence",
581 .type
= OPTIONS_TABLE_NUMBER
,
587 { .name
= "other-pane-height",
588 .type
= OPTIONS_TABLE_NUMBER
,
594 { .name
= "other-pane-width",
595 .type
= OPTIONS_TABLE_NUMBER
,
601 { .name
= "pane-base-index",
602 .type
= OPTIONS_TABLE_NUMBER
,
604 .maximum
= USHRT_MAX
,
608 { .name
= "remain-on-exit",
609 .type
= OPTIONS_TABLE_FLAG
,
613 { .name
= "synchronize-panes",
614 .type
= OPTIONS_TABLE_FLAG
,
619 .type
= OPTIONS_TABLE_FLAG
,
620 .default_num
= 0 /* overridden in main() */
623 { .name
= "window-status-activity-attr",
624 .type
= OPTIONS_TABLE_ATTRIBUTES
,
625 .default_num
= GRID_ATTR_REVERSE
628 { .name
= "window-status-activity-bg",
629 .type
= OPTIONS_TABLE_COLOUR
,
633 { .name
= "window-status-activity-fg",
634 .type
= OPTIONS_TABLE_COLOUR
,
638 { .name
= "window-status-bell-attr",
639 .type
= OPTIONS_TABLE_ATTRIBUTES
,
640 .default_num
= GRID_ATTR_REVERSE
643 { .name
= "window-status-bell-bg",
644 .type
= OPTIONS_TABLE_COLOUR
,
648 { .name
= "window-status-bell-fg",
649 .type
= OPTIONS_TABLE_COLOUR
,
653 { .name
= "window-status-content-attr",
654 .type
= OPTIONS_TABLE_ATTRIBUTES
,
655 .default_num
= GRID_ATTR_REVERSE
658 { .name
= "window-status-content-bg",
659 .type
= OPTIONS_TABLE_COLOUR
,
663 { .name
= "window-status-content-fg",
664 .type
= OPTIONS_TABLE_COLOUR
,
668 { .name
= "window-status-attr",
669 .type
= OPTIONS_TABLE_ATTRIBUTES
,
673 { .name
= "window-status-bg",
674 .type
= OPTIONS_TABLE_COLOUR
,
678 { .name
= "window-status-current-attr",
679 .type
= OPTIONS_TABLE_ATTRIBUTES
,
683 { .name
= "window-status-current-bg",
684 .type
= OPTIONS_TABLE_COLOUR
,
688 { .name
= "window-status-current-fg",
689 .type
= OPTIONS_TABLE_COLOUR
,
693 { .name
= "window-status-current-format",
694 .type
= OPTIONS_TABLE_STRING
,
695 .default_str
= "#I:#W#F"
698 { .name
= "window-status-last-attr",
699 .type
= OPTIONS_TABLE_ATTRIBUTES
,
703 { .name
= "window-status-last-bg",
704 .type
= OPTIONS_TABLE_COLOUR
,
708 { .name
= "window-status-last-fg",
709 .type
= OPTIONS_TABLE_COLOUR
,
713 { .name
= "window-status-fg",
714 .type
= OPTIONS_TABLE_COLOUR
,
718 { .name
= "window-status-format",
719 .type
= OPTIONS_TABLE_STRING
,
720 .default_str
= "#I:#W#F"
723 { .name
= "window-status-separator",
724 .type
= OPTIONS_TABLE_STRING
,
728 { .name
= "wrap-search",
729 .type
= OPTIONS_TABLE_FLAG
,
733 { .name
= "xterm-keys",
734 .type
= OPTIONS_TABLE_FLAG
,
741 /* Populate an options tree from a table. */
743 options_table_populate_tree(
744 const struct options_table_entry
*table
, struct options
*oo
)
746 const struct options_table_entry
*oe
;
748 for (oe
= table
; oe
->name
!= NULL
; oe
++) {
749 if (oe
->default_str
!= NULL
)
750 options_set_string(oo
, oe
->name
, "%s", oe
->default_str
);
752 options_set_number(oo
, oe
->name
, oe
->default_num
);
756 /* Print an option using its type from the table. */
758 options_table_print_entry(const struct options_table_entry
*oe
,
759 struct options_entry
*o
, int no_quotes
)
761 static char out
[BUFSIZ
];
766 case OPTIONS_TABLE_STRING
:
768 xsnprintf(out
, sizeof out
, "%s", o
->str
);
770 xsnprintf(out
, sizeof out
, "\"%s\"", o
->str
);
772 case OPTIONS_TABLE_NUMBER
:
773 xsnprintf(out
, sizeof out
, "%lld", o
->num
);
775 case OPTIONS_TABLE_KEY
:
776 xsnprintf(out
, sizeof out
, "%s",
777 key_string_lookup_key(o
->num
));
779 case OPTIONS_TABLE_COLOUR
:
780 s
= colour_tostring(o
->num
);
781 xsnprintf(out
, sizeof out
, "%s", s
);
783 case OPTIONS_TABLE_ATTRIBUTES
:
784 s
= attributes_tostring(o
->num
);
785 xsnprintf(out
, sizeof out
, "%s", s
);
787 case OPTIONS_TABLE_FLAG
:
789 strlcpy(out
, "on", sizeof out
);
791 strlcpy(out
, "off", sizeof out
);
793 case OPTIONS_TABLE_CHOICE
:
794 s
= oe
->choices
[o
->num
];
795 xsnprintf(out
, sizeof out
, "%s", s
);
801 /* Find an option. */
804 const char *optstr
, const struct options_table_entry
**table
,
805 const struct options_table_entry
**oe
)
807 static const struct options_table_entry
*tables
[] = {
808 server_options_table
,
809 window_options_table
,
810 session_options_table
812 const struct options_table_entry
*oe_loop
;
815 for (i
= 0; i
< nitems(tables
); i
++) {
816 for (oe_loop
= tables
[i
]; oe_loop
->name
!= NULL
; oe_loop
++) {
817 if (strncmp(oe_loop
->name
, optstr
, strlen(optstr
)) != 0)
820 /* If already found, ambiguous. */
826 /* Bail now if an exact match. */
827 if (strcmp((*oe
)->name
, optstr
) == 0)