From ed9abb1851e31b98b79b1b06eef5ceeccdbb7372 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E2=82=AC=C5=A1m=CC=B0=CC=B0=CC=B0=CC=B0=CC=B0=CC=B0=CC=B0?= =?UTF-8?q?=CC=B0=CC=B0=CC=B0=CC=B0=CC=B0=CC=B0=CC=B0=CC=B0=CC=B0=CC=B0?= =?UTF-8?q?=CC=B0=CC=B0=CC=B0=CC=B0=CC=B0=CC=B0=CC=B0=CC=B0=CC=B0=CC=B0?= =?UTF-8?q?=CC=B0=CC=B0=CC=B0=CC=B0=CC=B0=CC=B0=CC=B0=CC=B0=CC=B0=CC=B0?= =?UTF-8?q?=CC=B0=CC=B0=CC=B0=CC=B0=CC=B0=CC=B0=CC=B0=CC=B0=CC=B0=CC=B0?= =?UTF-8?q?=CC=B0=CC=B0=CC=B0=CC=B0=CC=B0=CC=B0=CC=B0=CC=B0=CC=B0=CC=B0?= =?UTF-8?q?=CC=B0=CC=B0=CC=B0=CC=B0=CC=B0=CC=B0=CC=B0=CC=B0=CC=B0=CC=B0?= =?UTF-8?q?=CC=B0=CC=B0=CC=B0=CC=B0=CC=B0=CC=B0=CC=B0=CC=B0=CC=B0=CC=B0?= =?UTF-8?q?=CC=B0=CC=B0=CC=B0=CC=B0=CC=B0=CC=B0=CC=B0=CC=B0=CC=B0=CC=B0?= =?UTF-8?q?=CC=B0=CC=B0=CC=B0=CC=B0=CC=B0=CC=B0=CC=B0=CC=B0=CC=B0=CC=B0?= =?UTF-8?q?=CC=B0=CC=B0=CC=B0=CC=B0=CC=B0=CC=B0=CC=B0=CC=B0=CC=B0=CC=B0?= =?UTF-8?q?=CC=B0=CC=B0=CC=B0=CC=B0=CC=B0=CC=B0=CC=B0=CC=B0=CC=B0=CC=B0?= =?UTF-8?q?=CC=B0=CC=B0=CC=B0=CC=B0=CC=B0=CC=B0=CC=B0=CC=B0=CC=B0=CC=B0?= =?UTF-8?q?=CC=B0=CC=B0=CC=B0=CC=B0=CC=B0=CC=B0=CC=B0=CC=B0=CC=B0=CC=B0?= =?UTF-8?q?=CC=B0=CC=B0=CC=B0=CC=B0=CC=B0=CC=B0=CC=B0=CC=B0=CC=B0=CC=B0?= =?UTF-8?q?=CC=B0=CC=B0=CC=B0=CC=B0=CC=B0=CC=B0=CC=B0=CC=B0=CC=B0=CC=B0?= =?UTF-8?q?=CC=B0=CC=B0=CC=B0=CC=B0=CC=B0=CC=B0=CC=B0=CC=B0=CC=B0=CC=B0?= =?UTF-8?q?=CC=B0=CC=B0=CC=B0=CC=B0=CC=B0=CC=B0=CC=B0=CC=B0=CC=B0=CC=B0?= =?UTF-8?q?=CC=B0=CC=B0=CC=B0=CC=B0=CC=B0=CC=B0=CC=B0=CC=B0=CC=B0=CC=B0?= =?UTF-8?q?=CC=B0=CC=B0=CC=B0=CC=B0=CC=B0=CC=B0=CC=B0=CC=B0=CC=B0=CC=B0?= =?UTF-8?q?=CC=B0=CC=B0=CC=B0=CC=B0=EF=BF=BD=C5=98=C2=A7=C5=AE=20=C3=82?= =?UTF-8?q?=C2=A3=E2=95=9F=C2=A9=E8=88=90=C3=A6=C3=98=C2=A2=C2=A3=C3=B0s?= =?UTF-8?q?=C3=9E=C2=A5=C2=BF=E2=80=94?= Date: Tue, 9 Dec 2025 03:22:10 +0000 Subject: [PATCH] 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 --- runtime/lua/vim/_core/exrc.lua | 19 +++++++++++++++++ runtime/lua/vim/_defaults.lua | 31 --------------------------- src/nvim/main.c | 38 ++++++++-------------------------- 3 files changed, 28 insertions(+), 60 deletions(-) create mode 100644 runtime/lua/vim/_core/exrc.lua diff --git a/runtime/lua/vim/_core/exrc.lua b/runtime/lua/vim/_core/exrc.lua new file mode 100644 index 0000000000..2fa586933b --- /dev/null +++ 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 index fa898719d6..e7d7735029 100644 --- 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 index d28b6cd8fc..76de92a972 100644 --- 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; + lua_State *const L = get_global_lstate(); + assert(L); - 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_getglobal(L, "require"); + lua_pushstring(L, "vim._core.exrc"); + if (nlua_pcall(L, 1, 0)) { + fprintf(stderr, "%s\n", lua_tostring(L, -1)); } }