Subject: Re: bug#78402: treesit after-change-functions

From: Yuan Fu <[email-masked]>
Date: Wed, 21 May 2025 22:36:06 -0700

> On May 21, 2025, at 10:47 AM, Stefan Monnier <[email-masked]> wrote:
> 
> Yuan Fu [2025-05-21 00:21:39] wrote:
>>> On May 20, 2025, at 11:35 PM, Juri Linkov <[email-masked]> wrote:
>>>>>> Btw, what’s the issue we’re trying to fix here? If some lisp want to have
>>>>>> up-to-date ranges, it can just call treesit--pre-redisplay or
>>>>>> treesit-update-ranges. Why do we get the node-outdated error?
>>>>> 
>>>>> Hmm... so what you're saying is that we should do something like the
>>>>> patch below?
>>>> 
>>>> Maybe Yuan could confirm if `treesit-update-ranges`
>>>> is already optimized for frequent calls on overlapping ranges
>>>> that don't need updating and where 'beg' and 'end' fall back
>>>> to (point-min) and (point-max).
>>> 
>>> It seems not optimized since in my tests outline-minor-mode
>>> is much slower with this change.
>> 
>> Hey, sorry for the delay. I've been busy with real life. As you said,
>> `treesit-update-ranges` doesn’t have any optimization for repeated
>> calls.
> 
> That seems like a potential problem for existing uses of that function
> (we're just "lucky" that they're expected to be used once-per-command).

Kind of, yeah. Most of the time fontification updates the ranges early enough that other lisp commands/functions never see the state when the ranges are not up to date.

> 
>> OTOH, `treesit--pre-redisplay` has optimization for repeated calls
>> while buffer content doesn’t change. Maybe the patch can use that instead?
> 
> Like in the patch below?
> 
> That sounds OK, but then `treesit--pre-redisplay` needs to be renamed to
> something like `treesit--update` or `treesit--sync`, and maybe
> `treesit-font-lock-fontify-region`, `treesit-indent`, and
> `treesit-indent-region` should use that function instead of
> `treesit-update-ranges`?
> 

Yeah. On top of that, we can try calling `treesit--pre-redisplay` in `treesit-node-at`, which should ensure range is always up-to-date. The downside is the potential cost of updating range for the whole buffer, especially when an edit changes actually does affect the whole buffer (like inserting /* in C) and we have to add/remove hundred of local parsers (eg, for doxygen).

Yuan