aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorshadmansaleh <13149513+shadmansaleh@users.noreply.github.com>2022-02-17 12:53:17 +0600
committershadmansaleh <13149513+shadmansaleh@users.noreply.github.com>2022-02-28 19:18:49 +0600
commit7b6ee3ef0a2d64657c8ca25f440e010c6dc75408 (patch)
treebfe569a15470eb33482563f9981a1a2a40a4dd6c
parentebfe083337701534887ac3ea3d8e7ad47f7a206a (diff)
downloadrneovim-7b6ee3ef0a2d64657c8ca25f440e010c6dc75408.tar.gz
rneovim-7b6ee3ef0a2d64657c8ca25f440e010c6dc75408.tar.bz2
rneovim-7b6ee3ef0a2d64657c8ca25f440e010c6dc75408.zip
fix: anonymous sid not working
-rw-r--r--src/nvim/eval.c25
-rw-r--r--src/nvim/lua/executor.c53
-rw-r--r--test/functional/ex_cmds/verbose_spec.lua15
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(&current_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, &current_sctx.sc_sid);
+ }
+ }
+ if (current_sctx.sc_sid == SID_STR || current_sctx.sc_sid == SID_LUA) {
new_script_item(NULL, &current_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()