vim-patch:9.1.1892: Not possible to know once Vim is done with sourcing vimrc (#36429)

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: vim/vim#18668

294bce21ee

Nvim has two more steps between sourcing startup scripts and loading
plugins. Set this variable after these two steps.

Co-authored-by: Evgeni Chasnovski <evgeni.chasnovski@gmail.com>
This commit is contained in:
zeertzjq
2025-11-02 18:07:33 +08:00
committed by GitHub
parent 02cd564896
commit 003b429a86
10 changed files with 76 additions and 20 deletions

View File

@@ -367,6 +367,7 @@ VIMSCRIPT
• |getcompletiontype()| gets command-line completion type for any string. • |getcompletiontype()| gets command-line completion type for any string.
• |prompt_getinput()| gets current user-input in prompt-buffer. • |prompt_getinput()| gets current user-input in prompt-buffer.
• |wildtrigger()| triggers command-line expansion. • |wildtrigger()| triggers command-line expansion.
• |v:vim_did_init| is set after sourcing |init.vim| but before |load-plugins|.
============================================================================== ==============================================================================
CHANGED FEATURES *news-changed* CHANGED FEATURES *news-changed*

View File

@@ -301,6 +301,12 @@ For writing a Vim script, see chapter 41 of the user manual |usr_41.txt|.
each directory is inserted before others), after each directory is inserted before others), after
loading the ftdetect scripts. loading the ftdetect scripts.
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).
*:packl* *:packloadall* *:packl* *:packloadall*
:packl[oadall][!] Load all packages in the "start" directory under each :packl[oadall][!] Load all packages in the "start" directory under each
entry in 'packpath'. entry in 'packpath'.

View File

