1 /* vi:set ts=8 sts=4 sw=4 noet:
3 * VIM - Vi IMproved by Bram Moolenaar
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.
13 * Vim originated from Stevie version 3.6 (Fish disk 217) by GRWalter (Fred)
14 * It has been changed beyond recognition since then.
16 * Differences between version 8.2 and 9.0 can be found with ":help version9".
17 * Differences between version 7.4 and 8.x can be found with ":help version8".
18 * Differences between version 6.4 and 7.x can be found with ":help version7".
19 * Differences between version 5.8 and 6.x can be found with ":help version6".
20 * Differences between version 4.x and 5.x can be found with ":help version5".
21 * Differences between version 3.0 and 4.x can be found with ":help version4".
22 * All the remarks about older versions have been removed, they are not very
28 char *Version = VIM_VERSION_SHORT;
29 static char *mediumVersion = VIM_VERSION_MEDIUM;
31 #if defined(HAVE_DATE_TIME) || defined(PROTO)
32 # if (defined(VMS) && defined(VAXC)) || defined(PROTO)
33 char longVersion[sizeof(VIM_VERSION_LONG_DATE) + sizeof(__DATE__)
34 + sizeof(__TIME__) + 3];
37 init_longVersion(void)
40 * Construct the long version string. Necessary because
41 * VAX C can't concatenate strings in the preprocessor.
43 strcpy(longVersion, VIM_VERSION_LONG_DATE);
45 strcat(longVersion, BUILD_DATE);
47 strcat(longVersion, __DATE__);
48 strcat(longVersion, " ");
49 strcat(longVersion, __TIME__);
51 strcat(longVersion, ")");
55 char *longVersion = NULL;
58 init_longVersion(void)
60 if (longVersion != NULL)
64 char *date_time = BUILD_DATE;
66 char *date_time = __DATE__ " " __TIME__;
68 char *msg = _("%s (%s, compiled %s)");
69 size_t len = strlen(msg)
70 + strlen(VIM_VERSION_LONG_ONLY)
71 + strlen(VIM_VERSION_DATE_ONLY)
74 longVersion = alloc(len);
75 if (longVersion == NULL)
76 longVersion = VIM_VERSION_LONG;
78 vim_snprintf(longVersion, len, msg,
79 VIM_VERSION_LONG_ONLY, VIM_VERSION_DATE_ONLY, date_time);
83 char *longVersion = VIM_VERSION_LONG;
86 init_longVersion(void)
92 static char *(features[]) =
99 #ifdef AMIGA // only for Amiga systems
112 #ifdef FEAT_AUTOCHDIR
117 #ifdef FEAT_AUTOSERVERNAME
122 #ifdef FEAT_BEVAL_GUI
127 #ifdef FEAT_BEVAL_TERM
128 "+balloon_eval_term",
130 "-balloon_eval_term",
143 #ifdef FEAT_JOB_CHANNEL
149 #ifdef FEAT_CLIENTSERVER
154 #ifdef FEAT_CLIPBOARD
184 #if defined(FEAT_CON_DIALOG) && defined(FEAT_GUI_DIALOG)
187 # if defined(FEAT_CON_DIALOG)
190 # if defined(FEAT_GUI_DIALOG)
207 #ifdef FEAT_GUI_MSWIN
220 #ifdef FEAT_EMACS_TAGS
231 #ifdef FEAT_SEARCH_EXTRA
250 // only interesting on Unix systems
251 #if !defined(USE_SYSTEM) && defined(UNIX)
255 # ifdef DYNAMIC_GETTEXT
264 #if (defined(HAVE_ICONV_H) && defined(USE_ICONV)) || defined(DYNAMIC_ICONV)
265 # ifdef DYNAMIC_ICONV
279 #ifdef FEAT_JOB_CHANNEL
305 #ifdef FEAT_LINEBREAK
334 #ifdef FEAT_MOUSESHAPE
340 #if defined(UNIX) || defined(VMS)
341 # ifdef FEAT_MOUSE_DEC
346 # ifdef FEAT_MOUSE_GPM
355 # ifdef FEAT_MOUSE_JSB
360 # ifdef FEAT_MOUSE_NET
368 # ifdef FEAT_MOUSE_PTERM
375 #if defined(UNIX) || defined(VMS)
377 # ifdef FEAT_SYSMOUSE
382 # ifdef FEAT_MOUSE_URXVT
390 #ifdef FEAT_MBYTE_IME
392 "+multi_byte_ime/dyn",
399 #ifdef FEAT_MULTI_LANG
405 # ifdef DYNAMIC_MZSCHEME
413 #ifdef FEAT_NETBEANS_INTG
419 #ifdef FEAT_GUI_MSWIN
441 #ifdef FEAT_PERSISTENT_UNDO
446 #ifdef FEAT_PROP_POPUP
452 # ifdef FEAT_POSTSCRIPT
467 # ifdef DYNAMIC_PYTHON
476 # ifdef DYNAMIC_PYTHON3
494 #ifdef FEAT_RIGHTLEFT
516 # ifdef DYNAMIC_SODIUM
550 // only interesting on Unix systems
551 #if defined(USE_SYSTEM) && defined(UNIX)
566 #ifdef FEAT_TERMGUICOLORS
577 // only Unix can have terminfo instead of termcap
584 #ifdef FEAT_TERMRESPONSE
590 #ifdef FEAT_PROP_POPUP
596 // unix always includes termcap support
641 #ifdef FEAT_WRITEBACKUP
646 #if defined(UNIX) || defined(VMS)
669 #elif defined(HAVE_XPM)
674 #if defined(UNIX) || defined(VMS)
675 # if defined(USE_XSMP_INTERACT)
677 # elif defined(USE_XSMP)
682 # ifdef FEAT_XCLIPBOARD
688 #ifdef FEAT_XTERM_SAVE
696 static int included_patches[] =
697 { /* Add new patch number below this line */
3347 * Place to put a short description when adding a feature with a patch.
3348 * Keep it short, e.g.,: "relative numbers", "persistent undo".
3349 * Also add a comment marker to separate the lines.
3350 * See the official Vim patches for the diff format: It must use a context of
3351 * one line only. Create it by hand or use "diff -C2" and edit the patch.
3353 static char *(extra_patches[]) =
3354 { /* Add your patch description below this line */
3362 // this relies on the highest patch number to be the first entry
3363 return included_patches[0];
3366 #if defined(FEAT_EVAL) || defined(PROTO)
3368 * Return TRUE if patch "n" has been included.
3375 // Perform a binary search.
3377 h = (int)ARRAY_LENGTH(included_patches) - 1;
3381 if (included_patches[m] == n)
3385 if (included_patches[m] < n)
3395 ex_version(exarg_T *eap)
3398 * Ignore a ":version 9.99" command.
3400 if (*eap->arg == NUL)
3408 * Output a string for the version message. If it's going to wrap, output a
3409 * newline, unless the message is too long to fit on the screen anyway.
3410 * When "wrap" is TRUE wrap the string in [].
3413 version_msg_wrap(char_u *s, int wrap)
3415 int len = vim_strsize(s) + (wrap ? 2 : 0);
3417 if (!got_int && len < (int)Columns && msg_col + len >= (int)Columns
3424 msg_puts((char *)s);
3431 version_msg(char *s)
3433 version_msg_wrap((char_u *)s, FALSE);
3437 * List all features aligned in columns, dictionary style.
3442 list_in_columns((char_u **)features, -1, -1);
3446 * List string items nicely aligned in columns.
3447 * When "size" is < 0 then the last entry is marked with NULL.
3448 * The entry with index "current" is inclosed in [].
3451 list_in_columns(char_u **items, int size, int current)
3460 int use_highlight = (items == (char_u **)features);
3463 // Find the length of the longest item, use that + 1 as the column
3465 for (i = 0; size < 0 ? items[i] != NULL : i < size; ++i)
3467 int l = vim_strsize(items[i]) + (i == current ? 2 : 0);
3475 if (Columns < width)
3477 // Not enough screen columns - show one per line
3478 for (i = 0; i < item_count; ++i)
3480 version_msg_wrap(items[i], i == current);
3481 if (msg_col > 0 && i < item_count - 1)
3487 // The rightmost column doesn't need a separator.
3488 // Sacrifice it to fit in one more column if possible.
3489 ncol = (int) (Columns + 1) / width;
3490 nrow = item_count / ncol + ((item_count % ncol) ? 1 : 0);
3492 // "i" counts columns then rows. "idx" counts rows then columns.
3493 for (i = 0; !got_int && i < nrow * ncol; ++i)
3495 int idx = (i / ncol) + (i % ncol) * nrow;
3497 if (idx < item_count)
3499 int last_col = (i + 1) % ncol == 0;
3504 if (use_highlight && items[idx][0] == '-')
3505 msg_puts_attr((char *)items[idx], HL_ATTR(HLF_W));
3508 msg_puts((char *)items[idx]);
3513 if (msg_col > 0 && cur_row < nrow)
3519 while (msg_col % width)
3525 // this row is out of items, thus at the end of the row
3544 * When adding features here, don't forget to update the list of
3545 * internal variables in eval.c!
3550 # ifdef FEAT_GUI_MSWIN
3553 msg_puts(_("\nMS-Windows 64-bit GUI/console version"));
3555 msg_puts(_("\nMS-Windows 32-bit GUI/console version"));
3559 msg_puts(_("\nMS-Windows 64-bit GUI version"));
3561 msg_puts(_("\nMS-Windows 32-bit GUI version"));
3565 msg_puts(_(" with OLE support"));
3569 msg_puts(_("\nMS-Windows 64-bit console version"));
3571 msg_puts(_("\nMS-Windows 32-bit console version"));
3575 #if defined(MACOS_X)
3576 # if defined(MACOS_X_DARWIN)
3577 msg_puts(_("\nmacOS version"));
3579 msg_puts(_("\nmacOS version w/o darwin feat."));
3581 # if defined(__arm64__)
3582 msg_puts(" - arm64");
3583 # elif defined(__x86_64__)
3584 msg_puts(" - x86_64");
3589 msg_puts(_("\nOpenVMS version"));
3590 # ifdef HAVE_PATHDEF
3591 if (*compiled_arch != NUL)
3594 msg_puts((char *)compiled_arch);
3600 // Print the list of patch numbers if there is at least one.
3601 // Print a range when patches are consecutive: "1-10, 12, 15-40, 42-45"
3602 if (included_patches[0] != 0)
3604 msg_puts(_("\nIncluded patches: "));
3606 i = (int)ARRAY_LENGTH(included_patches) - 1;
3610 first = included_patches[i];
3611 if (i == 0 || included_patches[i - 1] != included_patches[i] + 1)
3615 msg_outnum((long)first);
3616 if (first != included_patches[i])
3619 msg_outnum((long)included_patches[i]);
3626 // Print the list of extra patch descriptions if there is at least one.
3627 if (extra_patches[0] != NULL)
3629 msg_puts(_("\nExtra patches: "));
3631 for (i = 0; extra_patches[i] != NULL; ++i)
3635 msg_puts(extra_patches[i]);
3641 msg_puts(_("Modified by "));
3642 msg_puts(MODIFIED_BY);
3646 if (*compiled_user != NUL || *compiled_sys != NUL)
3648 msg_puts(_("\nCompiled "));
3649 if (*compiled_user != NUL)
3652 msg_puts((char *)compiled_user);
3654 if (*compiled_sys != NUL)
3657 msg_puts((char *)compiled_sys);
3662 #if defined(FEAT_HUGE)
3663 msg_puts(_("\nHuge version "));
3664 #elif defined(FEAT_NORMAL)
3665 msg_puts(_("\nNormal version "));
3667 msg_puts(_("\nTiny version "));
3669 #if !defined(FEAT_GUI)
3670 msg_puts(_("without GUI."));
3671 #elif defined(FEAT_GUI_GTK)
3672 # if defined(USE_GTK3)
3673 msg_puts(_("with GTK3 GUI."));
3674 # elif defined(FEAT_GUI_GNOME)
3675 msg_puts(_("with GTK2-GNOME GUI."));
3677 msg_puts(_("with GTK2 GUI."));
3679 #elif defined(FEAT_GUI_MOTIF)
3680 msg_puts(_("with X11-Motif GUI."));
3681 #elif defined(FEAT_GUI_HAIKU)
3682 msg_puts(_("with Haiku GUI."));
3683 #elif defined(FEAT_GUI_PHOTON)
3684 msg_puts(_("with Photon GUI."));
3685 #elif defined(MSWIN)
3686 msg_puts(_("with GUI."));
3688 version_msg(_(" Features included (+) or not (-):\n"));
3694 #ifdef SYS_VIMRC_FILE
3695 version_msg(_(" system vimrc file: \""));
3696 version_msg(SYS_VIMRC_FILE);
3697 version_msg("\"\n");
3699 #ifdef USR_VIMRC_FILE
3700 version_msg(_(" user vimrc file: \""));
3701 version_msg(USR_VIMRC_FILE);
3702 version_msg("\"\n");
3704 #ifdef USR_VIMRC_FILE2
3705 version_msg(_(" 2nd user vimrc file: \""));
3706 version_msg(USR_VIMRC_FILE2);
3707 version_msg("\"\n");
3709 #ifdef USR_VIMRC_FILE3
3710 version_msg(_(" 3rd user vimrc file: \""));
3711 version_msg(USR_VIMRC_FILE3);
3712 version_msg("\"\n");
3714 #ifdef USR_EXRC_FILE
3715 version_msg(_(" user exrc file: \""));
3716 version_msg(USR_EXRC_FILE);
3717 version_msg("\"\n");
3719 #ifdef USR_EXRC_FILE2
3720 version_msg(_(" 2nd user exrc file: \""));
3721 version_msg(USR_EXRC_FILE2);
3722 version_msg("\"\n");
3725 # ifdef SYS_GVIMRC_FILE
3726 version_msg(_(" system gvimrc file: \""));
3727 version_msg(SYS_GVIMRC_FILE);
3728 version_msg("\"\n");
3730 version_msg(_(" user gvimrc file: \""));
3731 version_msg(USR_GVIMRC_FILE);
3732 version_msg("\"\n");
3733 # ifdef USR_GVIMRC_FILE2
3734 version_msg(_("2nd user gvimrc file: \""));
3735 version_msg(USR_GVIMRC_FILE2);
3736 version_msg("\"\n");
3738 # ifdef USR_GVIMRC_FILE3
3739 version_msg(_("3rd user gvimrc file: \""));
3740 version_msg(USR_GVIMRC_FILE3);
3741 version_msg("\"\n");
3744 version_msg(_(" defaults file: \""));
3745 version_msg(VIM_DEFAULTS_FILE);
3746 version_msg("\"\n");
3748 # ifdef SYS_MENU_FILE
3749 version_msg(_(" system menu file: \""));
3750 version_msg(SYS_MENU_FILE);
3751 version_msg("\"\n");
3755 if (*default_vim_dir != NUL)
3757 version_msg(_(" fall-back for $VIM: \""));
3758 version_msg((char *)default_vim_dir);
3759 version_msg("\"\n");
3761 if (*default_vimruntime_dir != NUL)
3763 version_msg(_(" f-b for $VIMRUNTIME: \""));
3764 version_msg((char *)default_vimruntime_dir);
3765 version_msg("\"\n");
3767 version_msg(_("Compilation: "));
3768 version_msg((char *)all_cflags);
3771 if (*compiler_version != NUL)
3773 version_msg(_("Compiler: "));
3774 version_msg((char *)compiler_version);
3778 version_msg(_("Linking: "));
3779 version_msg((char *)all_lflags);
3783 version_msg(_(" DEBUG BUILD"));
3787 static void do_intro_line(int row, char_u *mesg, int add_version, int attr);
3788 static void intro_message(int colon);
3791 * Show the intro message when not editing a file.
3794 maybe_intro_message(void)
3797 && curbuf->b_fname == NULL
3798 && firstwin->w_next == NULL
3799 && vim_strchr(p_shm, SHM_INTRO) == NULL)
3800 intro_message(FALSE);
3804 * Give an introductory message about Vim.
3805 * Only used when starting Vim on an empty file, without a file name.
3806 * Or with the ":intro" command (for Sven :-).
3810 int colon) // TRUE for ":intro"
3817 static char *(lines[]) =
3819 N_("VIM - Vi IMproved"),
3822 N_("by Bram Moolenaar et al."),
3826 N_("Vim is open source and freely distributable"),
3828 N_("Help poor children in Uganda!"),
3829 N_("type :help iccf<Enter> for information "),
3831 N_("type :q<Enter> to exit "),
3832 N_("type :help<Enter> or <F1> for on-line help"),
3833 N_("type :help version9<Enter> for version info"),
3836 N_("Running in Vi compatible mode"),
3837 N_("type :set nocp<Enter> for Vim defaults"),
3838 N_("type :help cp-default<Enter> for info on this"),
3841 static char *(gui_lines[]) =
3853 N_("menu Help->Orphans for information "),
3855 N_("Running modeless, typed text is inserted"),
3856 N_("menu Edit->Global Settings->Toggle Insert Mode "),
3857 N_(" for two modes "),
3861 N_("menu Edit->Global Settings->Toggle Vi Compatible"),
3862 N_(" for Vim defaults "),
3866 // blanklines = screen height - # message lines
3867 blanklines = (int)Rows - (ARRAY_LENGTH(lines) - 1);
3869 blanklines += 4; // add 4 for not showing "Vi compatible" message
3871 // Don't overwrite a statusline. Depends on 'cmdheight'.
3873 blanklines -= Rows - topframe->fr_height;
3877 // Show the sponsor and register message one out of four times, the Uganda
3878 // message two out of four times.
3879 sponsor = (int)time(NULL);
3880 sponsor = ((sponsor & 2) == 0) - ((sponsor & 4) == 0);
3882 // start displaying the message lines after half of the blank lines
3883 row = blanklines / 2;
3884 if ((row >= 2 && Columns >= 50) || colon)
3886 for (i = 0; i < (int)ARRAY_LENGTH(lines); ++i)
3890 if (p_im && gui.in_use && gui_lines[i] != NULL)
3901 if (strstr(p, "children") != NULL)
3903 ? N_("Sponsor Vim development!")
3904 : N_("Become a registered Vim user!");
3905 else if (strstr(p, "iccf") != NULL)
3907 ? N_("type :help sponsor<Enter> for information ")
3908 : N_("type :help register<Enter> for information ");
3909 else if (strstr(p, "Orphans") != NULL)
3910 p = N_("menu Help->Sponsor/Register for information ");
3913 do_intro_line(row, (char_u *)_(p), i == 2, 0);
3918 // Make the wait-return message appear just below the text.
3936 # define MODBY_LEN 150
3937 char_u modby[MODBY_LEN];
3941 vim_strncpy(modby, (char_u *)_("Modified by "), MODBY_LEN - 1);
3942 l = (int)STRLEN(modby);
3943 vim_strncpy(modby + l, (char_u *)MODIFIED_BY, MODBY_LEN - l - 1);
3948 // Center the message horizontally.
3949 col = vim_strsize(mesg);
3952 STRCPY(vers, mediumVersion);
3953 if (highest_patch())
3955 // Check for 9.9x or 9.9xx, alpha/beta version
3956 if (isalpha((int)vers[3]))
3958 int len = (isalpha((int)vers[4])) ? 5 : 4;
3959 sprintf((char *)vers + len, ".%d%s", highest_patch(),
3960 mediumVersion + len);
3963 sprintf((char *)vers + 3, ".%d", highest_patch());
3965 col += (int)STRLEN(vers);
3967 col = (Columns - col) / 2;
3971 // Split up in parts to highlight <> items differently.
3972 for (p = mesg; *p != NUL; p += l)
3975 for (l = 0; p[l] != NUL
3976 && (l == 0 || (p[l] != '<' && p[l - 1] != '>')); ++l)
3980 clen += ptr2cells(p + l);
3981 l += (*mb_ptr2len)(p + l) - 1;
3984 clen += byte2cells(p[l]);
3986 screen_puts_len(p, l, row, col, *p == '<' ? HL_ATTR(HLF_8) : attr);
3990 // Add the version number to the version line.
3992 screen_puts(vers, row, col, 0);
3996 * ":intro": clear screen, display intro screen and wait for return.
3999 ex_intro(exarg_T *eap UNUSED)
4002 intro_message(TRUE);