1 /* vi:set ts=8 sts=4 sw=4 noet: 2 * 3 * VIM - Vi IMproved by Bram Moolenaar 4 * 5 * Do ":help uganda" in Vim to read copying and usage conditions. 6 * Do ":help credits" in Vim to see a list of people who contributed. 7 * See README.txt for an overview of the Vim source code. 8 */ 9 10 #include "vim.h" 11 12 #ifdef AMIGA 13 # include <time.h> // for time() 14 #endif 15 16 /* 17 * Vim originated from Stevie version 3.6 (Fish disk 217) by GRWalter (Fred) 18 * It has been changed beyond recognition since then. 19 * 20 * Differences between version 7.4 and 8.x can be found with ":help version8". 21 * Differences between version 6.4 and 7.x can be found with ":help version7". 22 * Differences between version 5.8 and 6.x can be found with ":help version6". 23 * Differences between version 4.x and 5.x can be found with ":help version5". 24 * Differences between version 3.0 and 4.x can be found with ":help version4". 25 * All the remarks about older versions have been removed, they are not very 26 * interesting. 27 */ 28 29 #include "version.h" 30 31 char *Version = VIM_VERSION_SHORT; 32 static char *mediumVersion = VIM_VERSION_MEDIUM; 33 34 #if defined(HAVE_DATE_TIME) || defined(PROTO) 35 # if (defined(VMS) && defined(VAXC)) || defined(PROTO) 36 char longVersion[sizeof(VIM_VERSION_LONG_DATE) + sizeof(__DATE__) 37 + sizeof(__TIME__) + 3]; 38 39 void 40 init_longVersion(void) 41 { 42 /* 43 * Construct the long version string. Necessary because 44 * VAX C can't concatenate strings in the preprocessor. 45 */ 46 strcpy(longVersion, VIM_VERSION_LONG_DATE); 47 strcat(longVersion, __DATE__); 48 strcat(longVersion, " "); 49 strcat(longVersion, __TIME__); 50 strcat(longVersion, ")"); 51 } 52 53 # else 54 void 55 init_longVersion(void) 56 { 57 char *date_time = __DATE__ " " __TIME__; 58 char *msg = _("%s (%s, compiled %s)"); 59 size_t len = strlen(msg) 60 + strlen(VIM_VERSION_LONG_ONLY) 61 + strlen(VIM_VERSION_DATE_ONLY) 62 + strlen(date_time); 63 64 longVersion = alloc(len); 65 if (longVersion == NULL) 66 longVersion = VIM_VERSION_LONG; 67 else 68 vim_snprintf(longVersion, len, msg, 69 VIM_VERSION_LONG_ONLY, VIM_VERSION_DATE_ONLY, date_time); 70 } 71 # endif 72 #else 73 char *longVersion = VIM_VERSION_LONG; 74 75 void 76 init_longVersion(void) 77 { 78 // nothing to do 79 } 80 #endif 81 82 static char *(features[]) = 83 { 84 #ifdef HAVE_ACL 85 "+acl", 86 #else 87 "-acl", 88 #endif 89 #ifdef AMIGA // only for Amiga systems 90 # ifdef FEAT_ARP 91 "+ARP", 92 # else 93 "-ARP", 94 # endif 95 #endif 96 #ifdef FEAT_ARABIC 97 "+arabic", 98 #else 99 "-arabic", 100 #endif 101 "+autocmd", 102 #ifdef FEAT_AUTOCHDIR 103 "+autochdir", 104 #else 105 "-autochdir", 106 #endif 107 #ifdef FEAT_AUTOSERVERNAME 108 "+autoservername", 109 #else 110 "-autoservername", 111 #endif 112 #ifdef FEAT_BEVAL_GUI 113 "+balloon_eval", 114 #else 115 "-balloon_eval", 116 #endif 117 #ifdef FEAT_BEVAL_TERM 118 "+balloon_eval_term", 119 #else 120 "-balloon_eval_term", 121 #endif 122 #ifdef FEAT_BROWSE 123 "+browse", 124 #else 125 "-browse", 126 #endif 127 #ifdef NO_BUILTIN_TCAPS 128 "-builtin_terms", 129 #endif 130 #ifdef SOME_BUILTIN_TCAPS 131 "+builtin_terms", 132 #endif 133 #ifdef ALL_BUILTIN_TCAPS 134 "++builtin_terms", 135 #endif 136 #ifdef FEAT_BYTEOFF 137 "+byte_offset", 138 #else 139 "-byte_offset", 140 #endif 141 #ifdef FEAT_JOB_CHANNEL 142 "+channel", 143 #else 144 "-channel", 145 #endif 146 #ifdef FEAT_CINDENT 147 "+cindent", 148 #else 149 "-cindent", 150 #endif 151 #ifdef FEAT_CLIENTSERVER 152 "+clientserver", 153 #else 154 "-clientserver", 155 #endif 156 #ifdef FEAT_CLIPBOARD 157 "+clipboard", 158 #else 159 "-clipboard", 160 #endif 161 "+cmdline_compl", 162 "+cmdline_hist", 163 #ifdef FEAT_CMDL_INFO 164 "+cmdline_info", 165 #else 166 "-cmdline_info", 167 #endif 168 "+comments", 169 #ifdef FEAT_CONCEAL 170 "+conceal", 171 #else 172 "-conceal", 173 #endif 174 #ifdef FEAT_CRYPT 175 "+cryptv", 176 #else 177 "-cryptv", 178 #endif 179 #ifdef FEAT_CSCOPE 180 "+cscope", 181 #else 182 "-cscope", 183 #endif 184 "+cursorbind", 185 #ifdef CURSOR_SHAPE 186 "+cursorshape", 187 #else 188 "-cursorshape", 189 #endif 190 #if defined(FEAT_CON_DIALOG) && defined(FEAT_GUI_DIALOG) 191 "+dialog_con_gui", 192 #else 193 # if defined(FEAT_CON_DIALOG) 194 "+dialog_con", 195 # else 196 # if defined(FEAT_GUI_DIALOG) 197 "+dialog_gui", 198 # else 199 "-dialog", 200 # endif 201 # endif 202 #endif 203 #ifdef FEAT_DIFF 204 "+diff", 205 #else 206 "-diff", 207 #endif 208 #ifdef FEAT_DIGRAPHS 209 "+digraphs", 210 #else 211 "-digraphs", 212 #endif 213 #ifdef FEAT_GUI_MSWIN 214 # ifdef FEAT_DIRECTX 215 "+directx", 216 # else 217 "-directx", 218 # endif 219 #endif 220 #ifdef FEAT_DND 221 "+dnd", 222 #else 223 "-dnd", 224 #endif 225 #ifdef EBCDIC 226 "+ebcdic", 227 #else 228 "-ebcdic", 229 #endif 230 #ifdef FEAT_EMACS_TAGS 231 "+emacs_tags", 232 #else 233 "-emacs_tags", 234 #endif 235 #ifdef FEAT_EVAL 236 "+eval", 237 #else 238 "-eval", 239 #endif 240 "+ex_extra", 241 #ifdef FEAT_SEARCH_EXTRA 242 "+extra_search", 243 #else 244 "-extra_search", 245 #endif 246 "-farsi", 247 #ifdef FEAT_SEARCHPATH 248 "+file_in_path", 249 #else 250 "-file_in_path", 251 #endif 252 #ifdef FEAT_FIND_ID 253 "+find_in_path", 254 #else 255 "-find_in_path", 256 #endif 257 #ifdef FEAT_FLOAT 258 "+float", 259 #else 260 "-float", 261 #endif 262 #ifdef FEAT_FOLDING 263 "+folding", 264 #else 265 "-folding", 266 #endif 267 #ifdef FEAT_FOOTER 268 "+footer", 269 #else 270 "-footer", 271 #endif 272 // only interesting on Unix systems 273 #if !defined(USE_SYSTEM) && defined(UNIX) 274 "+fork()", 275 #endif 276 #ifdef FEAT_GETTEXT 277 # ifdef DYNAMIC_GETTEXT 278 "+gettext/dyn", 279 # else 280 "+gettext", 281 # endif 282 #else 283 "-gettext", 284 #endif 285 "-hangul_input", 286 #if (defined(HAVE_ICONV_H) && defined(USE_ICONV)) || defined(DYNAMIC_ICONV) 287 # ifdef DYNAMIC_ICONV 288 "+iconv/dyn", 289 # else 290 "+iconv", 291 # endif 292 #else 293 "-iconv", 294 #endif 295 "+insert_expand", 296 #ifdef FEAT_JOB_CHANNEL 297 "+job", 298 #else 299 "-job", 300 #endif 301 #ifdef FEAT_JUMPLIST 302 "+jumplist", 303 #else 304 "-jumplist", 305 #endif 306 #ifdef FEAT_KEYMAP 307 "+keymap", 308 #else 309 "-keymap", 310 #endif 311 #ifdef FEAT_EVAL 312 "+lambda", 313 #else 314 "-lambda", 315 #endif 316 #ifdef FEAT_LANGMAP 317 "+langmap", 318 #else 319 "-langmap", 320 #endif 321 #ifdef FEAT_LIBCALL 322 "+libcall", 323 #else 324 "-libcall", 325 #endif 326 #ifdef FEAT_LINEBREAK 327 "+linebreak", 328 #else 329 "-linebreak", 330 #endif 331 #ifdef FEAT_LISP 332 "+lispindent", 333 #else 334 "-lispindent", 335 #endif 336 "+listcmds", 337 "+localmap", 338 #ifdef FEAT_LUA 339 # ifdef DYNAMIC_LUA 340 "+lua/dyn", 341 # else 342 "+lua", 343 # endif 344 #else 345 "-lua", 346 #endif 347 #ifdef FEAT_MENU 348 "+menu", 349 #else 350 "-menu", 351 #endif 352 #ifdef FEAT_SESSION 353 "+mksession", 354 #else 355 "-mksession", 356 #endif 357 "+modify_fname", 358 "+mouse", 359 #ifdef FEAT_MOUSESHAPE 360 "+mouseshape", 361 #else 362 "-mouseshape", 363 #endif 364 365 #if defined(UNIX) || defined(VMS) 366 # ifdef FEAT_MOUSE_DEC 367 "+mouse_dec", 368 # else 369 "-mouse_dec", 370 # endif 371 # ifdef FEAT_MOUSE_GPM 372 "+mouse_gpm", 373 # else 374 "-mouse_gpm", 375 # endif 376 # ifdef FEAT_MOUSE_JSB 377 "+mouse_jsbterm", 378 # else 379 "-mouse_jsbterm", 380 # endif 381 # ifdef FEAT_MOUSE_NET 382 "+mouse_netterm", 383 # else 384 "-mouse_netterm", 385 # endif 386 #endif 387 388 #ifdef __QNX__ 389 # ifdef FEAT_MOUSE_PTERM 390 "+mouse_pterm", 391 # else 392 "-mouse_pterm", 393 # endif 394 #endif 395 396 #if defined(UNIX) || defined(VMS) 397 "+mouse_sgr", 398 # ifdef FEAT_SYSMOUSE 399 "+mouse_sysmouse", 400 # else 401 "-mouse_sysmouse", 402 # endif 403 # ifdef FEAT_MOUSE_URXVT 404 "+mouse_urxvt", 405 # else 406 "-mouse_urxvt", 407 # endif 408 "+mouse_xterm", 409 #endif 410 411 #ifdef FEAT_MBYTE_IME 412 # ifdef DYNAMIC_IME 413 "+multi_byte_ime/dyn", 414 # else 415 "+multi_byte_ime", 416 # endif 417 #else 418 "+multi_byte", 419 #endif 420 #ifdef FEAT_MULTI_LANG 421 "+multi_lang", 422 #else 423 "-multi_lang", 424 #endif 425 #ifdef FEAT_MZSCHEME 426 # ifdef DYNAMIC_MZSCHEME 427 "+mzscheme/dyn", 428 # else 429 "+mzscheme", 430 # endif 431 #else 432 "-mzscheme", 433 #endif 434 #ifdef FEAT_NETBEANS_INTG 435 "+netbeans_intg", 436 #else 437 "-netbeans_intg", 438 #endif 439 #ifdef FEAT_NUM64 440 "+num64", 441 #else 442 "-num64", 443 #endif 444 #ifdef FEAT_GUI_MSWIN 445 # ifdef FEAT_OLE 446 "+ole", 447 # else 448 "-ole", 449 # endif 450 #endif 451 #ifdef FEAT_EVAL 452 "+packages", 453 #else 454 "-packages", 455 #endif 456 #ifdef FEAT_PATH_EXTRA 457 "+path_extra", 458 #else 459 "-path_extra", 460 #endif 461 #ifdef FEAT_PERL 462 # ifdef DYNAMIC_PERL 463 "+perl/dyn", 464 # else 465 "+perl", 466 # endif 467 #else 468 "-perl", 469 #endif 470 #ifdef FEAT_PERSISTENT_UNDO 471 "+persistent_undo", 472 #else 473 "-persistent_undo", 474 #endif 475 #ifdef FEAT_PROP_POPUP 476 "+popupwin", 477 #else 478 "-popupwin", 479 #endif 480 #ifdef FEAT_PRINTER 481 # ifdef FEAT_POSTSCRIPT 482 "+postscript", 483 # else 484 "-postscript", 485 # endif 486 "+printer", 487 #else 488 "-printer", 489 #endif 490 #ifdef FEAT_PROFILE 491 "+profile", 492 #else 493 "-profile", 494 #endif 495 #ifdef FEAT_PYTHON 496 # ifdef DYNAMIC_PYTHON 497 "+python/dyn", 498 # else 499 "+python", 500 # endif 501 #else 502 "-python", 503 #endif 504 #ifdef FEAT_PYTHON3 505 # ifdef DYNAMIC_PYTHON3 506 "+python3/dyn", 507 # else 508 "+python3", 509 # endif 510 #else 511 "-python3", 512 #endif 513 #ifdef FEAT_QUICKFIX 514 "+quickfix", 515 #else 516 "-quickfix", 517 #endif 518 #ifdef FEAT_RELTIME 519 "+reltime", 520 #else 521 "-reltime", 522 #endif 523 #ifdef FEAT_RIGHTLEFT 524 "+rightleft", 525 #else 526 "-rightleft", 527 #endif 528 #ifdef FEAT_RUBY 529 # ifdef DYNAMIC_RUBY 530 "+ruby/dyn", 531 # else 532 "+ruby", 533 # endif 534 #else 535 "-ruby", 536 #endif 537 "+scrollbind", 538 #ifdef FEAT_SIGNS 539 "+signs", 540 #else 541 "-signs", 542 #endif 543 #ifdef FEAT_SMARTINDENT 544 "+smartindent", 545 #else 546 "-smartindent", 547 #endif 548 #ifdef FEAT_SOUND 549 "+sound", 550 #else 551 "-sound", 552 #endif 553 #ifdef FEAT_SPELL 554 "+spell", 555 #else 556 "-spell", 557 #endif 558 #ifdef STARTUPTIME 559 "+startuptime", 560 #else 561 "-startuptime", 562 #endif 563 #ifdef FEAT_STL_OPT 564 "+statusline", 565 #else 566 "-statusline", 567 #endif 568 "-sun_workshop", 569 #ifdef FEAT_SYN_HL 570 "+syntax", 571 #else 572 "-syntax", 573 #endif 574 // only interesting on Unix systems 575 #if defined(USE_SYSTEM) && defined(UNIX) 576 "+system()", 577 #endif 578 #ifdef FEAT_TAG_BINS 579 "+tag_binary", 580 #else 581 "-tag_binary", 582 #endif 583 "-tag_old_static", 584 "-tag_any_white", 585 #ifdef FEAT_TCL 586 # ifdef DYNAMIC_TCL 587 "+tcl/dyn", 588 # else 589 "+tcl", 590 # endif 591 #else 592 "-tcl", 593 #endif 594 #ifdef FEAT_TERMGUICOLORS 595 "+termguicolors", 596 #else 597 "-termguicolors", 598 #endif 599 #ifdef FEAT_TERMINAL 600 "+terminal", 601 #else 602 "-terminal", 603 #endif 604 #if defined(UNIX) 605 // only Unix can have terminfo instead of termcap 606 # ifdef TERMINFO 607 "+terminfo", 608 # else 609 "-terminfo", 610 # endif 611 #endif 612 #ifdef FEAT_TERMRESPONSE 613 "+termresponse", 614 #else 615 "-termresponse", 616 #endif 617 #ifdef FEAT_TEXTOBJ 618 "+textobjects", 619 #else 620 "-textobjects", 621 #endif 622 #ifdef FEAT_PROP_POPUP 623 "+textprop", 624 #else 625 "-textprop", 626 #endif 627 #if !defined(UNIX) 628 // unix always includes termcap support 629 # ifdef HAVE_TGETENT 630 "+tgetent", 631 # else 632 "-tgetent", 633 # endif 634 #endif 635 #ifdef FEAT_TIMERS 636 "+timers", 637 #else 638 "-timers", 639 #endif 640 #ifdef FEAT_TITLE 641 "+title", 642 #else 643 "-title", 644 #endif 645 #ifdef FEAT_TOOLBAR 646 "+toolbar", 647 #else 648 "-toolbar", 649 #endif 650 "+user_commands", 651 #ifdef FEAT_VARTABS 652 "+vartabs", 653 #else 654 "-vartabs", 655 #endif 656 "+vertsplit", 657 "+virtualedit", 658 "+visual", 659 "+visualextra", 660 #ifdef FEAT_VIMINFO 661 "+viminfo", 662 #else 663 "-viminfo", 664 #endif 665 "+vreplace", 666 #ifdef MSWIN 667 # ifdef FEAT_VTP 668 "+vtp", 669 # else 670 "-vtp", 671 # endif 672 #endif 673 #ifdef FEAT_WILDIGN 674 "+wildignore", 675 #else 676 "-wildignore", 677 #endif 678 #ifdef FEAT_WILDMENU 679 "+wildmenu", 680 #else 681 "-wildmenu", 682 #endif 683 "+windows", 684 #ifdef FEAT_WRITEBACKUP 685 "+writebackup", 686 #else 687 "-writebackup", 688 #endif 689 #if defined(UNIX) || defined(VMS) 690 # ifdef FEAT_X11 691 "+X11", 692 # else 693 "-X11", 694 # endif 695 #endif 696 #ifdef FEAT_XFONTSET 697 "+xfontset", 698 #else 699 "-xfontset", 700 #endif 701 #ifdef FEAT_XIM 702 "+xim", 703 #else 704 "-xim", 705 #endif 706 #ifdef MSWIN 707 # ifdef FEAT_XPM_W32 708 "+xpm_w32", 709 # else 710 "-xpm_w32", 711 # endif 712 #else 713 # ifdef HAVE_XPM 714 "+xpm", 715 # else 716 "-xpm", 717 # endif 718 #endif 719 #if defined(UNIX) || defined(VMS) 720 # ifdef USE_XSMP_INTERACT 721 "+xsmp_interact", 722 # else 723 # ifdef USE_XSMP 724 "+xsmp", 725 # else 726 "-xsmp", 727 # endif 728 # endif 729 # ifdef FEAT_XCLIPBOARD 730 "+xterm_clipboard", 731 # else 732 "-xterm_clipboard", 733 # endif 734 #endif 735 #ifdef FEAT_XTERM_SAVE 736 "+xterm_save", 737 #else 738 "-xterm_save", 739 #endif 740 NULL 741 }; 742 743 static int included_patches[] = 744 { /* Add new patch number below this line */ 745 /**/ 746 79, 747 /**/ 748 78, 749 /**/ 750 77, 751 /**/ 752 76, 753 /**/ 754 75, 755 /**/ 756 74, 757 /**/ 758 73, 759 /**/ 760 72, 761 /**/ 762 71, 763 /**/ 764 70, 765 /**/ 766 69, 767 /**/ 768 68, 769 /**/ 770 67, 771 /**/ 772 66, 773 /**/ 774 65, 775 /**/ 776 64, 777 /**/ 778 63, 779 /**/ 780 62, 781 /**/ 782 61, 783 /**/ 784 60, 785 /**/ 786 59, 787 /**/ 788 58, 789 /**/ 790 57, 791 /**/ 792 56, 793 /**/ 794 55, 795 /**/ 796 54, 797 /**/ 798 53, 799 /**/ 800 52, 801 /**/ 802 51, 803 /**/ 804 50, 805 /**/ 806 49, 807 /**/ 808 48, 809 /**/ 810 47, 811 /**/ 812 46, 813 /**/ 814 45, 815 /**/ 816 44, 817 /**/ 818 43, 819 /**/ 820 42, 821 /**/ 822 41, 823 /**/ 824 40, 825 /**/ 826 39, 827 /**/ 828 38, 829 /**/ 830 37, 831 /**/ 832 36, 833 /**/ 834 35, 835 /**/ 836 34, 837 /**/ 838 33, 839 /**/ 840 32, 841 /**/ 842 31, 843 /**/ 844 30, 845 /**/ 846 29, 847 /**/ 848 28, 849 /**/ 850 27, 851 /**/ 852 26, 853 /**/ 854 25, 855 /**/ 856 24, 857 /**/ 858 23, 859 /**/ 860 22, 861 /**/ 862 21, 863 /**/ 864 20, 865 /**/ 866 19, 867 /**/ 868 18, 869 /**/ 870 17, 871 /**/ 872 16, 873 /**/ 874 15, 875 /**/ 876 14, 877 /**/ 878 13, 879 /**/ 880 12, 881 /**/ 882 11, 883 /**/ 884 10, 885 /**/ 886 9, 887 /**/ 888 8, 889 /**/ 890 7, 891 /**/ 892 6, 893 /**/ 894 5, 895 /**/ 896 4, 897 /**/ 898 3, 899 /**/ 900 2, 901 /**/ 902 1, 903 /**/ 904 0 905 }; 906 907 /* 908 * Place to put a short description when adding a feature with a patch. 909 * Keep it short, e.g.,: "relative numbers", "persistent undo". 910 * Also add a comment marker to separate the lines. 911 * See the official Vim patches for the diff format: It must use a context of 912 * one line only. Create it by hand or use "diff -C2" and edit the patch. 913 */ 914 static char *(extra_patches[]) = 915 { /* Add your patch description below this line */ 916 /**/ 917 NULL 918 }; 919 920 int 921 highest_patch(void) 922 { 923 // this relies on the highest patch number to be the first entry 924 return included_patches[0]; 925 } 926 927 #if defined(FEAT_EVAL) || defined(PROTO) 928 /* 929 * Return TRUE if patch "n" has been included. 930 */ 931 int 932 has_patch(int n) 933 { 934 int i; 935 936 for (i = 0; included_patches[i] != 0; ++i) 937 if (included_patches[i] == n) 938 return TRUE; 939 return FALSE; 940 } 941 #endif 942 943 void 944 ex_version(exarg_T *eap) 945 { 946 /* 947 * Ignore a ":version 9.99" command. 948 */ 949 if (*eap->arg == NUL) 950 { 951 msg_putchar('\n'); 952 list_version(); 953 } 954 } 955 956 /* 957 * Output a string for the version message. If it's going to wrap, output a 958 * newline, unless the message is too long to fit on the screen anyway. 959 * When "wrap" is TRUE wrap the string in []. 960 */ 961 static void 962 version_msg_wrap(char_u *s, int wrap) 963 { 964 int len = (int)vim_strsize(s) + (wrap ? 2 : 0); 965 966 if (!got_int && len < (int)Columns && msg_col + len >= (int)Columns 967 && *s != '\n') 968 msg_putchar('\n'); 969 if (!got_int) 970 { 971 if (wrap) 972 msg_puts("["); 973 msg_puts((char *)s); 974 if (wrap) 975 msg_puts("]"); 976 } 977 } 978 979 static void 980 version_msg(char *s) 981 { 982 version_msg_wrap((char_u *)s, FALSE); 983 } 984 985 /* 986 * List all features aligned in columns, dictionary style. 987 */ 988 static void 989 list_features(void) 990 { 991 list_in_columns((char_u **)features, -1, -1); 992 } 993 994 /* 995 * List string items nicely aligned in columns. 996 * When "size" is < 0 then the last entry is marked with NULL. 997 * The entry with index "current" is inclosed in []. 998 */ 999 void 1000 list_in_columns(char_u **items, int size, int current) 1001 { 1002 int i; 1003 int ncol; 1004 int nrow; 1005 int cur_row = 1; 1006 int item_count = 0; 1007 int width = 0; 1008 #ifdef FEAT_SYN_HL 1009 int use_highlight = (items == (char_u **)features); 1010 #endif 1011 1012 // Find the length of the longest item, use that + 1 as the column 1013 // width. 1014 for (i = 0; size < 0 ? items[i] != NULL : i < size; ++i) 1015 { 1016 int l = (int)vim_strsize(items[i]) + (i == current ? 2 : 0); 1017 1018 if (l > width) 1019 width = l; 1020 ++item_count; 1021 } 1022 width += 1; 1023 1024 if (Columns < width) 1025 { 1026 // Not enough screen columns - show one per line 1027 for (i = 0; i < item_count; ++i) 1028 { 1029 version_msg_wrap(items[i], i == current); 1030 if (msg_col > 0 && i < item_count - 1) 1031 msg_putchar('\n'); 1032 } 1033 return; 1034 } 1035 1036 // The rightmost column doesn't need a separator. 1037 // Sacrifice it to fit in one more column if possible. 1038 ncol = (int) (Columns + 1) / width; 1039 nrow = item_count / ncol + (item_count % ncol ? 1 : 0); 1040 1041 // "i" counts columns then rows. "idx" counts rows then columns. 1042 for (i = 0; !got_int && i < nrow * ncol; ++i) 1043 { 1044 int idx = (i / ncol) + (i % ncol) * nrow; 1045 1046 if (idx < item_count) 1047 { 1048 int last_col = (i + 1) % ncol == 0; 1049 1050 if (idx == current) 1051 msg_putchar('['); 1052 #ifdef FEAT_SYN_HL 1053 if (use_highlight && items[idx][0] == '-') 1054 msg_puts_attr((char *)items[idx], HL_ATTR(HLF_W)); 1055 else 1056 #endif 1057 msg_puts((char *)items[idx]); 1058 if (idx == current) 1059 msg_putchar(']'); 1060 if (last_col) 1061 { 1062 if (msg_col > 0 && cur_row < nrow) 1063 msg_putchar('\n'); 1064 ++cur_row; 1065 } 1066 else 1067 { 1068 while (msg_col % width) 1069 msg_putchar(' '); 1070 } 1071 } 1072 else 1073 { 1074 // this row is out of items, thus at the end of the row 1075 if (msg_col > 0) 1076 { 1077 if (cur_row < nrow) 1078 msg_putchar('\n'); 1079 ++cur_row; 1080 } 1081 } 1082 } 1083 } 1084 1085 void 1086 list_version(void) 1087 { 1088 int i; 1089 int first; 1090 char *s = ""; 1091 1092 /* 1093 * When adding features here, don't forget to update the list of 1094 * internal variables in eval.c! 1095 */ 1096 init_longVersion(); 1097 msg(longVersion); 1098 #ifdef MSWIN 1099 # ifdef FEAT_GUI_MSWIN 1100 # ifdef VIMDLL 1101 # ifdef _WIN64 1102 msg_puts(_("\nMS-Windows 64-bit GUI/console version")); 1103 # else 1104 msg_puts(_("\nMS-Windows 32-bit GUI/console version")); 1105 # endif 1106 # else 1107 # ifdef _WIN64 1108 msg_puts(_("\nMS-Windows 64-bit GUI version")); 1109 # else 1110 msg_puts(_("\nMS-Windows 32-bit GUI version")); 1111 # endif 1112 # endif 1113 # ifdef FEAT_OLE 1114 msg_puts(_(" with OLE support")); 1115 # endif 1116 # else 1117 # ifdef _WIN64 1118 msg_puts(_("\nMS-Windows 64-bit console version")); 1119 # else 1120 msg_puts(_("\nMS-Windows 32-bit console version")); 1121 # endif 1122 # endif 1123 #endif 1124 #if defined(MACOS_X) 1125 # if defined(MACOS_X_DARWIN) 1126 msg_puts(_("\nmacOS version")); 1127 # else 1128 msg_puts(_("\nmacOS version w/o darwin feat.")); 1129 # endif 1130 #endif 1131 1132 #ifdef VMS 1133 msg_puts(_("\nOpenVMS version")); 1134 # ifdef HAVE_PATHDEF 1135 if (*compiled_arch != NUL) 1136 { 1137 msg_puts(" - "); 1138 msg_puts((char *)compiled_arch); 1139 } 1140 # endif 1141 1142 #endif 1143 1144 // Print the list of patch numbers if there is at least one. 1145 // Print a range when patches are consecutive: "1-10, 12, 15-40, 42-45" 1146 if (included_patches[0] != 0) 1147 { 1148 msg_puts(_("\nIncluded patches: ")); 1149 first = -1; 1150 // find last one 1151 for (i = 0; included_patches[i] != 0; ++i) 1152 ; 1153 while (--i >= 0) 1154 { 1155 if (first < 0) 1156 first = included_patches[i]; 1157 if (i == 0 || included_patches[i - 1] != included_patches[i] + 1) 1158 { 1159 msg_puts(s); 1160 s = ", "; 1161 msg_outnum((long)first); 1162 if (first != included_patches[i]) 1163 { 1164 msg_puts("-"); 1165 msg_outnum((long)included_patches[i]); 1166 } 1167 first = -1; 1168 } 1169 } 1170 } 1171 1172 // Print the list of extra patch descriptions if there is at least one. 1173 if (extra_patches[0] != NULL) 1174 { 1175 msg_puts(_("\nExtra patches: ")); 1176 s = ""; 1177 for (i = 0; extra_patches[i] != NULL; ++i) 1178 { 1179 msg_puts(s); 1180 s = ", "; 1181 msg_puts(extra_patches[i]); 1182 } 1183 } 1184 1185 #ifdef MODIFIED_BY 1186 msg_puts("\n"); 1187 msg_puts(_("Modified by ")); 1188 msg_puts(MODIFIED_BY); 1189 #endif 1190 1191 #ifdef HAVE_PATHDEF 1192 if (*compiled_user != NUL || *compiled_sys != NUL) 1193 { 1194 msg_puts(_("\nCompiled ")); 1195 if (*compiled_user != NUL) 1196 { 1197 msg_puts(_("by ")); 1198 msg_puts((char *)compiled_user); 1199 } 1200 if (*compiled_sys != NUL) 1201 { 1202 msg_puts("@"); 1203 msg_puts((char *)compiled_sys); 1204 } 1205 } 1206 #endif 1207 1208 #ifdef FEAT_HUGE 1209 msg_puts(_("\nHuge version ")); 1210 #else 1211 # ifdef FEAT_BIG 1212 msg_puts(_("\nBig version ")); 1213 # else 1214 # ifdef FEAT_NORMAL 1215 msg_puts(_("\nNormal version ")); 1216 # else 1217 # ifdef FEAT_SMALL 1218 msg_puts(_("\nSmall version ")); 1219 # else 1220 msg_puts(_("\nTiny version ")); 1221 # endif 1222 # endif 1223 # endif 1224 #endif 1225 #ifndef FEAT_GUI 1226 msg_puts(_("without GUI.")); 1227 #else 1228 # ifdef FEAT_GUI_GTK 1229 # ifdef USE_GTK3 1230 msg_puts(_("with GTK3 GUI.")); 1231 # else 1232 # ifdef FEAT_GUI_GNOME 1233 msg_puts(_("with GTK2-GNOME GUI.")); 1234 # else 1235 msg_puts(_("with GTK2 GUI.")); 1236 # endif 1237 # endif 1238 # else 1239 # ifdef FEAT_GUI_MOTIF 1240 msg_puts(_("with X11-Motif GUI.")); 1241 # else 1242 # ifdef FEAT_GUI_ATHENA 1243 # ifdef FEAT_GUI_NEXTAW 1244 msg_puts(_("with X11-neXtaw GUI.")); 1245 # else 1246 msg_puts(_("with X11-Athena GUI.")); 1247 # endif 1248 # else 1249 # ifdef FEAT_GUI_PHOTON 1250 msg_puts(_("with Photon GUI.")); 1251 # else 1252 # if defined(MSWIN) 1253 msg_puts(_("with GUI.")); 1254 # else 1255 # if defined(TARGET_API_MAC_CARBON) && TARGET_API_MAC_CARBON 1256 msg_puts(_("with Carbon GUI.")); 1257 # else 1258 # if defined(TARGET_API_MAC_OSX) && TARGET_API_MAC_OSX 1259 msg_puts(_("with Cocoa GUI.")); 1260 # else 1261 # endif 1262 # endif 1263 # endif 1264 # endif 1265 # endif 1266 # endif 1267 # endif 1268 #endif 1269 version_msg(_(" Features included (+) or not (-):\n")); 1270 1271 list_features(); 1272 if (msg_col > 0) 1273 msg_putchar('\n'); 1274 1275 #ifdef SYS_VIMRC_FILE 1276 version_msg(_(" system vimrc file: \"")); 1277 version_msg(SYS_VIMRC_FILE); 1278 version_msg("\"\n"); 1279 #endif 1280 #ifdef USR_VIMRC_FILE 1281 version_msg(_(" user vimrc file: \"")); 1282 version_msg(USR_VIMRC_FILE); 1283 version_msg("\"\n"); 1284 #endif 1285 #ifdef USR_VIMRC_FILE2 1286 version_msg(_(" 2nd user vimrc file: \"")); 1287 version_msg(USR_VIMRC_FILE2); 1288 version_msg("\"\n"); 1289 #endif 1290 #ifdef USR_VIMRC_FILE3 1291 version_msg(_(" 3rd user vimrc file: \"")); 1292 version_msg(USR_VIMRC_FILE3); 1293 version_msg("\"\n"); 1294 #endif 1295 #ifdef USR_EXRC_FILE 1296 version_msg(_(" user exrc file: \"")); 1297 version_msg(USR_EXRC_FILE); 1298 version_msg("\"\n"); 1299 #endif 1300 #ifdef USR_EXRC_FILE2 1301 version_msg(_(" 2nd user exrc file: \"")); 1302 version_msg(USR_EXRC_FILE2); 1303 version_msg("\"\n"); 1304 #endif 1305 #ifdef FEAT_GUI 1306 # ifdef SYS_GVIMRC_FILE 1307 version_msg(_(" system gvimrc file: \"")); 1308 version_msg(SYS_GVIMRC_FILE); 1309 version_msg("\"\n"); 1310 # endif 1311 version_msg(_(" user gvimrc file: \"")); 1312 version_msg(USR_GVIMRC_FILE); 1313 version_msg("\"\n"); 1314 # ifdef USR_GVIMRC_FILE2 1315 version_msg(_("2nd user gvimrc file: \"")); 1316 version_msg(USR_GVIMRC_FILE2); 1317 version_msg("\"\n"); 1318 # endif 1319 # ifdef USR_GVIMRC_FILE3 1320 version_msg(_("3rd user gvimrc file: \"")); 1321 version_msg(USR_GVIMRC_FILE3); 1322 version_msg("\"\n"); 1323 # endif 1324 #endif 1325 version_msg(_(" defaults file: \"")); 1326 version_msg(VIM_DEFAULTS_FILE); 1327 version_msg("\"\n"); 1328 #ifdef FEAT_GUI 1329 # ifdef SYS_MENU_FILE 1330 version_msg(_(" system menu file: \"")); 1331 version_msg(SYS_MENU_FILE); 1332 version_msg("\"\n"); 1333 # endif 1334 #endif 1335 #ifdef HAVE_PATHDEF 1336 if (*default_vim_dir != NUL) 1337 { 1338 version_msg(_(" fall-back for $VIM: \"")); 1339 version_msg((char *)default_vim_dir); 1340 version_msg("\"\n"); 1341 } 1342 if (*default_vimruntime_dir != NUL) 1343 { 1344 version_msg(_(" f-b for $VIMRUNTIME: \"")); 1345 version_msg((char *)default_vimruntime_dir); 1346 version_msg("\"\n"); 1347 } 1348 version_msg(_("Compilation: ")); 1349 version_msg((char *)all_cflags); 1350 version_msg("\n"); 1351 #ifdef VMS 1352 if (*compiler_version != NUL) 1353 { 1354 version_msg(_("Compiler: ")); 1355 version_msg((char *)compiler_version); 1356 version_msg("\n"); 1357 } 1358 #endif 1359 version_msg(_("Linking: ")); 1360 version_msg((char *)all_lflags); 1361 #endif 1362 #ifdef DEBUG 1363 version_msg("\n"); 1364 version_msg(_(" DEBUG BUILD")); 1365 #endif 1366 } 1367 1368 static void do_intro_line(int row, char_u *mesg, int add_version, int attr); 1369 1370 /* 1371 * Show the intro message when not editing a file. 1372 */ 1373 void 1374 maybe_intro_message(void) 1375 { 1376 if (BUFEMPTY() 1377 && curbuf->b_fname == NULL 1378 && firstwin->w_next == NULL 1379 && vim_strchr(p_shm, SHM_INTRO) == NULL) 1380 intro_message(FALSE); 1381 } 1382 1383 /* 1384 * Give an introductory message about Vim. 1385 * Only used when starting Vim on an empty file, without a file name. 1386 * Or with the ":intro" command (for Sven :-). 1387 */ 1388 void 1389 intro_message( 1390 int colon) // TRUE for ":intro" 1391 { 1392 int i; 1393 int row; 1394 int blanklines; 1395 int sponsor; 1396 char *p; 1397 static char *(lines[]) = 1398 { 1399 N_("VIM - Vi IMproved"), 1400 "", 1401 N_("version "), 1402 N_("by Bram Moolenaar et al."), 1403 #ifdef MODIFIED_BY 1404 " ", 1405 #endif 1406 N_("Vim is open source and freely distributable"), 1407 "", 1408 N_("Help poor children in Uganda!"), 1409 N_("type :help iccf<Enter> for information "), 1410 "", 1411 N_("type :q<Enter> to exit "), 1412 N_("type :help<Enter> or <F1> for on-line help"), 1413 N_("type :help version8<Enter> for version info"), 1414 NULL, 1415 "", 1416 N_("Running in Vi compatible mode"), 1417 N_("type :set nocp<Enter> for Vim defaults"), 1418 N_("type :help cp-default<Enter> for info on this"), 1419 }; 1420 #ifdef FEAT_GUI 1421 static char *(gui_lines[]) = 1422 { 1423 NULL, 1424 NULL, 1425 NULL, 1426 NULL, 1427 #ifdef MODIFIED_BY 1428 NULL, 1429 #endif 1430 NULL, 1431 NULL, 1432 NULL, 1433 N_("menu Help->Orphans for information "), 1434 NULL, 1435 N_("Running modeless, typed text is inserted"), 1436 N_("menu Edit->Global Settings->Toggle Insert Mode "), 1437 N_(" for two modes "), 1438 NULL, 1439 NULL, 1440 NULL, 1441 N_("menu Edit->Global Settings->Toggle Vi Compatible"), 1442 N_(" for Vim defaults "), 1443 }; 1444 #endif 1445 1446 // blanklines = screen height - # message lines 1447 blanklines = (int)Rows - ((sizeof(lines) / sizeof(char *)) - 1); 1448 if (!p_cp) 1449 blanklines += 4; // add 4 for not showing "Vi compatible" message 1450 1451 // Don't overwrite a statusline. Depends on 'cmdheight'. 1452 if (p_ls > 1) 1453 blanklines -= Rows - topframe->fr_height; 1454 if (blanklines < 0) 1455 blanklines = 0; 1456 1457 // Show the sponsor and register message one out of four times, the Uganda 1458 // message two out of four times. 1459 sponsor = (int)time(NULL); 1460 sponsor = ((sponsor & 2) == 0) - ((sponsor & 4) == 0); 1461 1462 // start displaying the message lines after half of the blank lines 1463 row = blanklines / 2; 1464 if ((row >= 2 && Columns >= 50) || colon) 1465 { 1466 for (i = 0; i < (int)(sizeof(lines) / sizeof(char *)); ++i) 1467 { 1468 p = lines[i]; 1469 #ifdef FEAT_GUI 1470 if (p_im && gui.in_use && gui_lines[i] != NULL) 1471 p = gui_lines[i]; 1472 #endif 1473 if (p == NULL) 1474 { 1475 if (!p_cp) 1476 break; 1477 continue; 1478 } 1479 if (sponsor != 0) 1480 { 1481 if (strstr(p, "children") != NULL) 1482 p = sponsor < 0 1483 ? N_("Sponsor Vim development!") 1484 : N_("Become a registered Vim user!"); 1485 else if (strstr(p, "iccf") != NULL) 1486 p = sponsor < 0 1487 ? N_("type :help sponsor<Enter> for information ") 1488 : N_("type :help register<Enter> for information "); 1489 else if (strstr(p, "Orphans") != NULL) 1490 p = N_("menu Help->Sponsor/Register for information "); 1491 } 1492 if (*p != NUL) 1493 do_intro_line(row, (char_u *)_(p), i == 2, 0); 1494 ++row; 1495 } 1496 } 1497 1498 // Make the wait-return message appear just below the text. 1499 if (colon) 1500 msg_row = row; 1501 } 1502 1503 static void 1504 do_intro_line( 1505 int row, 1506 char_u *mesg, 1507 int add_version, 1508 int attr) 1509 { 1510 char_u vers[20]; 1511 int col; 1512 char_u *p; 1513 int l; 1514 int clen; 1515 #ifdef MODIFIED_BY 1516 # define MODBY_LEN 150 1517 char_u modby[MODBY_LEN]; 1518 1519 if (*mesg == ' ') 1520 { 1521 vim_strncpy(modby, (char_u *)_("Modified by "), MODBY_LEN - 1); 1522 l = (int)STRLEN(modby); 1523 vim_strncpy(modby + l, (char_u *)MODIFIED_BY, MODBY_LEN - l - 1); 1524 mesg = modby; 1525 } 1526 #endif 1527 1528 // Center the message horizontally. 1529 col = vim_strsize(mesg); 1530 if (add_version) 1531 { 1532 STRCPY(vers, mediumVersion); 1533 if (highest_patch()) 1534 { 1535 // Check for 9.9x or 9.9xx, alpha/beta version 1536 if (isalpha((int)vers[3])) 1537 { 1538 int len = (isalpha((int)vers[4])) ? 5 : 4; 1539 sprintf((char *)vers + len, ".%d%s", highest_patch(), 1540 mediumVersion + len); 1541 } 1542 else 1543 sprintf((char *)vers + 3, ".%d", highest_patch()); 1544 } 1545 col += (int)STRLEN(vers); 1546 } 1547 col = (Columns - col) / 2; 1548 if (col < 0) 1549 col = 0; 1550 1551 // Split up in parts to highlight <> items differently. 1552 for (p = mesg; *p != NUL; p += l) 1553 { 1554 clen = 0; 1555 for (l = 0; p[l] != NUL 1556 && (l == 0 || (p[l] != '<' && p[l - 1] != '>')); ++l) 1557 { 1558 if (has_mbyte) 1559 { 1560 clen += ptr2cells(p + l); 1561 l += (*mb_ptr2len)(p + l) - 1; 1562 } 1563 else 1564 clen += byte2cells(p[l]); 1565 } 1566 screen_puts_len(p, l, row, col, *p == '<' ? HL_ATTR(HLF_8) : attr); 1567 col += clen; 1568 } 1569 1570 // Add the version number to the version line. 1571 if (add_version) 1572 screen_puts(vers, row, col, 0); 1573 } 1574 1575 /* 1576 * ":intro": clear screen, display intro screen and wait for return. 1577 */ 1578 void 1579 ex_intro(exarg_T *eap UNUSED) 1580 { 1581 screenclear(); 1582 intro_message(TRUE); 1583 wait_return(TRUE); 1584 } 1585