bug#72573: 29.4; js-mode/JSX: forward-sexp behavior at end of string in JSX fragments

2024-09-01 Thread Juri Linkov
>> @@ -3929,7 +3929,8 @@ js-ts-mode
>> (sexp ,(js--regexp-opt-symbol js--treesit-sexp-nodes))
>> (sentence ,(js--regexp-opt-symbol 
>> js--treesit-sentence-nodes))
>> (text ,(js--regexp-opt-symbol '("comment"
>> -   "template_string"))
>> +   "template_string"
>> +   "string_fragment"))
>> 
>> But since this bug report about the default non-ts behavior,
>> I have no idea why the default forward-sexp-function moves to
>> the beginning of the next string.  Maybe this was implemented
>> because the default ad-hoc syntax parsing is not reliable and might
>> mix up string beginnings and endings.  tree-sitter has no such problem.
>
> So what is our way forward with this?  Should we install the above
> patch, or should we close this bug ans wontfix?

I pushed the above patch with small changes to master.

Since the report was about non-ts modes, and it's not easy to change
the default behavior, probably this can be closed as wontfix.





bug#72757: No symbols in etc/NEWS

2024-09-01 Thread Juri Linkov
close 72757 30.0.60
thanks

>> > M-: (modify-syntax-entry ?' "\"") RET
>> >
>> > in the NEWS buffer and C-h o seems to work everywhere.  I am not sure if
>> > we want ' to be "string quote" or punctuation like " already is, or
>> > something else.
>> 
>> Thanks, this looks like the right thing to do.
>
> I made that change, but please note that it is not enough to show each
> symbol in NEWS as the default when you type "C-h o".  This is because
> "C-h o" tests symbol-at-point for being bound, either as a function or
> a variable or a face etc., and if the corresponding library is not yet
> loaded, those tests will fail.

The problem was that 'describe-symbol' uses 'function-called-at-point',
but not anything to get a variable at point.  But now this is fixed,
and when a library is not loaded this is not a problem.

> If this is deemed okay, we can close this bug.

So I'm closing this bug.  The fix helped me to check
documentation while rereading some parts of etc/NEWS,
so small doc fixes are pushed now as well.





bug#72951: Hideshow support for treesitter

2024-09-02 Thread Juri Linkov
> Are there any plans to add treesitter support for hideshow, it seems easy
> enough to do and also very helpful, especially for langs that don't
> excessively use parens, such as python

There is already treesitter support for outline-minor-mode,
so you could look into implementation to do something similar.





bug#73018: 31.0.50; wdired + replace-regexp only modifies the visible portion of the buffer

2024-09-04 Thread Juri Linkov
>> +  (font-lock-ensure)
>>(run-mode-hooks 'wdired-mode-hook)
>>(message "%s" (substitute-command-keys
>>   "Press \\[wdired-finish-edit] when finished \
>
> Yip.  When we do this (guess we don't have a choice), my preferred
> solution would be to hook this into the corresponding isearch function.
> Because calling `font-lock-ensure' can be really slow in large dired
> buffers (several seconds).  Or we manage to rewrite things so that the
> work is done on the fly in some way.

So you prefer to slow down only when the user types C-s?
This is possible by adding a local hook in
wdired-change-to-wdired-mode:

  (add-hook 'isearch-mode-hook #'font-lock-ensure nil t)





bug#73027: Fwd: 31.0.50; tab-bar-formal-global erased global-modeline-string's mouse hover/click action menu

2024-09-04 Thread Juri Linkov
> I'm using tab-bar-mode, and I've included `tab-bar-format-global` in
> `tab-bar-format`.  This displays `global-mode-string` on the tab-bar.
>
> However, in `global-mode-string`, I have `mu4e`.  The tab-bar seems to
> remove the hover and mouse click actions from `global-mode-string`.

Please show your `global-mode-string` with `mu4e` in it.





bug#73027: Fwd: 31.0.50; tab-bar-formal-global erased global-modeline-string's mouse hover/click action menu

2024-09-04 Thread Juri Linkov
>>> I'm using tab-bar-mode, and I've included `tab-bar-format-global` in
>>> `tab-bar-format`.  This displays `global-mode-string` on the tab-bar.
>>>
>>> However, in `global-mode-string`, I have `mu4e`.  The tab-bar seems to
>>> remove the hover and mouse click actions from `global-mode-string`.
>>
>> Please show your `global-mode-string` with `mu4e` in it.
>
> I execute describe-variable global-mode-string, it's:
>
> global-mode-string is a variable defined in xdisp.c.
>
> Value
> ((:eval (mu4e--modeline-string)) (t (:eval (lsp--progress-status)))
>  ((t lsp-java-progress-string)) (:eval (exec/git-mode-string))
>  (:eval (exec/gc-mode-string)) flycheck-mode-line)

Also please eval these calls and show their return values.





bug#73018: 31.0.50; wdired + replace-regexp only modifies the visible portion of the buffer

2024-09-05 Thread Juri Linkov
>> So you prefer to slow down only when the user types C-s?
>> This is possible by adding a local hook in
>> wdired-change-to-wdired-mode:
>>
>>   (add-hook 'isearch-mode-hook #'font-lock-ensure nil t)
>
> A step back: I now tried to reproduce the recipe, but I only see the
> clobbered match data error (randomly) - I don't see only the visible
> buffer portion operated on.  With other words: I can't reproduce the
> issue, at least not with the "visible buffer portion" interpretation,
> and I don't see that we would need to call `font-lock-ensure' at all.

Maybe this is reproducible only on very long Dired buffers?

> Second: I'm confused.  Apparently, when `dired-isearch-filenames-mode'
> is on, why do `search-forward-regexp' and `replace-regexp' behave
> differently?  `search-forward-regexp' does find matches outside of file
> names that `replace-regexp' ignores.

`replace-regexp' uses Isearch functions,
`search-forward-regexp' is a core function that doesn't use Isearch.





bug#73027: Fwd: 31.0.50; tab-bar-formal-global erased global-modeline-string's mouse hover/click action menu

2024-09-05 Thread Juri Linkov
>>> global-mode-string is a variable defined in xdisp.c.
>>> Value
>>> ((:eval (mu4e--modeline-string)) (t (:eval (lsp--progress-status)))
>>>  ((t lsp-java-progress-string)) (:eval (exec/git-mode-string))
>>>  (:eval (exec/gc-mode-string)) flycheck-mode-line)
>
> 1. (mu4e--modeline-string) :
>
> #(" 🌀0/0 "
>   1 2 (help-echo "mu4e favorite bookmark"
>mouse-face mode-line-highlight
>keymap (mode-line keymap (mouse-1 . mu4e-jump-to-favorite)
> (mouse-2 . mu4e-jump-to-favorite)
> (mouse-3 . mu4e-jump-to-favorite)))
>   2 3 (mouse-face mode-line-highlight
>keymap (mode-line keymap (mouse-1 . mu4e-jump-to-favorite)
> (mouse-2 . mu4e-jump-to-favorite)
> (mouse-3 . mu4e-jump-to-favorite))
>face mu4e-header-key-face
>help-echo "mu4e favorite bookmark")
>   3 4 (help-echo "mu4e favorite bookmark"
>mouse-face mode-line-highlight
>keymap (mode-line keymap (mouse-1 . mu4e-jump-to-favorite)
> (mouse-2 . mu4e-jump-to-favorite)
> (mouse-3 . mu4e-jump-to-favorite)))
>   4 5 (mouse-face mode-line-highlight
>keymap (mode-line keymap (mouse-1 . mu4e-jump-to-favorite)
> (mouse-2 . mu4e-jump-to-favorite)
> (mouse-3 . mu4e-jump-to-favorite))
>help-echo "mu4e favorite bookmark")
>   5 6 (help-echo "mu4e favorite bookmark"
>mouse-face mode-line-highlight
>keymap (mode-line keymap (mouse-1 . mu4e-jump-to-favorite)
> (mouse-2 . mu4e-jump-to-favorite)
> (mouse-3 . mu4e-jump-to-favorite
>
> Addition, I eval (flycheck-status-emoji-mode-line-text) got:
> (" " "😐")
> -- 
> Addition: my emacs tab-bar looks like this:
> https://imgur.com/a/IyXki2P

Thanks, looks nice 😉





bug#73004: [PATCH] Make `dired-do-open' work on non GNU/Linux systems

2024-09-05 Thread Juri Linkov
>>> > And is xdg-open reliably available on BSD systems, so that we don't
>>> > generate an opaque error message if that is not the case?
>>>
>>> I think it would work whether xdg-open is install or not because
>>> `shell-command-guess-open' is defined by testing the presence of
>>> xdg-open.  So if xdg-open is not installed, `command' in the code above
>>> will be nil and nothing will happen.
>>
>> Then why do we need to condition this by system-type at all?
>
> Juri implemented the command, so perhaps he could explain.  I don't
> understand why one doesn't just use `shell-command-guess-open' directly?

The current implementation is based on long discussions including bug#18132.
So everyone is welcome to improve it, it's not cast in stone.





bug#73050: 30.0.90; Empty tool tip when hovering over tab-bar separator

2024-09-07 Thread Juri Linkov
>> This is only a minor issue. After enabling `tab-bar-mode' when hovering
>> with the mouse over the `tab-bar-separator' space, an empty tool tip
>> will be shown after a short delay.
>>
>> To reproduce:
>>
>> 1. Start emacs -Q
>> 2. M-x tab-bar-mode
>> 3. Move the mouse pointer over the space right after the "*scratch*" tab
>>
>> Would it make sense to somehow prevent displaying blank tool tips, e.g.,
>> via the following advice? Or maybe blank tool tips could be prevented on
>> the tab-bar level?
>>
>> (defun x-show-tip-adv (str &rest _) (string-blank-p str))
>> (advice-add #'x-show-tip :before-until #'x-show-tip-adv)
>
> Juri, can we prevent such empty tooltips from being shown by tab bar?

Maybe this unasked-for default fallback is not needed after all:

diff --git a/src/xdisp.c b/src/xdisp.c
index f9a10267bad..18834c6b781 100644
--- a/src/xdisp.c
+++ b/src/xdisp.c
@@ -15155,8 +15155,6 @@ note_tab_bar_highlight (struct frame *f, int x, int y)
   help_echo_object = help_echo_window = Qnil;
   help_echo_pos = -1;
   help_echo_string = AREF (f->tab_bar_items, prop_idx + TAB_BAR_ITEM_HELP);
-  if (NILP (help_echo_string))
-help_echo_string = AREF (f->tab_bar_items, prop_idx + 
TAB_BAR_ITEM_CAPTION);
 }
 
 #endif /* HAVE_WINDOW_SYSTEM */





bug#73117: 30.0.90; Imenu missing entries when flattening by group

2024-09-07 Thread Juri Linkov
> This issue appears to be similar to the issue reported in 70846, but
> this is specifically regarding when Imenu is configured to flatten
> into "groups" (as opposed to "annotation" as was reported there).
> When "imenu-flatten" is set to "group", I see an issue where nested
> entries, with the same name but belonging to different parents, aren't
> all displayed.
>
> I've included an example below (based on the example menu
> configuration described in 70846).  This example cycles through
> flattening based on "index", "group" and "annotation" with the example
> menu configuration.
>
> For "prefix" and "annotation" configurations, it appears to work
> correctly, as pressing "M-" when the menu prompt is displayed, I
> can see both entries identified in the "*Completions*" buffer.
>
> However, when I do this with "imenu-flatten" set to "group" and press
> "M-" to display the completions window, the window indicates "2
> possible completions" but only one is actually displayed and
> selectable (i.e., the one under "Bar").  The menu entry "Foo" under
> "Baz" is not displayed at all and it appears there is no way to select
> it.
>
> ```
> ;; begin
> (progn
>   (require 'imenu)
>   (dolist (flatten '(prefix group annotation))
> (setq imenu-flatten flatten)
>
> (imenu-choose-buffer-index (format "(%s) Index item: " flatten)
>`(("Bar" . (("Foo" . ,(point-min-marker
>  ("Baz" . (("Foo" . ,(point-max-marker
> ;; end
> ```

Sorry for leaving out of documentation an unapparent mention
of `completions-group`.  We are discussing this currently at
https://mail.gnu.org/archive/html/emacs-devel/2024-08/msg00241.html
So a prerequisite would be to use `(setopt completions-group t)`.
But currently this should be mentioned in the docstring.

Also in the same discussion we came to conclusion that
`M-` can't be used to select imenu items for
`annotation` and `group`.  So this limitation was
documented recently in the docstring of `imenu-flatten`:

  @@ -158,6 +158,9 @@ imenu-flatten
   with a suffix that is the section name to which it belongs.
   If the value is `group', split completion candidates into groups
   according to the sections.
  +Since the values `annotation' and `group' rely on text properties,
  +you can use them only by selecting candidates from the completions
  +buffer, not by typing in the minibuffer.

Otherwise, `group` should work nicely when using ``
with `minibuffer-visible-completions`.





bug#73050: 30.0.90; Empty tool tip when hovering over tab-bar separator

2024-09-08 Thread Juri Linkov
>> >> This is only a minor issue. After enabling `tab-bar-mode' when hovering
>> >> with the mouse over the `tab-bar-separator' space, an empty tool tip
>> >> will be shown after a short delay.
>> >>
>> >> To reproduce:
>> >>
>> >> 1. Start emacs -Q
>> >> 2. M-x tab-bar-mode
>> >> 3. Move the mouse pointer over the space right after the "*scratch*" tab
>> >>
>> >> Would it make sense to somehow prevent displaying blank tool tips, e.g.,
>> >> via the following advice? Or maybe blank tool tips could be prevented on
>> >> the tab-bar level?
>> >>
>> >> (defun x-show-tip-adv (str &rest _) (string-blank-p str))
>> >> (advice-add #'x-show-tip :before-until #'x-show-tip-adv)
>> >
>> > Juri, can we prevent such empty tooltips from being shown by tab bar?
>>
>> Maybe this unasked-for default fallback is not needed after all:
>>
>> diff --git a/src/xdisp.c b/src/xdisp.c
>> index f9a10267bad..18834c6b781 100644
>> --- a/src/xdisp.c
>> +++ b/src/xdisp.c
>> @@ -15155,8 +15155,6 @@ note_tab_bar_highlight (struct frame *f, int x, int 
>> y)
>>help_echo_object = help_echo_window = Qnil;
>>help_echo_pos = -1;
>>help_echo_string = AREF (f->tab_bar_items, prop_idx + TAB_BAR_ITEM_HELP);
>> -  if (NILP (help_echo_string))
>> -help_echo_string = AREF (f->tab_bar_items, prop_idx + 
>> TAB_BAR_ITEM_CAPTION);
>>  }
>>
>>  #endif /* HAVE_WINDOW_SYSTEM */
>
> Do you remember why was this introduced?

It was copy-pasted from tool-bar code.





bug#73117: 30.0.90; Imenu missing entries when flattening by group

2024-09-08 Thread Juri Linkov
> Maybe using `(setopt completion-auto-help t)`
> and hitting TAB is a better method.

Or just using `(setopt imenu-eager-completion-buffer nil)`
because otherwise with its default value you need to hit
'?' (minibuffer-completion-help) instead of TAB
to show the completions buffer with two identical
completions in different groups.

> I did try adding your suggested settings to the above code snippet,
> but they did not seem to improve anything with regards to what shows
> up in the completions buffer:
>
> ```
> (setopt completions-group t)
> (setopt minibuffer-visible-completions t)
> ```

I'm so sorry, I forgot to check with `emacs -Q`, and there is
an additional important setting that affects the groups:

```
(setopt completions-group t)
(setopt completions-format 'vertical)
```

The default value of 'completions-format' is 'horizontal'
that doesn't support groups, and I don't know why.

Maybe Daniel (Cc:ed) could help us understand
why 'completion--insert-horizontal' doesn't display groups.





bug#73018: 31.0.50; wdired + replace-regexp only modifies the visible portion of the buffer

2024-09-08 Thread Juri Linkov
>> > Maybe this is reproducible only on very long Dired buffers?
>
> After following the recipe literally, I could reproduce that thing, too.
>
> Maybe this issue occurring depends on what exactly is replaced - symlink
> targets.  In this case, (font-lock-ensure) does make a
> difference.
>
> Yesterday I had experimented with replacing in symlink names - in that
> case, the whole buffer had been considered.

I tried this:

(dired "/dev/char")

M-: (buffer-substring (- (point-max) 2) (- (point-max) 1))
=> #("7" 0 1 (fontified nil invisible dired-hide-details-link))

M-> ;; (end-of-buffer)

M-: (buffer-substring (- (point-max) 2) (- (point-max) 1))
=> #("7" 0 1 (face default dired-symlink-filename t fontified t invisible 
dired-hide-details-link))

And indeed, after going to the end of the Dired buffer
the last file gets an additional property `dired-symlink-filename'
used by Isearch/Replace.

Also noticed that doing the first replacement always raises an error:

Debugger entered--Lisp error: (error "Match data clobbered by buffer 
modification hooks")
  replace-match("!" nil nil)
  replace-match-maybe-edit("!" nil nil nil (672 673 #) nil)
  perform-replace("7" "!" t t nil nil nil nil nil nil nil)
  query-replace-regexp("7" "!" nil nil nil nil nil)
  funcall-interactively(query-replace-regexp "7" "!" nil nil nil nil nil)
  command-execute(query-replace-regexp)





bug#73050: 30.0.90; Empty tool tip when hovering over tab-bar separator

2024-09-09 Thread Juri Linkov
>> >> Maybe this unasked-for default fallback is not needed after all:
>> >>
>> >> diff --git a/src/xdisp.c b/src/xdisp.c
>> >> index f9a10267bad..18834c6b781 100644
>> >> --- a/src/xdisp.c
>> >> +++ b/src/xdisp.c
>> >> @@ -15155,8 +15155,6 @@ note_tab_bar_highlight (struct frame *f, int x, 
>> >> int y)
>> >>help_echo_object = help_echo_window = Qnil;
>> >>help_echo_pos = -1;
>> >>help_echo_string = AREF (f->tab_bar_items, prop_idx + 
>> >> TAB_BAR_ITEM_HELP);
>> >> -  if (NILP (help_echo_string))
>> >> -help_echo_string = AREF (f->tab_bar_items, prop_idx + 
>> >> TAB_BAR_ITEM_CAPTION);
>> >>  }
>> >>
>> >>  #endif /* HAVE_WINDOW_SYSTEM */
>> >
>> > Do you remember why was this introduced?
>> 
>> It was copy-pasted from tool-bar code.
>
> But on the tool bar there are no empty space between buttons.  On the
> tab bar, there is.  What I don't understand is why those empty spaces
> have tooltips.  Because each tab-bar button has a valid, non-nil
> tooltip, so the problem is with the tooltips popped up when the mouse
> is between buttons.  Do you understand why this happens?

When there is no TAB_BAR_ITEM_HELP, then it falls back to TAB_BAR_ITEM_CAPTION.
But the tab bar doesn't need tooltips on spaces.  So this patch is needed.





bug#73018: 31.0.50; wdired + replace-regexp only modifies the visible portion of the buffer

2024-09-09 Thread Juri Linkov
> Would something like this be good?
>
> @@ -3740,8 +3740,12 @@ dired-isearch-search-filenames
> -  (isearch-search-fun-in-text-property
> -   (funcall orig-fun) '(dired-filename dired-symlink-filename)))
> +  (let ((search-fun
> + (isearch-search-fun-in-text-property
> +  (funcall orig-fun) '(dired-filename dired-symlink-filename
> +(lambda (&rest args)
> +  (font-lock-ensure)
> +  (apply search-fun args

This will call 'font-lock-ensure' for every search hit?
Wouldn't it be better to call 'font-lock-ensure' only once
at the beginning of the search?

> A related question is whether everybody always wants to search in
> symlink targets when isearching file names in dired... I don't.  Would
> it be worth to add an option for that?  Currently the properties are
> just hardcoded.
>
> Then, in the above patch we could make the `font-lock-ensure' call
> depend on the value of that option.

Maybe not an option, but just a simple variable?





bug#73018: 31.0.50; wdired + replace-regexp only modifies the visible portion of the buffer

2024-09-09 Thread Juri Linkov
>> Also noticed that doing the first replacement always raises an error:
>>
>> Debugger entered--Lisp error: (error "Match data clobbered by buffer
>> modification hooks")
>>   replace-match("!" nil nil)
>>   replace-match-maybe-edit("!" nil nil nil (672 673 #) nil)
>>   perform-replace("7" "!" t t nil nil nil nil nil nil nil)
>>   query-replace-regexp("7" "!" nil nil nil nil nil)
>>   funcall-interactively(query-replace-regexp "7" "!" nil nil nil nil nil)
>>   command-execute(query-replace-regexp)
>
> Do I interpret the code in replace_match correctly: this error doesn't
> even mean the match data has been clobbered - only that modification
> hooks called searching functions?  I don't know what the referenced
> search_regs.num_regs exactly contains.  But we already seem to ensure
> not to clobber match data.

It fails in emacs-30, but not in emacs-29.
So this is a regression.





bug#73050: 30.0.90; Empty tool tip when hovering over tab-bar separator

2024-09-09 Thread Juri Linkov
close 73050 30.0.60
thanks

>> > But on the tool bar there are no empty space between buttons.  On the
>> > tab bar, there is.  What I don't understand is why those empty spaces
>> > have tooltips.  Because each tab-bar button has a valid, non-nil
>> > tooltip, so the problem is with the tooltips popped up when the mouse
>> > is between buttons.  Do you understand why this happens?
>> 
>> When there is no TAB_BAR_ITEM_HELP, then it falls back to 
>> TAB_BAR_ITEM_CAPTION.
>> But the tab bar doesn't need tooltips on spaces.  So this patch is needed.
>
> Fine, then let's install it, and thanks.

So now installed on master.





bug#73027: Fwd: 31.0.50; tab-bar-formal-global erased global-modeline-string's mouse hover/click action menu

2024-09-09 Thread Juri Linkov
>> Also please eval these calls and show their return values.
>
> 1. (mu4e--modeline-string) :
>
> #(" 🌀0/0 " 1 2 (help-echo "mu4e favorite bookmark 'Unread messages':

Thanks for the reproducible test case.

The problem is that the mode-line keymap can't be used without
replacing the symbol 'mode-line' with 'tab-bar'.  This means that
this recipe doesn't work:

```elisp
(defun mu4e--modeline-string ()
  #(" 🌀0/0 "
  0 5 (help-echo "mu4e favorite bookmark"
   mouse-face mode-line-highlight
   keymap (mode-line . (keymap (mouse-1 . mu4e-jump-to-favorite)
   (mouse-2 . mu4e-jump-to-favorite)
   (mouse-3 . mu4e-jump-to-favorite))

(add-to-list 'global-mode-string '(:eval (mu4e--modeline-string)) t)

(defun mu4e-jump-to-favorite ()
  (interactive)
  (message "DONE"))

(setopt tab-bar-format (append tab-bar-format '(tab-bar-format-align-right
tab-bar-format-global)))
(tab-bar-mode)
```

But after remapping the symbol 'mode-line' with 'tab-bar',
it works nicely:

```elisp
(defun mu4e--modeline-string ()
  #(" 🌀0/0 "
  0 5 (help-echo "mu4e favorite bookmark"
   mouse-face mode-line-highlight
   keymap (keymap (tab-bar . (keymap (mouse-1 . mu4e-jump-to-favorite)
 (mouse-2 . mu4e-jump-to-favorite)
 (mouse-3 . mu4e-jump-to-favorite)))
```





bug#73018: 31.0.50; wdired + replace-regexp only modifies the visible portion of the buffer

2024-09-09 Thread Juri Linkov
>>> Also noticed that doing the first replacement always raises an error:
>>>
>>> Debugger entered--Lisp error: (error "Match data clobbered by buffer
>>> modification hooks")
>>>   replace-match("!" nil nil)
>>>   replace-match-maybe-edit("!" nil nil nil (672 673 #) nil)
>>>   perform-replace("7" "!" t t nil nil nil nil nil nil nil)
>>>   query-replace-regexp("7" "!" nil nil nil nil nil)
>>>   funcall-interactively(query-replace-regexp "7" "!" nil nil nil nil nil)
>>>   command-execute(query-replace-regexp)
>>
>> Do I interpret the code in replace_match correctly: this error doesn't
>> even mean the match data has been clobbered - only that modification
>> hooks called searching functions?  I don't know what the referenced
>> search_regs.num_regs exactly contains.  But we already seem to ensure
>> not to clobber match data.
>
> It fails in emacs-30, but not in emacs-29.
> So this is a regression.

This is caused by commit 63588775fcb, so Cc-ing Stefan.

But probably this commit just exposed the problem
that existed before?

Anyway here is 100% reproducible recipe:

0. emacs -Q
1. 'C-x C-q' in a Dired with symlinks
2. 'C-M-% some_part_of_symlink RET anything RET'
3. 'y'

=> (error "Match data clobbered by buffer modification hooks")

This happens only for the first replacement after `emacs -Q`.