fix: anonymous sid not working

This commit is contained in:
shadmansaleh 2022-02-17 12:53:17 +06:00
parent ebfe083337
commit 7b6ee3ef0a
3 changed files with 59 additions and 34 deletions

View File

@ -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;

View File

@ -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)

View File

@ -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()