Description
I am currently implementing incremental injection query matching for Neovim, but making a query able to run incrementally requires adding some extra information to all its patterns. Currently, it's #set! nvim.injection-root @some-node
, but that would mean that Neovim's injection queries would diverge from other editors/upstream, and that's not desirable.
If running injection queries incrementally is desirable for Helix, then we should come up with a better name, and probably open an issue in tree-sitter as well.
The basic idea with running tree-sitter queries incrementally is that majority of patterns have a "root" node, i.e. such a node, for which the text/syntax changes outside its range don't change whether the pattern matches on it or not.
E.g. for this pattern:
((call_expression
function: (identifier) @_function
arguments: (argument_list
(_)
.
(string_literal
(string_content) @injection.content)))
(#eq? @_function "fprintf")
(#set! injection.language "printf"))
the "root" node is call_expression
, because only changes to its children affect whether the node matches or not.
After a change, there's no need to rerun the query matches iterator on the entire file, only on changed ranges. And matches outside the changed ranges can be reused.
See neovim/neovim#31809 for more details, and neovim/neovim#31975 for the implementation.