Subject: Re: bug#78221: 31.0.50; Improving *-change-functions notifications

From: Alan Mackenzie <[email-masked]>
Date: Sat, 3 May 2025 15:15:24 +0000

Hello, Eli.

On Sat, May 03, 2025 at 17:45:22 +0300, Eli Zaretskii wrote:
> > Date: Sat, 3 May 2025 14:13:40 +0000
> > Cc: [email-masked], Eli Zaretskii <[email-masked]>,
> >   João Távora <[email-masked]>,
> >   Ihor Radchenko <[email-masked]>, [email-masked]
> > From: Alan Mackenzie <[email-masked]>

> > before/after-change-functions functions SHOULDN'T themselves make
> > changes to the buffer text (apart from text properties).

> That's not how nested notifications happen in most, if not all, the
> cases.  They happen because a function that calls the before-change at
> the beginning and an after-change at the end calls, as part of its
> processing, some other function, which itself modifies buffer text or
> the text properties, and thus emits its own "nested" notifications.

OK.  Most Lisp code shouldn't be running the hook explicitly, though.  I
think the Elisp manual might even say this.

But such calls are rare.  On running $ find . -name '*.el' | xargs grep
-n '\(before\|after\)-change-functions' | grep run-hook on master, I
only got the following matches:

../lisp/progmodes/verilog-mode.el:3558:      (run-hook-with-args 'before-change-functions (point-min) (point-max))
../lisp/progmodes/verilog-mode.el:3570:        (run-hook-with-args 'after-change-functions (point-min) (point-max)
../lisp/cedet/srecode/insert.el:132:       (run-hook-with-args 'after-change-functions
../lisp/subr.el:5414:        (run-hook-with-args 'before-change-functions beg end))
../lisp/subr.el:5471:        (run-hook-with-args 'after-change-functions
../lisp/emulation/viper-cmd.el:139:  (run-hook-with-args 'viper-after-change-functions beg end len))
../lisp/emulation/viper-cmd.el:143:  (run-hook-with-args 'viper-before-change-functions beg end))
../lisp/format.el:472:      (run-hook-with-args 'after-change-functions (point) (+ (point) size) 0))
../test/lisp/emacs-lisp/track-changes-tests.el:141:                   (run-hook-with-args 'after-change-functions
../test/lisp/emacs-lisp/track-changes-tests.el:143:                 (run-hook-with-args 'before-change-functions beg end))))

(plus one wrong match).

The invocations in subr.el are legitimate.  The others are few enough to
be examined and fixed.  Of course there may be such occurrences in users'
code.  Maybe we could emit a compile time warning for such things.

-- 
Alan Mackenzie (Nuremberg, Germany).