aboutsummaryrefslogtreecommitdiff
path: root/src/nvim/lua
diff options
context:
space:
mode:
Diffstat (limited to 'src/nvim/lua')
-rw-r--r--src/nvim/lua/converter.c16
-rw-r--r--src/nvim/lua/executor.c70
-rw-r--r--src/nvim/lua/stdlib.c49
-rw-r--r--src/nvim/lua/treesitter.c3
4 files changed, 103 insertions, 35 deletions
diff --git a/src/nvim/lua/converter.c b/src/nvim/lua/converter.c
index ca3c4f604a..9f2372f831 100644
--- a/src/nvim/lua/converter.c
+++ b/src/nvim/lua/converter.c
@@ -62,7 +62,7 @@ static LuaTableProps nlua_traverse_table(lua_State *const lstate)
LuaTableProps ret;
memset(&ret, 0, sizeof(ret));
if (!lua_checkstack(lstate, lua_gettop(lstate) + 3)) {
- emsgf(_("E1502: Lua failed to grow stack to %i"), lua_gettop(lstate) + 2);
+ semsg(_("E1502: Lua failed to grow stack to %i"), lua_gettop(lstate) + 2);
ret.type = kObjectTypeNil;
return ret;
}
@@ -198,7 +198,7 @@ bool nlua_pop_typval(lua_State *lstate, typval_T *ret_tv)
kvi_push(stack, ((TVPopStackItem) { ret_tv, false, false, 0 }));
while (ret && kv_size(stack)) {
if (!lua_checkstack(lstate, lua_gettop(lstate) + 3)) {
- emsgf(_("E1502: Lua failed to grow stack to %i"), lua_gettop(lstate) + 3);
+ semsg(_("E1502: Lua failed to grow stack to %i"), lua_gettop(lstate) + 3);
ret = false;
break;
}
@@ -376,7 +376,7 @@ bool nlua_pop_typval(lua_State *lstate, typval_T *ret_tv)
cur.tv->vval.v_float = (float_T)table_props.val;
break;
case kObjectTypeNil:
- EMSG(_("E5100: Cannot convert given lua table: table "
+ emsg(_("E5100: Cannot convert given lua table: table "
"should either have a sequence of positive integer keys "
"or contain only string keys"));
ret = false;
@@ -408,13 +408,13 @@ nlua_pop_typval_table_processing_end:
cur.tv->v_type = VAR_SPECIAL;
cur.tv->vval.v_special = kSpecialVarNull;
} else {
- EMSG(_("E5101: Cannot convert given lua type"));
+ emsg(_("E5101: Cannot convert given lua type"));
ret = false;
}
break;
}
default:
- EMSG(_("E5101: Cannot convert given lua type"));
+ emsg(_("E5101: Cannot convert given lua type"));
ret = false;
break;
}
@@ -503,7 +503,7 @@ static bool typval_conv_special = false;
#define TYPVAL_ENCODE_CONV_LIST_START(tv, len) \
do { \
if (!lua_checkstack(lstate, lua_gettop(lstate) + 3)) { \
- emsgf(_("E5102: Lua failed to grow stack to %i"), \
+ semsg(_("E5102: Lua failed to grow stack to %i"), \
lua_gettop(lstate) + 3); \
return false; \
} \
@@ -526,7 +526,7 @@ static bool typval_conv_special = false;
#define TYPVAL_ENCODE_CONV_DICT_START(tv, dict, len) \
do { \
if (!lua_checkstack(lstate, lua_gettop(lstate) + 3)) { \
- emsgf(_("E5102: Lua failed to grow stack to %i"), \
+ semsg(_("E5102: Lua failed to grow stack to %i"), \
lua_gettop(lstate) + 3); \
return false; \
} \
@@ -614,7 +614,7 @@ bool nlua_push_typval(lua_State *lstate, typval_T *const tv, bool special)
const int initial_size = lua_gettop(lstate);
if (!lua_checkstack(lstate, initial_size + 2)) {
- emsgf(_("E1502: Lua failed to grow stack to %i"), initial_size + 4);
+ semsg(_("E1502: Lua failed to grow stack to %i"), initial_size + 4);
return false;
}
if (encode_vim_to_lua(lstate, tv, "nlua_push_typval argument") == FAIL) {
diff --git a/src/nvim/lua/executor.c b/src/nvim/lua/executor.c
index 05c33d7918..b27b1ae7a8 100644
--- a/src/nvim/lua/executor.c
+++ b/src/nvim/lua/executor.c
@@ -80,11 +80,32 @@ static void nlua_error(lua_State *const lstate, const char *const msg)
const char *const str = lua_tolstring(lstate, -1, &len);
msg_ext_set_kind("lua_error");
- emsgf_multiline(msg, (int)len, str);
+ semsg_multiline(msg, (int)len, str);
lua_pop(lstate, 1);
}
+/// Like lua_pcall, but use debug.traceback as errfunc.
+///
+/// @param lstate Lua interpreter state
+/// @param[in] nargs Number of arguments expected by the function being called.
+/// @param[in] nresults Number of results the function returns.
+static int nlua_pcall(lua_State *lstate, int nargs, int nresults)
+{
+ lua_getglobal(lstate, "debug");
+ lua_getfield(lstate, -1, "traceback");
+ lua_remove(lstate, -2);
+ lua_insert(lstate, -2 - nargs);
+ int status = lua_pcall(lstate, nargs, nresults, -2 - nargs);
+ if (status) {
+ lua_remove(lstate, -2);
+ } else {
+ lua_remove(lstate, -1 - nresults);
+ }
+ return status;
+}
+
+
/// Gets the version of the current Nvim build.
///
/// @param lstate Lua interpreter state.
@@ -101,7 +122,7 @@ static void nlua_luv_error_event(void **argv)
{
char *error = (char *)argv[0];
msg_ext_set_kind("lua_error");
- emsgf_multiline("Error executing luv callback:\n%s", error);
+ semsg_multiline("Error executing luv callback:\n%s", error);
xfree(error);
}
@@ -115,7 +136,7 @@ static int nlua_luv_cfpcall(lua_State *lstate, int nargs, int nresult, int flags
in_fast_callback++;
int top = lua_gettop(lstate);
- int status = lua_pcall(lstate, nargs, nresult, 0);
+ int status = nlua_pcall(lstate, nargs, nresult);
if (status) {
if (status == LUA_ERRMEM && !(flags & LUVF_CALLBACK_NOEXIT)) {
// consider out of memory errors unrecoverable, just like xmalloc()
@@ -146,7 +167,7 @@ static void nlua_schedule_event(void **argv)
lua_State *const lstate = global_lstate;
nlua_pushref(lstate, cb);
nlua_unref(lstate, cb);
- if (lua_pcall(lstate, 0, 0, 0)) {
+ if (nlua_pcall(lstate, 0, 0)) {
nlua_error(lstate, _("Error executing vim.schedule lua callback: %.*s"));
}
}
@@ -183,7 +204,7 @@ static void dummy_timer_close_cb(TimeWatcher *tw, void *data)
static bool nlua_wait_condition(lua_State *lstate, int *status, bool *callback_result)
{
lua_pushvalue(lstate, 2);
- *status = lua_pcall(lstate, 0, 1, 0);
+ *status = nlua_pcall(lstate, 0, 1);
if (*status) {
return true; // break on error, but keep error on stack
}
@@ -385,7 +406,7 @@ static int nlua_state_init(lua_State *const lstate) FUNC_ATTR_NONNULL_ALL
{
const char *code = (char *)&shared_module[0];
if (luaL_loadbuffer(lstate, code, strlen(code), "@vim/shared.lua")
- || lua_pcall(lstate, 0, 0, 0)) {
+ || nlua_pcall(lstate, 0, 0)) {
nlua_error(lstate, _("E5106: Error while creating shared module: %.*s"));
return 1;
}
@@ -397,7 +418,7 @@ static int nlua_state_init(lua_State *const lstate) FUNC_ATTR_NONNULL_ALL
const char *code = (char *)&inspect_module[0];
if (luaL_loadbuffer(lstate, code, strlen(code), "@vim/inspect.lua")
- || lua_pcall(lstate, 0, 1, 0)) {
+ || nlua_pcall(lstate, 0, 1)) {
nlua_error(lstate, _("E5106: Error while creating inspect module: %.*s"));
return 1;
}
@@ -406,7 +427,7 @@ static int nlua_state_init(lua_State *const lstate) FUNC_ATTR_NONNULL_ALL
code = (char *)&lua_F_module[0];
if (luaL_loadbuffer(lstate, code, strlen(code), "@vim/F.lua")
- || lua_pcall(lstate, 0, 1, 0)) {
+ || nlua_pcall(lstate, 0, 1)) {
nlua_error(lstate, _("E5106: Error while creating vim.F module: %.*s"));
return 1;
}
@@ -419,7 +440,7 @@ static int nlua_state_init(lua_State *const lstate) FUNC_ATTR_NONNULL_ALL
{
const char *code = (char *)&vim_module[0];
if (luaL_loadbuffer(lstate, code, strlen(code), "@vim.lua")
- || lua_pcall(lstate, 0, 0, 0)) {
+ || nlua_pcall(lstate, 0, 0)) {
nlua_error(lstate, _("E5106: Error while creating vim module: %.*s"));
return 1;
}
@@ -431,7 +452,7 @@ static int nlua_state_init(lua_State *const lstate) FUNC_ATTR_NONNULL_ALL
const char *code = (char *)&lua_meta_module[0];
if (luaL_loadbuffer(lstate, code, strlen(code), "@vim/_meta.lua")
- || lua_pcall(lstate, 0, 1, 0)) {
+ || nlua_pcall(lstate, 0, 1)) {
nlua_error(lstate, _("E5106: Error while creating vim._meta module: %.*s"));
return 1;
}
@@ -458,7 +479,7 @@ void nlua_init(void)
lua_State *lstate = luaL_newstate();
if (lstate == NULL) {
- EMSG(_("E970: Failed to initialize lua interpreter"));
+ emsg(_("E970: Failed to initialize lua interpreter"));
preserve_exit();
}
luaL_openlibs(lstate);
@@ -519,10 +540,10 @@ static void nlua_print_event(void **argv)
}
break;
}
- msg((char_u *)str + start);
+ msg(str + start);
}
if (len && str[len - 1] == NUL) { // Last was newline
- msg((char_u *)"");
+ msg("");
}
xfree(str);
}
@@ -549,6 +570,7 @@ static int nlua_print(lua_State *const lstate)
for (; curargidx <= nargs; curargidx++) {
lua_pushvalue(lstate, -1); // tostring
lua_pushvalue(lstate, curargidx); // arg
+ // Do not use nlua_pcall here to avoid duplicate stack trace information
if (lua_pcall(lstate, 1, 1, 0)) {
errmsg = lua_tolstring(lstate, -1, &errmsg_len);
goto nlua_print_error;
@@ -616,7 +638,7 @@ static int nlua_debug(lua_State *lstate)
if (luaL_loadbuffer(lstate, (const char *)input.vval.v_string,
STRLEN(input.vval.v_string), "=(debug command)")) {
nlua_error(lstate, _("E5115: Error while loading debug string: %.*s"));
- } else if (lua_pcall(lstate, 0, 0, 0)) {
+ } else if (nlua_pcall(lstate, 0, 0)) {
nlua_error(lstate, _("E5116: Error while calling debug string: %.*s"));
}
tv_clear(&input);
@@ -909,7 +931,7 @@ static void nlua_typval_exec(const char *lcmd, size_t lcmd_len, const char *name
PUSH_ALL_TYPVALS(lstate, args, argcount, special);
- if (lua_pcall(lstate, argcount, ret_tv ? 1 : 0, 0)) {
+ if (nlua_pcall(lstate, argcount, ret_tv ? 1 : 0)) {
nlua_error(lstate, _("E5108: Error executing lua %.*s"));
return;
}
@@ -964,7 +986,7 @@ int typval_exec_lua_callable(lua_State *lstate, LuaCallable lua_cb, int argcount
PUSH_ALL_TYPVALS(lstate, argvars, argcount, false);
- if (lua_pcall(lstate, argcount, 1, 0)) {
+ if (nlua_pcall(lstate, argcount, 1)) {
nlua_print(lstate);
return ERROR_OTHER;
}
@@ -999,7 +1021,7 @@ Object nlua_exec(const String str, const Array args, Error *err)
nlua_push_Object(lstate, args.items[i], false);
}
- if (lua_pcall(lstate, (int)args.size, 1, 0)) {
+ if (nlua_pcall(lstate, (int)args.size, 1)) {
size_t len;
const char *errstr = lua_tolstring(lstate, -1, &len);
api_set_error(err, kErrorTypeException,
@@ -1032,7 +1054,7 @@ Object nlua_call_ref(LuaRef ref, const char *name, Array args, bool retval, Erro
nlua_push_Object(lstate, args.items[i], false);
}
- if (lua_pcall(lstate, nargs, retval ? 1 : 0, 0)) {
+ if (nlua_pcall(lstate, nargs, retval ? 1 : 0)) {
// if err is passed, the caller will deal with the error.
if (err) {
size_t len;
@@ -1091,7 +1113,7 @@ void ex_luado(exarg_T *const eap)
FUNC_ATTR_NONNULL_ALL
{
if (u_save(eap->line1 - 1, eap->line2 + 1) == FAIL) {
- EMSG(_("cannot save undo information"));
+ emsg(_("cannot save undo information"));
return;
}
const char *const cmd = (const char *)eap->arg;
@@ -1126,7 +1148,7 @@ void ex_luado(exarg_T *const eap)
if (lcmd_len >= IOSIZE) {
xfree(lcmd);
}
- if (lua_pcall(lstate, 0, 1, 0)) {
+ if (nlua_pcall(lstate, 0, 1)) {
nlua_error(lstate, _("E5110: Error executing lua: %.*s"));
return;
}
@@ -1138,7 +1160,7 @@ void ex_luado(exarg_T *const eap)
const char *old_line = (const char *)ml_get_buf(curbuf, l, false);
lua_pushstring(lstate, old_line);
lua_pushnumber(lstate, (lua_Number)l);
- if (lua_pcall(lstate, 2, 1, 0)) {
+ if (nlua_pcall(lstate, 2, 1)) {
nlua_error(lstate, _("E5111: Error calling lua: %.*s"));
break;
}
@@ -1189,7 +1211,7 @@ bool nlua_exec_file(const char *path)
return false;
}
- if (lua_pcall(lstate, 0, 0, 0)) {
+ if (nlua_pcall(lstate, 0, 0)) {
nlua_error(lstate, _("E5113: Error while calling lua chunk: %.*s"));
return false;
}
@@ -1241,7 +1263,7 @@ int nlua_expand_pat(expand_T *xp, char_u *pat, int *num_results, char_u ***resul
// [ vim, vim._on_key, buf ]
lua_pushlstring(lstate, (const char *)pat, STRLEN(pat));
- if (lua_pcall(lstate, 1, 2, 0) != 0) {
+ if (nlua_pcall(lstate, 1, 2) != 0) {
nlua_error(lstate,
_("Error executing vim._expand_pat: %.*s"));
return FAIL;
@@ -1394,7 +1416,7 @@ void nlua_execute_on_key(int c)
// [ vim, vim._on_key, buf ]
lua_pushlstring(lstate, (const char *)buf, buf_len);
- if (lua_pcall(lstate, 1, 0, 0)) {
+ if (nlua_pcall(lstate, 1, 0)) {
nlua_error(lstate,
_("Error executing vim.on_key Lua callback: %.*s"));
}
diff --git a/src/nvim/lua/stdlib.c b/src/nvim/lua/stdlib.c
index 2d969357b4..db79e9e7e9 100644
--- a/src/nvim/lua/stdlib.c
+++ b/src/nvim/lua/stdlib.c
@@ -216,6 +216,45 @@ static int nlua_str_utf_pos(lua_State *const lstate) FUNC_ATTR_NONNULL_ALL
return 1;
}
+/// Return the offset from the 1-indexed byte position to the first byte of the
+/// current character.
+///
+/// Expects a string and an int.
+///
+/// Returns the byte offset to the first byte of the current character
+/// pointed into by the offset.
+static int nlua_str_utf_start(lua_State *const lstate) FUNC_ATTR_NONNULL_ALL
+{
+ size_t s1_len;
+ const char *s1 = luaL_checklstring(lstate, 1, &s1_len);
+ long offset = luaL_checkinteger(lstate, 2);
+ if (offset < 0 || offset > (intptr_t)s1_len) {
+ return luaL_error(lstate, "index out of range");
+ }
+ int tail_offset = mb_head_off((char_u *)s1, (char_u *)s1 + (char_u)offset - 1);
+ lua_pushinteger(lstate, tail_offset);
+ return 1;
+}
+
+/// Return the offset from the 1-indexed byte position to the last
+/// byte of the current character.
+///
+/// Expects a string and an int.
+///
+/// Returns the byte offset to the last byte of the current character
+/// pointed into by the offset.
+static int nlua_str_utf_end(lua_State *const lstate) FUNC_ATTR_NONNULL_ALL
+{
+ size_t s1_len;
+ const char *s1 = luaL_checklstring(lstate, 1, &s1_len);
+ long offset = luaL_checkinteger(lstate, 2);
+ if (offset < 0 || offset > (intptr_t)s1_len) {
+ return luaL_error(lstate, "index out of range");
+ }
+ int tail_offset = mb_tail_off((char_u *)s1, (char_u *)s1 + (char_u)offset - 1);
+ lua_pushinteger(lstate, tail_offset);
+ return 1;
+}
/// convert UTF-32 or UTF-16 indices to byte index.
///
@@ -272,7 +311,8 @@ int nlua_regex(lua_State *lstate)
return 1;
}
-static dict_T *nlua_get_var_scope(lua_State *lstate) {
+static dict_T *nlua_get_var_scope(lua_State *lstate)
+{
const char *scope = luaL_checkstring(lstate, 1);
handle_T handle = (handle_T)luaL_checkinteger(lstate, 2);
dict_T *dict = NULL;
@@ -424,7 +464,6 @@ static int nlua_stricmp(lua_State *const lstate) FUNC_ATTR_NONNULL_ALL
}
-
void nlua_state_add_stdlib(lua_State *const lstate)
{
// stricmp
@@ -439,6 +478,12 @@ void nlua_state_add_stdlib(lua_State *const lstate)
// str_utf_pos
lua_pushcfunction(lstate, &nlua_str_utf_pos);
lua_setfield(lstate, -2, "str_utf_pos");
+ // str_utf_start
+ lua_pushcfunction(lstate, &nlua_str_utf_start);
+ lua_setfield(lstate, -2, "str_utf_start");
+ // str_utf_end
+ lua_pushcfunction(lstate, &nlua_str_utf_end);
+ lua_setfield(lstate, -2, "str_utf_end");
// regex
lua_pushcfunction(lstate, &nlua_regex);
lua_setfield(lstate, -2, "regex");
diff --git a/src/nvim/lua/treesitter.c b/src/nvim/lua/treesitter.c
index 02bd612149..60a000843f 100644
--- a/src/nvim/lua/treesitter.c
+++ b/src/nvim/lua/treesitter.c
@@ -1195,7 +1195,8 @@ int tslua_parse_query(lua_State *L)
}
-static const char *query_err_string(TSQueryError err) {
+static const char *query_err_string(TSQueryError err)
+{
switch (err) {
case TSQueryErrorSyntax:
return "invalid syntax";