diff options
author | Thomas Vigouroux <tomvig38@gmail.com> | 2020-06-16 08:17:25 +0200 |
---|---|---|
committer | Thomas Vigouroux <tomvig38@gmail.com> | 2020-06-29 22:21:06 +0200 |
commit | b652f74ca3a6722ad0d185a0f4093907a6af65d7 (patch) | |
tree | 96f33724c9a4d5a282c3064398a8e9e9f346b633 | |
parent | 558893b1b979d2ec9006ee496c19648edbbf5b1c (diff) | |
download | rneovim-b652f74ca3a6722ad0d185a0f4093907a6af65d7.tar.gz rneovim-b652f74ca3a6722ad0d185a0f4093907a6af65d7.tar.bz2 rneovim-b652f74ca3a6722ad0d185a0f4093907a6af65d7.zip |
treesitter: use nodes to mark ranges
-rw-r--r-- | runtime/lua/vim/treesitter.lua | 2 | ||||
-rw-r--r-- | src/nvim/lua/treesitter.c | 119 | ||||
-rw-r--r-- | test/functional/lua/treesitter_spec.lua | 45 |
3 files changed, 82 insertions, 84 deletions
diff --git a/runtime/lua/vim/treesitter.lua b/runtime/lua/vim/treesitter.lua index d5bc8e0a1b..f356673839 100644 --- a/runtime/lua/vim/treesitter.lua +++ b/runtime/lua/vim/treesitter.lua @@ -31,7 +31,7 @@ function Parser:_on_lines(bufnr, _, start_row, old_stop_row, stop_row, old_byte_ end function Parser:set_included_ranges(ranges) - self._parser:set_included_ranges(self.bufnr, ranges) + self._parser:set_included_ranges(ranges) -- The buffer will need to be parsed again later self.valid = false end 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, "<node "); @@ -588,7 +573,7 @@ static int node_tostring(lua_State *L) static int node_eq(lua_State *L) { TSNode node; - if (!node_check(L, &node)) { + if (!node_check(L, 1, &node)) { return 0; } // This should only be called if both x and y in "x == y" has the @@ -605,7 +590,7 @@ static int node_eq(lua_State *L) static int node_range(lua_State *L) { TSNode node; - if (!node_check(L, &node)) { + if (!node_check(L, 1, &node)) { return 0; } TSPoint start = ts_node_start_point(node); @@ -620,7 +605,7 @@ static int node_range(lua_State *L) static int node_start(lua_State *L) { TSNode node; - if (!node_check(L, &node)) { + if (!node_check(L, 1, &node)) { return 0; } TSPoint start = ts_node_start_point(node); @@ -634,7 +619,7 @@ static int node_start(lua_State *L) static int node_end(lua_State *L) { TSNode node; - if (!node_check(L, &node)) { + if (!node_check(L,1, &node)) { return 0; } TSPoint end = ts_node_end_point(node); @@ -648,7 +633,7 @@ static int node_end(lua_State *L) static int node_child_count(lua_State *L) { TSNode node; - if (!node_check(L, &node)) { + if (!node_check(L, 1, &node)) { return 0; } uint32_t count = ts_node_child_count(node); @@ -659,7 +644,7 @@ static int node_child_count(lua_State *L) static int node_named_child_count(lua_State *L) { TSNode node; - if (!node_check(L, &node)) { + if (!node_check(L,1, &node)) { return 0; } uint32_t count = ts_node_named_child_count(node); @@ -670,7 +655,7 @@ static int node_named_child_count(lua_State *L) static int node_type(lua_State *L) { TSNode node; - if (!node_check(L, &node)) { + if (!node_check(L, 1, &node)) { return 0; } lua_pushstring(L, ts_node_type(node)); @@ -680,7 +665,7 @@ static int node_type(lua_State *L) static int node_symbol(lua_State *L) { TSNode node; - if (!node_check(L, &node)) { + if (!node_check(L, 1, &node)) { return 0; } TSSymbol symbol = ts_node_symbol(node); @@ -691,7 +676,7 @@ static int node_symbol(lua_State *L) static int node_named(lua_State *L) { TSNode node; - if (!node_check(L, &node)) { + if (!node_check(L, 1, &node)) { return 0; } lua_pushboolean(L, ts_node_is_named(node)); @@ -701,7 +686,7 @@ static int node_named(lua_State *L) static int node_sexpr(lua_State *L) { TSNode node; - if (!node_check(L, &node)) { + if (!node_check(L, 1, &node)) { return 0; } char *allocated = ts_node_string(node); @@ -713,7 +698,7 @@ static int node_sexpr(lua_State *L) static int node_missing(lua_State *L) { TSNode node; - if (!node_check(L, &node)) { + if (!node_check(L, 1, &node)) { return 0; } lua_pushboolean(L, ts_node_is_missing(node)); @@ -723,7 +708,7 @@ static int node_missing(lua_State *L) static int node_has_error(lua_State *L) { TSNode node; - if (!node_check(L, &node)) { + if (!node_check(L, 1, &node)) { return 0; } lua_pushboolean(L, ts_node_has_error(node)); @@ -733,7 +718,7 @@ static int node_has_error(lua_State *L) static int node_child(lua_State *L) { TSNode node; - if (!node_check(L, &node)) { + if (!node_check(L, 1, &node)) { return 0; } long num = lua_tointeger(L, 2); @@ -746,7 +731,7 @@ static int node_child(lua_State *L) static int node_named_child(lua_State *L) { TSNode node; - if (!node_check(L, &node)) { + if (!node_check(L, 1, &node)) { return 0; } long num = lua_tointeger(L, 2); @@ -759,7 +744,7 @@ static int node_named_child(lua_State *L) static int node_descendant_for_range(lua_State *L) { TSNode node; - if (!node_check(L, &node)) { + if (!node_check(L, 1, &node)) { return 0; } TSPoint start = { (uint32_t)lua_tointeger(L, 2), @@ -775,7 +760,7 @@ static int node_descendant_for_range(lua_State *L) static int node_named_descendant_for_range(lua_State *L) { TSNode node; - if (!node_check(L, &node)) { + if (!node_check(L, 1, &node)) { return 0; } TSPoint start = { (uint32_t)lua_tointeger(L, 2), @@ -791,7 +776,7 @@ static int node_named_descendant_for_range(lua_State *L) static int node_parent(lua_State *L) { TSNode node; - if (!node_check(L, &node)) { + if (!node_check(L, 1, &node)) { return 0; } TSNode parent = ts_node_parent(node); @@ -873,7 +858,7 @@ static int query_next_capture(lua_State *L) static int node_rawquery(lua_State *L) { TSNode node; - if (!node_check(L, &node)) { + if (!node_check(L, 1, &node)) { return 0; } TSQuery *query = query_check(L, 2); diff --git a/test/functional/lua/treesitter_spec.lua b/test/functional/lua/treesitter_spec.lua index 1fd93d5f56..539c2b5e7c 100644 --- a/test/functional/lua/treesitter_spec.lua +++ b/test/functional/lua/treesitter_spec.lua @@ -417,31 +417,44 @@ static int nlua_schedule(lua_State *const lstate) eq({0, 0, 19, 0}, res) local res = exec_lua([[ - parser:set_included_ranges({{0, 0, 1, 0}}) + local root = parser:parse():root() + parser:set_included_ranges({{root:child(0), root:child(0)}}) parser.valid = false return { parser:parse():root():range() } ]]) - eq({0, 0, 1, 0}, res) + eq({0, 0, 18, 1}, res) -- Pick random samples local res = exec_lua([[ - parser:set_included_ranges({{8, 0, 9, 0}, {12, 0, 13 ,0}}) + query = vim.treesitter.parse_query("c", "(declaration) @decl") + + local nodes = {} + for _, node in query:iter_captures(parser:parse():root(), 0, 0, 19) do + table.insert(nodes, { node, node }) + end + + parser:set_included_ranges(nodes) + local root = parser:parse():root() - return {{root:child(0):range()}, {root:child(1):range()}} + + local res = {} + for i=0,(root:named_child_count() - 1) do + table.insert(res, { root:named_child(i):range() }) + end + return res ]]) - eq({{ - 8, - 2, - 8, - 33 - }, - { - 12, - 4, - 12, - 37 - }}, res) + eq({ + { 2, 2, 2, 40 }, + { 3, 3, 3, 32 }, + { 4, 7, 4, 8 }, + { 4, 8, 4, 25 }, + { 8, 2, 8, 6 }, + { 8, 7, 8, 33 }, + { 9, 8, 9, 20 }, + { 10, 4, 10, 5 }, + { 10, 5, 10, 20 }, + { 14, 9, 14, 27 } }, res) end) end) |