From ebfe083337701534887ac3ea3d8e7ad47f7a206a Mon Sep 17 00:00:00 2001 From: shadmansaleh <13149513+shadmansaleh@users.noreply.github.com> Date: Sat, 8 Jan 2022 00:39:44 +0600 Subject: feat(lua): show proper verbose output for lua configuration `:verbose` didn't work properly with lua configs (For example: options or keymaps are set from lua, just say that they were set from lua, doesn't say where they were set at. This fixes that issue. Now `:verbose` will provide filename and line no when option/keymap is set from lua. Changes: - compiles lua/vim/keymap.lua as vim/keymap.lua - When souring a lua file current_sctx.sc_sid is set to SID_LUA - Moved finding scripts SID out of `do_source()` to `get_current_script_id()`. So it can be reused for lua files. - Added new function `nlua_get_sctx` that extracts current lua scripts name and line no with debug library. And creates a sctx for it. NOTE: This function ignores C functions and blacklist which currently contains only vim/_meta.lua so vim.o/opt wrappers aren't targeted. - Added function `nlua_set_sctx` that changes provided sctx to current lua scripts sctx if a lua file is being executed. - Added tests in tests/functional/lua/verbose_spec.lua - add primary support for additional types (:autocmd, :function, :syntax) to lua verbose Note: These can't yet be directly set from lua but once that's possible :verbose should work for them hopefully :D - add :verbose support for nvim_exec & nvim_command within lua Currently auto commands/commands/functions ... can only be defined by nvim_exec/nvim_command this adds support for them. Means if those Are defined within lua with vim.cmd/nvim_exec :verbose will show their location . Though note it'll show the line no on which nvim_exec call was made. --- src/nvim/lua/executor.c | 73 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 73 insertions(+) (limited to 'src/nvim/lua/executor.c') diff --git a/src/nvim/lua/executor.c b/src/nvim/lua/executor.c index 18abf04ff6..3e9786eb1e 100644 --- a/src/nvim/lua/executor.c +++ b/src/nvim/lua/executor.c @@ -16,6 +16,7 @@ #include "nvim/change.h" #include "nvim/cursor.h" #include "nvim/eval/userfunc.h" +#include "nvim/eval/typval.h" #include "nvim/event/loop.h" #include "nvim/event/time.h" #include "nvim/ex_cmds2.h" @@ -652,6 +653,15 @@ static int nlua_state_init(lua_State *const lstate) FUNC_ATTR_NONNULL_ALL // [package, loaded, module] lua_setfield(lstate, -2, "vim.filetype"); // [package, loaded] + code = (char *)&lua_keymap_module[0]; + if (luaL_loadbuffer(lstate, code, sizeof(lua_keymap_module) - 1, "@vim/keymap.lua") + || nlua_pcall(lstate, 0, 1)) { + nlua_error(lstate, _("E5106: Error while creating vim.keymap module: %.*s")); + return 1; + } + // [package, loaded, module] + lua_setfield(lstate, -2, "vim.keymap"); // [package, loaded] + lua_pop(lstate, 2); // [] } @@ -1808,6 +1818,69 @@ 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) +{ + for (int i = 0; i < ignorelist_size; i++) { + if (strncmp(ignorelist[i], str, strlen(ignorelist[i])) == 0) { + return true; + } + } + 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 + // like vim.o/opt etc are defined in _meta.lua + char *ignorelist[] = { + "vim/_meta.lua", + "vim/keymap.lua", + }; + int blacklist_size = sizeof(ignorelist) / sizeof(ignorelist[0]); + + for (int level = 1; true; level++) { + if (lua_getstack(lstate, level, info) != 1) { + goto cleanup; + } + if (lua_getinfo(lstate, "nSl", info) == 0) { + goto cleanup; + } + + if (info->what[0] == 'C' || info->source[0] != '@' + || is_in_ignorelist(info->source+1, ignorelist, blacklist_size)) { + continue; + } + break; + } + char *source_path = fix_fname(info->source + 1); + get_current_script_id((char_u *)source_path, retval); + xfree(source_path); + retval->sc_lnum = info->currentline; + +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) { lua_State *const lstate = global_lstate; -- cgit From 7b6ee3ef0a2d64657c8ca25f440e010c6dc75408 Mon Sep 17 00:00:00 2001 From: shadmansaleh <13149513+shadmansaleh@users.noreply.github.com> Date: Thu, 17 Feb 2022 12:53:17 +0600 Subject: fix: anonymous sid not working --- src/nvim/lua/executor.c | 53 ++++++++++++++++++++----------------------------- 1 file changed, 21 insertions(+), 32 deletions(-) (limited to 'src/nvim/lua/executor.c') 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) -- cgit