diff options
Diffstat (limited to 'src/nvim/lua')
-rw-r--r-- | src/nvim/lua/converter.c | 16 | ||||
-rw-r--r-- | src/nvim/lua/executor.c | 70 | ||||
-rw-r--r-- | src/nvim/lua/stdlib.c | 49 | ||||
-rw-r--r-- | src/nvim/lua/treesitter.c | 3 |
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"; |