all messages for Emacs-related lists mirrored at yhetil.org
 help / color / mirror / code / Atom feed
From: Yuan Fu <casouri@gmail.com>
To: Dmitry Gutov <dmitry@gutov.dev>, Eli Zaretskii <eliz@gnu.org>,
	Stefan Monnier <monnier@IRO.UMontreal.CA>
Cc: 66732@debbugs.gnu.org, dominik@honnef.co
Subject: bug#66732: tree-sitter fontification doesn't update multi-line syntax reliably
Date: Mon, 11 Dec 2023 23:50:53 -0800	[thread overview]
Message-ID: <8c7cd429-bdc3-4fac-ad1c-fbad793bf1a0@gmail.com> (raw)
In-Reply-To: <50920549-006c-0153-2471-02e41a3dada7@gutov.dev>



On 12/11/23 7:53 AM, Dmitry Gutov wrote:
> On 11/12/2023 06:16, Yuan Fu wrote:
>> The way we achieves this is thought parser notifiers. When 
>> tree-sitter parser reparses, it notifies us of which part of the 
>> buffer was affected by the reparse. For font-lock, we have this 
>> font-lock notifier that marks the affected buffer region as "not 
>> fontified", so redisplay will refontify those areas.
>>
>> (defun treesit--font-lock-notifier (ranges parser)
>>    "Ensures updated parts of the parse-tree are refontified.
>> RANGES is a list of (BEG . END) ranges, PARSER is the tree-sitter
>> parser notifying of the change."
>>    (with-current-buffer (treesit-parser-buffer parser)
>>      (dolist (range ranges)
>>        (when treesit--font-lock-verbose
>>          (message "Notifier received range: %s-%s"
>>                   (car range) (cdr range)))
>>        (with-silent-modifications
>>          (put-text-property (car range) (cdr range) 'fontified nil)))))
>>
>> This notifier function will be called during redisplay [1]. I suspect 
>> that because of this timing, redisplay doesn't refontify the marked 
>> region immediately. So I added a timer, I think that ensures we mark 
>> the affected region in the next command loop?
>>
>> (defun treesit--font-lock-notifier (ranges parser)
>>    "Ensures updated parts of the parse-tree are refontified.
>> RANGES is a list of (BEG . END) ranges, PARSER is the tree-sitter
>> parser notifying of the change."
>>    (with-current-buffer (treesit-parser-buffer parser)
>>      (dolist (range ranges)
>>        (when treesit--font-lock-verbose
>>          (message "Notifier received range: %s-%s"
>>                   (car range) (cdr range)))
>>        (run-with-timer
>>         0 nil
>>         (lambda ()
>>           (with-silent-modifications
>>             (put-text-property (car range) (cdr range)
>>                                'fontified nil)))))))
>>
>> This seems to work. Eli, do you see any problem using run-with-timer 
>> this way? What's the correct way to mark some region unfontified?
>>
>> [1] The chain of events if roughly: user types the last "/" -> 
>> redisplay -> fontify that character -> access parser -> parser 
>> reparses -> calls notifier.
>
> Note that it's not just font-lock. syntax-propertize has the same 
> problem (I've described it in https://debbugs.gnu.org/67262#23).
>
> And a timer wouldn't help because syntax-ppss needs to have up-to-date 
> information whenever it's called, not later.
>

I feel that font-lock and syntax-ppss have different problems and 
requires different solutions. For font-lock, we need to mark affected 
range unfontified; we just need to make sure we do that after 
jit-lock-fontify-now. For syntax-ppss, we need to force a reparse before 
entering syntax-ppss so that syntax text properties are up-to-date when 
syntax-ppss do its work.
> Here's a draft solution based on *-extend-region-functions, attached.
>
> Alas, while it works fine in python-ts-mode (for both syntax and 
> font-lock), making it behave better than python-mode, in c-ts-mode it 
> doesn't quite have the same effect: when you backspace over the 
> closing "/", the highlighting is properly updated only after you make 
> the next edit (any edit), or select another window. I'm not sure, 
> though, if it's due to my own problems with Emacs's failure to 
> redisplay (reported elsewhere), so more testing is welcome.
>
> But that might also be related to the use of 
> c-ts-mode--emacs-set-ranges: printing a backtrace calls inside 
> treesit--font-lock-notifier shows that the last notification comes 
> also during font-lock but after treesit--font-lock-extend-region, 
> inside c-ts-mode--emacs-set-ranges. I don't quite understand this 
> design where the ranges are applied inside the font-lock code.
c-ts-mode--emacs-set-ranges is registered as a range rule, so many 
tree-sitter function calls it before doing anything to make sure range 
is up-to-date. treesit-font-lock-fontify-region calls 
treesit-update-ranges at the beginning of its body, and 
treesit-update-ranges calls c-ts-mode--emacs-set-ranges.

Yuan





  reply	other threads:[~2023-12-12  7:50 UTC|newest]

Thread overview: 58+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-10-24 14:22 bug#66732: tree-sitter fontification doesn't update multi-line syntax reliably Dominik Honnef
2023-10-24 23:15 ` Dmitry Gutov
2023-10-29 12:22   ` Eli Zaretskii
2023-11-18  8:37     ` Eli Zaretskii
2023-12-11  4:16       ` Yuan Fu
2023-12-11 12:05         ` Eli Zaretskii
2023-12-11 14:35           ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors
2023-12-11 15:53         ` Dmitry Gutov
2023-12-12  7:50           ` Yuan Fu [this message]
2023-12-12 12:43             ` Dmitry Gutov
2023-12-13  3:28               ` Yuan Fu
2023-12-13  3:45                 ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors
2023-12-13  7:12                   ` Yuan Fu
2023-12-13 14:30                     ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors
2023-12-14  1:43                 ` Dmitry Gutov
2023-12-14  8:29                   ` Yuan Fu
2023-12-15  1:01                     ` Dmitry Gutov
2023-12-15  7:12                       ` Yuan Fu
2023-12-16  5:56                         ` Yuan Fu
2023-12-16 15:22                           ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors
2023-12-16 17:11                             ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors
2023-12-16 17:23                               ` Dmitry Gutov
2023-12-16 17:43                                 ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors
2023-12-16 19:18                                   ` Yuan Fu
2023-12-16 19:57                                     ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors
2023-12-16 23:09                                     ` Dmitry Gutov
2023-12-17  1:16                                       ` Yuan Fu
2023-12-17 18:32                                         ` Dmitry Gutov
2023-12-19  3:12                                           ` Yuan Fu
2023-12-20  1:52                                             ` Dmitry Gutov
2023-12-20  5:43                                               ` Yuan Fu
2023-12-20 11:31                                                 ` Dmitry Gutov
2023-12-16 23:02                                   ` Dmitry Gutov
2023-12-20  2:01                               ` Dmitry Gutov
2023-12-20  3:08                                 ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors
2023-12-16 22:56                           ` Dmitry Gutov
2023-12-18 18:27                             ` Dmitry Gutov
2023-12-18 19:12                               ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors
2023-12-18 19:33                                 ` Eli Zaretskii
2023-12-18 23:10                                   ` Dmitry Gutov
2023-12-19  3:22                                     ` Eli Zaretskii
2023-12-19  3:40                                       ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors
2023-12-19 12:41                                         ` Eli Zaretskii
2023-12-19 12:44                                           ` Dmitry Gutov
2023-12-20 20:50                                           ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors
2023-12-23 10:17                                             ` Eli Zaretskii
2023-12-23 18:02                                               ` Yuan Fu
2023-12-23 20:46                                                 ` Dmitry Gutov
2023-12-23 20:51                                                   ` Dmitry Gutov
2023-12-23 23:07                                                     ` Yuan Fu
2023-12-24  2:10                                                       ` Dmitry Gutov
2023-12-24  3:02                                                         ` Yuan Fu
2023-12-23 20:55                                               ` Dmitry Gutov
2023-12-24  6:03                                                 ` Eli Zaretskii
2024-02-08  1:40                                                   ` Yuan Fu
2023-12-18 23:08                                 ` Dmitry Gutov
2023-12-20 20:50                                   ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors
2023-12-12 15:34             ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=8c7cd429-bdc3-4fac-ad1c-fbad793bf1a0@gmail.com \
    --to=casouri@gmail.com \
    --cc=66732@debbugs.gnu.org \
    --cc=dmitry@gutov.dev \
    --cc=dominik@honnef.co \
    --cc=eliz@gnu.org \
    --cc=monnier@IRO.UMontreal.CA \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this external index

	https://git.savannah.gnu.org/cgit/emacs.git
	https://git.savannah.gnu.org/cgit/emacs/org-mode.git

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.