aboutsummaryrefslogtreecommitdiff
path: root/src/nvim/lua
diff options
context:
space:
mode:
Diffstat (limited to 'src/nvim/lua')
-rw-r--r--src/nvim/lua/converter.c2
-rw-r--r--src/nvim/lua/converter.h2
-rw-r--r--src/nvim/lua/executor.c35
-rw-r--r--src/nvim/lua/executor.h2
-rw-r--r--src/nvim/lua/stdlib.c56
-rw-r--r--src/nvim/lua/treesitter.c87
-rw-r--r--src/nvim/lua/xdiff.c6
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(&params, 0, sizeof(params));
- memset(&ecb, 0, sizeof(ecb));
+ CLEAR_FIELD(cfg);
+ CLEAR_FIELD(params);
+ CLEAR_FIELD(ecb);
NluaXdiffMode mode = kNluaXdiffModeUnified;