Execution order conflict in mixed Vimscript and Lua configurations
0 reputation · 17 Jan 2023, 03:41 UTC
0 reputation · 17 Jan 2023, 03:41 UTC
Neovim allows the coexistence of legacy Vimscript and modern Lua configurations, typically transitioning from init.vim to init.lua. While vim.fn enables Lua to call Vimscript functions, the execution order between these two languages can become ambiguous when complex plugin dependencies are involved.
When utilizing the vim.api module to manipulate buffers and options, the timing of these calls relative to legacy Vimscript autocmd events is critical. There is uncertainty regarding how Neovim prioritizes the loading of Lua-based settings when they are triggered by Vimscript-defined events, potentially leading to settings being overwritten or ignored during the startup sequence.
Neovim does not automatically load both init.vim and init.lua at startup. If an init.lua file is present, it is used and init.vim is ignored unless you explicitly source it. Consequently, any execution‑order conflict only occurs when you deliberately source the other language’s file (for example, lua require('my_vim_config') inside init.lua or source ~/.config/nvim/init.lua inside init.vim).
When you have manually sourced both, the order in which autocmds are defined determines the order they run for a given event. Neovim stores autocmds in a list; when an event fires, callbacks are invoked in the exact sequence they were registered. Therefore:
autocmd is defined (or sourced) before a Lua autocmd that modifies the same global option, the Lua callback runs later and its change will overwrite the Vimscript change.This rule applies to any event (BufReadPre, VimEnter, etc.) and to direct option changes made outside of autocmds: the last executed statement wins.
To guarantee that your Lua code executes after every Vimscript plugin and setting has finished, use one of the following documented mechanisms:
vim.api.nvim_create_autocmd('VimEnter', {
callback = function()
-- Your Lua logic that must run last
end
})
vim.schedule(function()
-- Code that runs after Vimscript finishes
end)
init.vim as the primary entry point, place lua require('my_lua_setup') as the very last line.To confirm which script last modified an option:
:verbose set <optionname> – shows the current value and the file/line that last set it.To inspect the order of registered handlers for a specific event:
:autocmd <EventName> – lists all callbacks in the order they will be executed.If you are using a plugin manager that loads plugins asynchronously (e.g., packer.nvim with lazy loading), the exact timing may shift; in that case, please confirm whether your plugins are loaded lazily or eagerly, as that can affect the recommendation.
Use comments to ask for clarification. Post a solution as an answer.
No question comments on this page.