@@ -517,7 +517,9 @@ accordingly, proceeding as follows:
< Skipped if ":syntax off" was called or if the "-u NONE" command < Skipped if ":syntax off" was called or if the "-u NONE" command
line argument was given. line argument was given.
10. Load the plugin scripts. *load-plugins* 10. Set the |v:vim_did_init| variable to 1.
11. Load the plugin scripts. *load-plugins*
This does the same as the command: > This does the same as the command: >
:runtime! plugin/**/*.{vim,lua} :runtime! plugin/**/*.{vim,lua}
< The result is that all directories in 'runtimepath' will be searched < The result is that all directories in 'runtimepath' will be searched
@@ -547,21 +549,21 @@ accordingly, proceeding as follows:
if packages have been found, but that should not add a directory if packages have been found, but that should not add a directory
ending in "after". ending in "after".
11. Set 'shellpipe' and 'shellredir' 12. Set 'shellpipe' and 'shellredir'
The 'shellpipe' and 'shellredir' options are set according to the The 'shellpipe' and 'shellredir' options are set according to the
value of the 'shell' option, unless they have been set before. value of the 'shell' option, unless they have been set before.
This means that Nvim will figure out the values of 'shellpipe' and This means that Nvim will figure out the values of 'shellpipe' and
'shellredir' for you, unless you have set them yourself. 'shellredir' for you, unless you have set them yourself.
12. Set 'updatecount' to zero, if "-n" command argument used. 13. Set 'updatecount' to zero, if "-n" command argument used.
13. Set binary options if the |-b| flag was given. 14. Set binary options if the |-b| flag was given.
14. Read the |shada-file|. 15. Read the |shada-file|.
15. Read the quickfix file if the |-q| flag was given, or exit on failure. 16. Read the quickfix file if the |-q| flag was given, or exit on failure.
16. Open all windows 17. Open all windows
When the |-o| flag was given, windows will be opened (but not When the |-o| flag was given, windows will be opened (but not
displayed yet). displayed yet).
When the |-p| flag was given, tab pages will be created (but not When the |-p| flag was given, tab pages will be created (but not
@@ -571,7 +573,7 @@ accordingly, proceeding as follows:
Buffers for all windows will be loaded, without triggering |BufAdd| Buffers for all windows will be loaded, without triggering |BufAdd|
autocommands. autocommands.
17. Execute startup commands 18. Execute startup commands
If a |-t| flag was given, the tag is jumped to. If a |-t| flag was given, the tag is jumped to.
Commands given with |-c| and |+cmd| are executed. Commands given with |-c| and |+cmd| are executed.
The starting flag is reset, has("vim_starting") will now return zero. The starting flag is reset, has("vim_starting") will now return zero.

View File

@@ -744,6 +744,12 @@ v:versionlong
*v:vim_did_enter* *vim_did_enter-variable* *v:vim_did_enter* *vim_did_enter-variable*
v:vim_did_enter v:vim_did_enter
0 during startup, 1 just before |VimEnter|. 0 during startup, 1 just before |VimEnter|.
Read-only.
*v:vim_did_init* *vim_did_init-variable*
v:vim_did_init
0 during initialization, 1 after sourcing |vimrc| and just
before |load-plugins|.
Read-only. Read-only.
*v:virtnum* *virtnum-variable* *v:virtnum* *virtnum-variable*

View File

@@ -793,6 +793,12 @@ vim.v.versionlong = ...
--- @type integer --- @type integer
vim.v.vim_did_enter = ... vim.v.vim_did_enter = ...
--- 0 during initialization, 1 after sourcing `vimrc` and just
--- before `load-plugins`.
--- Read-only.
--- @type integer
vim.v.vim_did_init = ...
--- Virtual line number for the 'statuscolumn' expression. --- Virtual line number for the 'statuscolumn' expression.
--- Negative when drawing the status column for virtual lines, zero --- Negative when drawing the status column for virtual lines, zero
--- when drawing an actual buffer line, and positive when drawing --- when drawing an actual buffer line, and positive when drawing

View File

@@ -203,6 +203,7 @@ static struct vimvar {
VV(VV_EXITING, "exiting", VAR_NUMBER, VV_RO), VV(VV_EXITING, "exiting", VAR_NUMBER, VV_RO),
VV(VV_MAXCOL, "maxcol", VAR_NUMBER, VV_RO), VV(VV_MAXCOL, "maxcol", VAR_NUMBER, VV_RO),
VV(VV_STACKTRACE, "stacktrace", VAR_LIST, VV_RO), VV(VV_STACKTRACE, "stacktrace", VAR_LIST, VV_RO),
VV(VV_VIM_DID_INIT, "vim_did_init", VAR_NUMBER, VV_RO),
// Neovim // Neovim
VV(VV_STDERR, "stderr", VAR_NUMBER, VV_RO), VV(VV_STDERR, "stderr", VAR_NUMBER, VV_RO),
VV(VV_MSGPACK_TYPES, "msgpack_types", VAR_DICT, VV_RO), VV(VV_MSGPACK_TYPES, "msgpack_types", VAR_DICT, VV_RO),

View File

@@ -123,6 +123,7 @@ typedef enum {
VV_EXITING, VV_EXITING,
VV_MAXCOL, VV_MAXCOL,
VV_STACKTRACE, VV_STACKTRACE,
VV_VIM_DID_INIT,
// Nvim // Nvim
VV_STDERR, VV_STDERR,
VV_MSGPACK_TYPES, VV_MSGPACK_TYPES,

View File

@@ -466,6 +466,8 @@ int main(int argc, char **argv)
syn_maybe_enable(); syn_maybe_enable();
} }
set_vim_var_nr(VV_VIM_DID_INIT, 1);
// Read all the plugin files. // Read all the plugin files.
load_plugins(); load_plugins();

View File

@@ -901,6 +901,14 @@ M.vars = {
Read-only. Read-only.
]=], ]=],
}, },
vim_did_init = {
type = 'integer',
desc = [=[
0 during initialization, 1 after sourcing |vimrc| and just
before |load-plugins|.
Read-only.
]=],
},
virtnum = { virtnum = {
type = 'integer', type = 'integer',
desc = [=[ desc = [=[

View File

@@ -22,9 +22,7 @@ endfunc
" 2. packages " 2. packages
" 3. plugins in after directories " 3. plugins in after directories
func Test_after_comes_later() func Test_after_comes_later()
if !has('packages') CheckFeature packages
return
endif
let before =<< trim [CODE] let before =<< trim [CODE]
set nocp viminfo+=nviminfo set nocp viminfo+=nviminfo
set guioptions+=M set guioptions+=M
@@ -46,14 +44,14 @@ func Test_after_comes_later()
quit quit
[CODE] [CODE]
call mkdir('Xhere/plugin', 'p') call mkdir('Xhere/plugin', 'pR')
call writefile(['let g:sequence .= "here "'], 'Xhere/plugin/here.vim') call writefile(['let g:sequence .= "here "'], 'Xhere/plugin/here.vim')
call mkdir('Xanother/plugin', 'p') call mkdir('Xanother/plugin', 'pR')
call writefile(['let g:sequence .= "another "'], 'Xanother/plugin/another.vim') call writefile(['let g:sequence .= "another "'], 'Xanother/plugin/another.vim')
call mkdir('Xhere/pack/foo/start/foobar/plugin', 'p') call mkdir('Xhere/pack/foo/start/foobar/plugin', 'p')
call writefile(['let g:sequence .= "pack "'], 'Xhere/pack/foo/start/foobar/plugin/foo.vim') call writefile(['let g:sequence .= "pack "'], 'Xhere/pack/foo/start/foobar/plugin/foo.vim')
call mkdir('Xdir/after/plugin', 'p') call mkdir('Xdir/after/plugin', 'pR')
call writefile(['let g:sequence .= "after "'], 'Xdir/after/plugin/later.vim') call writefile(['let g:sequence .= "after "'], 'Xdir/after/plugin/later.vim')
if RunVim(before, after, '') if RunVim(before, after, '')
@@ -75,15 +73,40 @@ func Test_after_comes_later()
call delete('Xtestout') call delete('Xtestout')
call delete('Xsequence') call delete('Xsequence')
call delete('Xhere', 'rf') endfunc
call delete('Xanother', 'rf')
call delete('Xdir', 'rf') 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 endfunc
func Test_pack_in_rtp_when_plugins_run() func Test_pack_in_rtp_when_plugins_run()
if !has('packages') CheckFeature packages
return
endif
let before =<< trim [CODE] let before =<< trim [CODE]
set nocp viminfo+=nviminfo set nocp viminfo+=nviminfo
set guioptions+=M set guioptions+=M