aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Vigouroux <tomvig38@gmail.com>2020-06-16 08:17:25 +0200
committerThomas Vigouroux <tomvig38@gmail.com>2020-06-29 22:21:06 +0200
commitb652f74ca3a6722ad0d185a0f4093907a6af65d7 (patch)
tree96f33724c9a4d5a282c3064398a8e9e9f346b633
parent558893b1b979d2ec9006ee496c19648edbbf5b1c (diff)
downloadrneovim-b652f74ca3a6722ad0d185a0f4093907a6af65d7.tar.gz
rneovim-b652f74ca3a6722ad0d185a0f4093907a6af65d7.tar.bz2
rneovim-b652f74ca3a6722ad0d185a0f4093907a6af65d7.zip
treesitter: use nodes to mark ranges
-rw-r--r--runtime/lua/vim/treesitter.lua2
-rw-r--r--src/nvim/lua/treesitter.c119
-rw-r--r--test/functional/lua/treesitter_spec.lua45
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)