From 36d71e775a44526abd70b2720a589a1113c650d7 Mon Sep 17 00:00:00 2001 From: Thomas Vigouroux Date: Sun, 7 Jun 2020 14:19:38 +0200 Subject: treesitter: simplify puhstree call process --- src/nvim/lua/executor.c | 12 +----------- src/nvim/lua/treesitter.c | 8 +++++++- 2 files changed, 8 insertions(+), 12 deletions(-) (limited to 'src') diff --git a/src/nvim/lua/executor.c b/src/nvim/lua/executor.c index 327ed6d6b7..4b47b34d8a 100644 --- a/src/nvim/lua/executor.c +++ b/src/nvim/lua/executor.c @@ -1128,21 +1128,11 @@ void ex_luafile(exarg_T *const eap) } } -static int create_tslua_parser(lua_State *L) -{ - if (lua_gettop(L) < 1 || !lua_isstring(L, 1)) { - return luaL_error(L, "string expected"); - } - - const char *lang_name = lua_tostring(L, 1); - return tslua_push_parser(L, lang_name); -} - static void nlua_add_treesitter(lua_State *const lstate) FUNC_ATTR_NONNULL_ALL { tslua_init(lstate); - lua_pushcfunction(lstate, create_tslua_parser); + lua_pushcfunction(lstate, tslua_push_parser); lua_setfield(lstate, -2, "_create_ts_parser"); lua_pushcfunction(lstate, tslua_add_language); diff --git a/src/nvim/lua/treesitter.c b/src/nvim/lua/treesitter.c index 51d9549033..3447af9114 100644 --- a/src/nvim/lua/treesitter.c +++ b/src/nvim/lua/treesitter.c @@ -214,8 +214,14 @@ int tslua_inspect_lang(lua_State *L) return 1; } -int tslua_push_parser(lua_State *L, const char *lang_name) +int tslua_push_parser(lua_State *L) { + + // Gather language + if (lua_gettop(L) < 1 || !lua_isstring(L, 1)) { + return luaL_error(L, "string expected"); + } + const char *lang_name = lua_tostring(L, 1); TSLanguage *lang = pmap_get(cstr_t)(langs, lang_name); if (!lang) { return luaL_error(L, "no such language: %s", lang_name); -- cgit From 333f3f19db612acc893791f04624da174efe04b5 Mon Sep 17 00:00:00 2001 From: Thomas Vigouroux Date: Sun, 7 Jun 2020 16:37:11 +0200 Subject: treesitter: add set_included_ranges to the parser This is the first step towards language injection using treesitter. --- src/nvim/lua/treesitter.c | 88 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 88 insertions(+) (limited to 'src') diff --git a/src/nvim/lua/treesitter.c b/src/nvim/lua/treesitter.c index 3447af9114..9e3bbb38fc 100644 --- a/src/nvim/lua/treesitter.c +++ b/src/nvim/lua/treesitter.c @@ -20,6 +20,7 @@ #include "nvim/lua/treesitter.h" #include "nvim/api/private/handle.h" #include "nvim/memline.h" +#include "nvim/buffer.h" typedef struct { TSParser *parser; @@ -41,6 +42,7 @@ static struct luaL_Reg parser_meta[] = { { "parse_buf", parser_parse_buf }, { "edit", parser_edit }, { "tree", parser_tree }, + { "set_included_ranges", parser_set_ranges }, { NULL, NULL } }; @@ -383,6 +385,92 @@ static int parser_edit(lua_State *L) return 0; } +static int parser_set_ranges(lua_State *L) { + if (lua_gettop(L) < 3) { + lua_pushstring(L, "not enough args to parser:set_ranges()"); + return lua_error(L); + } + + TSLua_parser *p = parser_check(L); + if (!p || !p->tree) { + return 0; + } + + int bufnr = lua_tointeger(L, 2); + + if (! lua_istable(L, 3)) { + lua_pushstring(L, "argument for parser:set_ranges() should be a table."); + return lua_error(L); + } + + size_t tbl_len = lua_objlen(L, 3); + TSRange *ranges = xmalloc(sizeof(TSRange) * tbl_len); + + + // [ parser, ranges ] + for (size_t index = 0; index < tbl_len; index++) { + lua_rawgeti(L, 3, index + 1); // [ parser, ranges, range ] + + if (!lua_istable(L, -1)) { + xfree(ranges); + lua_pushstring(L, "argument for parser:set_ranges() should be a table of tables."); + return lua_error(L); + } + + if (lua_objlen(L, -1) < 4 ) { + xfree(ranges); + lua_pushstring(L, "argument for parser:set_ranges() should be a table of ranges of 4 elements."); + return lua_error(L); + } + + lua_rawgeti(L, -1, 1); // [ parser, ranges, range, num ] + unsigned int start_row = lua_tointeger(L, -1); + lua_pop(L, 1); // [ parser, ranges, range ] + + + lua_rawgeti(L, -1, 2); // [ parser, ranges, range, num ] + unsigned int start_col = lua_tointeger(L, -1); + lua_pop(L, 1); // [ parser, ranges, range ] + + lua_rawgeti(L, -1, 3); // [ parser, ranges, range, num ] + unsigned int stop_row = lua_tointeger(L, -1); + lua_pop(L, 1); // [ parser, ranges, range ] + + lua_rawgeti(L, -1, 4); // [ parser, ranges, range, num ] + unsigned int stop_col = lua_tointeger(L, -1); + lua_pop(L, 1); // [ parser, ranges, range ] + + buf_T * buf = buflist_findnr(bufnr); + + if (!buf) { + buf = curbuf; + } + + // TODO: For sure that's wrong, try to find a way to get the byte offset directly + uint32_t start_byte = ml_find_line_or_offset(buf, start_row, NULL, false) + start_col; + uint32_t stop_byte = ml_find_line_or_offset(buf, stop_row, NULL, false) + stop_col; + + ranges[index] = (TSRange) { + .start_point = (TSPoint) { + .row = start_row, + .column = start_col + }, + .end_point = (TSPoint) { + .row = stop_row, + .column = stop_col + }, + .start_byte = start_byte, + .end_byte = stop_byte + }; + } + + // This memcpies ranges, thus we can free it. + ts_parser_set_included_ranges(p->parser, ranges, tbl_len); + xfree(ranges); + + return 0; +} + // Tree methods -- cgit From ac18403d6e58a08956f9465998f2223df4e19108 Mon Sep 17 00:00:00 2001 From: Thomas Vigouroux Date: Sun, 14 Jun 2020 18:50:22 +0200 Subject: treesitter: test newly added set_included_ranges --- src/nvim/lua/treesitter.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/nvim/lua/treesitter.c b/src/nvim/lua/treesitter.c index 9e3bbb38fc..6176a1b7c3 100644 --- a/src/nvim/lua/treesitter.c +++ b/src/nvim/lua/treesitter.c @@ -447,8 +447,9 @@ static int parser_set_ranges(lua_State *L) { } // TODO: For sure that's wrong, try to find a way to get the byte offset directly - uint32_t start_byte = ml_find_line_or_offset(buf, start_row, NULL, false) + start_col; - uint32_t stop_byte = ml_find_line_or_offset(buf, stop_row, NULL, false) + stop_col; + // Lines are 0 based for consistency + uint32_t start_byte = ml_find_line_or_offset(buf, start_row + 1, NULL, false) + start_col; + uint32_t stop_byte = ml_find_line_or_offset(buf, stop_row + 1, NULL, false) + stop_col; ranges[index] = (TSRange) { .start_point = (TSPoint) { -- cgit From 75a1239eb51a805837111ac60e5dbddfadc8cb6f Mon Sep 17 00:00:00 2001 From: Thomas Vigouroux Date: Sun, 14 Jun 2020 19:03:36 +0200 Subject: treesitter: fix some clint errors Also fixes some mismatches on the name of the function --- src/nvim/lua/treesitter.c | 45 ++++++++++++++++++++++++++------------------- 1 file changed, 26 insertions(+), 19 deletions(-) (limited to 'src') diff --git a/src/nvim/lua/treesitter.c b/src/nvim/lua/treesitter.c index 6176a1b7c3..6e554d9b54 100644 --- a/src/nvim/lua/treesitter.c +++ b/src/nvim/lua/treesitter.c @@ -218,7 +218,6 @@ int tslua_inspect_lang(lua_State *L) int tslua_push_parser(lua_State *L) { - // Gather language if (lua_gettop(L) < 1 || !lua_isstring(L, 1)) { return luaL_error(L, "string expected"); @@ -385,7 +384,8 @@ static int parser_edit(lua_State *L) return 0; } -static int parser_set_ranges(lua_State *L) { +static int parser_set_ranges(lua_State *L) +{ if (lua_gettop(L) < 3) { lua_pushstring(L, "not enough args to parser:set_ranges()"); return lua_error(L); @@ -398,8 +398,8 @@ static int parser_set_ranges(lua_State *L) { int bufnr = lua_tointeger(L, 2); - if (! lua_istable(L, 3)) { - lua_pushstring(L, "argument for parser:set_ranges() should be a table."); + if (!lua_istable(L, 3)) { + lua_pushstring(L, "argument for parser:set_included_ranges() should be a table."); return lua_error(L); } @@ -409,36 +409,40 @@ static int parser_set_ranges(lua_State *L) { // [ parser, ranges ] for (size_t index = 0; index < tbl_len; index++) { - lua_rawgeti(L, 3, index + 1); // [ parser, ranges, range ] + lua_rawgeti(L, 3, index + 1); // [ parser, ranges, range ] if (!lua_istable(L, -1)) { xfree(ranges); - lua_pushstring(L, "argument for parser:set_ranges() should be a table of tables."); + lua_pushstring( + L, + "argument for parser:set_included_ranges() should be a table of tables."); return lua_error(L); } - if (lua_objlen(L, -1) < 4 ) { + if (lua_objlen(L, -1) < 4) { xfree(ranges); - lua_pushstring(L, "argument for parser:set_ranges() should be a table of ranges of 4 elements."); + lua_pushstring( + L, + "argument for parser:set_included_ranges() should be a table of ranges of 4 elements."); return lua_error(L); } - lua_rawgeti(L, -1, 1); // [ parser, ranges, range, num ] + lua_rawgeti(L, -1, 1); // [ parser, ranges, range, num ] unsigned int start_row = lua_tointeger(L, -1); - lua_pop(L, 1); // [ parser, ranges, range ] + lua_pop(L, 1); // [ parser, ranges, range ] - lua_rawgeti(L, -1, 2); // [ parser, ranges, range, num ] + lua_rawgeti(L, -1, 2); // [ parser, ranges, range, num ] unsigned int start_col = lua_tointeger(L, -1); - lua_pop(L, 1); // [ parser, ranges, range ] + lua_pop(L, 1); // [ parser, ranges, range ] - lua_rawgeti(L, -1, 3); // [ parser, ranges, range, num ] + lua_rawgeti(L, -1, 3); // [ parser, ranges, range, num ] unsigned int stop_row = lua_tointeger(L, -1); - lua_pop(L, 1); // [ parser, ranges, range ] + lua_pop(L, 1); // [ parser, ranges, range ] - lua_rawgeti(L, -1, 4); // [ parser, ranges, range, num ] + lua_rawgeti(L, -1, 4); // [ parser, ranges, range, num ] unsigned int stop_col = lua_tointeger(L, -1); - lua_pop(L, 1); // [ parser, ranges, range ] + lua_pop(L, 1); // [ parser, ranges, range ] buf_T * buf = buflist_findnr(bufnr); @@ -446,10 +450,13 @@ static int parser_set_ranges(lua_State *L) { buf = curbuf; } - // TODO: For sure that's wrong, try to find a way to get the byte offset directly + // TODO(vigoux): For sure that's wrong, try to find a way to get the + // byte offset directly // Lines are 0 based for consistency - uint32_t start_byte = ml_find_line_or_offset(buf, start_row + 1, NULL, false) + start_col; - uint32_t stop_byte = ml_find_line_or_offset(buf, stop_row + 1, NULL, false) + stop_col; + uint32_t start_byte = + ml_find_line_or_offset(buf, start_row + 1, NULL, false) + start_col; + uint32_t stop_byte = + ml_find_line_or_offset(buf, stop_row + 1, NULL, false) + stop_col; ranges[index] = (TSRange) { .start_point = (TSPoint) { -- cgit From b652f74ca3a6722ad0d185a0f4093907a6af65d7 Mon Sep 17 00:00:00 2001 From: Thomas Vigouroux Date: Tue, 16 Jun 2020 08:17:25 +0200 Subject: treesitter: use nodes to mark ranges --- src/nvim/lua/treesitter.c | 119 ++++++++++++++++++++-------------------------- 1 file changed, 52 insertions(+), 67 deletions(-) (limited to 'src') diff --git a/src/nvim/lua/treesitter.c b/src/nvim/lua/treesitter.c index 6e554d9b54..aa76ff33a4 100644 --- a/src/nvim/lua/treesitter.c +++ b/src/nvim/lua/treesitter.c @@ -386,8 +386,8 @@ static int parser_edit(lua_State *L) static int parser_set_ranges(lua_State *L) { - if (lua_gettop(L) < 3) { - lua_pushstring(L, "not enough args to parser:set_ranges()"); + if (lua_gettop(L) < 2) { + lua_pushstring(L, "not enough args to parser:set_included_ranges()"); return lua_error(L); } @@ -396,20 +396,18 @@ static int parser_set_ranges(lua_State *L) return 0; } - int bufnr = lua_tointeger(L, 2); - - if (!lua_istable(L, 3)) { + if (!lua_istable(L, 2)) { lua_pushstring(L, "argument for parser:set_included_ranges() should be a table."); return lua_error(L); } - size_t tbl_len = lua_objlen(L, 3); + size_t tbl_len = lua_objlen(L, 2); TSRange *ranges = xmalloc(sizeof(TSRange) * tbl_len); // [ parser, ranges ] for (size_t index = 0; index < tbl_len; index++) { - lua_rawgeti(L, 3, index + 1); // [ parser, ranges, range ] + lua_rawgeti(L, 2, index + 1); // [ parser, ranges, range ] if (!lua_istable(L, -1)) { xfree(ranges); @@ -419,60 +417,47 @@ static int parser_set_ranges(lua_State *L) return lua_error(L); } - if (lua_objlen(L, -1) < 4) { + if (lua_objlen(L, -1) != 2) { xfree(ranges); lua_pushstring( L, - "argument for parser:set_included_ranges() should be a table of ranges of 4 elements."); + "argument for parser:set_included_ranges() should be a table of ranges of 2 elements."); return lua_error(L); } - lua_rawgeti(L, -1, 1); // [ parser, ranges, range, num ] - unsigned int start_row = lua_tointeger(L, -1); - lua_pop(L, 1); // [ parser, ranges, range ] - - - lua_rawgeti(L, -1, 2); // [ parser, ranges, range, num ] - unsigned int start_col = lua_tointeger(L, -1); - lua_pop(L, 1); // [ parser, ranges, range ] - - lua_rawgeti(L, -1, 3); // [ parser, ranges, range, num ] - unsigned int stop_row = lua_tointeger(L, -1); - lua_pop(L, 1); // [ parser, ranges, range ] - lua_rawgeti(L, -1, 4); // [ parser, ranges, range, num ] - unsigned int stop_col = lua_tointeger(L, -1); + lua_rawgeti(L, -1, 1); // [ parser, ranges, range, start_node ] + TSNode start_node; + if (!node_check(L, -1, &start_node)) { + xfree(ranges); + lua_pushstring( + L, + "ranges should be tables of nodes."); + return lua_error(L); + } lua_pop(L, 1); // [ parser, ranges, range ] - buf_T * buf = buflist_findnr(bufnr); - - if (!buf) { - buf = curbuf; + lua_rawgeti(L, -1, 1); // [ parser, ranges, range, stop_node ] + TSNode stop_node; + if (!node_check(L, -1, &stop_node)) { + xfree(ranges); + lua_pushstring( + L, + "ranges should be tables of nodes."); + return lua_error(L); } - - // TODO(vigoux): For sure that's wrong, try to find a way to get the - // byte offset directly - // Lines are 0 based for consistency - uint32_t start_byte = - ml_find_line_or_offset(buf, start_row + 1, NULL, false) + start_col; - uint32_t stop_byte = - ml_find_line_or_offset(buf, stop_row + 1, NULL, false) + stop_col; + lua_pop(L, 1); // [ parser, ranges, range ] ranges[index] = (TSRange) { - .start_point = (TSPoint) { - .row = start_row, - .column = start_col - }, - .end_point = (TSPoint) { - .row = stop_row, - .column = stop_col - }, - .start_byte = start_byte, - .end_byte = stop_byte + .start_point = ts_node_start_point(start_node), + .end_point = ts_node_end_point(stop_node), + .start_byte = ts_node_start_byte(start_node), + .end_byte = ts_node_end_byte(stop_node) }; + lua_pop(L, 1); // [ parser, ranges ] } - // This memcpies ranges, thus we can free it. + // This memcpies ranges, thus we can free it afterwards ts_parser_set_included_ranges(p->parser, ranges, tbl_len); xfree(ranges); @@ -561,9 +546,9 @@ static void push_node(lua_State *L, TSNode node, int uindex) lua_setfenv(L, -2); // [udata] } -static bool node_check(lua_State *L, TSNode *res) +static bool node_check(lua_State *L, int index, TSNode *res) { - TSNode *ud = luaL_checkudata(L, 1, "treesitter_node"); + TSNode *ud = luaL_checkudata(L, index, "treesitter_node"); if (ud) { *res = *ud; return true; @@ -575,7 +560,7 @@ static bool node_check(lua_State *L, TSNode *res) static int node_tostring(lua_State *L) { TSNode node; - if (!node_check(L, &node)) { + if (!node_check(L,1, &node)) { return 0; } lua_pushstring(L, " Date: Tue, 23 Jun 2020 09:08:56 +0200 Subject: treesitter: fix lint --- src/nvim/lua/treesitter.c | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) (limited to 'src') diff --git a/src/nvim/lua/treesitter.c b/src/nvim/lua/treesitter.c index aa76ff33a4..913be5afe8 100644 --- a/src/nvim/lua/treesitter.c +++ b/src/nvim/lua/treesitter.c @@ -387,8 +387,9 @@ static int parser_edit(lua_State *L) static int parser_set_ranges(lua_State *L) { if (lua_gettop(L) < 2) { - lua_pushstring(L, "not enough args to parser:set_included_ranges()"); - return lua_error(L); + return luaL_error( + L, + "not enough args to parser:set_included_ranges()"); } TSLua_parser *p = parser_check(L); @@ -397,8 +398,9 @@ static int parser_set_ranges(lua_State *L) } if (!lua_istable(L, 2)) { - lua_pushstring(L, "argument for parser:set_included_ranges() should be a table."); - return lua_error(L); + return luaL_error( + L, + "argument for parser:set_included_ranges() should be a table."); } size_t tbl_len = lua_objlen(L, 2); @@ -411,18 +413,16 @@ static int parser_set_ranges(lua_State *L) if (!lua_istable(L, -1)) { xfree(ranges); - lua_pushstring( + return luaL_error( L, "argument for parser:set_included_ranges() should be a table of tables."); - return lua_error(L); } if (lua_objlen(L, -1) != 2) { xfree(ranges); - lua_pushstring( + return luaL_error( L, "argument for parser:set_included_ranges() should be a table of ranges of 2 elements."); - return lua_error(L); } @@ -560,7 +560,7 @@ static bool node_check(lua_State *L, int index, TSNode *res) static int node_tostring(lua_State *L) { TSNode node; - if (!node_check(L,1, &node)) { + if (!node_check(L, 1, &node)) { return 0; } lua_pushstring(L, " Date: Mon, 29 Jun 2020 23:02:30 +0200 Subject: treesitter: use single nodes in set_ranges fixup! treesitter: fix lint --- src/nvim/lua/treesitter.c | 43 +++++++------------------------------------ 1 file changed, 7 insertions(+), 36 deletions(-) (limited to 'src') diff --git a/src/nvim/lua/treesitter.c b/src/nvim/lua/treesitter.c index 913be5afe8..ddf54720a7 100644 --- a/src/nvim/lua/treesitter.c +++ b/src/nvim/lua/treesitter.c @@ -411,50 +411,21 @@ static int parser_set_ranges(lua_State *L) for (size_t index = 0; index < tbl_len; index++) { lua_rawgeti(L, 2, index + 1); // [ parser, ranges, range ] - if (!lua_istable(L, -1)) { + TSNode node; + if (!node_check(L, -1, &node)) { xfree(ranges); return luaL_error( - L, - "argument for parser:set_included_ranges() should be a table of tables."); - } - - if (lua_objlen(L, -1) != 2) { - xfree(ranges); - return luaL_error( - L, - "argument for parser:set_included_ranges() should be a table of ranges of 2 elements."); - } - - - lua_rawgeti(L, -1, 1); // [ parser, ranges, range, start_node ] - TSNode start_node; - if (!node_check(L, -1, &start_node)) { - xfree(ranges); - lua_pushstring( - L, - "ranges should be tables of nodes."); - return lua_error(L); - } - lua_pop(L, 1); // [ parser, ranges, range ] - - lua_rawgeti(L, -1, 1); // [ parser, ranges, range, stop_node ] - TSNode stop_node; - if (!node_check(L, -1, &stop_node)) { - xfree(ranges); - lua_pushstring( L, "ranges should be tables of nodes."); - return lua_error(L); } - lua_pop(L, 1); // [ parser, ranges, range ] + lua_pop(L, 1); // [ parser, ranges ] ranges[index] = (TSRange) { - .start_point = ts_node_start_point(start_node), - .end_point = ts_node_end_point(stop_node), - .start_byte = ts_node_start_byte(start_node), - .end_byte = ts_node_end_byte(stop_node) + .start_point = ts_node_start_point(node), + .end_point = ts_node_end_point(node), + .start_byte = ts_node_start_byte(node), + .end_byte = ts_node_end_byte(node) }; - lua_pop(L, 1); // [ parser, ranges ] } // This memcpies ranges, thus we can free it afterwards -- cgit