fix(exrc): exrc knows its own location (#34638)

fix(exrc): lua exrc files know their location

Problem:
'exrc' files are inherently bound to their location / workspace and
therefore require to "know" their location on the filesystem. However,
currently using `debug.getinfo(1, 'S')` returns `"<nvim>"`.

Solution:
Include the filepath as chunkname in `loadstring()` and `nlua_exec()`.
This commit is contained in:
Yochem van Rosmalen
2025-06-29 17:19:10 +02:00
committed by GitHub
parent 2f95abddfa
commit f7c939fa7a
12 changed files with 24 additions and 11 deletions

View File

@ -2527,6 +2527,8 @@ A jump table for the options with a short description can be found at |Q_op|.
Unset 'exrc' to stop further searching of 'exrc' files in parent
directories, similar to |editorconfig.root|.
To get its own location, Lua exrc files can use |debug.getinfo()|.
Compare 'exrc' to |editorconfig|:
- 'exrc' can execute any code; editorconfig only specifies settings.
- 'exrc' is Nvim-specific; editorconfig works in other editors.

View File

@ -2114,7 +2114,8 @@ expand({string} [, {nosuf} [, {list}]]) *expand()*
<SID> "<SNR>123_" where "123" is the
current script ID |<SID>|
<script> sourced script file, or script file
where the current function was defined
where the current function was defined.
Use |debug.getinfo()| in Lua scripts.
<stack> call stack
<cword> word under the cursor
<cWORD> WORD under the cursor

View File

@ -956,7 +956,7 @@ do
local trusted = vim.secure.read(file) --[[@as string|nil]]
if trusted then
if vim.endswith(file, '.lua') then
assert(loadstring(trusted))()
assert(loadstring(trusted, '@' .. file))()
else
vim.api.nvim_exec2(trusted, {})
end

View File

@ -2194,6 +2194,8 @@ vim.bo.et = vim.bo.expandtab
--- Unset 'exrc' to stop further searching of 'exrc' files in parent
--- directories, similar to `editorconfig.root`.
---
--- To get its own location, Lua exrc files can use `debug.getinfo()`.
---
--- Compare 'exrc' to `editorconfig`:
--- - 'exrc' can execute any code; editorconfig only specifies settings.
--- - 'exrc' is Nvim-specific; editorconfig works in other editors.

View File

@ -1871,7 +1871,8 @@ function vim.fn.exp(expr) end
--- <SID> "<SNR>123_" where "123" is the
--- current script ID |<SID>|
--- <script> sourced script file, or script file
--- where the current function was defined
--- where the current function was defined.
--- Use |debug.getinfo()| in Lua scripts.
--- <stack> call stack
--- <cword> word under the cursor
--- <cWORD> WORD under the cursor

View File

@ -62,7 +62,7 @@ Object nvim_execute_lua(String code, Array args, Arena *arena, Error *err)
FUNC_API_DEPRECATED_SINCE(7)
FUNC_API_REMOTE_ONLY
{
return nlua_exec(code, args, kRetObject, arena, err);
return nlua_exec(code, NULL, args, kRetObject, arena, err);
}
/// Gets the buffer number

View File

@ -513,7 +513,7 @@ Object nvim_exec_lua(String code, Array args, Arena *arena, Error *err)
FUNC_API_REMOTE_ONLY
{
// TODO(bfredl): convert directly from msgpack to lua and then back again
return nlua_exec(code, args, kRetObject, arena, err);
return nlua_exec(code, NULL, args, kRetObject, arena, err);
}
/// Calculates the number of display cells occupied by `text`.

View File

@ -2421,7 +2421,8 @@ M.funcs = {
<SID> "<SNR>123_" where "123" is the
current script ID |<SID>|
<script> sourced script file, or script file
where the current function was defined
where the current function was defined.
Use |debug.getinfo()| in Lua scripts.
<stack> call stack
<cword> word under the cursor
<cWORD> WORD under the cursor

View File

@ -1512,17 +1512,20 @@ int typval_exec_lua_callable(LuaRef lua_cb, int argcount, typval_T *argvars, typ
/// Used for nvim_exec_lua() and internally to execute a lua string.
///
/// @param[in] str String to execute.
/// @param[in] chunkname Chunkname, defaults to "<nvim>".
/// @param[in] args array of ... args
/// @param[in] mode Whether and how the the return value should be converted to Object
/// @param[in] arena can be NULL, then nested allocations are used
/// @param[out] err Location where error will be saved.
///
/// @return Return value of the execution.
Object nlua_exec(const String str, const Array args, LuaRetMode mode, Arena *arena, Error *err)
Object nlua_exec(const String str, const char *chunkname, const Array args, LuaRetMode mode,
Arena *arena, Error *err)
{
lua_State *const lstate = global_lstate;
if (luaL_loadbuffer(lstate, str.data, str.size, "<nvim>")) {
const char *name = (chunkname && chunkname[0]) ? chunkname : "<nvim>";
if (luaL_loadbuffer(lstate, str.data, str.size, name)) {
size_t len;
const char *errstr = lua_tolstring(lstate, -1, &len);
api_set_error(err, kErrorTypeValidation, "Lua: %.*s", (int)len, errstr);

View File

@ -26,7 +26,7 @@ typedef struct {
} nlua_ref_state_t;
#define NLUA_EXEC_STATIC(cstr, arg, mode, arena, err) \
nlua_exec(STATIC_CSTR_AS_STRING(cstr), arg, mode, arena, err)
nlua_exec(STATIC_CSTR_AS_STRING(cstr), NULL, arg, mode, arena, err)
#define NLUA_CLEAR_REF(x) \
do { \

View File

@ -961,7 +961,7 @@ static void remote_request(mparm_T *params, int remote_args, char *server_addr,
ADD_C(a, CSTR_AS_OBJ(connect_error));
ADD_C(a, ARRAY_OBJ(args));
String s = STATIC_CSTR_AS_STRING("return vim._cs_remote(...)");
Object o = nlua_exec(s, a, kRetObject, NULL, &err);
Object o = nlua_exec(s, NULL, a, kRetObject, NULL, &err);
kv_destroy(args);
if (ERROR_SET(&err)) {
fprintf(stderr, "%s\n", err.msg);
@ -2062,7 +2062,8 @@ static void do_exrc_initialization(void)
str = nlua_read_secure(VIMRC_LUA_FILE);
if (str != NULL) {
Error err = ERROR_INIT;
nlua_exec(cstr_as_string(str), (Array)ARRAY_DICT_INIT, kRetNilBool, NULL, &err);
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);

View File

@ -2792,6 +2792,8 @@ local options = {
Unset 'exrc' to stop further searching of 'exrc' files in parent
directories, similar to |editorconfig.root|.
To get its own location, Lua exrc files can use |debug.getinfo()|.
Compare 'exrc' to |editorconfig|:
- 'exrc' can execute any code; editorconfig only specifies settings.
- 'exrc' is Nvim-specific; editorconfig works in other editors.