diff options
Diffstat (limited to 'src/nvim/lua')
-rw-r--r-- | src/nvim/lua/converter.c | 2 | ||||
-rw-r--r-- | src/nvim/lua/converter.h | 2 | ||||
-rw-r--r-- | src/nvim/lua/executor.c | 35 | ||||
-rw-r--r-- | src/nvim/lua/executor.h | 2 | ||||
-rw-r--r-- | src/nvim/lua/stdlib.c | 56 | ||||
-rw-r--r-- | src/nvim/lua/treesitter.c | 87 | ||||
-rw-r--r-- | src/nvim/lua/xdiff.c | 6 |
7 files changed, 168 insertions, 22 deletions
diff --git a/src/nvim/lua/converter.c b/src/nvim/lua/converter.c index 4d6e6090b8..49d49f76b9 100644 --- a/src/nvim/lua/converter.c +++ b/src/nvim/lua/converter.c @@ -59,7 +59,7 @@ static LuaTableProps nlua_traverse_table(lua_State *const lstate) size_t other_keys_num = 0; // Number of keys that are not string, integral // or type keys. LuaTableProps ret; - memset(&ret, 0, sizeof(ret)); + CLEAR_FIELD(ret); if (!lua_checkstack(lstate, lua_gettop(lstate) + 3)) { semsg(_("E1502: Lua failed to grow stack to %i"), lua_gettop(lstate) + 2); ret.type = kObjectTypeNil; diff --git a/src/nvim/lua/converter.h b/src/nvim/lua/converter.h index 1c9e60e4b2..f6a85900ba 100644 --- a/src/nvim/lua/converter.h +++ b/src/nvim/lua/converter.h @@ -6,7 +6,7 @@ #include <stdint.h> #include "nvim/api/private/defs.h" -#include "nvim/eval.h" +#include "nvim/eval/typval.h" #include "nvim/func_attr.h" typedef struct { diff --git a/src/nvim/lua/executor.c b/src/nvim/lua/executor.c index 661dbfc4c2..42aa13cfc1 100644 --- a/src/nvim/lua/executor.c +++ b/src/nvim/lua/executor.c @@ -15,12 +15,14 @@ #include "nvim/buffer_defs.h" #include "nvim/change.h" #include "nvim/cursor.h" +#include "nvim/drawscreen.h" +#include "nvim/eval.h" #include "nvim/eval/funcs.h" #include "nvim/eval/typval.h" #include "nvim/eval/userfunc.h" #include "nvim/event/loop.h" #include "nvim/event/time.h" -#include "nvim/ex_cmds2.h" +#include "nvim/ex_cmds.h" #include "nvim/ex_getln.h" #include "nvim/extmark.h" #include "nvim/func_attr.h" @@ -37,7 +39,7 @@ #include "nvim/msgpack_rpc/channel.h" #include "nvim/os/os.h" #include "nvim/profile.h" -#include "nvim/screen.h" +#include "nvim/runtime.h" #include "nvim/undo.h" #include "nvim/usercmd.h" #include "nvim/version.h" @@ -447,7 +449,7 @@ static nlua_ref_state_t *nlua_new_ref_state(lua_State *lstate, bool is_thread) FUNC_ATTR_NONNULL_ALL { nlua_ref_state_t *ref_state = lua_newuserdata(lstate, sizeof(*ref_state)); - memset(ref_state, 0, sizeof(*ref_state)); + CLEAR_POINTER(ref_state); ref_state->nil_ref = LUA_NOREF; ref_state->empty_dict_ref = LUA_NOREF; if (!is_thread) { @@ -988,7 +990,7 @@ int nlua_in_fast_event(lua_State *lstate) static bool viml_func_is_fast(const char *name) { - const EvalFuncDef *const fdef = find_internal_func((const char *)name); + const EvalFuncDef *const fdef = find_internal_func(name); if (fdef) { return fdef->fast; } @@ -1025,7 +1027,7 @@ int nlua_call(lua_State *lstate) // TODO(bfredl): this should be simplified in error handling refactor force_abort = false; suppress_errthrow = false; - current_exception = NULL; + did_throw = false; did_emsg = false; try_start(); @@ -1091,7 +1093,7 @@ static int nlua_rpc(lua_State *lstate, bool request) Object result = rpc_send_call(chan_id, name, args, &res_mem, &err); if (!ERROR_SET(&err)) { nlua_push_Object(lstate, result, false); - arena_mem_free(res_mem, NULL); + arena_mem_free(res_mem); } } else { if (!rpc_send_event(chan_id, name, args)) { @@ -1313,12 +1315,11 @@ static void nlua_typval_exec(const char *lcmd, size_t lcmd_len, const char *name int nlua_source_using_linegetter(LineGetter fgetline, void *cookie, char *name) { - const linenr_T save_sourcing_lnum = sourcing_lnum; const sctx_T save_current_sctx = current_sctx; current_sctx.sc_sid = SID_STR; current_sctx.sc_seq = 0; current_sctx.sc_lnum = 0; - sourcing_lnum = 0; + estack_push(ETYPE_SCRIPT, name, 0); garray_T ga; char_u *line = NULL; @@ -1331,7 +1332,7 @@ int nlua_source_using_linegetter(LineGetter fgetline, void *cookie, char *name) size_t len = strlen(code); nlua_typval_exec(code, len, name, NULL, 0, false, NULL); - sourcing_lnum = save_sourcing_lnum; + estack_pop(); current_sctx = save_current_sctx; ga_clear_strings(&ga); xfree(code); @@ -1577,7 +1578,7 @@ void ex_luado(exarg_T *const eap) } lua_pop(lstate, 1); check_cursor(); - update_screen(NOT_VALID); + update_screen(UPD_NOT_VALID); } /// Run lua file @@ -1661,6 +1662,9 @@ static void nlua_add_treesitter(lua_State *const lstate) FUNC_ATTR_NONNULL_ALL lua_pushcfunction(lstate, tslua_has_language); lua_setfield(lstate, -2, "_ts_has_language"); + lua_pushcfunction(lstate, tslua_remove_lang); + lua_setfield(lstate, -2, "_ts_remove_language"); + lua_pushcfunction(lstate, tslua_inspect_lang); lua_setfield(lstate, -2, "_ts_inspect_language"); @@ -1906,7 +1910,7 @@ void nlua_set_sctx(sctx_T *current) break; } char *source_path = fix_fname(info->source + 1); - get_current_script_id((char_u *)source_path, current); + get_current_script_id(&source_path, current); xfree(source_path); current->sc_lnum = info->currentline; current->sc_seq = -1; @@ -1939,8 +1943,13 @@ int nlua_do_ucmd(ucmd_T *cmd, exarg_T *eap, bool preview) // Split args by unescaped whitespace |<f-args>| (nargs dependent) if (cmd->uc_argt & EX_NOSPC) { - // Commands where nargs = 1 or "?" fargs is the same as args - lua_rawseti(lstate, -2, 1); + if ((cmd->uc_argt & EX_NEEDARG) || STRLEN(eap->arg)) { + // For commands where nargs is 1 or "?" and argument is passed, fargs = { args } + lua_rawseti(lstate, -2, 1); + } else { + // if nargs = "?" and no argument is passed, fargs = {} + lua_pop(lstate, 1); // Pop the reference of opts.args + } } else if (eap->args == NULL) { // For commands with more than one possible argument, split if argument list isn't available. lua_pop(lstate, 1); // Pop the reference of opts.args diff --git a/src/nvim/lua/executor.h b/src/nvim/lua/executor.h index 2afbbebfe7..78346fd81f 100644 --- a/src/nvim/lua/executor.h +++ b/src/nvim/lua/executor.h @@ -24,6 +24,8 @@ typedef struct { #endif } nlua_ref_state_t; +#define NLUA_EXEC_STATIC(cstr, arg, err) nlua_exec(STATIC_CSTR_AS_STRING(cstr), arg, err) + #define NLUA_CLEAR_REF(x) \ do { \ /* Take the address to avoid double evaluation. #1375 */ \ diff --git a/src/nvim/lua/stdlib.c b/src/nvim/lua/stdlib.c index 6ba0056f48..1b874e673a 100644 --- a/src/nvim/lua/stdlib.c +++ b/src/nvim/lua/stdlib.c @@ -16,10 +16,11 @@ #include "nvim/buffer_defs.h" #include "nvim/change.h" #include "nvim/cursor.h" +#include "nvim/eval.h" #include "nvim/eval/userfunc.h" #include "nvim/event/loop.h" #include "nvim/event/time.h" -#include "nvim/ex_cmds2.h" +#include "nvim/ex_eval.h" #include "nvim/ex_getln.h" #include "nvim/extmark.h" #include "nvim/func_attr.h" @@ -473,6 +474,52 @@ static int nlua_stricmp(lua_State *const lstate) FUNC_ATTR_NONNULL_ALL return 1; } +#if defined(HAVE_ICONV) + +/// Convert string from one encoding to another +static int nlua_iconv(lua_State *lstate) +{ + int narg = lua_gettop(lstate); + + if (narg < 3) { + return luaL_error(lstate, "Expected at least 3 arguments"); + } + + for (int i = 1; i <= 3; i++) { + if (lua_type(lstate, i) != LUA_TSTRING) { + return luaL_argerror(lstate, i, "expected string"); + } + } + + size_t str_len = 0; + const char *str = lua_tolstring(lstate, 1, &str_len); + + char_u *from = (char_u *)enc_canonize(enc_skip((char *)lua_tolstring(lstate, 2, NULL))); + char_u *to = (char_u *)enc_canonize(enc_skip((char *)lua_tolstring(lstate, 3, NULL))); + + vimconv_T vimconv; + vimconv.vc_type = CONV_NONE; + convert_setup_ext(&vimconv, from, false, to, false); + + char_u *ret = (char_u *)string_convert(&vimconv, (char *)str, &str_len); + + convert_setup(&vimconv, NULL, NULL); + + xfree(from); + xfree(to); + + if (ret == NULL) { + lua_pushnil(lstate); + } else { + lua_pushlstring(lstate, (char *)ret, str_len); + xfree(ret); + } + + return 1; +} + +#endif + void nlua_state_add_stdlib(lua_State *const lstate, bool is_thread) { if (!is_thread) { @@ -518,6 +565,13 @@ void nlua_state_add_stdlib(lua_State *const lstate, bool is_thread) // vim.spell luaopen_spell(lstate); lua_setfield(lstate, -2, "spell"); + +#if defined(HAVE_ICONV) + // vim.iconv + // depends on p_ambw, p_emoji + lua_pushcfunction(lstate, &nlua_iconv); + lua_setfield(lstate, -2, "iconv"); +#endif } // vim.mpack diff --git a/src/nvim/lua/treesitter.c b/src/nvim/lua/treesitter.c index f0d847e352..7ff4fbbff4 100644 --- a/src/nvim/lua/treesitter.c +++ b/src/nvim/lua/treesitter.c @@ -14,11 +14,14 @@ #include <stdint.h> #include <stdlib.h> #include <string.h> +#include <uv.h> #include "nvim/api/private/helpers.h" #include "nvim/buffer.h" #include "nvim/lib/kvec.h" +#include "nvim/log.h" #include "nvim/lua/treesitter.h" +#include "nvim/map.h" #include "nvim/memline.h" #include "tree_sitter/api.h" @@ -85,6 +88,10 @@ static struct luaL_Reg node_meta[] = { { "prev_sibling", node_prev_sibling }, { "next_named_sibling", node_next_named_sibling }, { "prev_named_sibling", node_prev_named_sibling }, + { "named_children", node_named_children }, + { "root", node_root }, + { "byte_length", node_byte_length }, + { NULL, NULL } }; @@ -145,18 +152,27 @@ int tslua_has_language(lua_State *L) return 1; } +// Creates the language into the internal language map. +// +// Returns true if the language is correctly loaded in the language map int tslua_add_language(lua_State *L) { const char *path = luaL_checkstring(L, 1); const char *lang_name = luaL_checkstring(L, 2); + const char *symbol_name = lang_name; + + if (lua_gettop(L) >= 3 && !lua_isnil(L, 3)) { + symbol_name = luaL_checkstring(L, 3); + } if (pmap_has(cstr_t)(&langs, lang_name)) { - return 0; + lua_pushboolean(L, true); + return 1; } #define BUFSIZE 128 char symbol_buf[BUFSIZE]; - snprintf(symbol_buf, BUFSIZE, "tree_sitter_%s", lang_name); + snprintf(symbol_buf, BUFSIZE, "tree_sitter_%s", symbol_name); #undef BUFSIZE uv_lib_t lib; @@ -179,6 +195,7 @@ int tslua_add_language(lua_State *L) TSLanguage *lang = lang_parser(); if (lang == NULL) { + uv_dlclose(&lib); return luaL_error(L, "Failed to load parser %s: internal error", path); } @@ -198,6 +215,19 @@ int tslua_add_language(lua_State *L) return 1; } +int tslua_remove_lang(lua_State *L) +{ + const char *lang_name = luaL_checkstring(L, 1); + bool present = pmap_has(cstr_t)(&langs, lang_name); + if (present) { + char *key = (char *)pmap_key(cstr_t)(&langs, lang_name); + pmap_del(cstr_t)(&langs, lang_name); + xfree(key); + } + lua_pushboolean(L, present); + return 1; +} + int tslua_inspect_lang(lua_State *L) { const char *lang_name = luaL_checkstring(L, 1); @@ -593,7 +623,7 @@ void push_tree(lua_State *L, TSTree *tree, bool do_copy) lua_setfenv(L, -2); // [udata] } -static TSTree **tree_check(lua_State *L, uint16_t index) +static TSTree **tree_check(lua_State *L, int index) { TSTree **ud = luaL_checkudata(L, index, TS_META_TREE); return ud; @@ -1036,6 +1066,57 @@ static int node_prev_named_sibling(lua_State *L) return 1; } +static int node_named_children(lua_State *L) +{ + TSNode source; + if (!node_check(L, 1, &source)) { + return 0; + } + TSTreeCursor cursor = ts_tree_cursor_new(source); + + lua_newtable(L); + int curr_index = 0; + + if (ts_tree_cursor_goto_first_child(&cursor)) { + do { + TSNode node = ts_tree_cursor_current_node(&cursor); + if (ts_node_is_named(node)) { + push_node(L, node, 1); + lua_rawseti(L, -2, ++curr_index); + } + } while (ts_tree_cursor_goto_next_sibling(&cursor)); + } + + ts_tree_cursor_delete(&cursor); + return 1; +} + +static int node_root(lua_State *L) +{ + TSNode node; + if (!node_check(L, 1, &node)) { + return 0; + } + + TSNode root = ts_tree_root_node(node.tree); + push_node(L, root, 1); + return 1; +} + +static int node_byte_length(lua_State *L) +{ + TSNode node; + if (!node_check(L, 1, &node)) { + return 0; + } + + uint32_t start_byte = ts_node_start_byte(node); + uint32_t end_byte = ts_node_end_byte(node); + + lua_pushnumber(L, end_byte - start_byte); + return 1; +} + /// assumes the match table being on top of the stack static void set_match(lua_State *L, TSQueryMatch *match, int nodeidx) { diff --git a/src/nvim/lua/xdiff.c b/src/nvim/lua/xdiff.c index 71f85385b6..b2b5dfedee 100644 --- a/src/nvim/lua/xdiff.c +++ b/src/nvim/lua/xdiff.c @@ -269,9 +269,9 @@ int nlua_xdl_diff(lua_State *lstate) xpparam_t params; xdemitcb_t ecb; - memset(&cfg, 0, sizeof(cfg)); - memset(¶ms, 0, sizeof(params)); - memset(&ecb, 0, sizeof(ecb)); + CLEAR_FIELD(cfg); + CLEAR_FIELD(params); + CLEAR_FIELD(ecb); NluaXdiffMode mode = kNluaXdiffModeUnified; |