aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDmytro Soltys <soap@slotos.net>2023-11-27 13:34:32 +0100
committerChristian Clason <c.clason@uni-graz.at>2023-11-27 15:53:26 +0100
commit72ed99319dd662f0e35b58e888b57f98ac3b3eec (patch)
treebab3c21a051ee815e80d3e967b513020ea479fcb
parent40139738eb479d0913ec6ce751ca5adfa50ad8c3 (diff)
downloadrneovim-72ed99319dd662f0e35b58e888b57f98ac3b3eec.tar.gz
rneovim-72ed99319dd662f0e35b58e888b57f98ac3b3eec.tar.bz2
rneovim-72ed99319dd662f0e35b58e888b57f98ac3b3eec.zip
fix(treesitter): don't invalidate parser when discovering injections
When parsing with a range, languagetree looks up injections and adds them if needed. This explicitly invalidates parser, making `is_valid` report `false` both when including and excluding children. This is an attempt to describe desired behaviour of `is_valid` in tests, with what ended up being a single line change to satisfy them.
-rw-r--r--runtime/lua/vim/treesitter/languagetree.lua2
-rw-r--r--test/functional/treesitter/parser_spec.lua117
2 files changed, 117 insertions, 2 deletions
diff --git a/runtime/lua/vim/treesitter/languagetree.lua b/runtime/lua/vim/treesitter/languagetree.lua
index 670f2797b7..0171b416cd 100644
--- a/runtime/lua/vim/treesitter/languagetree.lua
+++ b/runtime/lua/vim/treesitter/languagetree.lua
@@ -508,7 +508,6 @@ function LanguageTree:add_child(lang)
end
self._children[lang] = child
- self:invalidate()
self:_do_callback('child_added', self._children[lang])
return self._children[lang]
@@ -524,7 +523,6 @@ function LanguageTree:remove_child(lang)
if child then
self._children[lang] = nil
child:destroy()
- self:invalidate()
self:_do_callback('child_removed', child)
end
end
diff --git a/test/functional/treesitter/parser_spec.lua b/test/functional/treesitter/parser_spec.lua
index 8222bb59c4..6f386115ae 100644
--- a/test/functional/treesitter/parser_spec.lua
+++ b/test/functional/treesitter/parser_spec.lua
@@ -1095,4 +1095,121 @@ int x = INT_MAX;
' ^',
'((identifier) @id \n(#eq? @id\n@ok.capture\n))')
end)
+
+ describe('is_valid()', function()
+ before_each(function()
+ insert(dedent[[
+ Treesitter integration *treesitter*
+
+ Nvim integrates the `tree-sitter` library for incremental parsing of buffers:
+ https://tree-sitter.github.io/tree-sitter/
+
+ ]])
+
+ feed(':set ft=help<cr>')
+
+ exec_lua [[
+ vim.treesitter.get_parser(0, "vimdoc", {
+ injections = {
+ vimdoc = "((codeblock (language) @injection.language (code) @injection.content) (#set! injection.include-children))"
+ }
+ })
+ ]]
+ end)
+
+ it('is valid excluding, invalid including children initially', function()
+ eq(true, exec_lua('return vim.treesitter.get_parser():is_valid(true)'))
+ eq(false, exec_lua('return vim.treesitter.get_parser():is_valid()'))
+ end)
+
+ it('is fully valid after a full parse', function()
+ exec_lua('vim.treesitter.get_parser():parse(true)')
+ eq(true, exec_lua('return vim.treesitter.get_parser():is_valid(true)'))
+ eq(true, exec_lua('return vim.treesitter.get_parser():is_valid()'))
+ end)
+
+ it('is fully valid after a parsing a range on parsed tree', function()
+ exec_lua('vim.treesitter.get_parser():parse({5, 7})')
+ eq(true, exec_lua('return vim.treesitter.get_parser():is_valid(true)'))
+ eq(true, exec_lua('return vim.treesitter.get_parser():is_valid()'))
+ end)
+
+ describe('when adding content with injections', function()
+ before_each(function()
+ feed('G')
+ insert(dedent[[
+ >lua
+ local a = {}
+ <
+
+ ]])
+ end)
+
+ it('is fully invalid after changes', function()
+ eq(false, exec_lua('return vim.treesitter.get_parser():is_valid(true)'))
+ eq(false, exec_lua('return vim.treesitter.get_parser():is_valid()'))
+ end)
+
+ it('is valid excluding, invalid including children after a rangeless parse', function()
+ exec_lua('vim.treesitter.get_parser():parse()')
+ eq(true, exec_lua('return vim.treesitter.get_parser():is_valid(true)'))
+ eq(false, exec_lua('return vim.treesitter.get_parser():is_valid()'))
+ end)
+
+ it('is fully valid after a range parse that leads to parsing not parsed injections', function()
+ exec_lua('vim.treesitter.get_parser():parse({5, 7})')
+ eq(true, exec_lua('return vim.treesitter.get_parser():is_valid(true)'))
+ eq(true, exec_lua('return vim.treesitter.get_parser():is_valid()'))
+ end)
+
+ it('is valid excluding, invalid including children after a range parse that does not lead to parsing not parsed injections', function()
+ exec_lua('vim.treesitter.get_parser():parse({2, 4})')
+ eq(true, exec_lua('return vim.treesitter.get_parser():is_valid(true)'))
+ eq(false, exec_lua('return vim.treesitter.get_parser():is_valid()'))
+ end)
+ end)
+
+ describe('when removing content with injections', function()
+ before_each(function()
+ feed('G')
+ insert(dedent[[
+ >lua
+ local a = {}
+ <
+
+ >lua
+ local a = {}
+ <
+
+ ]])
+
+ exec_lua('vim.treesitter.get_parser():parse(true)')
+
+ feed('Gd3k')
+ end)
+
+ it('is fully invalid after changes', function()
+ eq(false, exec_lua('return vim.treesitter.get_parser():is_valid(true)'))
+ eq(false, exec_lua('return vim.treesitter.get_parser():is_valid()'))
+ end)
+
+ it('is valid excluding, invalid including children after a rangeless parse', function()
+ exec_lua('vim.treesitter.get_parser():parse()')
+ eq(true, exec_lua('return vim.treesitter.get_parser():is_valid(true)'))
+ eq(false, exec_lua('return vim.treesitter.get_parser():is_valid()'))
+ end)
+
+ it('is fully valid after a range parse that leads to parsing modified child tree', function()
+ exec_lua('vim.treesitter.get_parser():parse({5, 7})')
+ eq(true, exec_lua('return vim.treesitter.get_parser():is_valid(true)'))
+ eq(true, exec_lua('return vim.treesitter.get_parser():is_valid()'))
+ end)
+
+ it('is valid excluding, invalid including children after a range parse that does not lead to parsing modified child tree', function()
+ exec_lua('vim.treesitter.get_parser():parse({2, 4})')
+ eq(true, exec_lua('return vim.treesitter.get_parser():is_valid(true)'))
+ eq(false, exec_lua('return vim.treesitter.get_parser():is_valid()'))
+ end)
+ end)
+ end)
end)