diff options
author | zeertzjq <zeertzjq@outlook.com> | 2025-02-27 21:49:57 +0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2025-02-27 13:49:57 +0000 |
commit | 89d6d6f25cf22175e8c8eedef7181d8d618f9898 (patch) | |
tree | 43184d9926113f55248d56f77e8de2dc325679fd | |
parent | f25dd7a8d54844effb44dad60e8154bc8172a67a (diff) | |
download | rneovim-89d6d6f25cf22175e8c8eedef7181d8d618f9898.tar.gz rneovim-89d6d6f25cf22175e8c8eedef7181d8d618f9898.tar.bz2 rneovim-89d6d6f25cf22175e8c8eedef7181d8d618f9898.zip |
fix(lua): wrong script context for option set by func from nvim_exec2 (#32659)
Problem: Wrong script context for option set by function defined by
nvim_exec2 in a Lua script.
Solution: Call nlua_set_sctx() after adding SOURCING_LNUM and always set
sc_lnum for a Lua script.
This is a bug discovered when testing #28486. Not sure if this actually
happens in practice, but it's easy to fix and required for #28486.
-rw-r--r-- | src/nvim/lua/executor.c | 16 | ||||
-rw-r--r-- | src/nvim/option.c | 2 | ||||
-rw-r--r-- | test/functional/ex_cmds/verbose_spec.lua | 26 |
3 files changed, 37 insertions, 7 deletions
diff --git a/src/nvim/lua/executor.c b/src/nvim/lua/executor.c index c4c6c19439..bd00df395c 100644 --- a/src/nvim/lua/executor.c +++ b/src/nvim/lua/executor.c @@ -2106,12 +2106,20 @@ bool nlua_execute_on_key(int c, char *typed_buf) return discard; } -// Sets the editor "script context" during Lua execution. Used by :verbose. -// @param[out] current +/// Sets the editor "script context" during Lua execution. Used by :verbose. +/// @param[out] current void nlua_set_sctx(sctx_T *current) { - if (p_verbose <= 0 || (current->sc_sid > 0 && current->sc_lnum > 0) - || !script_is_lua(current->sc_sid)) { + if (!script_is_lua(current->sc_sid)) { + return; + } + + // This function is called after adding SOURCING_LNUM to sc_lnum. + // SOURCING_LNUM can sometimes be non-zero (e.g. with ETYPE_UFUNC), + // but it's unrelated to the line number in Lua scripts. + current->sc_lnum = 0; + + if (p_verbose <= 0) { return; } lua_State *const lstate = global_lstate; diff --git a/src/nvim/option.c b/src/nvim/option.c index 4506c21668..3d4c2e65f9 100644 --- a/src/nvim/option.c +++ b/src/nvim/option.c @@ -1813,12 +1813,12 @@ sctx_T *get_option_sctx(OptIndex opt_idx) void set_option_sctx(OptIndex opt_idx, int opt_flags, sctx_T script_ctx) { bool both = (opt_flags & (OPT_LOCAL | OPT_GLOBAL)) == 0; - nlua_set_sctx(&script_ctx); // Modeline already has the line number set. if (!(opt_flags & OPT_MODELINE)) { script_ctx.sc_lnum += SOURCING_LNUM; } + nlua_set_sctx(&script_ctx); // Remember where the option was set. For local options need to do that // in the buffer or window structure. diff --git a/test/functional/ex_cmds/verbose_spec.lua b/test/functional/ex_cmds/verbose_spec.lua index 071e9690fa..0187baf4ac 100644 --- a/test/functional/ex_cmds/verbose_spec.lua +++ b/test/functional/ex_cmds/verbose_spec.lua @@ -23,7 +23,7 @@ local function last_set_lua_verbose_tests(cmd, v1) write_file( script_file, - [[ + [=[ vim.api.nvim_set_option_value('hlsearch', false, {}) vim.bo.expandtab = true vim.opt.number = true @@ -70,8 +70,17 @@ endfunction\ let &tw = s:return80()\ ", {}) +local set_list = ([[ + func SetList() +%s + set list + endfunc + call SetList() +]]):format(('\n'):rep(1234)) +vim.api.nvim_exec2(set_list, {}) + vim.api.nvim_create_autocmd('User', { pattern = 'set_mouse', callback = cb }) -]] +]=] ) exec(cmd .. ' ' .. script_file) exec('doautocmd User set_mouse') @@ -259,6 +268,19 @@ TestHL2 xxx guibg=Green result ) end) + + it('for option set by function in nvim_exec2', function() + local result = exec_capture(':verbose set list?') + eq( + string.format( + [[ + list + Last set from %s]], + get_last_set_location(54) + ), + result + ) + end) end describe('lua :verbose with -V1', function() |