treesitter: use nodes to mark ranges
This commit is contained in:
parent
558893b1b9
commit
b652f74ca3
|
@ -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
|
||||
|
|
|
@ -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_pop(L, 1); // [ parser, ranges, range ]
|
||||
|
||||
buf_T * buf = buflist_findnr(bufnr);
|
||||
|
||||
if (!buf) {
|
||||
buf = curbuf;
|
||||
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 ]
|
||||
|
||||
// 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_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 ]
|
||||
|
||||
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);
|
||||
|
|
|
@ -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)
|
||||
|
|
Loading…
Reference in New Issue