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