Add window-status-separator option, from Thomas Adam.
[tmux-openbsd.git] / options-table.c
blob28e4af7e44d47b7e9439a2eb53361c0a4cbdfce8
1 /* $OpenBSD$ */
3 /*
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>
21 #include <string.h>
22 #include <paths.h>
24 #include "tmux.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[] = {
37 "emacs", "vi", NULL
39 const char *options_table_mode_mouse_list[] = {
40 "off", "on", "copy-mode", NULL
42 const char *options_table_clock_mode_style_list[] = {
43 "12", "24", NULL
45 const char *options_table_status_keys_list[] = {
46 "emacs", "vi", NULL
48 const char *options_table_status_justify_list[] = {
49 "left", "centre", "right", NULL
51 const char *options_table_status_position_list[] = {
52 "top", "bottom", NULL
54 const char *options_table_bell_action_list[] = {
55 "none", "any", "current", NULL
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
67 { .name = "escape-time",
68 .type = OPTIONS_TABLE_NUMBER,
69 .minimum = 0,
70 .maximum = INT_MAX,
71 .default_num = 500
74 { .name = "exit-unattached",
75 .type = OPTIONS_TABLE_FLAG,
76 .default_num = 0
79 { .name = "quiet",
80 .type = OPTIONS_TABLE_FLAG,
81 .default_num = 0 /* overridden in main() */
84 { .name = "set-clipboard",
85 .type = OPTIONS_TABLE_FLAG,
86 .default_num = 1
89 { .name = NULL }
92 /* Session options. */
93 const struct options_table_entry session_options_table[] = {
94 { .name = "base-index",
95 .type = OPTIONS_TABLE_NUMBER,
96 .minimum = 0,
97 .maximum = INT_MAX,
98 .default_num = 0
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,
109 .default_num = 0
112 { .name = "default-command",
113 .type = OPTIONS_TABLE_STRING,
114 .default_str = ""
117 { .name = "default-path",
118 .type = OPTIONS_TABLE_STRING,
119 .default_str = ""
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,
134 .default_num = 0
137 { .name = "detach-on-destroy",
138 .type = OPTIONS_TABLE_FLAG,
139 .default_num = 1
142 { .name = "display-panes-active-colour",
143 .type = OPTIONS_TABLE_COLOUR,
144 .default_num = 1
147 { .name = "display-panes-colour",
148 .type = OPTIONS_TABLE_COLOUR,
149 .default_num = 4
152 { .name = "display-panes-time",
153 .type = OPTIONS_TABLE_NUMBER,
154 .minimum = 1,
155 .maximum = INT_MAX,
156 .default_num = 1000
159 { .name = "display-time",
160 .type = OPTIONS_TABLE_NUMBER,
161 .minimum = 1,
162 .maximum = INT_MAX,
163 .default_num = 750
166 { .name = "history-limit",
167 .type = OPTIONS_TABLE_NUMBER,
168 .minimum = 0,
169 .maximum = INT_MAX,
170 .default_num = 2000
173 { .name = "lock-after-time",
174 .type = OPTIONS_TABLE_NUMBER,
175 .minimum = 0,
176 .maximum = INT_MAX,
177 .default_num = 0
180 { .name = "lock-command",
181 .type = OPTIONS_TABLE_STRING,
182 .default_str = "lock -np"
185 { .name = "lock-server",
186 .type = OPTIONS_TABLE_FLAG,
187 .default_num = 1
190 { .name = "message-attr",
191 .type = OPTIONS_TABLE_ATTRIBUTES,
192 .default_num = 0
195 { .name = "message-bg",
196 .type = OPTIONS_TABLE_COLOUR,
197 .default_num = 3
200 { .name = "message-command-attr",
201 .type = OPTIONS_TABLE_ATTRIBUTES,
202 .default_num = 0
205 { .name = "message-command-bg",
206 .type = OPTIONS_TABLE_COLOUR,
207 .default_num = 0
210 { .name = "message-command-fg",
211 .type = OPTIONS_TABLE_COLOUR,
212 .default_num = 3
215 { .name = "message-fg",
216 .type = OPTIONS_TABLE_COLOUR,
217 .default_num = 0
220 { .name = "message-limit",
221 .type = OPTIONS_TABLE_NUMBER,
222 .minimum = 0,
223 .maximum = INT_MAX,
224 .default_num = 20
227 { .name = "mouse-resize-pane",
228 .type = OPTIONS_TABLE_FLAG,
229 .default_num = 0
232 { .name = "mouse-select-pane",
233 .type = OPTIONS_TABLE_FLAG,
234 .default_num = 0
237 { .name = "mouse-select-window",
238 .type = OPTIONS_TABLE_FLAG,
239 .default_num = 0
242 { .name = "mouse-utf8",
243 .type = OPTIONS_TABLE_FLAG,
244 .default_num = 0
247 { .name = "pane-active-border-bg",
248 .type = OPTIONS_TABLE_COLOUR,
249 .default_num = 8
252 { .name = "pane-active-border-fg",
253 .type = OPTIONS_TABLE_COLOUR,
254 .default_num = 2
257 { .name = "pane-border-bg",
258 .type = OPTIONS_TABLE_COLOUR,
259 .default_num = 8
262 { .name = "pane-border-fg",
263 .type = OPTIONS_TABLE_COLOUR,
264 .default_num = 8
267 { .name = "prefix",
268 .type = OPTIONS_TABLE_KEY,
269 .default_num = '\002',
272 { .name = "prefix2",
273 .type = OPTIONS_TABLE_KEY,
274 .default_num = KEYC_NONE,
277 { .name = "repeat-time",
278 .type = OPTIONS_TABLE_NUMBER,
279 .minimum = 0,
280 .maximum = SHRT_MAX,
281 .default_num = 500
284 { .name = "set-remain-on-exit",
285 .type = OPTIONS_TABLE_FLAG,
286 .default_num = 0
289 { .name = "set-titles",
290 .type = OPTIONS_TABLE_FLAG,
291 .default_num = 0
294 { .name = "set-titles-string",
295 .type = OPTIONS_TABLE_STRING,
296 .default_str = "#S:#I:#W - \"#T\""
299 { .name = "status",
300 .type = OPTIONS_TABLE_FLAG,
301 .default_num = 1
304 { .name = "status-attr",
305 .type = OPTIONS_TABLE_ATTRIBUTES,
306 .default_num = 0
309 { .name = "status-bg",
310 .type = OPTIONS_TABLE_COLOUR,
311 .default_num = 2
314 { .name = "status-fg",
315 .type = OPTIONS_TABLE_COLOUR,
316 .default_num = 0
319 { .name = "status-interval",
320 .type = OPTIONS_TABLE_NUMBER,
321 .minimum = 0,
322 .maximum = INT_MAX,
323 .default_num = 15
326 { .name = "status-justify",
327 .type = OPTIONS_TABLE_CHOICE,
328 .choices = options_table_status_justify_list,
329 .default_num = 0
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,
345 .default_num = 0
348 { .name = "status-left-bg",
349 .type = OPTIONS_TABLE_COLOUR,
350 .default_num = 8
353 { .name = "status-left-fg",
354 .type = OPTIONS_TABLE_COLOUR,
355 .default_num = 8
358 { .name = "status-left-length",
359 .type = OPTIONS_TABLE_NUMBER,
360 .minimum = 0,
361 .maximum = SHRT_MAX,
362 .default_num = 10
365 { .name = "status-position",
366 .type = OPTIONS_TABLE_CHOICE,
367 .choices = options_table_status_position_list,
368 .default_num = 1
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,
378 .default_num = 0
381 { .name = "status-right-bg",
382 .type = OPTIONS_TABLE_COLOUR,
383 .default_num = 8
386 { .name = "status-right-fg",
387 .type = OPTIONS_TABLE_COLOUR,
388 .default_num = 8
391 { .name = "status-right-length",
392 .type = OPTIONS_TABLE_NUMBER,
393 .minimum = 0,
394 .maximum = SHRT_MAX,
395 .default_num = 40
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,
420 .default_num = 0
423 { .name = "visual-bell",
424 .type = OPTIONS_TABLE_FLAG,
425 .default_num = 0
428 { .name = "visual-content",
429 .type = OPTIONS_TABLE_FLAG,
430 .default_num = 0
433 { .name = "visual-silence",
434 .type = OPTIONS_TABLE_FLAG,
435 .default_num = 0
438 { .name = "word-separators",
439 .type = OPTIONS_TABLE_STRING,
440 .default_str = " -_@"
443 { .name = NULL }
446 /* Window options. */
447 const struct options_table_entry window_options_table[] = {
448 { .name = "aggressive-resize",
449 .type = OPTIONS_TABLE_FLAG,
450 .default_num = 0
453 { .name = "allow-rename",
454 .type = OPTIONS_TABLE_FLAG,
455 .default_num = 1
458 { .name = "alternate-screen",
459 .type = OPTIONS_TABLE_FLAG,
460 .default_num = 1
463 { .name = "automatic-rename",
464 .type = OPTIONS_TABLE_FLAG,
465 .default_num = 1
469 { .name = "c0-change-trigger",
470 .type = OPTIONS_TABLE_NUMBER,
471 .default_num = 250,
472 .minimum = 0,
473 .maximum = USHRT_MAX
476 { .name = "c0-change-interval",
477 .type = OPTIONS_TABLE_NUMBER,
478 .default_num = 100,
479 .minimum = 1,
480 .maximum = USHRT_MAX
483 { .name = "clock-mode-colour",
484 .type = OPTIONS_TABLE_COLOUR,
485 .default_num = 4
488 { .name = "clock-mode-style",
489 .type = OPTIONS_TABLE_CHOICE,
490 .choices = options_table_clock_mode_style_list,
491 .default_num = 1
494 { .name = "force-height",
495 .type = OPTIONS_TABLE_NUMBER,
496 .minimum = 0,
497 .maximum = INT_MAX,
498 .default_num = 0
501 { .name = "force-width",
502 .type = OPTIONS_TABLE_NUMBER,
503 .minimum = 0,
504 .maximum = INT_MAX,
505 .default_num = 0
508 { .name = "layout-history-limit",
509 .type = OPTIONS_TABLE_NUMBER,
510 .minimum = 1,
511 .maximum = USHRT_MAX,
512 .default_num = 20
515 { .name = "main-pane-height",
516 .type = OPTIONS_TABLE_NUMBER,
517 .minimum = 1,
518 .maximum = INT_MAX,
519 .default_num = 24
522 { .name = "main-pane-width",
523 .type = OPTIONS_TABLE_NUMBER,
524 .minimum = 1,
525 .maximum = INT_MAX,
526 .default_num = 80
529 { .name = "mode-attr",
530 .type = OPTIONS_TABLE_ATTRIBUTES,
531 .default_num = 0
534 { .name = "mode-bg",
535 .type = OPTIONS_TABLE_COLOUR,
536 .default_num = 3
539 { .name = "mode-fg",
540 .type = OPTIONS_TABLE_COLOUR,
541 .default_num = 0
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,
553 .default_num = 0
556 { .name = "monitor-activity",
557 .type = OPTIONS_TABLE_FLAG,
558 .default_num = 0
561 { .name = "monitor-content",
562 .type = OPTIONS_TABLE_STRING,
563 .default_str = ""
566 { .name = "monitor-silence",
567 .type = OPTIONS_TABLE_NUMBER,
568 .minimum = 0,
569 .maximum = INT_MAX,
570 .default_num = 0
573 { .name = "other-pane-height",
574 .type = OPTIONS_TABLE_NUMBER,
575 .minimum = 0,
576 .maximum = INT_MAX,
577 .default_num = 0
580 { .name = "other-pane-width",
581 .type = OPTIONS_TABLE_NUMBER,
582 .minimum = 0,
583 .maximum = INT_MAX,
584 .default_num = 0
587 { .name = "pane-base-index",
588 .type = OPTIONS_TABLE_NUMBER,
589 .minimum = 0,
590 .maximum = USHRT_MAX,
591 .default_num = 0
594 { .name = "remain-on-exit",
595 .type = OPTIONS_TABLE_FLAG,
596 .default_num = 0
599 { .name = "synchronize-panes",
600 .type = OPTIONS_TABLE_FLAG,
601 .default_num = 0
604 { .name = "utf8",
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,
616 .default_num = 8
619 { .name = "window-status-activity-fg",
620 .type = OPTIONS_TABLE_COLOUR,
621 .default_num = 8
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,
631 .default_num = 8
634 { .name = "window-status-bell-fg",
635 .type = OPTIONS_TABLE_COLOUR,
636 .default_num = 8
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,
646 .default_num = 8
649 { .name = "window-status-content-fg",
650 .type = OPTIONS_TABLE_COLOUR,
651 .default_num = 8
654 { .name = "window-status-attr",
655 .type = OPTIONS_TABLE_ATTRIBUTES,
656 .default_num = 0
659 { .name = "window-status-bg",
660 .type = OPTIONS_TABLE_COLOUR,
661 .default_num = 8
664 { .name = "window-status-current-attr",
665 .type = OPTIONS_TABLE_ATTRIBUTES,
666 .default_num = 0
669 { .name = "window-status-current-bg",
670 .type = OPTIONS_TABLE_COLOUR,
671 .default_num = 8
674 { .name = "window-status-current-fg",
675 .type = OPTIONS_TABLE_COLOUR,
676 .default_num = 8
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,
686 .default_num = 8
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,
696 .default_str = " "
699 { .name = "wrap-search",
700 .type = OPTIONS_TABLE_FLAG,
701 .default_num = 1
704 { .name = "xterm-keys",
705 .type = OPTIONS_TABLE_FLAG,
706 .default_num = 0
709 { .name = NULL }
712 /* Populate an options tree from a table. */
713 void
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);
722 else
723 options_set_number(oo, oe->name, oe->default_num);
727 /* Print an option using its type from the table. */
728 const char *
729 options_table_print_entry(
730 const struct options_table_entry *oe, struct options_entry *o)
732 static char out[BUFSIZ];
733 const char *s;
735 *out = '\0';
736 switch (oe->type) {
737 case OPTIONS_TABLE_STRING:
738 xsnprintf(out, sizeof out, "\"%s\"", o->str);
739 break;
740 case OPTIONS_TABLE_NUMBER:
741 xsnprintf(out, sizeof out, "%lld", o->num);
742 break;
743 case OPTIONS_TABLE_KEY:
744 xsnprintf(out, sizeof out, "%s", key_string_lookup_key(o->num));
745 break;
746 case OPTIONS_TABLE_COLOUR:
747 s = colour_tostring(o->num);
748 xsnprintf(out, sizeof out, "%s", s);
749 break;
750 case OPTIONS_TABLE_ATTRIBUTES:
751 s = attributes_tostring(o->num);
752 xsnprintf(out, sizeof out, "%s", s);
753 break;
754 case OPTIONS_TABLE_FLAG:
755 if (o->num)
756 strlcpy(out, "on", sizeof out);
757 else
758 strlcpy(out, "off", sizeof out);
759 break;
760 case OPTIONS_TABLE_CHOICE:
761 s = oe->choices[o->num];
762 xsnprintf(out, sizeof out, "%s", s);
763 break;
765 return (out);
768 /* Find an option. */
770 options_table_find(
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;
780 u_int i;
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)
785 continue;
787 /* If already found, ambiguous. */
788 if (*oe != NULL)
789 return (-1);
790 *oe = oe_loop;
791 *table = tables[i];
793 /* Bail now if an exact match. */
794 if (strcmp((*oe)->name, optstr) == 0)
795 break;
798 return (0);