> On Jun 27, 2023, at 7:23 PM, Troy Brown wrote: > > 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 > > 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-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(#) > which-func-update() > apply(which-func-update nil) > timer-event-handler([t 0 0 500000 t which-func-update nil idle 0 nil]) Thanks for the backtrace, it’s very helpful. 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. Yuan