Subject: bug#64321: closed (Re: bug#64321: 29.0.92; Tree-Sitter/which-function Narrow/Widen causes modified buffer)

From: [email-masked] (GNU bug Tracking System)
Date: Wed, 28 Jun 2023 20:11:01 +0000

Your bug report

#64321: 29.0.92; Tree-Sitter/which-function Narrow/Widen causes modified buffer

which was filed against the emacs package, has been closed.

The explanation is attached below, along with your original report.
If you require more details, please reply to [email-masked].

-- 
64321: https://debbugs.gnu.org/cgi/bugreport.cgi?bug=64321
GNU Bug Tracking System
Contact [email-masked] with problems

Subject: Re: bug#64321: 29.0.92; Tree-Sitter/which-function Narrow/Widen causes modified buffer
From: Yuan Fu <[email-masked]>
To: Troy Brown <[email-masked]>
Cc: Eli Zaretskii <[email-masked]>, [email-masked]
Date: Wed, 28 Jun 2023 13:09:41 -0700
List-Id: <debbugs-submit.debbugs.gnu.org>

> On Jun 28, 2023, at 9:25 AM, Troy Brown <[email-masked]> wrote:
> 
> On Wed, Jun 28, 2023 at 12:04 AM Yuan Fu <[email-masked]> wrote:
>> 
>> Narrowing and widening are transparent to tree-sitter, so when the buffer widens, from tree-sitter’s POV, text are added to the buffer. Which-func calling the tree-sitter current-defund function ultimately leads to tree-sitter calling treesit—font-lock-notifier which puts text properties on the “added” portion of the buffer, which changed the modified status.
>> 
>> treesit—font-lock-notifier should put text properties without changing modified status, like what jit-lock does. This patch should fix it.
>> 
> 
> Thanks for the explanation and the supplied patch.  I can confirm that
> this patch fixes the issue.

Cool, thanks, pushed.

Yuan

Subject: 29.0.92; Tree-Sitter/which-function Narrow/Widen causes modified buffer
From: Troy Brown <[email-masked]>
To: [email-masked]
Date: Tue, 27 Jun 2023 22:23:52 -0400
List-Id: <debbugs-submit.debbugs.gnu.org>

This problem seems to manifest with multiple tree-sitter modes.  It
appears there is an interaction with which-function-mode and tree-sitter
which causes the buffer to be considered modified either after a narrow
or widen of the buffer.

To reproduce this, use a "hello_world.c" as follows:

--8<---------------cut here---------------start------------->8---
#include <stdio.h>

int main (void)
{
  printf("Hello, world!\n");
  return 0;
}
--8<---------------cut here---------------end--------------->8---

Running "emacs -Q" with the corresponding tree-sitter grammar library
installed.  Move into the main function and narrow-to-defun.  In some
modes, I've seen this cause the buffer to show as modified, however with
this example, it seems to occur after widening.

The following sequence of commands can be used to reproduce the issue:

C-x C-f ~/hello_world.c
M-x c-ts-mode
M-x which-function-mode
C-x n d
C-x n w

At this point, the modeline shows that the buffer is modified, and
running "M-: (buffer-modified-p)" indicates "t".  As previously
mentioned, this appears to only happen with tree-sitter modes when
which-function-mode is enabled in the buffer.

I then repeated the same but also triggered a backtrace on the first
change as follows:

M-: (add-to-list 'first-change-hook #'backtrace)

With that in place, the following is the generated traceback:

  backtrace()
  treesit--font-lock-notifier(((1 . 21)) #<treesit-parser for c>)
  treesit-buffer-root-node(c)
  treesit-node-at(68)
  treesit--things-around(68
"\\(?:class_specifier\\|enum_specifier\\|function_defi..."
c-ts-mode--defun-valid-p)
  treesit-thing-at-point(("\\(?:class_specifier\\|enum_specifier\\|function_defi..."
. c-ts-mode--defun-valid-p) top-level)
  treesit-defun-at-point()
  treesit-add-log-current-defun()
  c-ts-mode--emacs-current-defun-name()
  add-log-current-defun()
  which-function()
  which-func-update-1(#<window 3 on hello_world.c>)
  which-func-update()
  apply(which-func-update nil)
  timer-event-handler([t 0 0 500000 t which-func-update nil idle 0 nil])