options-table.c revision 1.32
1/* $OpenBSD: options-table.c,v 1.32 2013/01/17 00:11:22 nicm Exp $ */ 2 3/* 4 * Copyright (c) 2011 Nicholas Marriott <nicm@users.sourceforge.net> 5 * 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. 9 * 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. 17 */ 18 19#include <sys/types.h> 20 21#include <string.h> 22#include <paths.h> 23 24#include "tmux.h" 25 26/* 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. 33 */ 34 35/* Choice option type lists. */ 36const char *options_table_mode_keys_list[] = { 37 "emacs", "vi", NULL 38}; 39const char *options_table_mode_mouse_list[] = { 40 "off", "on", "copy-mode", NULL 41}; 42const char *options_table_clock_mode_style_list[] = { 43 "12", "24", NULL 44}; 45const char *options_table_status_keys_list[] = { 46 "emacs", "vi", NULL 47}; 48const char *options_table_status_justify_list[] = { 49 "left", "centre", "right", NULL 50}; 51const char *options_table_status_position_list[] = { 52 "top", "bottom", NULL 53}; 54const char *options_table_bell_action_list[] = { 55 "none", "any", "current", NULL 56}; 57 58/* Server options. */ 59const 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 65 }, 66 67 { .name = "escape-time", 68 .type = OPTIONS_TABLE_NUMBER, 69 .minimum = 0, 70 .maximum = INT_MAX, 71 .default_num = 500 72 }, 73 74 { .name = "exit-unattached", 75 .type = OPTIONS_TABLE_FLAG, 76 .default_num = 0 77 }, 78 79 { .name = "quiet", 80 .type = OPTIONS_TABLE_FLAG, 81 .default_num = 0 /* overridden in main() */ 82 }, 83 84 { .name = "set-clipboard", 85 .type = OPTIONS_TABLE_FLAG, 86 .default_num = 1 87 }, 88 89 { .name = NULL } 90}; 91 92/* Session options. */ 93const struct options_table_entry session_options_table[] = { 94 { .name = "assume-paste-time", 95 .type = OPTIONS_TABLE_NUMBER, 96 .minimum = 0, 97 .maximum = INT_MAX, 98 .default_num = 1, 99 }, 100 101 { .name = "base-index", 102 .type = OPTIONS_TABLE_NUMBER, 103 .minimum = 0, 104 .maximum = INT_MAX, 105 .default_num = 0 106 }, 107 108 { .name = "bell-action", 109 .type = OPTIONS_TABLE_CHOICE, 110 .choices = options_table_bell_action_list, 111 .default_num = BELL_ANY 112 }, 113 114 { .name = "bell-on-alert", 115 .type = OPTIONS_TABLE_FLAG, 116 .default_num = 0 117 }, 118 119 { .name = "default-command", 120 .type = OPTIONS_TABLE_STRING, 121 .default_str = "" 122 }, 123 124 { .name = "default-path", 125 .type = OPTIONS_TABLE_STRING, 126 .default_str = "" 127 }, 128 129 { .name = "default-shell", 130 .type = OPTIONS_TABLE_STRING, 131 .default_str = _PATH_BSHELL 132 }, 133 134 { .name = "default-terminal", 135 .type = OPTIONS_TABLE_STRING, 136 .default_str = "screen" 137 }, 138 139 { .name = "destroy-unattached", 140 .type = OPTIONS_TABLE_FLAG, 141 .default_num = 0 142 }, 143 144 { .name = "detach-on-destroy", 145 .type = OPTIONS_TABLE_FLAG, 146 .default_num = 1 147 }, 148 149 { .name = "display-panes-active-colour", 150 .type = OPTIONS_TABLE_COLOUR, 151 .default_num = 1 152 }, 153 154 { .name = "display-panes-colour", 155 .type = OPTIONS_TABLE_COLOUR, 156 .default_num = 4 157 }, 158 159 { .name = "display-panes-time", 160 .type = OPTIONS_TABLE_NUMBER, 161 .minimum = 1, 162 .maximum = INT_MAX, 163 .default_num = 1000 164 }, 165 166 { .name = "display-time", 167 .type = OPTIONS_TABLE_NUMBER, 168 .minimum = 1, 169 .maximum = INT_MAX, 170 .default_num = 750 171 }, 172 173 { .name = "history-limit", 174 .type = OPTIONS_TABLE_NUMBER, 175 .minimum = 0, 176 .maximum = INT_MAX, 177 .default_num = 2000 178 }, 179 180 { .name = "lock-after-time", 181 .type = OPTIONS_TABLE_NUMBER, 182 .minimum = 0, 183 .maximum = INT_MAX, 184 .default_num = 0 185 }, 186 187 { .name = "lock-command", 188 .type = OPTIONS_TABLE_STRING, 189 .default_str = "lock -np" 190 }, 191 192 { .name = "lock-server", 193 .type = OPTIONS_TABLE_FLAG, 194 .default_num = 1 195 }, 196 197 { .name = "message-attr", 198 .type = OPTIONS_TABLE_ATTRIBUTES, 199 .default_num = 0 200 }, 201 202 { .name = "message-bg", 203 .type = OPTIONS_TABLE_COLOUR, 204 .default_num = 3 205 }, 206 207 { .name = "message-command-attr", 208 .type = OPTIONS_TABLE_ATTRIBUTES, 209 .default_num = 0 210 }, 211 212 { .name = "message-command-bg", 213 .type = OPTIONS_TABLE_COLOUR, 214 .default_num = 0 215 }, 216 217 { .name = "message-command-fg", 218 .type = OPTIONS_TABLE_COLOUR, 219 .default_num = 3 220 }, 221 222 { .name = "message-fg", 223 .type = OPTIONS_TABLE_COLOUR, 224 .default_num = 0 225 }, 226 227 { .name = "message-limit", 228 .type = OPTIONS_TABLE_NUMBER, 229 .minimum = 0, 230 .maximum = INT_MAX, 231 .default_num = 20 232 }, 233 234 { .name = "mouse-resize-pane", 235 .type = OPTIONS_TABLE_FLAG, 236 .default_num = 0 237 }, 238 239 { .name = "mouse-select-pane", 240 .type = OPTIONS_TABLE_FLAG, 241 .default_num = 0 242 }, 243 244 { .name = "mouse-select-window", 245 .type = OPTIONS_TABLE_FLAG, 246 .default_num = 0 247 }, 248 249 { .name = "mouse-utf8", 250 .type = OPTIONS_TABLE_FLAG, 251 .default_num = 0 252 }, 253 254 { .name = "pane-active-border-bg", 255 .type = OPTIONS_TABLE_COLOUR, 256 .default_num = 8 257 }, 258 259 { .name = "pane-active-border-fg", 260 .type = OPTIONS_TABLE_COLOUR, 261 .default_num = 2 262 }, 263 264 { .name = "pane-border-bg", 265 .type = OPTIONS_TABLE_COLOUR, 266 .default_num = 8 267 }, 268 269 { .name = "pane-border-fg", 270 .type = OPTIONS_TABLE_COLOUR, 271 .default_num = 8 272 }, 273 274 { .name = "prefix", 275 .type = OPTIONS_TABLE_KEY, 276 .default_num = '\002', 277 }, 278 279 { .name = "prefix2", 280 .type = OPTIONS_TABLE_KEY, 281 .default_num = KEYC_NONE, 282 }, 283 284 { .name = "renumber-windows", 285 .type = OPTIONS_TABLE_FLAG, 286 .default_num = 0 287 }, 288 289 { .name = "repeat-time", 290 .type = OPTIONS_TABLE_NUMBER, 291 .minimum = 0, 292 .maximum = SHRT_MAX, 293 .default_num = 500 294 }, 295 296 { .name = "set-remain-on-exit", 297 .type = OPTIONS_TABLE_FLAG, 298 .default_num = 0 299 }, 300 301 { .name = "set-titles", 302 .type = OPTIONS_TABLE_FLAG, 303 .default_num = 0 304 }, 305 306 { .name = "set-titles-string", 307 .type = OPTIONS_TABLE_STRING, 308 .default_str = "#S:#I:#W - \"#T\"" 309 }, 310 311 { .name = "status", 312 .type = OPTIONS_TABLE_FLAG, 313 .default_num = 1 314 }, 315 316 { .name = "status-attr", 317 .type = OPTIONS_TABLE_ATTRIBUTES, 318 .default_num = 0 319 }, 320 321 { .name = "status-bg", 322 .type = OPTIONS_TABLE_COLOUR, 323 .default_num = 2 324 }, 325 326 { .name = "status-fg", 327 .type = OPTIONS_TABLE_COLOUR, 328 .default_num = 0 329 }, 330 331 { .name = "status-interval", 332 .type = OPTIONS_TABLE_NUMBER, 333 .minimum = 0, 334 .maximum = INT_MAX, 335 .default_num = 15 336 }, 337 338 { .name = "status-justify", 339 .type = OPTIONS_TABLE_CHOICE, 340 .choices = options_table_status_justify_list, 341 .default_num = 0 342 }, 343 344 { .name = "status-keys", 345 .type = OPTIONS_TABLE_CHOICE, 346 .choices = options_table_status_keys_list, 347 .default_num = MODEKEY_EMACS 348 }, 349 350 { .name = "status-left", 351 .type = OPTIONS_TABLE_STRING, 352 .default_str = "[#S]" 353 }, 354 355 { .name = "status-left-attr", 356 .type = OPTIONS_TABLE_ATTRIBUTES, 357 .default_num = 0 358 }, 359 360 { .name = "status-left-bg", 361 .type = OPTIONS_TABLE_COLOUR, 362 .default_num = 8 363 }, 364 365 { .name = "status-left-fg", 366 .type = OPTIONS_TABLE_COLOUR, 367 .default_num = 8 368 }, 369 370 { .name = "status-left-length", 371 .type = OPTIONS_TABLE_NUMBER, 372 .minimum = 0, 373 .maximum = SHRT_MAX, 374 .default_num = 10 375 }, 376 377 { .name = "status-position", 378 .type = OPTIONS_TABLE_CHOICE, 379 .choices = options_table_status_position_list, 380 .default_num = 1 381 }, 382 383 { .name = "status-right", 384 .type = OPTIONS_TABLE_STRING, 385 .default_str = "\"#22T\" %H:%M %d-%b-%y" 386 }, 387 388 { .name = "status-right-attr", 389 .type = OPTIONS_TABLE_ATTRIBUTES, 390 .default_num = 0 391 }, 392 393 { .name = "status-right-bg", 394 .type = OPTIONS_TABLE_COLOUR, 395 .default_num = 8 396 }, 397 398 { .name = "status-right-fg", 399 .type = OPTIONS_TABLE_COLOUR, 400 .default_num = 8 401 }, 402 403 { .name = "status-right-length", 404 .type = OPTIONS_TABLE_NUMBER, 405 .minimum = 0, 406 .maximum = SHRT_MAX, 407 .default_num = 40 408 }, 409 410 { .name = "status-utf8", 411 .type = OPTIONS_TABLE_FLAG, 412 .default_num = 0 /* overridden in main() */ 413 }, 414 415 { .name = "terminal-overrides", 416 .type = OPTIONS_TABLE_STRING, 417 .default_str = "*88col*:colors=88,*256col*:colors=256" 418 ",xterm*:XT:Ms=\\E]52;%p1%s;%p2%s\\007" 419 ":Cc=\\E]12;%p1%s\\007:Cr=\\E]112\\007" 420 ":Cs=\\E[%p1%d q:Csr=\\E[2 q,screen*:XT" 421 }, 422 423 { .name = "update-environment", 424 .type = OPTIONS_TABLE_STRING, 425 .default_str = "DISPLAY SSH_ASKPASS SSH_AUTH_SOCK SSH_AGENT_PID " 426 "SSH_CONNECTION WINDOWID XAUTHORITY" 427 428 }, 429 430 { .name = "visual-activity", 431 .type = OPTIONS_TABLE_FLAG, 432 .default_num = 0 433 }, 434 435 { .name = "visual-bell", 436 .type = OPTIONS_TABLE_FLAG, 437 .default_num = 0 438 }, 439 440 { .name = "visual-content", 441 .type = OPTIONS_TABLE_FLAG, 442 .default_num = 0 443 }, 444 445 { .name = "visual-silence", 446 .type = OPTIONS_TABLE_FLAG, 447 .default_num = 0 448 }, 449 450 { .name = "word-separators", 451 .type = OPTIONS_TABLE_STRING, 452 .default_str = " -_@" 453 }, 454 455 { .name = NULL } 456}; 457 458/* Window options. */ 459const struct options_table_entry window_options_table[] = { 460 { .name = "aggressive-resize", 461 .type = OPTIONS_TABLE_FLAG, 462 .default_num = 0 463 }, 464 465 { .name = "allow-rename", 466 .type = OPTIONS_TABLE_FLAG, 467 .default_num = 1 468 }, 469 470 { .name = "alternate-screen", 471 .type = OPTIONS_TABLE_FLAG, 472 .default_num = 1 473 }, 474 475 { .name = "automatic-rename", 476 .type = OPTIONS_TABLE_FLAG, 477 .default_num = 1 478 }, 479 480 481 { .name = "c0-change-trigger", 482 .type = OPTIONS_TABLE_NUMBER, 483 .default_num = 250, 484 .minimum = 0, 485 .maximum = USHRT_MAX 486 }, 487 488 { .name = "c0-change-interval", 489 .type = OPTIONS_TABLE_NUMBER, 490 .default_num = 100, 491 .minimum = 1, 492 .maximum = USHRT_MAX 493 }, 494 495 { .name = "clock-mode-colour", 496 .type = OPTIONS_TABLE_COLOUR, 497 .default_num = 4 498 }, 499 500 { .name = "clock-mode-style", 501 .type = OPTIONS_TABLE_CHOICE, 502 .choices = options_table_clock_mode_style_list, 503 .default_num = 1 504 }, 505 506 { .name = "force-height", 507 .type = OPTIONS_TABLE_NUMBER, 508 .minimum = 0, 509 .maximum = INT_MAX, 510 .default_num = 0 511 }, 512 513 { .name = "force-width", 514 .type = OPTIONS_TABLE_NUMBER, 515 .minimum = 0, 516 .maximum = INT_MAX, 517 .default_num = 0 518 }, 519 520 { .name = "main-pane-height", 521 .type = OPTIONS_TABLE_NUMBER, 522 .minimum = 1, 523 .maximum = INT_MAX, 524 .default_num = 24 525 }, 526 527 { .name = "main-pane-width", 528 .type = OPTIONS_TABLE_NUMBER, 529 .minimum = 1, 530 .maximum = INT_MAX, 531 .default_num = 80 532 }, 533 534 { .name = "mode-attr", 535 .type = OPTIONS_TABLE_ATTRIBUTES, 536 .default_num = 0 537 }, 538 539 { .name = "mode-bg", 540 .type = OPTIONS_TABLE_COLOUR, 541 .default_num = 3 542 }, 543 544 { .name = "mode-fg", 545 .type = OPTIONS_TABLE_COLOUR, 546 .default_num = 0 547 }, 548 549 { .name = "mode-keys", 550 .type = OPTIONS_TABLE_CHOICE, 551 .choices = options_table_mode_keys_list, 552 .default_num = MODEKEY_EMACS 553 }, 554 555 { .name = "mode-mouse", 556 .type = OPTIONS_TABLE_CHOICE, 557 .choices = options_table_mode_mouse_list, 558 .default_num = 0 559 }, 560 561 { .name = "monitor-activity", 562 .type = OPTIONS_TABLE_FLAG, 563 .default_num = 0 564 }, 565 566 { .name = "monitor-content", 567 .type = OPTIONS_TABLE_STRING, 568 .default_str = "" 569 }, 570 571 { .name = "monitor-silence", 572 .type = OPTIONS_TABLE_NUMBER, 573 .minimum = 0, 574 .maximum = INT_MAX, 575 .default_num = 0 576 }, 577 578 { .name = "other-pane-height", 579 .type = OPTIONS_TABLE_NUMBER, 580 .minimum = 0, 581 .maximum = INT_MAX, 582 .default_num = 0 583 }, 584 585 { .name = "other-pane-width", 586 .type = OPTIONS_TABLE_NUMBER, 587 .minimum = 0, 588 .maximum = INT_MAX, 589 .default_num = 0 590 }, 591 592 { .name = "pane-base-index", 593 .type = OPTIONS_TABLE_NUMBER, 594 .minimum = 0, 595 .maximum = USHRT_MAX, 596 .default_num = 0 597 }, 598 599 { .name = "remain-on-exit", 600 .type = OPTIONS_TABLE_FLAG, 601 .default_num = 0 602 }, 603 604 { .name = "synchronize-panes", 605 .type = OPTIONS_TABLE_FLAG, 606 .default_num = 0 607 }, 608 609 { .name = "utf8", 610 .type = OPTIONS_TABLE_FLAG, 611 .default_num = 0 /* overridden in main() */ 612 }, 613 614 { .name = "window-status-activity-attr", 615 .type = OPTIONS_TABLE_ATTRIBUTES, 616 .default_num = GRID_ATTR_REVERSE 617 }, 618 619 { .name = "window-status-activity-bg", 620 .type = OPTIONS_TABLE_COLOUR, 621 .default_num = 8 622 }, 623 624 { .name = "window-status-activity-fg", 625 .type = OPTIONS_TABLE_COLOUR, 626 .default_num = 8 627 }, 628 629 { .name = "window-status-bell-attr", 630 .type = OPTIONS_TABLE_ATTRIBUTES, 631 .default_num = GRID_ATTR_REVERSE 632 }, 633 634 { .name = "window-status-bell-bg", 635 .type = OPTIONS_TABLE_COLOUR, 636 .default_num = 8 637 }, 638 639 { .name = "window-status-bell-fg", 640 .type = OPTIONS_TABLE_COLOUR, 641 .default_num = 8 642 }, 643 644 { .name = "window-status-content-attr", 645 .type = OPTIONS_TABLE_ATTRIBUTES, 646 .default_num = GRID_ATTR_REVERSE 647 }, 648 649 { .name = "window-status-content-bg", 650 .type = OPTIONS_TABLE_COLOUR, 651 .default_num = 8 652 }, 653 654 { .name = "window-status-content-fg", 655 .type = OPTIONS_TABLE_COLOUR, 656 .default_num = 8 657 }, 658 659 { .name = "window-status-attr", 660 .type = OPTIONS_TABLE_ATTRIBUTES, 661 .default_num = 0 662 }, 663 664 { .name = "window-status-bg", 665 .type = OPTIONS_TABLE_COLOUR, 666 .default_num = 8 667 }, 668 669 { .name = "window-status-current-attr", 670 .type = OPTIONS_TABLE_ATTRIBUTES, 671 .default_num = 0 672 }, 673 674 { .name = "window-status-current-bg", 675 .type = OPTIONS_TABLE_COLOUR, 676 .default_num = 8 677 }, 678 679 { .name = "window-status-current-fg", 680 .type = OPTIONS_TABLE_COLOUR, 681 .default_num = 8 682 }, 683 684 { .name = "window-status-current-format", 685 .type = OPTIONS_TABLE_STRING, 686 .default_str = "#I:#W#F" 687 }, 688 689 { .name = "window-status-last-attr", 690 .type = OPTIONS_TABLE_ATTRIBUTES, 691 .default_num = 0 692 }, 693 694 { .name = "window-status-last-bg", 695 .type = OPTIONS_TABLE_COLOUR, 696 .default_num = 8 697 }, 698 699 { .name = "window-status-last-fg", 700 .type = OPTIONS_TABLE_COLOUR, 701 .default_num = 8 702 }, 703 704 { .name = "window-status-fg", 705 .type = OPTIONS_TABLE_COLOUR, 706 .default_num = 8 707 }, 708 709 { .name = "window-status-format", 710 .type = OPTIONS_TABLE_STRING, 711 .default_str = "#I:#W#F" 712 }, 713 714 { .name = "window-status-separator", 715 .type = OPTIONS_TABLE_STRING, 716 .default_str = " " 717 }, 718 719 { .name = "wrap-search", 720 .type = OPTIONS_TABLE_FLAG, 721 .default_num = 1 722 }, 723 724 { .name = "xterm-keys", 725 .type = OPTIONS_TABLE_FLAG, 726 .default_num = 0 727 }, 728 729 { .name = NULL } 730}; 731 732/* Populate an options tree from a table. */ 733void 734options_table_populate_tree( 735 const struct options_table_entry *table, struct options *oo) 736{ 737 const struct options_table_entry *oe; 738 739 for (oe = table; oe->name != NULL; oe++) { 740 if (oe->default_str != NULL) 741 options_set_string(oo, oe->name, "%s", oe->default_str); 742 else 743 options_set_number(oo, oe->name, oe->default_num); 744 } 745} 746 747/* Print an option using its type from the table. */ 748const char * 749options_table_print_entry( 750 const struct options_table_entry *oe, struct options_entry *o) 751{ 752 static char out[BUFSIZ]; 753 const char *s; 754 755 *out = '\0'; 756 switch (oe->type) { 757 case OPTIONS_TABLE_STRING: 758 xsnprintf(out, sizeof out, "\"%s\"", o->str); 759 break; 760 case OPTIONS_TABLE_NUMBER: 761 xsnprintf(out, sizeof out, "%lld", o->num); 762 break; 763 case OPTIONS_TABLE_KEY: 764 xsnprintf(out, sizeof out, "%s", key_string_lookup_key(o->num)); 765 break; 766 case OPTIONS_TABLE_COLOUR: 767 s = colour_tostring(o->num); 768 xsnprintf(out, sizeof out, "%s", s); 769 break; 770 case OPTIONS_TABLE_ATTRIBUTES: 771 s = attributes_tostring(o->num); 772 xsnprintf(out, sizeof out, "%s", s); 773 break; 774 case OPTIONS_TABLE_FLAG: 775 if (o->num) 776 strlcpy(out, "on", sizeof out); 777 else 778 strlcpy(out, "off", sizeof out); 779 break; 780 case OPTIONS_TABLE_CHOICE: 781 s = oe->choices[o->num]; 782 xsnprintf(out, sizeof out, "%s", s); 783 break; 784 } 785 return (out); 786} 787 788/* Find an option. */ 789int 790options_table_find( 791 const char *optstr, const struct options_table_entry **table, 792 const struct options_table_entry **oe) 793{ 794 static const struct options_table_entry *tables[] = { 795 server_options_table, 796 window_options_table, 797 session_options_table 798 }; 799 const struct options_table_entry *oe_loop; 800 u_int i; 801 802 for (i = 0; i < nitems(tables); i++) { 803 for (oe_loop = tables[i]; oe_loop->name != NULL; oe_loop++) { 804 if (strncmp(oe_loop->name, optstr, strlen(optstr)) != 0) 805 continue; 806 807 /* If already found, ambiguous. */ 808 if (*oe != NULL) 809 return (-1); 810 *oe = oe_loop; 811 *table = tables[i]; 812 813 /* Bail now if an exact match. */ 814 if (strcmp((*oe)->name, optstr) == 0) 815 break; 816 } 817 } 818 return (0); 819} 820