diff options
author | shadmansaleh <13149513+shadmansaleh@users.noreply.github.com> | 2022-02-17 12:53:17 +0600 |
---|---|---|
committer | shadmansaleh <13149513+shadmansaleh@users.noreply.github.com> | 2022-02-28 19:18:49 +0600 |
commit | 7b6ee3ef0a2d64657c8ca25f440e010c6dc75408 (patch) | |
tree | bfe569a15470eb33482563f9981a1a2a40a4dd6c | |
parent | ebfe083337701534887ac3ea3d8e7ad47f7a206a (diff) | |
download | rneovim-7b6ee3ef0a2d64657c8ca25f440e010c6dc75408.tar.gz rneovim-7b6ee3ef0a2d64657c8ca25f440e010c6dc75408.tar.bz2 rneovim-7b6ee3ef0a2d64657c8ca25f440e010c6dc75408.zip |
fix: anonymous sid not working
-rw-r--r-- | src/nvim/eval.c | 25 | ||||
-rw-r--r-- | src/nvim/lua/executor.c | 53 | ||||
-rw-r--r-- | test/functional/ex_cmds/verbose_spec.lua | 15 |
3 files changed, 59 insertions, 34 deletions
diff --git a/src/nvim/eval.c b/src/nvim/eval.c index 0322898827..d95b9560c2 100644 --- a/src/nvim/eval.c +++ b/src/nvim/eval.c @@ -9369,10 +9369,31 @@ static hashtab_T *find_var_ht_dict(const char *name, const size_t name_len, cons } else if (*name == 'l' && funccal != NULL) { // local variable *d = &funccal->l_vars; } else if (*name == 's' // script variable - && (current_sctx.sc_sid > 0 || current_sctx.sc_sid == SID_STR) + && (current_sctx.sc_sid > 0 || current_sctx.sc_sid == SID_STR + || current_sctx.sc_sid == SID_LUA) && current_sctx.sc_sid <= ga_scripts.ga_len) { // For anonymous scripts without a script item, create one now so script vars can be used - if (current_sctx.sc_sid == SID_STR) { + if (current_sctx.sc_sid == SID_LUA) { + // try to resolve lua filename & line no so it can be shown in lastset messages. + nlua_set_sctx(¤t_sctx); + if (current_sctx.sc_sid != SID_LUA) { + // Great we have valid location. Now here this out we'll create a new + // script context with the name and lineno of this one. why ? + // for behavioral consistency. With this different anonymous exec from + // same file can't access each others script local stuff. We need to do + // this all other cases except this will act like that otherwise. + const LastSet last_set = (LastSet){ + .script_ctx = current_sctx, + .channel_id = LUA_INTERNAL_CALL, + }; + bool should_free; + // should_free is ignored as script_sctx will be resolved to a fnmae + // & new_script_item will consume it. + char_u *sc_name = get_scriptname(last_set, &should_free); + new_script_item(sc_name, ¤t_sctx.sc_sid); + } + } + if (current_sctx.sc_sid == SID_STR || current_sctx.sc_sid == SID_LUA) { new_script_item(NULL, ¤t_sctx.sc_sid); } *d = &SCRIPT_SV(current_sctx.sc_sid)->sv_dict; diff --git a/src/nvim/lua/executor.c b/src/nvim/lua/executor.c index 3e9786eb1e..7c62ba2283 100644 --- a/src/nvim/lua/executor.c +++ b/src/nvim/lua/executor.c @@ -1818,24 +1818,14 @@ void nlua_execute_on_key(int c) #endif } -// Checks if str is in blacklist array -static bool is_in_ignorelist(const char *str, char *ignorelist[], int ignorelist_size) +// Sets the editor "script context" during Lua execution. Used by :verbose. +// @param[out] current +void nlua_set_sctx(sctx_T *current) { - for (int i = 0; i < ignorelist_size; i++) { - if (strncmp(ignorelist[i], str, strlen(ignorelist[i])) == 0) { - return true; - } + if (p_verbose <= 0 || current->sc_sid != SID_LUA) { + return; } - return false; -} -// Get sctx of current file being sourced if doesn't exist generate it -static sctx_T *nlua_get_sourcing_sctx(void) -{ lua_State *const lstate = global_lstate; - sctx_T *retval = (sctx_T *)xmalloc(sizeof(sctx_T)); - retval->sc_seq = -1; - retval->sc_sid = SID_LUA; - retval->sc_lnum = -1; lua_Debug *info = (lua_Debug *)xmalloc(sizeof(lua_Debug)); // Files where internal wrappers are defined so we can ignore them @@ -1844,7 +1834,7 @@ static sctx_T *nlua_get_sourcing_sctx(void) "vim/_meta.lua", "vim/keymap.lua", }; - int blacklist_size = sizeof(ignorelist) / sizeof(ignorelist[0]); + int ignorelist_size = sizeof(ignorelist) / sizeof(ignorelist[0]); for (int level = 1; true; level++) { if (lua_getstack(lstate, level, info) != 1) { @@ -1854,31 +1844,30 @@ static sctx_T *nlua_get_sourcing_sctx(void) goto cleanup; } - if (info->what[0] == 'C' || info->source[0] != '@' - || is_in_ignorelist(info->source+1, ignorelist, blacklist_size)) { + bool is_ignored = false; + if (info->what[0] == 'C' || info->source[0] != '@') { + is_ignored = true; + } else { + for (int i = 0; i < ignorelist_size; i++) { + if (strncmp(ignorelist[i], info->source+1, strlen(ignorelist[i])) == 0) { + is_ignored = true; + break; + } + } + } + if (is_ignored) { continue; } break; } char *source_path = fix_fname(info->source + 1); - get_current_script_id((char_u *)source_path, retval); + get_current_script_id((char_u *)source_path, current); xfree(source_path); - retval->sc_lnum = info->currentline; + current->sc_lnum = info->currentline; + current->sc_seq = -1; cleanup: xfree(info); - return retval; -} - -// 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 == SID_LUA) { - sctx_T *lua_sctx = nlua_get_sourcing_sctx(); - *current = *lua_sctx; - xfree(lua_sctx); - } } void nlua_do_ucmd(ucmd_T *cmd, exarg_T *eap) diff --git a/test/functional/ex_cmds/verbose_spec.lua b/test/functional/ex_cmds/verbose_spec.lua index f1c3d3fe16..326104dc3c 100644 --- a/test/functional/ex_cmds/verbose_spec.lua +++ b/test/functional/ex_cmds/verbose_spec.lua @@ -38,6 +38,13 @@ function Close_Window() abort\ wincmd -\ endfunction\ ", false) + +local ret = vim.api.nvim_exec ("\ +function! s:return80()\ + return 80\ +endfunction\ +let &tw = s:return80()\ +", true) ]]) exec(':source '..script_file) end) @@ -125,6 +132,14 @@ test_group FileType endfunction]], script_location), result) end) + + it('"Last set" works with anonymous sid', function() + local result = exec_capture(':verbose set tw?') + eq(string.format([[ + textwidth=80 + Last set from %s line 22]], + script_location), result) + end) end) describe('lua verbose:', function() |