aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.github/workflows/test.yml7
-rw-r--r--runtime/lua/vim/treesitter/languagetree.lua94
-rwxr-xr-xsrc/nvim/CMakeLists.txt2
-rw-r--r--src/nvim/lua/treesitter.c19
4 files changed, 63 insertions, 59 deletions
diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml
index 0d18f874c4..7794e07077 100644
--- a/.github/workflows/test.yml
+++ b/.github/workflows/test.yml
@@ -376,13 +376,13 @@ jobs:
libluajit-5.1-dev \
libmsgpack-dev \
libtermkey-dev \
- libtree-sitter-dev \
libunibilium-dev \
libuv1-dev \
lua-filesystem \
lua-lpeg \
lua-mpack \
luajit
+ # libtree-sitter-dev \
# libvterm-dev \
# lua-luv-dev
@@ -397,7 +397,10 @@ jobs:
# dependencies don't have the required version available. We use the
# bundled versions for these with the hopes of being able to remove them
# later on.
- cmake -S cmake.deps -B .deps -G Ninja -D USE_BUNDLED=OFF -D USE_BUNDLED_LUV=ON -D USE_BUNDLED_LIBVTERM=ON
+ cmake -S cmake.deps -B .deps -G Ninja -D USE_BUNDLED=OFF \
+ -D USE_BUNDLED_LUV=ON \
+ -D USE_BUNDLED_LIBVTERM=ON \
+ -D USE_BUNDLED_TS=ON
cmake --build .deps
- name: Build
diff --git a/runtime/lua/vim/treesitter/languagetree.lua b/runtime/lua/vim/treesitter/languagetree.lua
index 922e4881ca..cf0ecbd839 100644
--- a/runtime/lua/vim/treesitter/languagetree.lua
+++ b/runtime/lua/vim/treesitter/languagetree.lua
@@ -57,7 +57,9 @@ local Range = require('vim.treesitter._range')
---@field private _injection_query Query Queries defining injected languages
---@field private _opts table Options
---@field private _parser TSParser Parser for language
----@field private _regions Range6[][] List of regions this tree should manage and parse
+---@field private _regions Range6[][]?
+---List of regions this tree should manage and parse. If nil then regions are
+---taken from _trees. This is mostly a short-lived cache for included_regions()
---@field private _lang string Language name
---@field private _source (integer|string) Buffer or string to parse
---@field private _trees TSTree[] Reference to parsed tree (one for each language)
@@ -91,7 +93,6 @@ function LanguageTree.new(source, lang, opts)
_source = source,
_lang = lang,
_children = {},
- _regions = {},
_trees = {},
_opts = opts,
_injection_query = injections[lang] and query.parse(lang, injections[lang])
@@ -237,27 +238,21 @@ function LanguageTree:parse()
--- At least 1 region is invalid
if not self:is_valid(true) then
- local function _parsetree(index)
- local parse_time, tree, tree_changes =
- tcall(self._parser.parse, self._parser, self._trees[index], self._source)
-
- self:_do_callback('changedtree', tree_changes, tree)
- self._trees[index] = tree
- vim.list_extend(changes, tree_changes)
-
- total_parse_time = total_parse_time + parse_time
- regions_parsed = regions_parsed + 1
- end
-
- if #self._regions > 0 then
- for i, ranges in ipairs(self._regions) do
- if not self._valid or not self._valid[i] then
- self._parser:set_included_ranges(ranges)
- _parsetree(i)
- end
+ -- If there are no ranges, set to an empty list
+ -- so the included ranges in the parser are cleared.
+ for i, ranges in ipairs(self:included_regions()) do
+ if not self._valid or not self._valid[i] then
+ self._parser:set_included_ranges(ranges)
+ local parse_time, tree, tree_changes =
+ tcall(self._parser.parse, self._parser, self._trees[i], self._source)
+
+ self:_do_callback('changedtree', tree_changes, tree)
+ self._trees[i] = tree
+ vim.list_extend(changes, tree_changes)
+
+ total_parse_time = total_parse_time + parse_time
+ regions_parsed = regions_parsed + 1
end
- else
- _parsetree(1)
end
end
@@ -403,7 +398,7 @@ function LanguageTree:_iter_regions(fn)
local all_valid = true
- for i, region in ipairs(self._regions) do
+ for i, region in ipairs(self:included_regions()) do
if self._valid[i] == nil then
self._valid[i] = true
end
@@ -454,7 +449,7 @@ function LanguageTree:set_included_regions(new_regions)
end
end
- if #self._regions ~= #new_regions then
+ if #self:included_regions() ~= #new_regions then
self._trees = {}
self:invalidate()
else
@@ -462,13 +457,28 @@ function LanguageTree:set_included_regions(new_regions)
return vim.deep_equal(new_regions[i], region)
end)
end
+
self._regions = new_regions
end
---Gets the set of included regions
---@return integer[][]
function LanguageTree:included_regions()
- return self._regions
+ if self._regions then
+ return self._regions
+ end
+
+ if #self._trees == 0 then
+ return { {} }
+ end
+
+ local regions = {} ---@type Range6[][]
+ for i, _ in ipairs(self._trees) do
+ regions[i] = self._trees[i]:included_ranges(true)
+ end
+
+ self._regions = regions
+ return regions
end
---@private
@@ -721,6 +731,8 @@ function LanguageTree:_edit(
)
end
+ self._regions = nil
+
local changed_range = {
start_row,
start_col,
@@ -730,42 +742,12 @@ function LanguageTree:_edit(
end_byte_old,
}
- local new_range = {
- start_row,
- start_col,
- start_byte,
- end_row_new,
- end_col_new,
- end_byte_new,
- }
-
- if #self._regions == 0 then
- self._valid = false
- end
-
-- Validate regions after editing the tree
self:_iter_regions(function(_, region)
- for i, r in ipairs(region) do
+ for _, r in ipairs(region) do
if Range.intercepts(r, changed_range) then
return false
end
-
- -- Range after change. Adjust
- if Range.cmp_pos.gt(r[1], r[2], changed_range[4], changed_range[5]) then
- local byte_offset = new_range[6] - changed_range[6]
- local row_offset = new_range[4] - changed_range[4]
-
- -- Update the range to avoid invalidation in set_included_regions()
- -- which will compare the regions against the parsed injection regions
- region[i] = {
- r[1] + row_offset,
- r[2],
- r[3] + byte_offset,
- r[4] + row_offset,
- r[5],
- r[6] + byte_offset,
- }
- end
end
return true
end)
diff --git a/src/nvim/CMakeLists.txt b/src/nvim/CMakeLists.txt
index cb688785df..c0466e3de9 100755
--- a/src/nvim/CMakeLists.txt
+++ b/src/nvim/CMakeLists.txt
@@ -21,7 +21,7 @@ find_package(Iconv REQUIRED)
find_package(Libtermkey 0.22 REQUIRED)
find_package(Libvterm 0.3 REQUIRED)
find_package(Msgpack 1.0.0 REQUIRED)
-find_package(Treesitter REQUIRED)
+find_package(Treesitter 0.20.8 REQUIRED)
find_package(Unibilium 2.0 REQUIRED)
target_link_libraries(main_lib INTERFACE
diff --git a/src/nvim/lua/treesitter.c b/src/nvim/lua/treesitter.c
index 289a0cb9b4..ae3a7b6d75 100644
--- a/src/nvim/lua/treesitter.c
+++ b/src/nvim/lua/treesitter.c
@@ -64,6 +64,7 @@ static struct luaL_Reg tree_meta[] = {
{ "__tostring", tree_tostring },
{ "root", tree_root },
{ "edit", tree_edit },
+ { "included_ranges", tree_get_ranges },
{ "copy", tree_copy },
{ NULL, NULL }
};
@@ -512,6 +513,24 @@ static int tree_edit(lua_State *L)
return 0;
}
+static int tree_get_ranges(lua_State *L)
+{
+ TSTree **tree = tree_check(L, 1);
+ if (!(*tree)) {
+ return 0;
+ }
+
+ bool include_bytes = (lua_gettop(L) >= 2) && lua_toboolean(L, 2);
+
+ uint32_t len;
+ TSRange *ranges = ts_tree_included_ranges(*tree, &len);
+
+ push_ranges(L, ranges, len, include_bytes);
+
+ xfree(ranges);
+ return 1;
+}
+
// Use the top of the stack (without popping it) to create a TSRange, it can be
// either a lua table or a TSNode
static void range_from_lua(lua_State *L, TSRange *range)