commit ed9abb1851e31b98b79b1b06eef5ceeccdbb7372
parent 2f9f77cd722a9dad71df46f39c71dca88815c290
Author: €šm̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰̰�Ř§Ů Â£╟©舐æØ¢£ðsÞ¥¿— <memchr@proton.me>
Date: Tue, 9 Dec 2025 03:22:10 +0000
fix(exrc): ensure consistent 'exrc' loading sequence #35148
Problem:
The execution of startup scripts in parent directories are too late
compared to scripts in current direcctory.
Solution:
Execute all startup scripts with `lua/_core/exrc.lua`.
closes: #35147
Diffstat:
3 files changed, 29 insertions(+), 61 deletions(-)
diff --git a/runtime/lua/vim/_core/exrc.lua b/runtime/lua/vim/_core/exrc.lua
@@ -0,0 +1,19 @@
+local files = vim.fs.find({ '.nvim.lua', '.nvimrc', '.exrc' }, {
+ type = 'file',
+ upward = true,
+ limit = math.huge,
+})
+for _, file in ipairs(files) do
+ local trusted = vim.secure.read(file) --[[@as string|nil]]
+ if trusted then
+ if vim.endswith(file, '.lua') then
+ assert(loadstring(trusted, '@' .. file))()
+ else
+ vim.api.nvim_exec2(trusted, {})
+ end
+ end
+ -- If the user unset 'exrc' in the current exrc then stop searching
+ if not vim.o.exrc then
+ break
+ end
+end
diff --git a/runtime/lua/vim/_defaults.lua b/runtime/lua/vim/_defaults.lua
@@ -952,37 +952,6 @@ do
end
end
- vim.api.nvim_create_autocmd('VimEnter', {
- group = vim.api.nvim_create_augroup('nvim.exrc', {}),
- desc = 'Find exrc files in parent directories',
- callback = function()
- if not vim.o.exrc then
- return
- end
- local files = vim.fs.find({ '.nvim.lua', '.nvimrc', '.exrc' }, {
- type = 'file',
- upward = true,
- limit = math.huge,
- -- exrc in cwd already handled from C, thus start in parent directory.
- path = vim.fs.dirname((vim.uv.cwd())),
- })
- for _, file in ipairs(files) do
- local trusted = vim.secure.read(file) --[[@as string|nil]]
- if trusted then
- if vim.endswith(file, '.lua') then
- assert(loadstring(trusted, '@' .. file))()
- else
- vim.api.nvim_exec2(trusted, {})
- end
- end
- -- If the user unset 'exrc' in the current exrc then stop searching
- if not vim.o.exrc then
- return
- end
- end
- end,
- })
-
if tty then
-- Show progress bars in supporting terminals
vim.api.nvim_create_autocmd('Progress', {
diff --git a/src/nvim/main.c b/src/nvim/main.c
@@ -2101,38 +2101,18 @@ static bool do_user_initialization(void)
}
// Read initialization commands from ".nvim.lua", ".nvimrc", or ".exrc" in
-// current directory. This is only done if the 'exrc' option is set.
-// Only do this if VIMRC_FILE is not the same as vimrc file sourced in
-// do_user_initialization.
+// current directory and all parent directories. This is only done if the 'exrc'
+// option is set. Only do this if VIMRC_FILE is not the same as vimrc file
+// sourced in do_user_initialization.
static void do_exrc_initialization(void)
{
- char *str;
-
- if (os_path_exists(VIMRC_LUA_FILE)) {
- str = nlua_read_secure(VIMRC_LUA_FILE);
- if (str != NULL) {
- Error err = ERROR_INIT;
- nlua_exec(cstr_as_string(str), "@"VIMRC_LUA_FILE, (Array)ARRAY_DICT_INIT, kRetNilBool, NULL,
- &err);
- xfree(str);
- if (ERROR_SET(&err)) {
- semsg("Error in %s:", VIMRC_LUA_FILE);
- semsg_multiline("emsg", err.msg);
- api_clear_error(&err);
- }
- }
- } else if (os_path_exists(VIMRC_FILE)) {
- str = nlua_read_secure(VIMRC_FILE);
- if (str != NULL) {
- do_source_str(str, VIMRC_FILE);
- xfree(str);
- }
- } else if (os_path_exists(EXRC_FILE)) {
- str = nlua_read_secure(EXRC_FILE);
- if (str != NULL) {
- do_source_str(str, EXRC_FILE);
- xfree(str);
- }
+ lua_State *const L = get_global_lstate();
+ assert(L);
+
+ lua_getglobal(L, "require");
+ lua_pushstring(L, "vim._core.exrc");
+ if (nlua_pcall(L, 1, 0)) {
+ fprintf(stderr, "%s\n", lua_tostring(L, -1));
}
}