mirror of
https://github.com/neovim/neovim.git
synced 2025-09-30 15:08:35 +00:00
feat(lua): print source locations of lua callbacks (#19597)
Co-authored-by: ii14 <ii14@users.noreply.github.com>
This commit is contained in:
@@ -944,7 +944,7 @@ void create_user_command(String name, Object command, Dict(user_command) *opts,
|
|||||||
cmd_addr_T addr_type_arg = ADDR_NONE;
|
cmd_addr_T addr_type_arg = ADDR_NONE;
|
||||||
int compl = EXPAND_NOTHING;
|
int compl = EXPAND_NOTHING;
|
||||||
char *compl_arg = NULL;
|
char *compl_arg = NULL;
|
||||||
char *rep = NULL;
|
const char *rep = NULL;
|
||||||
LuaRef luaref = LUA_NOREF;
|
LuaRef luaref = LUA_NOREF;
|
||||||
LuaRef compl_luaref = LUA_NOREF;
|
LuaRef compl_luaref = LUA_NOREF;
|
||||||
LuaRef preview_luaref = LUA_NOREF;
|
LuaRef preview_luaref = LUA_NOREF;
|
||||||
@@ -1116,8 +1116,7 @@ void create_user_command(String name, Object command, Dict(user_command) *opts,
|
|||||||
if (opts->desc.type == kObjectTypeString) {
|
if (opts->desc.type == kObjectTypeString) {
|
||||||
rep = opts->desc.data.string.data;
|
rep = opts->desc.data.string.data;
|
||||||
} else {
|
} else {
|
||||||
snprintf((char *)IObuff, IOSIZE, "<Lua function %d>", luaref);
|
rep = "";
|
||||||
rep = (char *)IObuff;
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case kObjectTypeString:
|
case kObjectTypeString:
|
||||||
|
@@ -196,9 +196,16 @@ static void aupat_show(AutoPat *ap, event_T event, int previous_group)
|
|||||||
if (ac->desc != NULL) {
|
if (ac->desc != NULL) {
|
||||||
size_t msglen = 100;
|
size_t msglen = 100;
|
||||||
char *msg = (char *)xmallocz(msglen);
|
char *msg = (char *)xmallocz(msglen);
|
||||||
snprintf(msg, msglen, "%s [%s]", exec_to_string, ac->desc);
|
if (ac->exec.type == CALLABLE_CB) {
|
||||||
|
msg_puts_attr(exec_to_string, HL_ATTR(HLF_8));
|
||||||
|
snprintf(msg, msglen, " [%s]", ac->desc);
|
||||||
|
} else {
|
||||||
|
snprintf(msg, msglen, "%s [%s]", exec_to_string, ac->desc);
|
||||||
|
}
|
||||||
msg_outtrans(msg);
|
msg_outtrans(msg);
|
||||||
XFREE_CLEAR(msg);
|
XFREE_CLEAR(msg);
|
||||||
|
} else if (ac->exec.type == CALLABLE_CB) {
|
||||||
|
msg_puts_attr(exec_to_string, HL_ATTR(HLF_8));
|
||||||
} else {
|
} else {
|
||||||
msg_outtrans(exec_to_string);
|
msg_outtrans(exec_to_string);
|
||||||
}
|
}
|
||||||
|
@@ -1657,13 +1657,14 @@ void callback_copy(Callback *dest, Callback *src)
|
|||||||
/// Generate a string description of a callback
|
/// Generate a string description of a callback
|
||||||
char *callback_to_string(Callback *cb)
|
char *callback_to_string(Callback *cb)
|
||||||
{
|
{
|
||||||
size_t msglen = 100;
|
if (cb->type == kCallbackLua) {
|
||||||
|
return nlua_funcref_str(cb->data.luaref);
|
||||||
|
}
|
||||||
|
|
||||||
|
const size_t msglen = 100;
|
||||||
char *msg = (char *)xmallocz(msglen);
|
char *msg = (char *)xmallocz(msglen);
|
||||||
|
|
||||||
switch (cb->type) {
|
switch (cb->type) {
|
||||||
case kCallbackLua:
|
|
||||||
snprintf(msg, msglen, "<lua: %d>", cb->data.luaref);
|
|
||||||
break;
|
|
||||||
case kCallbackFuncref:
|
case kCallbackFuncref:
|
||||||
// TODO(tjdevries): Is this enough space for this?
|
// TODO(tjdevries): Is this enough space for this?
|
||||||
snprintf(msg, msglen, "<vim function: %s>", cb->data.funcref);
|
snprintf(msg, msglen, "<vim function: %s>", cb->data.funcref);
|
||||||
@@ -1672,7 +1673,7 @@ char *callback_to_string(Callback *cb)
|
|||||||
snprintf(msg, msglen, "<vim partial: %s>", cb->data.partial->pt_name);
|
snprintf(msg, msglen, "<vim partial: %s>", cb->data.partial->pt_name);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
snprintf(msg, msglen, "%s", "");
|
*msg = '\0';
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
return msg;
|
return msg;
|
||||||
|
@@ -5440,7 +5440,7 @@ char *uc_validate_name(char *name)
|
|||||||
/// This function takes ownership of compl_arg, compl_luaref, and luaref.
|
/// This function takes ownership of compl_arg, compl_luaref, and luaref.
|
||||||
///
|
///
|
||||||
/// @return OK if the command is created, FAIL otherwise.
|
/// @return OK if the command is created, FAIL otherwise.
|
||||||
int uc_add_command(char *name, size_t name_len, char *rep, uint32_t argt, long def, int flags,
|
int uc_add_command(char *name, size_t name_len, const char *rep, uint32_t argt, long def, int flags,
|
||||||
int compl, char *compl_arg, LuaRef compl_luaref, LuaRef preview_luaref,
|
int compl, char *compl_arg, LuaRef compl_luaref, LuaRef preview_luaref,
|
||||||
cmd_addr_T addr_type, LuaRef luaref, bool force)
|
cmd_addr_T addr_type, LuaRef luaref, bool force)
|
||||||
FUNC_ATTR_NONNULL_ARG(1, 3)
|
FUNC_ATTR_NONNULL_ARG(1, 3)
|
||||||
@@ -5762,6 +5762,16 @@ static void uc_list(char *name, size_t name_len)
|
|||||||
IObuff[len] = '\0';
|
IObuff[len] = '\0';
|
||||||
msg_outtrans((char *)IObuff);
|
msg_outtrans((char *)IObuff);
|
||||||
|
|
||||||
|
if (cmd->uc_luaref != LUA_NOREF) {
|
||||||
|
char *fn = nlua_funcref_str(cmd->uc_luaref);
|
||||||
|
msg_puts_attr(fn, HL_ATTR(HLF_8));
|
||||||
|
xfree(fn);
|
||||||
|
// put the description on a new line
|
||||||
|
if (*cmd->uc_rep != NUL) {
|
||||||
|
msg_puts("\n ");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
msg_outtrans_special(cmd->uc_rep, false,
|
msg_outtrans_special(cmd->uc_rep, false,
|
||||||
name_len == 0 ? Columns - 47 : 0);
|
name_len == 0 ? Columns - 47 : 0);
|
||||||
if (p_verbose > 0) {
|
if (p_verbose > 0) {
|
||||||
|
@@ -2076,3 +2076,34 @@ int nlua_do_ucmd(ucmd_T *cmd, exarg_T *eap, bool preview)
|
|||||||
|
|
||||||
return retv;
|
return retv;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// String representation of a Lua function reference
|
||||||
|
///
|
||||||
|
/// @return Allocated string
|
||||||
|
char *nlua_funcref_str(LuaRef ref)
|
||||||
|
{
|
||||||
|
lua_State *const lstate = global_lstate;
|
||||||
|
StringBuilder str = KV_INITIAL_VALUE;
|
||||||
|
kv_resize(str, 16);
|
||||||
|
|
||||||
|
if (!lua_checkstack(lstate, 1)) {
|
||||||
|
goto plain;
|
||||||
|
}
|
||||||
|
nlua_pushref(lstate, ref);
|
||||||
|
if (!lua_isfunction(lstate, -1)) {
|
||||||
|
lua_pop(lstate, 1);
|
||||||
|
goto plain;
|
||||||
|
}
|
||||||
|
|
||||||
|
lua_Debug ar;
|
||||||
|
if (lua_getinfo(lstate, ">S", &ar) && *ar.source == '@' && ar.linedefined >= 0) {
|
||||||
|
char *src = home_replace_save(NULL, ar.source + 1);
|
||||||
|
kv_printf(str, "<Lua %d: %s:%d>", ref, src, ar.linedefined);
|
||||||
|
xfree(src);
|
||||||
|
return str.items;
|
||||||
|
}
|
||||||
|
|
||||||
|
plain:
|
||||||
|
kv_printf(str, "<Lua %d>", ref);
|
||||||
|
return str.items;
|
||||||
|
}
|
||||||
|
@@ -196,9 +196,9 @@ static void showmap(mapblock_T *mp, bool local)
|
|||||||
// Use false below if we only want things like <Up> to show up as such on
|
// Use false below if we only want things like <Up> to show up as such on
|
||||||
// the rhs, and not M-x etc, true gets both -- webb
|
// the rhs, and not M-x etc, true gets both -- webb
|
||||||
if (mp->m_luaref != LUA_NOREF) {
|
if (mp->m_luaref != LUA_NOREF) {
|
||||||
char msg[100];
|
char *str = nlua_funcref_str(mp->m_luaref);
|
||||||
snprintf(msg, sizeof(msg), "<Lua function %d>", mp->m_luaref);
|
msg_puts_attr(str, HL_ATTR(HLF_8));
|
||||||
msg_puts_attr(msg, HL_ATTR(HLF_8));
|
xfree(str);
|
||||||
} else if (mp->m_str[0] == NUL) {
|
} else if (mp->m_str[0] == NUL) {
|
||||||
msg_puts_attr("<Nop>", HL_ATTR(HLF_8));
|
msg_puts_attr("<Nop>", HL_ATTR(HLF_8));
|
||||||
} else {
|
} else {
|
||||||
@@ -2110,10 +2110,7 @@ static void get_maparg(typval_T *argvars, typval_T *rettv, int exact)
|
|||||||
rettv->vval.v_string = str2special_save((char *)rhs, false, false);
|
rettv->vval.v_string = str2special_save((char *)rhs, false, false);
|
||||||
}
|
}
|
||||||
} else if (rhs_lua != LUA_NOREF) {
|
} else if (rhs_lua != LUA_NOREF) {
|
||||||
size_t msglen = 100;
|
rettv->vval.v_string = nlua_funcref_str(mp->m_luaref);
|
||||||
char *msg = (char *)xmalloc(msglen);
|
|
||||||
snprintf(msg, msglen, "<Lua function %d>", mp->m_luaref);
|
|
||||||
rettv->vval.v_string = msg;
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
tv_dict_alloc_ret(rettv);
|
tv_dict_alloc_ret(rettv);
|
||||||
|
@@ -1143,7 +1143,7 @@ size_t home_replace(const buf_T *const buf, const char *src, char *const dst, si
|
|||||||
/// Like home_replace, store the replaced string in allocated memory.
|
/// Like home_replace, store the replaced string in allocated memory.
|
||||||
/// @param buf When not NULL, check for help files
|
/// @param buf When not NULL, check for help files
|
||||||
/// @param src Input file name
|
/// @param src Input file name
|
||||||
char *home_replace_save(buf_T *buf, char *src)
|
char *home_replace_save(buf_T *buf, const char *src)
|
||||||
FUNC_ATTR_NONNULL_RET
|
FUNC_ATTR_NONNULL_RET
|
||||||
{
|
{
|
||||||
size_t len = 3; // space for "~/" and trailing NUL
|
size_t len = 3; // space for "~/" and trailing NUL
|
||||||
|
@@ -822,7 +822,7 @@ describe('nvim_set_keymap, nvim_del_keymap', function()
|
|||||||
vim.api.nvim_set_keymap ('n', 'asdf', '', {callback = function() print('jkl;') end })
|
vim.api.nvim_set_keymap ('n', 'asdf', '', {callback = function() print('jkl;') end })
|
||||||
]]
|
]]
|
||||||
assert.truthy(string.match(exec_lua[[return vim.api.nvim_exec(':nmap asdf', true)]],
|
assert.truthy(string.match(exec_lua[[return vim.api.nvim_exec(':nmap asdf', true)]],
|
||||||
"^\nn asdf <Lua function %d+>"))
|
"^\nn asdf <Lua %d+>"))
|
||||||
end)
|
end)
|
||||||
|
|
||||||
it ('mapcheck() returns lua mapping correctly', function()
|
it ('mapcheck() returns lua mapping correctly', function()
|
||||||
@@ -830,7 +830,7 @@ describe('nvim_set_keymap, nvim_del_keymap', function()
|
|||||||
vim.api.nvim_set_keymap ('n', 'asdf', '', {callback = function() print('jkl;') end })
|
vim.api.nvim_set_keymap ('n', 'asdf', '', {callback = function() print('jkl;') end })
|
||||||
]]
|
]]
|
||||||
assert.truthy(string.match(funcs.mapcheck('asdf', 'n'),
|
assert.truthy(string.match(funcs.mapcheck('asdf', 'n'),
|
||||||
"^<Lua function %d+>"))
|
"^<Lua %d+>"))
|
||||||
end)
|
end)
|
||||||
|
|
||||||
it ('maparg() returns lua mapping correctly', function()
|
it ('maparg() returns lua mapping correctly', function()
|
||||||
@@ -838,7 +838,7 @@ describe('nvim_set_keymap, nvim_del_keymap', function()
|
|||||||
vim.api.nvim_set_keymap ('n', 'asdf', '', {callback = function() print('jkl;') end })
|
vim.api.nvim_set_keymap ('n', 'asdf', '', {callback = function() print('jkl;') end })
|
||||||
]]
|
]]
|
||||||
assert.truthy(string.match(funcs.maparg('asdf', 'n'),
|
assert.truthy(string.match(funcs.maparg('asdf', 'n'),
|
||||||
"^<Lua function %d+>"))
|
"^<Lua %d+>"))
|
||||||
local mapargs = funcs.maparg('asdf', 'n', false, true)
|
local mapargs = funcs.maparg('asdf', 'n', false, true)
|
||||||
assert(type(mapargs.callback) == 'number', 'callback is not luaref number')
|
assert(type(mapargs.callback) == 'number', 'callback is not luaref number')
|
||||||
mapargs.callback = nil
|
mapargs.callback = nil
|
||||||
|
Reference in New Issue
Block a user