Merge pull request #15079 from shadmansaleh/feat/verbose_lua

feat(lua): add :verbose support for lua config
This commit is contained in:
bfredl
2022-03-01 13:13:11 +01:00
committed by GitHub
23 changed files with 386 additions and 73 deletions

View File

@@ -64,6 +64,7 @@ set(LUA_F_MODULE_SOURCE ${PROJECT_SOURCE_DIR}/runtime/lua/vim/F.lua)
set(LUA_META_MODULE_SOURCE ${PROJECT_SOURCE_DIR}/runtime/lua/vim/_meta.lua)
set(LUA_FILETYPE_MODULE_SOURCE ${PROJECT_SOURCE_DIR}/runtime/lua/vim/filetype.lua)
set(LUA_LOAD_PACKAGE_MODULE_SOURCE ${PROJECT_SOURCE_DIR}/runtime/lua/vim/_load_package.lua)
set(LUA_KEYMAP_MODULE_SOURCE ${PROJECT_SOURCE_DIR}/runtime/lua/vim/keymap.lua)
set(CHAR_BLOB_GENERATOR ${GENERATOR_DIR}/gen_char_blob.lua)
set(LINT_SUPPRESS_FILE ${PROJECT_BINARY_DIR}/errors.json)
set(LINT_SUPPRESS_URL_BASE "https://raw.githubusercontent.com/neovim/doc/gh-pages/reports/clint")
@@ -338,6 +339,7 @@ add_custom_command(
${LUA_META_MODULE_SOURCE} lua_meta_module
${LUA_FILETYPE_MODULE_SOURCE} lua_filetype_module
${LUA_LOAD_PACKAGE_MODULE_SOURCE} lua_load_package_module
${LUA_KEYMAP_MODULE_SOURCE} lua_keymap_module
DEPENDS
${CHAR_BLOB_GENERATOR}
${LUA_VIM_MODULE_SOURCE}
@@ -347,6 +349,7 @@ add_custom_command(
${LUA_META_MODULE_SOURCE}
${LUA_FILETYPE_MODULE_SOURCE}
${LUA_LOAD_PACKAGE_MODULE_SOURCE}
${LUA_KEYMAP_MODULE_SOURCE}
VERBATIM
)

View File

@@ -953,11 +953,11 @@ ArrayOf(Dictionary) nvim_buf_get_keymap(uint64_t channel_id, Buffer buffer, Stri
/// @see |nvim_set_keymap()|
///
/// @param buffer Buffer handle, or 0 for current buffer
void nvim_buf_set_keymap(Buffer buffer, String mode, String lhs, String rhs, Dict(keymap) *opts,
Error *err)
void nvim_buf_set_keymap(uint64_t channel_id, Buffer buffer, String mode, String lhs, String rhs,
Dict(keymap) *opts, Error *err)
FUNC_API_SINCE(6)
{
modify_keymap(buffer, false, mode, lhs, rhs, opts, err);
modify_keymap(channel_id, buffer, false, mode, lhs, rhs, opts, err);
}
/// Unmaps a buffer-local |mapping| for the given mode.
@@ -965,11 +965,12 @@ void nvim_buf_set_keymap(Buffer buffer, String mode, String lhs, String rhs, Dic
/// @see |nvim_del_keymap()|
///
/// @param buffer Buffer handle, or 0 for current buffer
void nvim_buf_del_keymap(Buffer buffer, String mode, String lhs, Error *err)
void nvim_buf_del_keymap(uint64_t channel_id, Buffer buffer, String mode,
String lhs, Error *err)
FUNC_API_SINCE(6)
{
String rhs = { .data = "", .size = 0 };
modify_keymap(buffer, true, mode, lhs, rhs, NULL, err);
modify_keymap(channel_id, buffer, true, mode, lhs, rhs, NULL, err);
}
/// Gets a map of buffer-local |user-commands|.

View File

@@ -22,11 +22,11 @@
/// @deprecated
/// @see nvim_exec
String nvim_command_output(String command, Error *err)
String nvim_command_output(uint64_t channel_id, String command, Error *err)
FUNC_API_SINCE(1)
FUNC_API_DEPRECATED_SINCE(7)
{
return nvim_exec(command, true, err);
return nvim_exec(channel_id, command, true, err);
}
/// @deprecated Use nvim_exec_lua() instead.

View File

@@ -586,8 +586,8 @@ Array string_to_array(const String input, bool crlf)
/// @param buffer Buffer handle for a specific buffer, or 0 for the current
/// buffer, or -1 to signify global behavior ("all buffers")
/// @param is_unmap When true, removes the mapping that matches {lhs}.
void modify_keymap(Buffer buffer, bool is_unmap, String mode, String lhs, String rhs,
Dict(keymap) *opts, Error *err)
void modify_keymap(uint64_t channel_id, Buffer buffer, bool is_unmap, String mode, String lhs,
String rhs, Dict(keymap) *opts, Error *err)
{
LuaRef lua_funcref = LUA_NOREF;
bool global = (buffer == -1);
@@ -600,6 +600,8 @@ void modify_keymap(Buffer buffer, bool is_unmap, String mode, String lhs, String
return;
}
const sctx_T save_current_sctx = api_set_sctx(channel_id);
if (opts != NULL && opts->callback.type == kObjectTypeLuaRef) {
lua_funcref = opts->callback.data.luaref;
opts->callback.data.luaref = LUA_NOREF;
@@ -711,6 +713,7 @@ void modify_keymap(Buffer buffer, bool is_unmap, String mode, String lhs, String
parsed_args.rhs_lua = LUA_NOREF; // don't clear ref on success
fail_and_free:
current_sctx = save_current_sctx;
NLUA_CLEAR_REF(parsed_args.rhs_lua);
xfree(parsed_args.rhs);
xfree(parsed_args.orig_rhs);
@@ -1623,3 +1626,20 @@ int find_sid(uint64_t channel_id)
return SID_API_CLIENT;
}
}
/// Sets sctx for API calls.
///
/// @param channel_id api clients id. Used to determine if it's a internal
/// call or a rpc call.
/// @return returns previous value of current_sctx. To be used
/// to be used for restoring sctx to previous state.
sctx_T api_set_sctx(uint64_t channel_id)
{
sctx_T old_current_sctx = current_sctx;
if (channel_id != VIML_INTERNAL_CALL) {
current_sctx.sc_sid =
channel_id == LUA_INTERNAL_CALL ? SID_LUA : SID_API_CLIENT;
current_sctx.sc_lnum = 0;
}
return old_current_sctx;
}

View File

@@ -1586,6 +1586,7 @@ ArrayOf(Dictionary) nvim_get_keymap(uint64_t channel_id, String mode)
/// nmap <nowait> <Space><NL> <Nop>
/// </pre>
///
/// @param channel_id
/// @param mode Mode short-name (map command prefix: "n", "i", "v", "x", …)
/// or "!" for |:map!|, or empty string for |:map|.
/// @param lhs Left-hand-side |{lhs}| of the mapping.
@@ -1597,10 +1598,11 @@ ArrayOf(Dictionary) nvim_get_keymap(uint64_t channel_id, String mode)
/// a Lua function to call when the mapping is executed.
/// Values are Booleans. Unknown key is an error.
/// @param[out] err Error details, if any.
void nvim_set_keymap(String mode, String lhs, String rhs, Dict(keymap) *opts, Error *err)
void nvim_set_keymap(uint64_t channel_id, String mode, String lhs, String rhs, Dict(keymap) *opts,
Error *err)
FUNC_API_SINCE(6)
{
modify_keymap(-1, false, mode, lhs, rhs, opts, err);
modify_keymap(channel_id, -1, false, mode, lhs, rhs, opts, err);
}
/// Unmaps a global |mapping| for the given mode.
@@ -1608,10 +1610,10 @@ void nvim_set_keymap(String mode, String lhs, String rhs, Dict(keymap) *opts, Er
/// To unmap a buffer-local mapping, use |nvim_buf_del_keymap()|.
///
/// @see |nvim_set_keymap()|
void nvim_del_keymap(String mode, String lhs, Error *err)
void nvim_del_keymap(uint64_t channel_id, String mode, String lhs, Error *err)
FUNC_API_SINCE(6)
{
nvim_buf_del_keymap(-1, mode, lhs, err);
nvim_buf_del_keymap(channel_id, -1, mode, lhs, err);
}
/// Gets a map of global (non-buffer-local) Ex commands.

View File

@@ -37,7 +37,7 @@
/// @param[out] err Error details (Vim error), if any
/// @return Output (non-error, non-shell |:!|) if `output` is true,
/// else empty string.
String nvim_exec(String src, Boolean output, Error *err)
String nvim_exec(uint64_t channel_id, String src, Boolean output, Error *err)
FUNC_API_SINCE(7)
{
const int save_msg_silent = msg_silent;
@@ -52,11 +52,16 @@ String nvim_exec(String src, Boolean output, Error *err)
if (output) {
msg_silent++;
}
const sctx_T save_current_sctx = api_set_sctx(channel_id);
do_source_str(src.data, "nvim_exec()");
if (output) {
capture_ga = save_capture_ga;
msg_silent = save_msg_silent;
}
current_sctx = save_current_sctx;
try_end(err);
if (ERROR_SET(err)) {

View File

@@ -1082,6 +1082,7 @@ int autocmd_register(int64_t id, event_T event, char_u *pat, int patlen, int gro
ac->exec = aucmd_exec_copy(aucmd);
ac->script_ctx = current_sctx;
ac->script_ctx.sc_lnum += sourcing_lnum;
nlua_set_sctx(&ac->script_ctx);
ac->next = NULL;
ac->once = once;
ac->nested = nested;

View File

@@ -256,7 +256,8 @@ static inline void ctx_save_funcs(Context *ctx, bool scriptonly)
size_t cmd_len = sizeof("func! ") + STRLEN(name);
char *cmd = xmalloc(cmd_len);
snprintf(cmd, cmd_len, "func! %s", name);
String func_body = nvim_exec(cstr_as_string(cmd), true, &err);
String func_body = nvim_exec(VIML_INTERNAL_CALL, cstr_as_string(cmd),
true, &err);
xfree(cmd);
if (!ERROR_SET(&err)) {
ADD(ctx->funcs, STRING_OBJ(func_body));

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

@@ -2573,6 +2573,7 @@ void ex_function(exarg_T *eap)
fp->uf_calls = 0;
fp->uf_script_ctx = current_sctx;
fp->uf_script_ctx.sc_lnum += sourcing_lnum_top;
nlua_set_sctx(&fp->uf_script_ctx);
goto ret_free;

View File

@@ -1823,7 +1823,9 @@ static int source_using_linegetter(void *cookie, LineGetter fgetline, const char
sourcing_lnum = 0;
const sctx_T save_current_sctx = current_sctx;
current_sctx.sc_sid = SID_STR;
if (current_sctx.sc_sid != SID_LUA) {
current_sctx.sc_sid = SID_STR;
}
current_sctx.sc_seq = 0;
current_sctx.sc_lnum = save_sourcing_lnum;
funccal_entry_T entry;
@@ -1904,7 +1906,6 @@ int do_source(char *fname, int check_other, int is_vimrc)
char_u *fname_exp;
char_u *firstline = NULL;
int retval = FAIL;
static int last_current_SID_seq = 0;
int save_debug_break_level = debug_break_level;
scriptitem_T *si = NULL;
proftime_T wait_start;
@@ -1952,7 +1953,7 @@ int do_source(char *fname, int check_other, int is_vimrc)
}
if (cookie.fp == NULL) {
if (p_verbose > 0) {
if (p_verbose > 1) {
verbose_enter();
if (sourcing_name == NULL) {
smsg(_("could not source \"%s\""), fname);
@@ -2028,37 +2029,8 @@ int do_source(char *fname, int check_other, int is_vimrc)
funccal_entry_T funccalp_entry;
save_funccal(&funccalp_entry);
// Check if this script was sourced before to find its SID.
// If it's new, generate a new SID.
// Always use a new sequence number.
const sctx_T save_current_sctx = current_sctx;
current_sctx.sc_seq = ++last_current_SID_seq;
current_sctx.sc_lnum = 0;
FileID file_id;
bool file_id_ok = os_fileid((char *)fname_exp, &file_id);
assert(script_items.ga_len >= 0);
for (current_sctx.sc_sid = script_items.ga_len; current_sctx.sc_sid > 0;
current_sctx.sc_sid--) {
si = &SCRIPT_ITEM(current_sctx.sc_sid);
// Compare dev/ino when possible, it catches symbolic links.
// Also compare file names, the inode may change when the file was edited.
bool file_id_equal = file_id_ok && si->file_id_valid
&& os_fileid_equal(&(si->file_id), &file_id);
if (si->sn_name != NULL
&& (file_id_equal || fnamecmp(si->sn_name, fname_exp) == 0)) {
break;
}
}
if (current_sctx.sc_sid == 0) {
si = new_script_item(fname_exp, &current_sctx.sc_sid);
fname_exp = vim_strsave(si->sn_name); // used for autocmd
if (file_id_ok) {
si->file_id_valid = true;
si->file_id = file_id;
} else {
si->file_id_valid = false;
}
}
si = get_current_script_id(fname_exp, &current_sctx);
if (l_do_profiling == PROF_YES) {
bool forceit = false;
@@ -2091,16 +2063,14 @@ int do_source(char *fname, int check_other, int is_vimrc)
firstline = p;
}
if (path_with_extension((const char *)fname, "lua")) {
// TODO(shadmansaleh): Properly handle :verbose for lua
// For now change currennt_sctx before sourcing lua files
// So verbose doesn't say everything was done in line 1 since we don't know
if (path_with_extension((const char *)fname_exp, "lua")) {
const sctx_T current_sctx_backup = current_sctx;
const linenr_T sourcing_lnum_backup = sourcing_lnum;
current_sctx.sc_sid = SID_LUA;
current_sctx.sc_lnum = 0;
sourcing_lnum = 0;
// Source the file as lua
nlua_exec_file((const char *)fname);
nlua_exec_file((const char *)fname_exp);
current_sctx = current_sctx_backup;
sourcing_lnum = sourcing_lnum_backup;
} else {
@@ -2173,6 +2143,52 @@ theend:
}
/// Check if fname was sourced before to finds its SID.
/// If it's new, generate a new SID.
/// @param[in] fname file path of script
/// @param[out] ret_sctx sctx of this script
scriptitem_T *get_current_script_id(char_u *fname, sctx_T *ret_sctx)
{
static int last_current_SID_seq = 0;
sctx_T script_sctx = { .sc_seq = ++last_current_SID_seq,
.sc_lnum = 0,
.sc_sid = 0 };
FileID file_id;
scriptitem_T *si = NULL;
bool file_id_ok = os_fileid((char *)fname, &file_id);
assert(script_items.ga_len >= 0);
for (script_sctx.sc_sid = script_items.ga_len; script_sctx.sc_sid > 0;
script_sctx.sc_sid--) {
si = &SCRIPT_ITEM(script_sctx.sc_sid);
// Compare dev/ino when possible, it catches symbolic links.
// Also compare file names, the inode may change when the file was edited.
bool file_id_equal = file_id_ok && si->file_id_valid
&& os_fileid_equal(&(si->file_id), &file_id);
if (si->sn_name != NULL
&& (file_id_equal || fnamecmp(si->sn_name, fname) == 0)) {
break;
}
}
if (script_sctx.sc_sid == 0) {
si = new_script_item(vim_strsave(fname), &script_sctx.sc_sid);
if (file_id_ok) {
si->file_id_valid = true;
si->file_id = file_id;
} else {
si->file_id_valid = false;
}
}
if (ret_sctx != NULL) {
*ret_sctx = script_sctx;
}
return si;
}
/// ":scriptnames"
void ex_scriptnames(exarg_T *eap)
{

View File

@@ -5277,6 +5277,7 @@ int uc_add_command(char_u *name, size_t name_len, char_u *rep, uint32_t argt, lo
cmd->uc_compl = compl;
cmd->uc_script_ctx = current_sctx;
cmd->uc_script_ctx.sc_lnum += sourcing_lnum;
nlua_set_sctx(&cmd->uc_script_ctx);
cmd->uc_compl_arg = compl_arg;
cmd->uc_compl_luaref = compl_luaref;
cmd->uc_addr_type = addr_type;

View File

@@ -3086,6 +3086,7 @@ int buf_do_map(int maptype, MapArguments *args, int mode, bool is_abbrev, buf_T
mp->m_expr = args->expr;
mp->m_script_ctx = current_sctx;
mp->m_script_ctx.sc_lnum += sourcing_lnum;
nlua_set_sctx(&mp->m_script_ctx);
if (args->desc != NULL) {
mp->m_desc = xstrdup(args->desc);
}
@@ -3166,6 +3167,7 @@ int buf_do_map(int maptype, MapArguments *args, int mode, bool is_abbrev, buf_T
mp->m_expr = args->expr;
mp->m_script_ctx = current_sctx;
mp->m_script_ctx.sc_lnum += sourcing_lnum;
nlua_set_sctx(&mp->m_script_ctx);
mp->m_desc = NULL;
if (args->desc != NULL) {
mp->m_desc = xstrdup(args->desc);

View File

@@ -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); // []
}
@@ -1811,6 +1821,58 @@ void nlua_execute_on_key(int c)
#endif
}
// 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) {
return;
}
lua_State *const lstate = global_lstate;
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 ignorelist_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;
}
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, current);
xfree(source_path);
current->sc_lnum = info->currentline;
current->sc_seq = -1;
cleanup:
xfree(info);
}
void nlua_do_ucmd(ucmd_T *cmd, exarg_T *eap)
{
lua_State *const lstate = global_lstate;

View File

@@ -43,6 +43,9 @@ assert(vim.inspect)
vim.filetype = package.loaded['vim.filetype']
assert(vim.filetype)
vim.keymap = package.loaded['vim.keymap']
assert(vim.keymap)
-- These are for loading runtime modules lazily since they aren't available in
-- the nvim binary as specified in executor.c
setmetatable(vim, {
@@ -69,9 +72,6 @@ setmetatable(vim, {
elseif key == 'ui' then
t.ui = require('vim.ui')
return t.ui
elseif key == 'keymap' then
t.keymap = require('vim.keymap')
return t.keymap
end
end
})

View File

@@ -3878,6 +3878,7 @@ static void set_option_sctx_idx(int opt_idx, int opt_flags, sctx_T script_ctx)
{
int both = (opt_flags & (OPT_LOCAL | OPT_GLOBAL)) == 0;
int indir = (int)options[opt_idx].indir;
nlua_set_sctx(&script_ctx);
const LastSet last_set = {
.script_ctx = {
script_ctx.sc_sid,

View File

@@ -153,7 +153,7 @@ int do_in_path(char_u *path, char *name, int flags, DoInRuntimepathCB callback,
if (flags & DIP_ERR) {
semsg(_(e_dirnotf), basepath, name);
} else if (p_verbose > 0) {
} else if (p_verbose > 1) {
verbose_enter();
smsg(_("not found in '%s': \"%s\""), basepath, name);
verbose_leave();
@@ -286,7 +286,7 @@ int do_in_cached_path(char_u *name, int flags, DoInRuntimepathCB callback, void
if (!did_one && name != NULL) {
if (flags & DIP_ERR) {
semsg(_(e_dirnotf), "runtime path", name);
} else if (p_verbose > 0) {
} else if (p_verbose > 1) {
verbose_enter();
smsg(_("not found in runtime path: \"%s\""), name);
verbose_leave();

View File

@@ -831,7 +831,7 @@ static int shada_read_file(const char *const file, const int flags)
ShaDaReadDef sd_reader;
const int of_ret = open_shada_file_for_reading(fname, &sd_reader);
if (p_verbose > 0) {
if (p_verbose > 1) {
verbose_enter();
smsg(_("Reading ShaDa file \"%s\"%s%s%s%s"),
fname,
@@ -3036,7 +3036,7 @@ shada_write_file_nomerge: {}
return FAIL;
}
if (p_verbose > 0) {
if (p_verbose > 1) {
verbose_enter();
smsg(_("Writing ShaDa file \"%s\""), fname);
verbose_leave();

View File

@@ -27,6 +27,7 @@
#include "nvim/highlight.h"
#include "nvim/indent_c.h"
#include "nvim/keymap.h"
#include "nvim/lua/executor.h"
#include "nvim/macros.h"
#include "nvim/mbyte.h"
#include "nvim/memline.h"
@@ -6919,6 +6920,7 @@ void do_highlight(const char *line, const bool forceit, const bool init)
hlgroup->sg_deflink = to_id;
hlgroup->sg_deflink_sctx = current_sctx;
hlgroup->sg_deflink_sctx.sc_lnum += sourcing_lnum;
nlua_set_sctx(&hlgroup->sg_deflink_sctx);
}
}
@@ -6939,6 +6941,7 @@ void do_highlight(const char *line, const bool forceit, const bool init)
hlgroup->sg_link = to_id;
hlgroup->sg_script_ctx = current_sctx;
hlgroup->sg_script_ctx.sc_lnum += sourcing_lnum;
nlua_set_sctx(&hlgroup->sg_script_ctx);
hlgroup->sg_cleared = false;
redraw_all_later(SOME_VALID);
@@ -7319,6 +7322,7 @@ void do_highlight(const char *line, const bool forceit, const bool init)
}
HL_TABLE()[idx].sg_script_ctx = current_sctx;
HL_TABLE()[idx].sg_script_ctx.sc_lnum += sourcing_lnum;
nlua_set_sctx(&HL_TABLE()[idx].sg_script_ctx);
}
xfree(key);
xfree(arg);