mirror of
https://github.com/neovim/neovim.git
synced 2025-09-29 14:38:32 +00:00
treesitter: add set_included_ranges to the parser
This is the first step towards language injection using treesitter.
This commit is contained in:
@@ -30,6 +30,12 @@ function Parser:_on_lines(bufnr, _, start_row, old_stop_row, stop_row, old_byte_
|
|||||||
self.valid = false
|
self.valid = false
|
||||||
end
|
end
|
||||||
|
|
||||||
|
function Parser:set_included_ranges(ranges)
|
||||||
|
self._parser:set_included_ranges(self.bufnr, ranges)
|
||||||
|
-- The buffer will need to be parsed again later
|
||||||
|
self.valid = false
|
||||||
|
end
|
||||||
|
|
||||||
local M = {
|
local M = {
|
||||||
parse_query = vim._ts_parse_query,
|
parse_query = vim._ts_parse_query,
|
||||||
}
|
}
|
||||||
|
@@ -20,6 +20,7 @@
|
|||||||
#include "nvim/lua/treesitter.h"
|
#include "nvim/lua/treesitter.h"
|
||||||
#include "nvim/api/private/handle.h"
|
#include "nvim/api/private/handle.h"
|
||||||
#include "nvim/memline.h"
|
#include "nvim/memline.h"
|
||||||
|
#include "nvim/buffer.h"
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
TSParser *parser;
|
TSParser *parser;
|
||||||
@@ -41,6 +42,7 @@ static struct luaL_Reg parser_meta[] = {
|
|||||||
{ "parse_buf", parser_parse_buf },
|
{ "parse_buf", parser_parse_buf },
|
||||||
{ "edit", parser_edit },
|
{ "edit", parser_edit },
|
||||||
{ "tree", parser_tree },
|
{ "tree", parser_tree },
|
||||||
|
{ "set_included_ranges", parser_set_ranges },
|
||||||
{ NULL, NULL }
|
{ NULL, NULL }
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -383,6 +385,92 @@ static int parser_edit(lua_State *L)
|
|||||||
return 0;
|
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
|
// Tree methods
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user