]> git.eshelyaron.com Git - emacs.git/commit
Ditch the async range update in tree-sitter (bug#78402)
authorYuan Fu <casouri@gmail.com>
Wed, 9 Jul 2025 06:15:58 +0000 (23:15 -0700)
committerEshel Yaron <me@eshelyaron.com>
Thu, 24 Jul 2025 07:52:18 +0000 (09:52 +0200)
commite48d5744c3e8d0b10f0e5eebf49a6e10a54b9153
tree1d8fd6a5f98e7e951228015f9cd80f63008e40b0
parent843426065091c0ee03d066ceb8432ab13ca1fa3e
Ditch the async range update in tree-sitter (bug#78402)

Right now in treesit-outline-search -> treesit-navigate-thing, a
freshly created tree-sitter node becomes outdated within the
function.  I'm not sure _exactly_ how it happend, but it might
look like this: we first get a node from, say, html parser, then
get another node from, say, liquid parser.  Creating the node
from liquid parser causes a reparse which updated the range of
the html parser, which rendered the html node outdated.

There're several problems with the current design, let's start
with the most obvious one: we add
treesit--font-lock-mark-ranges-to-fontify as a notifier of the
primar parser in treesit-major-mode-setup.  Now, if a ts major
mode inherits another major mode, treesit-major-mode-setup will
be called twice, once in the parent mode and once in the child
node, and two parsers will have the notifier.  But
treesit--font-lock-mark-ranges-to-fontify is designed to run
only once.

I believe this bug, together with some mysterious async
execution order, led to the problems we saw in the bug report.
My solution is to just make everything synchronous.

So I added treesit-parser-changed-regions, and modified
treesit--font-lock-mark-ranges-to-fontify to use it.  Now we
don't need to add the notifier to the primary parser anymore.

I also applied the tree-sitter-outline change we discussed in
the bug report.  (Change to treesit-outline-search, and remove
treesit--after-change.)

* lisp/treesit.el:
(treesit--font-lock-mark-ranges-to-fontify): Remove the unused
PARSER arg.
(treesit--pre-redisplay): Make use of
treesit-parser-changed-regions.
(treesit-outline-search): Call treesit--pre-redisplay in the
beginning.
(treesit--after-change): Remove function.
(treesit-major-mode-setup): Don't add notifier to primary parser.

(cherry picked from commit 159ddd27ee6b6c8cd261c6ff495e66ddb6166685)
lisp/treesit.el