From 294bce21ee837aab209a1008d0efc3e305cf188f Mon Sep 17 00:00:00 2001 From: Evgeni Chasnovski Date: Sat, 1 Nov 2025 15:54:35 +0000 Subject: [PATCH] patch 9.1.1892: Not possible to know once Vim is done with sourcing vimrc Problem: A plugin does not know when startup scripts were already triggered. This is useful to determine if a function is called inside vimrc or after (like when sourcing 'plugin/' files). Solution: Add the v:vim_did_init variable (Evgeni Chasnovski) closes: #18668 Signed-off-by: Evgeni Chasnovski Signed-off-by: Christian Brabandt --- runtime/doc/eval.txt | 6 +++++- runtime/doc/repeat.txt | 8 +++++++- runtime/doc/starting.txt | 5 ++++- runtime/doc/tags | 2 ++ runtime/doc/version9.txt | 3 ++- runtime/syntax/vim.vim | 4 ++-- src/evalvars.c | 1 + src/main.c | 4 ++++ src/testdir/test_startup.vim | 30 ++++++++++++++++++++++++++++++ src/version.c | 2 ++ src/vim.h | 3 ++- 11 files changed, 61 insertions(+), 7 deletions(-) diff --git a/runtime/doc/eval.txt b/runtime/doc/eval.txt index 9140ff2359..b4b28e80cc 100644 --- a/runtime/doc/eval.txt +++ b/runtime/doc/eval.txt @@ -1,4 +1,4 @@ -*eval.txt* For Vim version 9.1. Last change: 2025 Oct 26 +*eval.txt* For Vim version 9.1. Last change: 2025 Nov 01 VIM REFERENCE MANUAL by Bram Moolenaar @@ -2988,6 +2988,10 @@ v:versionlong Like v:version, but also including the patchlevel in the last v:vim_did_enter Zero until most of startup is done. It is set to one just before |VimEnter| autocommands are triggered. + *v:vim_did_init* *vim_did_init-variable* +v:vim_did_init Zero until initialization is done. It is set to one just + after |vimrc| is sourced and before |load-plugins|. + *v:warningmsg* *warningmsg-variable* v:warningmsg Last given warning message. It's allowed to set this variable. diff --git a/runtime/doc/repeat.txt b/runtime/doc/repeat.txt index d1b2012ced..79b293c576 100644 --- a/runtime/doc/repeat.txt +++ b/runtime/doc/repeat.txt @@ -1,4 +1,4 @@ -*repeat.txt* For Vim version 9.1. Last change: 2025 Oct 13 +*repeat.txt* For Vim version 9.1. Last change: 2025 Nov 01 VIM REFERENCE MANUAL by Bram Moolenaar @@ -328,6 +328,12 @@ For writing a Vim script, see chapter 41 of the user manual |usr_41.txt|. you will need to write `filetype plugin indent on` AFTER all `packadd!` commands. + To programmatically decide if `!` is needed during + startup, check |v:vim_did_init|: use `!` if 0 (to not + duplicate |load-plugins| step), no `!` otherwise (to + force load plugin files as otherwise they won't be + loaded automatically). + Also see |pack-add|. {only available when compiled with |+eval|} diff --git a/runtime/doc/starting.txt b/runtime/doc/starting.txt index ec18a96dc0..7f718d7b6d 100644 --- a/runtime/doc/starting.txt +++ b/runtime/doc/starting.txt @@ -1,4 +1,4 @@ -*starting.txt* For Vim version 9.1. Last change: 2025 Oct 12 +*starting.txt* For Vim version 9.1. Last change: 2025 Nov 01 VIM REFERENCE MANUAL by Bram Moolenaar @@ -843,6 +843,9 @@ accordingly. Vim proceeds in this order: If Vim was started in Ex mode with the "-s" argument, all following initializations until 4. are skipped. Only the "-u" option is interpreted. + + The |v:vim_did_init| variable is set to 1 after this step is finished. + *evim.vim* a. If Vim was started as |evim| or |eview| or with the |-y| argument, the script $VIMRUNTIME/evim.vim will be loaded. diff --git a/runtime/doc/tags b/runtime/doc/tags index 0fb8c021d7..3a35834216 100644 --- a/runtime/doc/tags +++ b/runtime/doc/tags @@ -11360,6 +11360,7 @@ v:var eval.txt /*v:var* v:version eval.txt /*v:version* v:versionlong eval.txt /*v:versionlong* v:vim_did_enter eval.txt /*v:vim_did_enter* +v:vim_did_init eval.txt /*v:vim_did_init* v:warningmsg eval.txt /*v:warningmsg* v:wayland_display eval.txt /*v:wayland_display* v:windowid eval.txt /*v:windowid* @@ -11634,6 +11635,7 @@ vim: options.txt /*vim:* vim_announce intro.txt /*vim_announce* vim_dev intro.txt /*vim_dev* vim_did_enter-variable eval.txt /*vim_did_enter-variable* +vim_did_init-variable eval.txt /*vim_did_init-variable* vim_mac intro.txt /*vim_mac* vim_starting builtin.txt /*vim_starting* vim_use intro.txt /*vim_use* diff --git a/runtime/doc/version9.txt b/runtime/doc/version9.txt index f40fe49fca..23f4bed554 100644 --- a/runtime/doc/version9.txt +++ b/runtime/doc/version9.txt @@ -1,4 +1,4 @@ -*version9.txt* For Vim version 9.1. Last change: 2025 Oct 26 +*version9.txt* For Vim version 9.1. Last change: 2025 Nov 01 VIM REFERENCE MANUAL by Bram Moolenaar @@ -41908,6 +41908,7 @@ Vim Variables: ~ |v:termda1| The escape sequence returned for the primary device attribute query (DA1). |v:termosc| The most recent received OSC response. +|v:vim_did_init| Set once Vim finishes startup initialization. |v:wayland_display| The name of the Wayland display Vim is connected to. Vim Arguments: ~ diff --git a/runtime/syntax/vim.vim b/runtime/syntax/vim.vim index 19d2a8d50d..4f0a148618 100644 --- a/runtime/syntax/vim.vim +++ b/runtime/syntax/vim.vim @@ -2,7 +2,7 @@ " Language: Vim script " Maintainer: Hirohito Higashi " Doug Kearns -" Last Change: 2025 Oct 27 +" Last Change: 2025 Nov 01 " Former Maintainer: Charles E. Campbell " DO NOT CHANGE DIRECTLY. @@ -166,7 +166,7 @@ syn keyword vimFuncName contained win_execute win_findbuf win_getid win_gettype " Predefined variable names {{{2 " GEN_SYN_VIM: vimVarName, START_STR='syn keyword vimVimVarName contained', END_STR='' syn keyword vimVimVarName contained count count1 prevcount errmsg warningmsg statusmsg shell_error this_session version lnum termresponse fname lang lc_time ctype charconvert_from charconvert_to fname_in fname_out fname_new fname_diff cmdarg foldstart foldend folddashes foldlevel progname servername dying exception throwpoint register cmdbang insertmode val key profiling fcs_reason fcs_choice beval_bufnr beval_winnr beval_winid beval_lnum beval_col beval_text scrollstart swapname swapchoice swapcommand char mouse_win mouse_winid mouse_lnum mouse_col operator searchforward hlsearch oldfiles windowid progpath completed_item option_new option_old option_oldlocal option_oldglobal option_command option_type errors false true none null numbermax numbermin numbersize -syn keyword vimVimVarName contained vim_did_enter testing t_number t_string t_func t_list t_dict t_float t_bool t_none t_job t_channel t_blob t_class t_object termrfgresp termrbgresp termu7resp termstyleresp termblinkresp event versionlong echospace argv collate exiting colornames sizeofint sizeoflong sizeofpointer maxcol python3_version t_typealias t_enum t_enumvalue stacktrace t_tuple wayland_display clipmethod termda1 termosc +syn keyword vimVimVarName contained vim_did_enter testing t_number t_string t_func t_list t_dict t_float t_bool t_none t_job t_channel t_blob t_class t_object termrfgresp termrbgresp termu7resp termstyleresp termblinkresp event versionlong echospace argv collate exiting colornames sizeofint sizeoflong sizeofpointer maxcol python3_version t_typealias t_enum t_enumvalue stacktrace t_tuple wayland_display clipmethod termda1 termosc vim_did_init "--- syntax here and above generated by runtime/syntax/generator/gen_syntax_vim.vim --- diff --git a/src/evalvars.c b/src/evalvars.c index c840d872bd..2acfc429a5 100644 --- a/src/evalvars.c +++ b/src/evalvars.c @@ -167,6 +167,7 @@ static struct vimvar {VV_NAME("clipmethod", VAR_STRING), NULL, VV_RO}, {VV_NAME("termda1", VAR_STRING), NULL, VV_RO}, {VV_NAME("termosc", VAR_STRING), NULL, VV_RO}, + {VV_NAME("vim_did_init", VAR_NUMBER), NULL, VV_RO}, }; // shorthand diff --git a/src/main.c b/src/main.c index d3730fe10b..ba5b5b7d83 100644 --- a/src/main.c +++ b/src/main.c @@ -433,6 +433,10 @@ main // Source startup scripts. source_startup_scripts(¶ms); +#ifdef FEAT_EVAL + set_vim_var_nr(VV_VIM_DID_INIT, 1L); +#endif + #ifdef FEAT_MZSCHEME /* * Newer version of MzScheme (Racket) require earlier (trampolined) diff --git a/src/testdir/test_startup.vim b/src/testdir/test_startup.vim index 02d1adf140..6693a76b4a 100644 --- a/src/testdir/test_startup.vim +++ b/src/testdir/test_startup.vim @@ -71,6 +71,36 @@ func Test_after_comes_later() call delete('Xsequence') endfunc +func Test_vim_did_init() + let before =<< trim [CODE] + set nocp viminfo+=nviminfo + set guioptions+=M + set loadplugins + set rtp=Xhere + set nomore + [CODE] + + let after =<< trim [CODE] + redir! > Xtestout + echo g:var_vimrc + echo g:var_plugin + redir END + quit + [CODE] + + call writefile(['let g:var_vimrc=v:vim_did_init'], 'Xvimrc', 'D') + call mkdir('Xhere/plugin', 'pR') + call writefile(['let g:var_plugin=v:vim_did_init'], 'Xhere/plugin/here.vim') + + if RunVim(before, after, '-u Xvimrc') + let lines = readfile('Xtestout') + call assert_equal('0', lines[1]) + call assert_equal('1', lines[2]) + endif + + call delete('Xtestout') +endfunc + func Test_pack_in_rtp_when_plugins_run() CheckFeature packages let before =<< trim [CODE] diff --git a/src/version.c b/src/version.c index df3adb3bb2..ff8121c4fd 100644 --- a/src/version.c +++ b/src/version.c @@ -729,6 +729,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ +/**/ + 1892, /**/ 1891, /**/ diff --git a/src/vim.h b/src/vim.h index 83521b9efc..1ca6112e63 100644 --- a/src/vim.h +++ b/src/vim.h @@ -2256,7 +2256,8 @@ typedef int sock_T; #define VV_CLIPMETHOD 113 #define VV_TERMDA1 114 #define VV_TERMOSC 115 -#define VV_LEN 116 // number of v: vars +#define VV_VIM_DID_INIT 116 +#define VV_LEN 117 // number of v: vars // used for v_number in VAR_BOOL and VAR_SPECIAL #define VVAL_FALSE 0L // VAR_BOOL -- 2.47.3