GNU bug report logs -
#78221
31.0.50; Improving *-change-functions notifications
Previous Next
To reply to this bug, email your comments to 78221 AT debbugs.gnu.org.
Toggle the display of automated, internal messages from the tracker.
Report forwarded
to
monnier <at> iro.umontreal.ca, acm <at> muc.de, bug-gnu-emacs <at> gnu.org
:
bug#78221
; Package
emacs
.
(Fri, 02 May 2025 21:49:02 GMT)
Full text and
rfc822 format available.
Acknowledgement sent
to
Stefan Monnier <monnier <at> iro.umontreal.ca>
:
New bug report received and forwarded. Copy sent to
monnier <at> iro.umontreal.ca, acm <at> muc.de, bug-gnu-emacs <at> gnu.org
.
(Fri, 02 May 2025 21:49:02 GMT)
Full text and
rfc822 format available.
Message #5 received at submit <at> debbugs.gnu.org (full text, mbox):
Package: Emacs
Version: 31.0.50
After a long discussion with Eli over bug#78042, we agreed there's
a need to improve the C side handling of
*-change-functions notifications.
Alan McKenzie made significant improvements in the past to the C code
that runs these hooks, so that we now rarely break our promises in terms
of how/when those notifications are sent, but there are still
cases lurking.
The main problem is that it's very hard to find the places where this
occurs and it's not always obvious that the corresponding fix is
harmless. A fix is likely to involve changes visible to the Elisp side,
such as new hooks, so it seemed out of scope for bug#78042.
Some of the possible avenues that came up or that I have considered and
not yet discarded (and they're not mutually exclusive either):
- Don't notify changes to text-properties.
Currently, things like `put-text-property` run the *-change-functions
like any other buffer modification. In practice this is of dubious value:
- It's already the case that most calls to `put-text-property` and
friends don't cause any notification because they are wrapped within
a `with-silent-modifications` or otherwise take place from code
which always runs with `inhibit-modification-hooks` set
(e.g. because it's run from a *-change-function).
So *-change-functions can't reliably track changes to text-properties.
- Most *-change-functions are *not* interested in text-property
changes anyway.
The above two points suggest maybe we could just refrain from
running *-change-functions when changing the text-properties (just
like we do for changes to overlay properties).
Then again, this would be a backward-incompatible change, so there's
a chance some packages out there would be negatively affected.
Another option would be to allow packages to choose whether to receive
notifications like now or only for changes to the text.
E.g. just like we have `buffer-modified-tick` and
`buffer-chars-modified-tick`, we could have `*-change-functions`
and `*-chars-change-functions` (with some questions remaining about
`first-change-hook` and the `modification-hooks` property).
Or we could rely on a (symbol) property being set on the functions
added to `*-change-functions` to tell whether they want to know about
changes to text-properties or not.
Or maybe a more crude way would be a buffer-local variable controlling
whether `*-change-functions` are called for text-property changes.
- Allow *-change-functions notifications to be nested.
E.g. allow a C function to call
BEFORE 10 100
BEFORE 20 30
AFTER 20 25 10
AFTER 10 90 90
AFTER 10 60 80
or something like that. This would require some way for the C code to
indicate which BEGIN corresponds to which AFTER. This could happen
for example by adding a "change-ID" to every notification, so we'd
get:
BEFORE nnn 10 100
BEFORE mmm 20 30
AFTER mmm 20 25 10
AFTER nnn 10 90 90
AFTER nnn 10 60 80
I don't know how we could do that in a backward compatible way, and
I can't think of any `*-change-functions` which would benefit from
this nesting (all the ones I can think of would either ignore the
extra info or use the change-ID to distinguish inner notifications
from outer ones and then ignore the inner ones).
- Maybe the last point can be turned into an internal change with no
ELisp-side changes: use an approach like the one above but filter out
the inner changes directly in the C code. This would provide
to ELisp the same behavior that was brought by the fix to bug#78042,
but without resorting to the "hammer" of `inhibit-modification-hooks`
which risks silencing legitimate notifications.
Stefan
Information forwarded
to
bug-gnu-emacs <at> gnu.org
:
bug#78221
; Package
emacs
.
(Sat, 03 May 2025 06:55:02 GMT)
Full text and
rfc822 format available.
Message #8 received at 78221 <at> debbugs.gnu.org (full text, mbox):
> Cc: monnier <at> iro.umontreal.ca, Alan Mackenzie <acm <at> muc.de>
> Date: Fri, 02 May 2025 17:48:11 -0400
> From: Stefan Monnier via "Bug reports for GNU Emacs,
> the Swiss army knife of text editors" <bug-gnu-emacs <at> gnu.org>
>
> - Allow *-change-functions notifications to be nested.
> E.g. allow a C function to call
>
> BEFORE 10 100
> BEFORE 20 30
> AFTER 20 25 10
> AFTER 10 90 90
> AFTER 10 60 80
>
> or something like that. This would require some way for the C code to
> indicate which BEGIN corresponds to which AFTER. This could happen
> for example by adding a "change-ID" to every notification, so we'd
> get:
>
> BEFORE nnn 10 100
> BEFORE mmm 20 30
> AFTER mmm 20 25 10
> AFTER nnn 10 90 90
> AFTER nnn 10 60 80
>
> I don't know how we could do that in a backward compatible way, and
> I can't think of any `*-change-functions` which would benefit from
> this nesting (all the ones I can think of would either ignore the
> extra info or use the change-ID to distinguish inner notifications
> from outer ones and then ignore the inner ones).
>
> - Maybe the last point can be turned into an internal change with no
> ELisp-side changes: use an approach like the one above but filter out
> the inner changes directly in the C code. This would provide
> to ELisp the same behavior that was brought by the fix to bug#78042,
> but without resorting to the "hammer" of `inhibit-modification-hooks`
> which risks silencing legitimate notifications.
On the "nested notifications" part of this, I'd like to hear specific
problems with them. (I've added to the discussion people who might
have real-life examples of the problems.) Specifically, I'm not sure
I have a good understanding of why they are a problem in the first
place. Is it only because of the difficulty to pair BEFORE and AFTER
notifications? or is there something else?
Due to the Emacs's highly-recursive workings and the various hooks we
have, which are ever-expanding, there's a virtually infinite number of
situations where some code, called while a buffer-change operation is
under way, itself calls a buffer-changing primitive, thus generating
nested notifications. Finding and fixing all of theses situations one
by one will take us infinite time, so I would like to consider more
practical alternatives. And for that, IMO we need a very good
understanding of the problems they cause.
Thanks.
Information forwarded
to
bug-gnu-emacs <at> gnu.org
:
bug#78221
; Package
emacs
.
(Sat, 03 May 2025 14:14:02 GMT)
Full text and
rfc822 format available.
Message #11 received at 78221 <at> debbugs.gnu.org (full text, mbox):
Hello, Stefan.
On Fri, May 02, 2025 at 17:48:11 -0400, Stefan Monnier wrote:
> Package: Emacs
> Version: 31.0.50
> After a long discussion with Eli over bug#78042, we agreed there's
> a need to improve the C side handling of
> *-change-functions notifications.
I've glanced at bug#78042, but haven't (as yet) followed the discussions
in detail.
> Alan Mackenzie made significant improvements in the past to the C code
> that runs these hooks, so that we now rarely break our promises in terms
> of how/when those notifications are sent, but there are still
> cases lurking.
By "those promises", I think you mean being that we invoke
before-change-functions and after-change-functions strictly in matched
pairs. We only actually do this most of the time.
On 2018-01-06, we formally agreed that these hooks will be invoked as
follows:
o - Every buffer changing primitive starts off with exactly one call
to b-c-f,
o - after which there will be zero, one, or several calls to a-c-f.
o - The b-c-f's region will enclose those of all the a-c-f regions,
but need not be the minimal such region.
I actually think a good strategy would be to invoke these hooks strictly
in matching pairs in all cases, but I'm sure I said that back in 2018
too.
> The main problem is that it's very hard to find the places where this
> occurs and it's not always obvious that the corresponding fix is
> harmless. A fix is likely to involve changes visible to the Elisp side,
> such as new hooks, so it seemed out of scope for bug#78042.
I don't think it's all that hard. In 2020, I made a list of which
non-static functions in insdel.c call before/after-change-functions.
The list, which is likely still valid, or very nearly so, looked like
this:
insert B/A
insert_and_inherit B/A
insert_char B/A
insert_string B/A
insert_before_markers B/A
insert_before_markers_and_inherit B/A
insert_1_both ?/-
insert_from_string B/A
insert_from_string_before_markers B/A
insert_from_gap_1 -/-
insert_from_gap -/-
insert_from_buffer B/A
del_range B/A
del_range_1 ?/A
del_range_byte B/A
del_range_both ?/A
del_range_2 -/-
replace_range ?/A
replace_range_2 -/-
modify_text B/-
(where B/A means both before- and after-change-functions are called,
etc.).
It would be comparatively easy to modify insdel.c so that _all_ buffer
changing functions invoked the two hooks in matched pairs. That would
require a willingness to make substantial changes in insdel.c, something
that hasn't been forthcoming in years gone bye.
But if an alternative is to allow nested calls to the hooks (something
we don't allow at the moment, even though the rule isn't explicitly
formulated anywhere), this is going to involve modifying insdel.c
anyway.
> Some of the possible avenues that came up or that I have considered and
> not yet discarded (and they're not mutually exclusive either):
> - Don't notify changes to text-properties.
> Currently, things like `put-text-property` run the *-change-functions
> like any other buffer modification. In practice this is of dubious value:
> - It's already the case that most calls to `put-text-property` and
> friends don't cause any notification because they are wrapped within
> a `with-silent-modifications` or otherwise take place from code
> which always runs with `inhibit-modification-hooks` set
> (e.g. because it's run from a *-change-function).
> So *-change-functions can't reliably track changes to text-properties.
> - Most *-change-functions are *not* interested in text-property
> changes anyway.
> The above two points suggest maybe we could just refrain from
> running *-change-functions when changing the text-properties (just
> like we do for changes to overlay properties).
> Then again, this would be a backward-incompatible change, so there's
> a chance some packages out there would be negatively affected.
> Another option would be to allow packages to choose whether to receive
> notifications like now or only for changes to the text.
> E.g. just like we have `buffer-modified-tick` and
> `buffer-chars-modified-tick`, we could have `*-change-functions`
> and `*-chars-change-functions` (with some questions remaining about
> `first-change-hook` and the `modification-hooks` property).
> Or we could rely on a (symbol) property being set on the functions
> added to `*-change-functions` to tell whether they want to know about
> changes to text-properties or not.
> Or maybe a more crude way would be a buffer-local variable controlling
> whether `*-change-functions` are called for text-property changes.
I think it was a mistake in the beginning to have text property
modifications trigger before/after-c-f. But seeing it's been that way
for so long, I don't think it would be a good idea to change it now.
> - Allow *-change-functions notifications to be nested.
> E.g. allow a C function to call
> BEFORE 10 100
> BEFORE 20 30
> AFTER 20 25 10
> AFTER 10 90 90
> AFTER 10 60 80
> or something like that. This would require some way for the C code to
> indicate which BEGIN corresponds to which AFTER. This could happen
> for example by adding a "change-ID" to every notification, so we'd
> get:
> BEFORE nnn 10 100
> BEFORE mmm 20 30
> AFTER mmm 20 25 10
> AFTER nnn 10 90 90
> AFTER nnn 10 60 80
> I don't know how we could do that in a backward compatible way, and
> I can't think of any `*-change-functions` which would benefit from
> this nesting (all the ones I can think of would either ignore the
> extra info or use the change-ID to distinguish inner notifications
> from outer ones and then ignore the inner ones).
> - Maybe the last point can be turned into an internal change with no
> ELisp-side changes: use an approach like the one above but filter out
> the inner changes directly in the C code. This would provide
> to ELisp the same behavior that was brought by the fix to bug#78042,
> but without resorting to the "hammer" of `inhibit-modification-hooks`
> which risks silencing legitimate notifications.
I don't think nested b/a-c-f are a good idea at all. It's one of these
ideas that would introduce a very great deal of complexity for rather
limited benefit. We would be paying a penalty in increased bug
complexity for the forseeable future.
before/after-change-functions functions SHOULDN'T themselves make
changes to the buffer text (apart from text properties). I don't think
it would be all that hard to instrument insdel.c to signal an error when
such changes do get made, just tedious. Running such an instrumented
Emacs on the test suite would catch a very great number of violations.
> Stefan
--
Alan Mackenzie (Nuremberg, Germany).
Information forwarded
to
bug-gnu-emacs <at> gnu.org
:
bug#78221
; Package
emacs
.
(Sat, 03 May 2025 14:47:02 GMT)
Full text and
rfc822 format available.
Message #14 received at 78221 <at> debbugs.gnu.org (full text, mbox):
> Date: Sat, 3 May 2025 14:13:40 +0000
> Cc: 78221 <at> debbugs.gnu.org, Eli Zaretskii <eliz <at> gnu.org>,
> João Távora <joaotavora <at> gmail.com>,
> Ihor Radchenko <yantar92 <at> posteo.net>, acm <at> muc.de
> From: Alan Mackenzie <acm <at> muc.de>
>
> 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.
Information forwarded
to
bug-gnu-emacs <at> gnu.org
:
bug#78221
; Package
emacs
.
(Sat, 03 May 2025 14:47:02 GMT)
Full text and
rfc822 format available.
Message #17 received at 78221 <at> debbugs.gnu.org (full text, mbox):
Hello, Eli.
Thanks for including me on the Cc: list.
On Sat, May 03, 2025 at 09:54:33 +0300, Eli Zaretskii wrote:
> > Cc: monnier <at> iro.umontreal.ca, Alan Mackenzie <acm <at> muc.de>
> > Date: Fri, 02 May 2025 17:48:11 -0400
> > From: Stefan Monnier via "Bug reports for GNU Emacs,
> > the Swiss army knife of text editors" <bug-gnu-emacs <at> gnu.org>
> > - Allow *-change-functions notifications to be nested.
> > E.g. allow a C function to call
> > BEFORE 10 100
> > BEFORE 20 30
> > AFTER 20 25 10
> > AFTER 10 90 90
> > AFTER 10 60 80
> > or something like that. This would require some way for the C code to
> > indicate which BEGIN corresponds to which AFTER. This could happen
> > for example by adding a "change-ID" to every notification, so we'd
> > get:
> > BEFORE nnn 10 100
> > BEFORE mmm 20 30
> > AFTER mmm 20 25 10
> > AFTER nnn 10 90 90
> > AFTER nnn 10 60 80
> > I don't know how we could do that in a backward compatible way, and
> > I can't think of any `*-change-functions` which would benefit from
> > this nesting (all the ones I can think of would either ignore the
> > extra info or use the change-ID to distinguish inner notifications
> > from outer ones and then ignore the inner ones).
> > - Maybe the last point can be turned into an internal change with no
> > ELisp-side changes: use an approach like the one above but filter out
> > the inner changes directly in the C code. This would provide
> > to ELisp the same behavior that was brought by the fix to bug#78042,
> > but without resorting to the "hammer" of `inhibit-modification-hooks`
> > which risks silencing legitimate notifications.
> On the "nested notifications" part of this, I'd like to hear specific
> problems with them. (I've added to the discussion people who might
> have real-life examples of the problems.) Specifically, I'm not sure
> I have a good understanding of why they are a problem in the first
> place. Is it only because of the difficulty to pair BEFORE and AFTER
> notifications? or is there something else?
I think nested invocations of before/after-change functions would be a
bad idea. It would be bound to increase complexity of bugs in this area
in the future. It reminds me of one of my proposals from some years ago,
to have a hook called when buffer narrowing changes. Richard advised me
in no uncertain terms that this would have been just _too_ powerful, and
would have enabled people to do things difficult to debug. I think
nested b/a-c-functions would be similarly unwise.
Yes, I've had specific problems in this area, in CC Mode. One difficult
to solve bug involved the setting of font text properties triggering the
change hooks spuriously (and slowing things down a lot). I can't
remember it all that clearly. But solving it involved ensuring
inhibit-modification-hooks was correctly set.
> Due to the Emacs's highly-recursive workings and the various hooks we
> have, which are ever-expanding, there's a virtually infinite number of
> situations where some code, called while a buffer-change operation is
> under way, itself calls a buffer-changing primitive, thus generating
> nested notifications. Finding and fixing all of theses situations one
> by one will take us infinite time, so I would like to consider more
> practical alternatives. And for that, IMO we need a very good
> understanding of the problems they cause.
As I proposed in my reply to Stefan M., I don't think finding most/all of
these situations need be too difficult. insdel.c could be temporarily
instrumented to signal an error on detecting an illegitimate buffer
change. The difficulty here might be false positives, when a program
intends to make buffer changes from inside a change hook function. I
don't think these are common, though.
> Thanks.
--
Alan Mackenzie (Nuremberg, Germany).
Information forwarded
to
bug-gnu-emacs <at> gnu.org
:
bug#78221
; Package
emacs
.
(Sat, 03 May 2025 15:15:01 GMT)
Full text and
rfc822 format available.
Message #20 received at 78221 <at> debbugs.gnu.org (full text, mbox):
>> Alan Mackenzie made significant improvements in the past to the C code
>> that runs these hooks, so that we now rarely break our promises in terms
>> of how/when those notifications are sent, but there are still
>> cases lurking.
> By "those promises", I think you mean being that we invoke
> before-change-functions and after-change-functions strictly in matched
> pairs.
No, I mean the looser promise that AFTERs are allowed to touch only text
within the region described by the last BEFORE.
> On 2018-01-06, we formally agreed that these hooks will be invoked as
> follows:
> o - Every buffer changing primitive starts off with exactly one call
> to b-c-f,
> o - after which there will be zero, one, or several calls to a-c-f.
> o - The b-c-f's region will enclose those of all the a-c-f regions,
> but need not be the minimal such region.
Exactly. And it's now documented in the manual.
> I actually think a good strategy would be to invoke these hooks
> strictly in matching pairs in all cases, but I'm sure I said that back
> in 2018 too.
🙂
>> The main problem is that it's very hard to find the places where this
>> occurs and it's not always obvious that the corresponding fix is
>> harmless. A fix is likely to involve changes visible to the Elisp side,
>> such as new hooks, so it seemed out of scope for bug#78042.
>
> I don't think it's all that hard. In 2020, I made a list of which
> non-static functions in insdel.c call before/after-change-functions.
> The list, which is likely still valid, or very nearly so, looked like
> this:
>
> insert B/A
> insert_and_inherit B/A
> insert_char B/A
> insert_string B/A
> insert_before_markers B/A
>
> insert_before_markers_and_inherit B/A
> insert_1_both ?/-
> insert_from_string B/A
> insert_from_string_before_markers B/A
> insert_from_gap_1 -/-
>
> insert_from_gap -/-
> insert_from_buffer B/A
> del_range B/A
> del_range_1 ?/A
> del_range_byte B/A
>
> del_range_both ?/A
> del_range_2 -/-
> replace_range ?/A
> replace_range_2 -/-
> modify_text B/-
Thanks, that's very helpful.
[ It lacks the ones coming from text-property modifications. ]
The ones above that are neither B/A nor -/- are the reason why making
changes in this area is ... delicate.
> But if an alternative is to allow nested calls to the hooks (something
> we don't allow at the moment, even though the rule isn't explicitly
> formulated anywhere),
The rule is implicitly formulated where we document that AFTERs can't
touch text outside of the last BEFORE.
> I think it was a mistake in the beginning to have text property
> modifications trigger before/after-c-f.
Agreed.
> But seeing it's been that way for so long, I don't think it would be
> a good idea to change it now.
FWIW, I'm now running my Emacs with such a change to see if the ELisp
code I use cares. But yeah, it seems too risky to do it without
providing some backward compatibility.
> before/after-change-functions functions SHOULDN'T themselves make
> changes to the buffer text (apart from text properties).
+1
> I don't think it would be all that hard to instrument insdel.c to
> signal an error when such changes do get made, just tedious.
> Running such an instrumented Emacs on the test suite would catch
> a very great number of violations.
It might be worthwhile adding such runtime tests and emit warnings when
before/after-change-functions make changes the buffer text, tho it's
orthogonal to what we're discussing here (where the nesting is not due
to ill-behaved before/after-change-functions but come straight from the
C code).
> As I proposed in my reply to Stefan M., I don't think finding most/all of
> these situations need be too difficult. insdel.c could be temporarily
> instrumented to signal an error on detecting an illegitimate buffer
> change. The difficulty here might be false positives, when a program
> intends to make buffer changes from inside a change hook function. I
> don't think these are common, though.
I'm running my Emacs sessions with a function added globally to
before/after-change-functions, which checks that we stick to our
promises (basically the `sanity-check-change-functions-*` code in
`test/src/editfns-tests.el`).
But that catches only those occurrences that are triggered by my
usage patterns.
Stefan
Information forwarded
to
bug-gnu-emacs <at> gnu.org
:
bug#78221
; Package
emacs
.
(Sat, 03 May 2025 15:16:02 GMT)
Full text and
rfc822 format available.
Message #23 received at 78221 <at> debbugs.gnu.org (full text, mbox):
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: 78221 <at> debbugs.gnu.org, Eli Zaretskii <eliz <at> gnu.org>,
> > João Távora <joaotavora <at> gmail.com>,
> > Ihor Radchenko <yantar92 <at> posteo.net>, acm <at> muc.de
> > From: Alan Mackenzie <acm <at> muc.de>
> > 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).
Information forwarded
to
bug-gnu-emacs <at> gnu.org
:
bug#78221
; Package
emacs
.
(Sat, 03 May 2025 15:53:02 GMT)
Full text and
rfc822 format available.
Message #26 received at 78221 <at> debbugs.gnu.org (full text, mbox):
> Date: Sat, 3 May 2025 15:15:24 +0000
> Cc: monnier <at> iro.umontreal.ca, 78221 <at> debbugs.gnu.org, joaotavora <at> gmail.com,
> yantar92 <at> posteo.net
> From: Alan Mackenzie <acm <at> muc.de>
>
> > 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.
No, but the C code does. And it's very easy to imagine a situation
where one such primitive is invoked in the middle of another. A case
in point is coding.c, where Stefan eliminated such a "nesting" just a
few hours ago (by a change that we have yet to see if it's safe).
With all the hooks we provide, such situations can emerge very easily.
Information forwarded
to
bug-gnu-emacs <at> gnu.org
:
bug#78221
; Package
emacs
.
(Sat, 03 May 2025 16:36:01 GMT)
Full text and
rfc822 format available.
Message #29 received at submit <at> debbugs.gnu.org (full text, mbox):
Stefan Monnier via "Bug reports for GNU Emacs, the Swiss army knife of
text editors" <bug-gnu-emacs <at> gnu.org> writes:
> Or we could rely on a (symbol) property being set on the functions
> added to `*-change-functions` to tell whether they want to know about
> changes to text-properties or not.
> Or maybe a more crude way would be a buffer-local variable controlling
> whether `*-change-functions` are called for text-property changes.
Or pass a 4th parameter to *-change-functions indicating whether the
change involved actual text edits or it only touched text-properties.
Org mode currently has to resort to
(eq org-fold-core--last-buffer-chars-modified-tick (buffer-chars-modified-tick))
checks to filter out changes in text properties.
--
Ihor Radchenko // yantar92,
Org mode maintainer,
Learn more about Org mode at <https://orgmode.org/>.
Support Org development at <https://liberapay.com/org-mode>,
or support my work at <https://liberapay.com/yantar92>
Information forwarded
to
bug-gnu-emacs <at> gnu.org
:
bug#78221
; Package
emacs
.
(Sat, 03 May 2025 16:36:02 GMT)
Full text and
rfc822 format available.
Information forwarded
to
bug-gnu-emacs <at> gnu.org
:
bug#78221
; Package
emacs
.
(Sat, 03 May 2025 16:46:01 GMT)
Full text and
rfc822 format available.
Message #35 received at 78221 <at> debbugs.gnu.org (full text, mbox):
> ../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)
I think these are OK.
It's doing something similar to `combine*change-functions`.
> ../lisp/cedet/srecode/insert.el:132: (run-hook-with-args 'after-change-functions
This one looks quite wrong.
> ../lisp/subr.el:5414: (run-hook-with-args 'before-change-functions beg end))
> ../lisp/subr.el:5471: (run-hook-with-args 'after-change-functions
These are for `combine*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))
False positives.
> ../lisp/format.el:472: (run-hook-with-args 'after-change-functions (point) (+ (point) size) 0))
Looks wrong as well.
> ../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))))
These are purposefully wrong (to check that `track-changes` is able to
withstand such occurrences).
Stefan
Information forwarded
to
bug-gnu-emacs <at> gnu.org
:
bug#78221
; Package
emacs
.
(Sat, 03 May 2025 17:05:02 GMT)
Full text and
rfc822 format available.
Message #38 received at 78221 <at> debbugs.gnu.org (full text, mbox):
Hello, Eli.
On Sat, May 03, 2025 at 18:52:11 +0300, Eli Zaretskii wrote:
> > Date: Sat, 3 May 2025 15:15:24 +0000
> > Cc: monnier <at> iro.umontreal.ca, 78221 <at> debbugs.gnu.org, joaotavora <at> gmail.com,
> > yantar92 <at> posteo.net
> > From: Alan Mackenzie <acm <at> muc.de>
> > > 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.
> No, but the C code does. And it's very easy to imagine a situation
> where one such primitive is invoked in the middle of another. A case
> in point is coding.c, where Stefan eliminated such a "nesting" just a
> few hours ago (by a change that we have yet to see if it's safe).
> With all the hooks we provide, such situations can emerge very easily.
The right tool to find these is cflow, combined with grep and awk (or
python or perl or whatever) to search and filter cflow's output. I've
used these before.
As you say, checking fixes to these bugs are safe is less mechanical.
--
Alan Mackenzie (Nuremberg, Germany).
Information forwarded
to
bug-gnu-emacs <at> gnu.org
:
bug#78221
; Package
emacs
.
(Sat, 03 May 2025 19:24:01 GMT)
Full text and
rfc822 format available.
Message #41 received at 78221 <at> debbugs.gnu.org (full text, mbox):
> Date: Sat, 3 May 2025 17:03:49 +0000
> Cc: monnier <at> iro.umontreal.ca, 78221 <at> debbugs.gnu.org, joaotavora <at> gmail.com,
> yantar92 <at> posteo.net, acm <at> muc.de
> From: Alan Mackenzie <acm <at> muc.de>
>
> Hello, Eli.
>
> On Sat, May 03, 2025 at 18:52:11 +0300, Eli Zaretskii wrote:
> > > Date: Sat, 3 May 2025 15:15:24 +0000
> > > Cc: monnier <at> iro.umontreal.ca, 78221 <at> debbugs.gnu.org, joaotavora <at> gmail.com,
> > > yantar92 <at> posteo.net
> > > From: Alan Mackenzie <acm <at> muc.de>
>
> > > > 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.
>
> > No, but the C code does. And it's very easy to imagine a situation
> > where one such primitive is invoked in the middle of another. A case
> > in point is coding.c, where Stefan eliminated such a "nesting" just a
> > few hours ago (by a change that we have yet to see if it's safe).
> > With all the hooks we provide, such situations can emerge very easily.
>
> The right tool to find these is cflow, combined with grep and awk (or
> python or perl or whatever) to search and filter cflow's output. I've
> used these before.
>
> As you say, checking fixes to these bugs are safe is less mechanical.
I'm not sure I even have a good idea regarding what are the safe fixes
for those cases.
Information forwarded
to
bug-gnu-emacs <at> gnu.org
:
bug#78221
; Package
emacs
.
(Sun, 04 May 2025 02:49:02 GMT)
Full text and
rfc822 format available.
Message #44 received at 78221 <at> debbugs.gnu.org (full text, mbox):
>> Or we could rely on a (symbol) property being set on the functions
>> added to `*-change-functions` to tell whether they want to know about
>> changes to text-properties or not.
>> Or maybe a more crude way would be a buffer-local variable controlling
>> whether `*-change-functions` are called for text-property changes.
> Or pass a 4th parameter to *-change-functions indicating whether the
> change involved actual text edits or it only touched text-properties.
But many functions used on this hook don't accept 4 parameters, so
that's not backward compatible.
[ FWIW: In my local Emacs, I used another incompatible approach which is
to pass `t` for the `oldlen` argument, since text-property changes
don't change the length. It seems not to cause too much trouble: most
hooks don't pay attention to `oldlen` and most text-property changes
are wrapped in `inhibit-modification-hooks`, but I did have to tweak
the code at a few spots. ]
> Org mode currently has to resort to (eq
> org-fold-core--last-buffer-chars-modified-tick
> (buffer-chars-modified-tick)) checks to filter out changes in
> text properties.
Interesting. What made you do that? IME, it's fairly rare for
text-property changes to trigger such notifications.
Stefan
Information forwarded
to
bug-gnu-emacs <at> gnu.org
:
bug#78221
; Package
emacs
.
(Sun, 04 May 2025 05:32:02 GMT)
Full text and
rfc822 format available.
Message #47 received at 78221 <at> debbugs.gnu.org (full text, mbox):
> Cc: 78221 <at> debbugs.gnu.org, Alan Mackenzie <acm <at> muc.de>
> Date: Sat, 03 May 2025 22:48:10 -0400
> From: Stefan Monnier via "Bug reports for GNU Emacs,
> the Swiss army knife of text editors" <bug-gnu-emacs <at> gnu.org>
>
> >> Or we could rely on a (symbol) property being set on the functions
> >> added to `*-change-functions` to tell whether they want to know about
> >> changes to text-properties or not.
> >> Or maybe a more crude way would be a buffer-local variable controlling
> >> whether `*-change-functions` are called for text-property changes.
> > Or pass a 4th parameter to *-change-functions indicating whether the
> > change involved actual text edits or it only touched text-properties.
>
> But many functions used on this hook don't accept 4 parameters, so
> that's not backward compatible.
We could use func-arity, couldn't we?
Information forwarded
to
bug-gnu-emacs <at> gnu.org
:
bug#78221
; Package
emacs
.
(Sun, 04 May 2025 06:17:06 GMT)
Full text and
rfc822 format available.
Message #50 received at 78221 <at> debbugs.gnu.org (full text, mbox):
Stefan Monnier <monnier <at> iro.umontreal.ca> writes:
>> Org mode currently has to resort to (eq
>> org-fold-core--last-buffer-chars-modified-tick
>> (buffer-chars-modified-tick)) checks to filter out changes in
>> text properties.
>
> Interesting. What made you do that? IME, it's fairly rare for
> text-property changes to trigger such notifications.
Some parts of Org mode (org-agenda, org-sparse-tree) use text properties
and trigger the notifications; usually that happens across the whole
buffer. And when that does happen, expensive processing of buffer
changes makes things very slow.
--
Ihor Radchenko // yantar92,
Org mode maintainer,
Learn more about Org mode at <https://orgmode.org/>.
Support Org development at <https://liberapay.com/org-mode>,
or support my work at <https://liberapay.com/yantar92>
Information forwarded
to
bug-gnu-emacs <at> gnu.org
:
bug#78221
; Package
emacs
.
(Sun, 04 May 2025 13:02:02 GMT)
Full text and
rfc822 format available.
Message #53 received at 78221 <at> debbugs.gnu.org (full text, mbox):
>>> Org mode currently has to resort to (eq
>>> org-fold-core--last-buffer-chars-modified-tick
>>> (buffer-chars-modified-tick)) checks to filter out changes in
>>> text properties.
>> Interesting. What made you do that? IME, it's fairly rare for
>> text-property changes to trigger such notifications.
> Some parts of Org mode (org-agenda, org-sparse-tree) use text properties
> and trigger the notifications; usually that happens across the whole
> buffer. And when that does happen, expensive processing of buffer
> changes makes things very slow.
I see. But then, why fix it on the side of your `*-change-functions`
rather than on using `inhibit-modification-hooks` (so it benefits all
the `*-change-functions`)?
IME, most ELisp code which calls things like `put-text-property` usually
does so within a `with-silent-modifications` wrapper, and not only to
avoid running `*-change-functions`: also to avoid setting the
`buffer-modified-p` flag or getting prompted if some other session is
modifying the same file at the same time, etc...
Stefan
Information forwarded
to
bug-gnu-emacs <at> gnu.org
:
bug#78221
; Package
emacs
.
(Sun, 04 May 2025 13:10:07 GMT)
Full text and
rfc822 format available.
Message #56 received at 78221 <at> debbugs.gnu.org (full text, mbox):
Stefan Monnier <monnier <at> iro.umontreal.ca> writes:
> I see. But then, why fix it on the side of your `*-change-functions`
> rather than on using `inhibit-modification-hooks` (so it benefits all
> the `*-change-functions`)?
Because I cannot ignore possibility that some third-party config is
making use of *-change-functions to detect Org putting properties.
Also, I cannot guarantee that all third-party packages do not use
put-text-property outside inhibit-modification-hooks.
--
Ihor Radchenko // yantar92,
Org mode maintainer,
Learn more about Org mode at <https://orgmode.org/>.
Support Org development at <https://liberapay.com/org-mode>,
or support my work at <https://liberapay.com/yantar92>
Information forwarded
to
bug-gnu-emacs <at> gnu.org
:
bug#78221
; Package
emacs
.
(Sun, 04 May 2025 13:44:02 GMT)
Full text and
rfc822 format available.
Message #59 received at 78221 <at> debbugs.gnu.org (full text, mbox):
Ihor Radchenko [2025-05-04 13:08:05] wrote:
> Stefan Monnier <monnier <at> iro.umontreal.ca> writes:
>> I see. But then, why fix it on the side of your `*-change-functions`
>> rather than on using `inhibit-modification-hooks` (so it benefits all
>> the `*-change-functions`)?
> Because I cannot ignore possibility that some third-party config is
> making use of *-change-functions to detect Org putting properties.
Ah, so the same reason why we're also resisting the urge to just just
stop running those hooks for changes to text-properties.
I wonder if someone actually knows of a `*-change-function` which wants
to be triggered when text-properties are modified. I'm not 100% sure
that I've never seen such a thing, but at least I can't remember seeing
(nor writing) such a thing.
Are these property-modifications spread all over the place or can you
point us to a few important places where they happen?
I'm curious to know as well how those deal with other related "usually
undesired" effects, such as modifying the `buffer-modified-p` flag,
stashing the property modifications into the `buffer-undo-list`, or
signaling errors when the buffer is read-only.
> Also, I cannot guarantee that all third-party packages do not use
> put-text-property outside inhibit-modification-hooks.
🙂
Stefan
Information forwarded
to
bug-gnu-emacs <at> gnu.org
:
bug#78221
; Package
emacs
.
(Sun, 04 May 2025 15:28:07 GMT)
Full text and
rfc822 format available.
Message #62 received at 78221 <at> debbugs.gnu.org (full text, mbox):
> The right tool to find these is cflow, combined with grep and awk (or
> python or perl or whatever) to search and filter cflow's output. I've
> used these before.
Do you happen to remember the magic incantation to let `cflow` process
our sources correctly? I tried the rule below and the errors file
suggests that the preprocessing is done correctly (it's full of
complaints but only about redefinitions), yet the result doesn't include
any info about the functions called by `insert_1_both` or
`Fput_text_property` (to take two randomly sampled cases of interest).
Stefan
diff --git a/src/Makefile.in b/src/Makefile.in
index e4fc2fef711..2c7aa92f9b9 100644
--- a/src/Makefile.in
+++ b/src/Makefile.in
@@ -699,6 +699,18 @@ MAKE_PDUMPER_FINGERPRINT =
MAKE_PDUMPER_FINGERPRINT =
endif
+cgraph.cflow:
+ cflow --all --brief --cpp='$(CC) -E $(ALL_CFLAGS)' \
+ $(ALLOBJS:.o=.c) \
+ >$@ 2>$@.errors
+
+cgraph-rev.cflow:
+ cflow --reverse --all --brief --cpp='$(CC) -E $(ALL_CFLAGS)' \
+ $(ALLOBJS:.o=.c) \
+ >$@ 2>$@.errors
+
+flowcharts: cgraph-rev.cflow cgraph.cflow
+
## We have to create $(etc) here because init_cmdargs tests its
## existence when setting Vinstallation_directory (FIXME?).
## This goes on to affect various things, and the emacs binary fails
Information forwarded
to
bug-gnu-emacs <at> gnu.org
:
bug#78221
; Package
emacs
.
(Sun, 04 May 2025 17:06:01 GMT)
Full text and
rfc822 format available.
Message #65 received at 78221 <at> debbugs.gnu.org (full text, mbox):
Hello, Stefan.
On Sun, May 04, 2025 at 11:27:23 -0400, Stefan Monnier wrote:
> > The right tool to find these is cflow, combined with grep and awk (or
> > python or perl or whatever) to search and filter cflow's output. I've
> > used these before.
> Do you happen to remember the magic incantation to let `cflow` process
> our sources correctly? I tried the rule below and the errors file
> suggests that the preprocessing is done correctly (it's full of
> complaints but only about redefinitions), yet the result doesn't include
> any info about the functions called by `insert_1_both` or
> `Fput_text_property` (to take two randomly sampled cases of interest).
From my notes from 2018, the command I used on cflow was:
$ cflow --reverse -b -i +s --cpp -I. -I../lib -I/usr/include/glib-2.0 \
-I/usr/lib64/glib-2.0/include -I/usr/include/libxml2 buffer.c \
callproc.c \
casefiddle.c cmds.c coding.c decompress.c editfns.c emacs.c \
fileio.c fns.c \
indent.c insdel.c print.c process.c search.c textprop.c \
xdisp.c xml.c 2> /dev/null > ~/cflow.20180102b.txt.
I no longer remember what the options mean, but the files I scanned were
those containing calls to insdel.c's externally visible functions.
I later analysed cflow.20180102b.txt with an elisp script, which I still
have, and could send to you if you're interested. (It's 125 lines long,
but poorly commented.) This script scanned the cflow output,
recursively finding callers (direct and indirect) of
signal_\(before\|after\)_change.
> Stefan
> diff --git a/src/Makefile.in b/src/Makefile.in
> index e4fc2fef711..2c7aa92f9b9 100644
> --- a/src/Makefile.in
> +++ b/src/Makefile.in
> @@ -699,6 +699,18 @@ MAKE_PDUMPER_FINGERPRINT =
> MAKE_PDUMPER_FINGERPRINT =
> endif
> +cgraph.cflow:
> + cflow --all --brief --cpp='$(CC) -E $(ALL_CFLAGS)' \
> + $(ALLOBJS:.o=.c) \
> + >$@ 2>$@.errors
> +
> +cgraph-rev.cflow:
> + cflow --reverse --all --brief --cpp='$(CC) -E $(ALL_CFLAGS)' \
> + $(ALLOBJS:.o=.c) \
> + >$@ 2>$@.errors
> +
> +flowcharts: cgraph-rev.cflow cgraph.cflow
> +
> ## We have to create $(etc) here because init_cmdargs tests its
> ## existence when setting Vinstallation_directory (FIXME?).
> ## This goes on to affect various things, and the emacs binary fails
--
Alan Mackenzie (Nuremberg, Germany).
Information forwarded
to
bug-gnu-emacs <at> gnu.org
:
bug#78221
; Package
emacs
.
(Sun, 04 May 2025 17:26:04 GMT)
Full text and
rfc822 format available.
Message #68 received at 78221 <at> debbugs.gnu.org (full text, mbox):
Stefan Monnier <monnier <at> iro.umontreal.ca> writes:
> I wonder if someone actually knows of a `*-change-function` which wants
> to be triggered when text-properties are modified. I'm not 100% sure
> that I've never seen such a thing, but at least I can't remember seeing
> (nor writing) such a thing.
Me neither.
Asking LLMs will just make them hallucinate :)
> Are these property-modifications spread all over the place or can you
> point us to a few important places where they happen?
- org-edit-latex-fragment
- org-display-custom-time
- org-agenda (in special org-agenda buffers). not relevant to
*-change-functions Org mode uses though
> I'm curious to know as well how those deal with other related "usually
> undesired" effects, such as modifying the `buffer-modified-p` flag,
> stashing the property modifications into the `buffer-undo-list`, or
> signaling errors when the buffer is read-only.
Not very well usually, until someone files a bug report.
--
Ihor Radchenko // yantar92,
Org mode maintainer,
Learn more about Org mode at <https://orgmode.org/>.
Support Org development at <https://liberapay.com/org-mode>,
or support my work at <https://liberapay.com/yantar92>
Information forwarded
to
bug-gnu-emacs <at> gnu.org
:
bug#78221
; Package
emacs
.
(Sun, 04 May 2025 18:13:06 GMT)
Full text and
rfc822 format available.
Message #71 received at 78221 <at> debbugs.gnu.org (full text, mbox):
Stefan Monnier <monnier <at> iro.umontreal.ca> writes:
>> The right tool to find these is cflow, combined with grep and awk (or
>> python or perl or whatever) to search and filter cflow's output. I've
>> used these before.
>
> Do you happen to remember the magic incantation to let `cflow` process
> our sources correctly? I tried the rule below and the errors file
> suggests that the preprocessing is done correctly (it's full of
> complaints but only about redefinitions), yet the result doesn't include
> any info about the functions called by `insert_1_both` or
> `Fput_text_property` (to take two randomly sampled cases of interest).
I use Clangd + Eglot + eglot-supplements if I have questions about who
call whom.
With clangd 20 one can display incoming and outgoing call trees. Only
inconvenience is that one has to expand nodes in the tree manually
because nodes are created on demand via LSP. And this of course only
sees what's compiled in.
Anyway, random example for add_text_properties_1, incoming call trees:
- add_text_properties_1 textprop.c:1170
- add_text_properties_1 add_text_properties_1:1182
• ⬁add_text_properties_1 add_text_properties_1:1182
- Fadd_text_properties Fadd_text_properties:1308
+ Fpropertize Fpropertize:3297
+ echo_add_key echo_add_key:548
+ echo_add_key echo_add_key:549
+ describe_key_maybe_fontify describe_key_maybe_fontify:3092
+ Sadd_text_properties Sadd_text_properties:1296
+ Fput_text_property Fput_text_property:1326
+ copy_text_properties copy_text_properties:2026
+ add_text_properties_from_list add_text_properties_from_list:2111
• tty_handle_tab_bar_click tty_handle_tab_bar_click:15384
+ store_mode_line_string store_mode_line_string:28515
+ store_mode_line_string store_mode_line_string:28542
+ store_mode_line_string store_mode_line_string:28558
+ Fadd_face_text_property Fadd_face_text_property:1368
- Fadd_text_properties Fadd_text_properties:1308
+ Fpropertize Fpropertize:3297
+ echo_add_key echo_add_key:548
+ echo_add_key echo_add_key:549
+ describe_key_maybe_fontify describe_key_maybe_fontify:3092
+ Sadd_text_properties Sadd_text_properties:1296
- Fput_text_property Fput_text_property:1326
+ Fcall_interactively Fcall_interactively:484
+ Fcall_interactively Fcall_interactively:536
+ Fcall_interactively Fcall_interactively:567
+ produce_charset produce_charset:7277
+ update_compositions update_compositions:530
- update_compositions update_compositions:571
+ casify_region casify_region:565
+ decode_coding_object decode_coding_object:8191
+ encode_coding_object encode_coding_object:8483
+ unwind_decompress unwind_decompress:190
+ Fzlib_decompress_region Fzlib_decompress_region:333
- Freplace_region_contents Freplace_region_contents:2190
+ Sreplace_region_contents Sreplace_region_contents:1923
+ Fsubst_char_in_region Fsubst_char_in_region:2412
+ Ftranslate_region_internal Ftranslate_region_internal:2599
+ Ftranspose_regions Ftranspose_regions:4666
+ Ftranspose_regions Ftranspose_regions:4667
+ Finsert_file_contents Finsert_file_contents:5008
- insert_from_buffer insert_from_buffer:1086
+ encode_coding_object encode_coding_object:8360
+ Finsert_buffer_substring Finsert_buffer_substring:1743
+ Finsert_file_contents Finsert_file_contents:4744
+ replace_range replace_range:1543
+ del_range_1 del_range_1:1743
+ del_range_byte del_range_byte:1785
+ del_range_both del_range_both:1829
+ Fcombine_after_change_execute Fcombine_after_change_execute:2392
+ insert insert:575
+ insert_and_inherit insert_and_inherit:590
+ insert_before_markers insert_before_markers:635
+ insert_before_markers_and_inherit insert_before_markers_and_inherit:651
+ insert_from_string insert_from_string:870
+ insert_from_string_before_markers insert_from_string_before_markers:890
+ Fjson_insert Fjson_insert:685
+ Freplace_match Freplace_match:2784
+ compose_text compose_text:638
+ read_minibuf read_minibuf:849
+ read_minibuf read_minibuf:851
+ read_minibuf read_minibuf:853
+ read_minibuf read_minibuf:875
+ Sput_text_property Sput_text_property:1314
+ copy_text_properties copy_text_properties:2026
+ add_text_properties_from_list add_text_properties_from_list:2111
• tty_handle_tab_bar_click tty_handle_tab_bar_click:15384
+ store_mode_line_string store_mode_line_string:28515
+ store_mode_line_string store_mode_line_string:28542
+ store_mode_line_string store_mode_line_string:28558
+ Fadd_face_text_property Fadd_face_text_property:1368
Information forwarded
to
bug-gnu-emacs <at> gnu.org
:
bug#78221
; Package
emacs
.
(Sun, 04 May 2025 18:19:01 GMT)
Full text and
rfc822 format available.
Message #74 received at 78221 <at> debbugs.gnu.org (full text, mbox):
> From my notes from 2018, the command I used on cflow was:
>
> $ cflow --reverse -b -i +s --cpp -I. -I../lib -I/usr/include/glib-2.0 \
> -I/usr/lib64/glib-2.0/include -I/usr/include/libxml2 buffer.c \
> callproc.c \
> casefiddle.c cmds.c coding.c decompress.c editfns.c emacs.c \
> fileio.c fns.c \
> indent.c insdel.c print.c process.c search.c textprop.c \
> xdisp.c xml.c 2> /dev/null > ~/cflow.20180102b.txt.
>
> I no longer remember what the options mean, but the files I scanned were
> those containing calls to insdel.c's externally visible functions.
Thanks. That gives me the same problems. 🙁
> I later analysed cflow.20180102b.txt with an elisp script, which I still
> have, and could send to you if you're interested. (It's 125 lines long,
> but poorly commented.) This script scanned the cflow output,
> recursively finding callers (direct and indirect) of
> signal_\(before\|after\)_change.
Can't hurt, thanks.
Stefan
Information forwarded
to
bug-gnu-emacs <at> gnu.org
:
bug#78221
; Package
emacs
.
(Sun, 04 May 2025 18:39:02 GMT)
Full text and
rfc822 format available.
Message #77 received at 78221 <at> debbugs.gnu.org (full text, mbox):
>> I wonder if someone actually knows of a `*-change-function` which wants
>> to be triggered when text-properties are modified. I'm not 100% sure
>> that I've never seen such a thing, but at least I can't remember seeing
>> (nor writing) such a thing.
> Me neither.
🙁
>> Are these property-modifications spread all over the place or can you
>> point us to a few important places where they happen?
>
> - org-edit-latex-fragment
Hmm... AFAICT it adds text properties to a string, not to a buffer.
> - org-display-custom-time
AFAICT this is called exclusively from font-lock, so
`inhibit-modifications-hooks` should always be set already.
> - org-agenda (in special org-agenda buffers). not relevant to
> *-change-functions Org mode uses though
`org-agenda.el` didn't quite fit on my screen (🙂), so I didn't
investigate, especially since you say it's not directly relevant.
Stefan
Information forwarded
to
bug-gnu-emacs <at> gnu.org
:
bug#78221
; Package
emacs
.
(Sun, 04 May 2025 18:41:01 GMT)
Full text and
rfc822 format available.
Message #80 received at 78221 <at> debbugs.gnu.org (full text, mbox):
[Message part 1 (text/plain, inline)]
On Sun, May 4, 2025, 19:12 Gerd Möllmann <gerd.moellmann <at> gmail.com> wrote:
> Stefan Monnier <monnier <at> iro.umontreal.ca> writes:
>
> >> The right tool to find these is cflow, combined with grep and awk (or
> >> python or perl or whatever) to search and filter cflow's output. I've
> >> used these before.
> >
> > Do you happen to remember the magic incantation to let `cflow` process
> > our sources correctly? I tried the rule below and the errors file
> > suggests that the preprocessing is done correctly (it's full of
> > complaints but only about redefinitions), yet the result doesn't include
> > any info about the functions called by `insert_1_both` or
> > `Fput_text_property` (to take two randomly sampled cases of interest).
>
> I use Clangd + Eglot + eglot-supplements if I have questions about who
> call whom.
>
> With clangd 20 one can display incoming and outgoing call trees. Only
> inconvenience is that one has to expand nodes in the tree manually
> because nodes are created on demand via LSP. And this of course only
> sees what's compiled in.
>
I was going to suggest mostly the and, except you don't need "eglot
supplements" since call hierarchies (and type, too) are blue in Eglot for
some months. See the manual of you're interested.
I clangd sees anything that compile_commands.json mentions, it doesn't
actually need to be or have been compiled.
Expanding node by node makes sense to me, as huge swaths of the graph
(which is sometimes cyclic) are uninteresting.
João
>
[Message part 2 (text/html, inline)]
Information forwarded
to
bug-gnu-emacs <at> gnu.org
:
bug#78221
; Package
emacs
.
(Sun, 04 May 2025 18:42:05 GMT)
Full text and
rfc822 format available.
Message #83 received at 78221 <at> debbugs.gnu.org (full text, mbox):
[Message part 1 (text/plain, inline)]
Hello, Stefan.
On Sun, May 04, 2025 at 14:18:35 -0400, Stefan Monnier wrote:
> > From my notes from 2018, the command I used on cflow was:
> > $ cflow --reverse -b -i +s --cpp -I. -I../lib -I/usr/include/glib-2.0 \
> > -I/usr/lib64/glib-2.0/include -I/usr/include/libxml2 buffer.c \
> > callproc.c \
> > casefiddle.c cmds.c coding.c decompress.c editfns.c emacs.c \
> > fileio.c fns.c \
> > indent.c insdel.c print.c process.c search.c textprop.c \
> > xdisp.c xml.c 2> /dev/null > ~/cflow.20180102b.txt.
> > I no longer remember what the options mean, but the files I scanned were
> > those containing calls to insdel.c's externally visible functions.
> Thanks. That gives me the same problems. 🙁
Sorry about that.
> > I later analysed cflow.20180102b.txt with an elisp script, which I still
> > have, and could send to you if you're interested. (It's 125 lines long,
> > but poorly commented.) This script scanned the cflow output,
> > recursively finding callers (direct and indirect) of
> > signal_\(before\|after\)_change.
> Can't hurt, thanks.
OK, it's attached. To run it, use M-: (find-change-functions), M-:
(find-primitives), or M-: (make-primitive-calls) (not very useful). For
these, the current buffers needs to be the cflow output.
> Stefan
--
Alan Mackenzie (Nuremberg, Germany).
[get-signal-change.el (text/plain, attachment)]
Information forwarded
to
bug-gnu-emacs <at> gnu.org
:
bug#78221
; Package
emacs
.
(Sun, 04 May 2025 18:43:02 GMT)
Full text and
rfc822 format available.
Message #86 received at 78221 <at> debbugs.gnu.org (full text, mbox):
[Message part 1 (text/plain, inline)]
Stupid auto-correct:
and -> same
blue -> built-in
João Távora
On Sun, May 4, 2025, 19:40 João Távora <joaotavora <at> gmail.com> wrote:
>
>
> On Sun, May 4, 2025, 19:12 Gerd Möllmann <gerd.moellmann <at> gmail.com> wrote:
>
>> Stefan Monnier <monnier <at> iro.umontreal.ca> writes:
>>
>> >> The right tool to find these is cflow, combined with grep and awk (or
>> >> python or perl or whatever) to search and filter cflow's output. I've
>> >> used these before.
>> >
>> > Do you happen to remember the magic incantation to let `cflow` process
>> > our sources correctly? I tried the rule below and the errors file
>> > suggests that the preprocessing is done correctly (it's full of
>> > complaints but only about redefinitions), yet the result doesn't include
>> > any info about the functions called by `insert_1_both` or
>> > `Fput_text_property` (to take two randomly sampled cases of interest).
>>
>> I use Clangd + Eglot + eglot-supplements if I have questions about who
>> call whom.
>>
>> With clangd 20 one can display incoming and outgoing call trees. Only
>> inconvenience is that one has to expand nodes in the tree manually
>> because nodes are created on demand via LSP. And this of course only
>> sees what's compiled in.
>>
>
> I was going to suggest mostly the and, except you don't need "eglot
> supplements" since call hierarchies (and type, too) are blue in Eglot for
> some months. See the manual of you're interested.
>
> I clangd sees anything that compile_commands.json mentions, it doesn't
> actually need to be or have been compiled.
>
> Expanding node by node makes sense to me, as huge swaths of the graph
> (which is sometimes cyclic) are uninteresting.
>
> João
>
>>
[Message part 2 (text/html, inline)]
Information forwarded
to
bug-gnu-emacs <at> gnu.org
:
bug#78221
; Package
emacs
.
(Sun, 04 May 2025 18:46:02 GMT)
Full text and
rfc822 format available.
Message #89 received at 78221 <at> debbugs.gnu.org (full text, mbox):
Stefan Monnier <monnier <at> iro.umontreal.ca> writes:
>> - org-edit-latex-fragment
>
> Hmm... AFAICT it adds text properties to a string, not to a buffer.
Right. I was thinking about read-only state we put during the edit, but
that's an overlay.
>> - org-display-custom-time
>
> AFAICT this is called exclusively from font-lock, so
> `inhibit-modifications-hooks` should always be set already.
I was close. `org-toggle-timestamp-overlays' (just above).
--
Ihor Radchenko // yantar92,
Org mode maintainer,
Learn more about Org mode at <https://orgmode.org/>.
Support Org development at <https://liberapay.com/org-mode>,
or support my work at <https://liberapay.com/yantar92>
Information forwarded
to
bug-gnu-emacs <at> gnu.org
:
bug#78221
; Package
emacs
.
(Sun, 04 May 2025 18:48:04 GMT)
Full text and
rfc822 format available.
Message #92 received at 78221 <at> debbugs.gnu.org (full text, mbox):
João Távora <joaotavora <at> gmail.com> writes:
> I was going to suggest mostly the and, except you don't need "eglot supplements" since call
> hierarchies (and type, too) are blue in Eglot for some months. See
> the manual of you're interested.
That's nice! Thanks.
Information forwarded
to
bug-gnu-emacs <at> gnu.org
:
bug#78221
; Package
emacs
.
(Mon, 05 May 2025 03:10:02 GMT)
Full text and
rfc822 format available.
Message #95 received at 78221 <at> debbugs.gnu.org (full text, mbox):
>>> - org-display-custom-time
>> AFAICT this is called exclusively from font-lock, so
>> `inhibit-modifications-hooks` should always be set already.
> I was close. `org-toggle-timestamp-overlays' (just above).
I see. I think this one would definitely benefit from a bit of
`with-silent-modifications` (currently, I suspect that a sequence like
open a file + call `org-toggle-timestamp-overlays` + call `undo` can
result in the `buffer-modified-p` flag being unwittingly set, and maybe
also the timestamp "overlays" may have reappeared).
Then again, I suspect this code needs to be moved to
`org-remove-font-lock-display-properties` anyway, otherwise the
`display` property might "stick" even after the user modifies the text
into something that's not a timestamp any more.
Stefan
Information forwarded
to
bug-gnu-emacs <at> gnu.org
:
bug#78221
; Package
emacs
.
(Fri, 09 May 2025 16:16:02 GMT)
Full text and
rfc822 format available.
Message #98 received at 78221 <at> debbugs.gnu.org (full text, mbox):
Hello, Eli.
On Sat, May 03, 2025 at 14:46:45 +0000, Alan Mackenzie wrote:
[ .... ]
> > Due to the Emacs's highly-recursive workings and the various hooks we
> > have, which are ever-expanding, there's a virtually infinite number of
> > situations where some code, called while a buffer-change operation is
> > under way, itself calls a buffer-changing primitive, thus generating
> > nested notifications. Finding and fixing all of theses situations one
> > by one will take us infinite time, so I would like to consider more
> > practical alternatives. And for that, IMO we need a very good
> > understanding of the problems they cause.
> As I proposed in my reply to Stefan M., I don't think finding most/all of
> these situations need be too difficult. insdel.c could be temporarily
> instrumented to signal an error on detecting an illegitimate buffer
> change. The difficulty here might be false positives, when a program
> intends to make buffer changes from inside a change hook function. I
> don't think these are common, though.
I no longer think we've got a systematic way of detecting all these
errors. But...
I instrumented insdel.c in this way on a slightly outdated code base.
(In particular, signal_before_change and signal_after_change were
modified to detect nested calls to *-change-functions.) I put Stefan's
recent amendment to editfns-tests.el into the mix, too. Then I ran the
test suite.
The instrumentation detected _only_ the error highlighted by that change
to editfns-tests.el, no others. It seems that nested calls of
*-change-functions are rare indeed. Again, I think that the
complications of handling the nested calls would not be justified by the
small number, possibly zero, of such bugs still in the code.
--
Alan Mackenzie (Nuremberg, Germany).
Information forwarded
to
bug-gnu-emacs <at> gnu.org
:
bug#78221
; Package
emacs
.
(Tue, 13 May 2025 03:49:02 GMT)
Full text and
rfc822 format available.
Message #101 received at 78221 <at> debbugs.gnu.org (full text, mbox):
>> - Don't notify changes to text-properties.
>> Currently, things like `put-text-property` run the *-change-functions
>> like any other buffer modification. In practice this is of dubious value:
>> - It's already the case that most calls to `put-text-property` and
>> friends don't cause any notification because they are wrapped within
>> a `with-silent-modifications` or otherwise take place from code
>> which always runs with `inhibit-modification-hooks` set
>> (e.g. because it's run from a *-change-function).
>> So *-change-functions can't reliably track changes to text-properties.
>> - Most *-change-functions are *not* interested in text-property
>> changes anyway.
>> The above two points suggest maybe we could just refrain from
>> running *-change-functions when changing the text-properties (just
>> like we do for changes to overlay properties).
>> Then again, this would be a backward-incompatible change, so there's
>> a chance some packages out there would be negatively affected.
>> Another option would be to allow packages to choose whether to receive
>> notifications like now or only for changes to the text.
>> E.g. just like we have `buffer-modified-tick` and
>> `buffer-chars-modified-tick`, we could have `*-change-functions`
>> and `*-chars-change-functions` (with some questions remaining about
>> `first-change-hook` and the `modification-hooks` property).
>> Or we could rely on a (symbol) property being set on the functions
>> added to `*-change-functions` to tell whether they want to know about
>> changes to text-properties or not.
>> Or maybe a more crude way would be a buffer-local variable controlling
>> whether `*-change-functions` are called for text-property changes.
>
> I think it was a mistake in the beginning to have text property
> modifications trigger before/after-c-f.
+1
> But seeing it's been that way for so long, I don't think it would be
> a good idea to change it now.
The more I look at it, the more I see it as a serious mistake, indeed.
I still have not found a single *-change-function that needs to know
about text-property changes.
On the contrary, I see that most code that changes text-properties
wraps those changes in `with-silent-modifications` to avoid the various
undesirable side-effects of treating text-properties as being part of
the text. Actually, the whole purpose of `with-silent-modifications` is
to work around that historical mistake.
Of all the code that touches text-properties I see that the majority is
wrapped (directly or indirectly) in `with-silent-modifications`, and of
the remaining ones, the majority would actually benefit from being
wrapped as well (the authors just haven't bumped (yet) into the
downsides).
The only case I have found so far where we do want to record
text-property changes (not to run *-change-functions, but to mark the
buffer as modified and to record the changes in the undo-list) is the
`enriched-mode`.
For that single use case the rest of ELisp code has had to pay the
complexity cost of `with-silent-modifications` (which is delicate to use
since its effect is nasty if you do modify the buffer's text) plus the
occasional performance cost of uselessly running the *-change-functions
and wasting memory by recording those changes on the undo-list (not to
mention the occasional breakage of promises of how *-change-functions
are run).
AFAICT, in the long term, ELisp code would benefit from fixing that
historical mistake.
I suggest we introduce a new boolean variable
`inhibit-recording-text-property-changes`: if nil we get the current
behavior, but if non-nil then all text-property modifications are
implicitly wrapped in a `with-silent-modifications`: they don't change
the modified-p flag, they don't change the undo list, they don't run any
modification hooks.
I'd expect it to default to nil (for obvious backward compatibility
reasons), and major modes can set it buffer-locally to t. Eventually,
I'd hope even `enriched-mode` will set it to t, and will instead record
the text-property changes "by hand".
Stefan
Information forwarded
to
bug-gnu-emacs <at> gnu.org
:
bug#78221
; Package
emacs
.
(Tue, 13 May 2025 04:13:01 GMT)
Full text and
rfc822 format available.
Message #104 received at 78221 <at> debbugs.gnu.org (full text, mbox):
On May 12, 2025 8:48:16 PM PDT, "Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors" <bug-gnu-emacs <at> gnu.org> wrote:
>>> - Don't notify changes to text-properties.
>>> Currently, things like `put-text-property` run the *-change-functions
>>> like any other buffer modification. In practice this is of dubious value:
>>> - It's already the case that most calls to `put-text-property` and
>>> friends don't cause any notification because they are wrapped within
>>> a `with-silent-modifications` or otherwise take place from code
>>> which always runs with `inhibit-modification-hooks` set
>>> (e.g. because it's run from a *-change-function).
>>> So *-change-functions can't reliably track changes to text-properties.
>>> - Most *-change-functions are *not* interested in text-property
>>> changes anyway.
>>> The above two points suggest maybe we could just refrain from
>>> running *-change-functions when changing the text-properties (just
>>> like we do for changes to overlay properties).
>>> Then again, this would be a backward-incompatible change, so there's
>>> a chance some packages out there would be negatively affected.
>>> Another option would be to allow packages to choose whether to receive
>>> notifications like now or only for changes to the text.
>>> E.g. just like we have `buffer-modified-tick` and
>>> `buffer-chars-modified-tick`, we could have `*-change-functions`
>>> and `*-chars-change-functions` (with some questions remaining about
>>> `first-change-hook` and the `modification-hooks` property).
>>> Or we could rely on a (symbol) property being set on the functions
>>> added to `*-change-functions` to tell whether they want to know about
>>> changes to text-properties or not.
>>> Or maybe a more crude way would be a buffer-local variable controlling
>>> whether `*-change-functions` are called for text-property changes.
>>
>> I think it was a mistake in the beginning to have text property
>> modifications trigger before/after-c-f.
>
>+1
The idea, I think, was for users to directly manipulate text properties to attach semantic information. That's why
In practice, text properties ended up being volatile implementation details.
I think XEmacs got this more right by directly exposing intervals (which we have anyway) as extents. Water under the bridge now.
>
>> But seeing it's been that way for so long, I don't think it would be
>> a good idea to change it now.
>
>The more I look at it, the more I see it as a serious mistake, indeed.
>I still have not found a single *-change-function that needs to know
>about text-property changes.
>
>On the contrary, I see that most code that changes text-properties
>wraps those changes in `with-silent-modifications` to avoid the various
>undesirable side-effects of treating text-properties as being part of
>the text. Actually, the whole purpose of `with-silent-modifications` is
>to work around that historical mistake.
>
>Of all the code that touches text-properties I see that the majority is
>wrapped (directly or indirectly) in `with-silent-modifications`, and of
>the remaining ones, the majority would actually benefit from being
>wrapped as well (the authors just haven't bumped (yet) into the
>downsides).
>
>The only case I have found so far where we do want to record
>text-property changes (not to run *-change-functions, but to mark the
>buffer as modified and to record the changes in the undo-list) is the
>`enriched-mode`.
Can we just delete enriched mode? Good idea, but the world ended up going in a different direction.
>For that single use case the rest of ELisp code has had to pay the
>complexity cost of `with-silent-modifications` (which is delicate to use
>since its effect is nasty if you do modify the buffer's text) plus the
>occasional performance cost of uselessly running the *-change-functions
>and wasting memory by recording those changes on the undo-list (not to
>mention the occasional breakage of promises of how *-change-functions
>are run).
>
>AFAICT, in the long term, ELisp code would benefit from fixing that
>historical mistake.
>
>I suggest we introduce a new boolean variable
>`inhibit-recording-text-property-changes`: if nil we get the current
>behavior, but if non-nil then all text-property modifications are
>implicitly wrapped in a `with-silent-modifications`: they don't change
>the modified-p flag, they don't change the undo list, they don't run any
>modification hooks.
>
>I'd expect it to default to nil (for obvious backward compatibility
>reasons), and major modes can set it buffer-locally to t. Eventually,
>I'd hope even `enriched-mode` will set it to t, and will instead record
>the text-property changes "by hand".
Minor modes might need it too. I think it's fine to add a new hook variable, but I don't think it's safe or even especially convenient (relative to the new variable) to have something that changes the behavior of existing code at a distance.
And speaking of hindsight: if we're going to add a new hook variable, how about making it a function compatible with add-function and such instead of a list of functions?
Information forwarded
to
bug-gnu-emacs <at> gnu.org
:
bug#78221
; Package
emacs
.
(Tue, 13 May 2025 04:14:02 GMT)
Full text and
rfc822 format available.
Information forwarded
to
bug-gnu-emacs <at> gnu.org
:
bug#78221
; Package
emacs
.
(Tue, 13 May 2025 12:01:01 GMT)
Full text and
rfc822 format available.
Message #110 received at 78221 <at> debbugs.gnu.org (full text, mbox):
> From: Stefan Monnier <monnier <at> iro.umontreal.ca>
> Cc: 78221 <at> debbugs.gnu.org, Eli Zaretskii <eliz <at> gnu.org>, Ihor Radchenko
> <yantar92 <at> posteo.net>, João Távora
> <joaotavora <at> gmail.com>
> Date: Mon, 12 May 2025 23:48:16 -0400
>
> I suggest we introduce a new boolean variable
> `inhibit-recording-text-property-changes`: if nil we get the current
> behavior, but if non-nil then all text-property modifications are
> implicitly wrapped in a `with-silent-modifications`: they don't change
> the modified-p flag, they don't change the undo list, they don't run any
> modification hooks.
I don't have a firm opinion on whether we should introduce this, let
alone if this was a "historical mistake" (at least conceptually, since
properties are part of buffer text, it follows that any change in them
is like changes in the text itself). But if we do decide to introduce
this variable, it should not be a simple boolean, but it should also
be possible to set it to a list of properties whose changes are not
inhibited from producing buffer-change notifications. This is because
(a) that's the Emacsy way of handling similar features, and (b) it
seems to me that you mainly have simple properties like faces in mind,
whereas the Emacs text properties can be very different in purpose, as
Daniel points out. It is quite possible that some application, or
even Emacs in general, would want certain properties to always
generate notifications, even if all the rest don't. I believe Org
uses many different properties for many purposes, so perhaps Ihor
could comment from Org perspective.
P.S. I don't think such a significant feature should be discussed on
the bug tracker. The right place is emacs-devel.
Information forwarded
to
bug-gnu-emacs <at> gnu.org
:
bug#78221
; Package
emacs
.
(Tue, 13 May 2025 12:11:01 GMT)
Full text and
rfc822 format available.
Message #113 received at 78221 <at> debbugs.gnu.org (full text, mbox):
> Date: Mon, 12 May 2025 21:12:29 -0700
> From: Daniel Colascione <dancol <at> dancol.org>
> CC: 78221 <at> debbugs.gnu.org, Eli Zaretskii <eliz <at> gnu.org>,
> Ihor Radchenko <yantar92 <at> posteo.net>,
> João Távora <joaotavora <at> gmail.com>
>
> >The only case I have found so far where we do want to record
> >text-property changes (not to run *-change-functions, but to mark the
> >buffer as modified and to record the changes in the undo-list) is the
> >`enriched-mode`.
>
> Can we just delete enriched mode? Good idea, but the world ended up going in a different direction.
This is a tangent, but I don't see any sense in deleting
enriched-mode. It's a stand-alone mode, which doesn't impose any
requirements on the rest of Emacs, and consumes almost no maintenance
(grand total of 10 real changes in the last 10 years).
OTOH, it provides a ready-to-use infrastructure for any feature that
wants to make text properties persistent. We needed that for
etc/HELLO (to avoid the need to encode it in ISO 2022 so as to
preserve the charset information), and it was very easy to leverage it
for that purpose. If enriched-mode didn't exist back then, we'd have
a much harder problem to solve.
Information forwarded
to
bug-gnu-emacs <at> gnu.org
:
bug#78221
; Package
emacs
.
(Tue, 13 May 2025 21:07:02 GMT)
Full text and
rfc822 format available.
Message #116 received at 78221 <at> debbugs.gnu.org (full text, mbox):
On Mon, May 12, 2025 at 23:48:16 -0400, Stefan Monnier wrote:
> >> - Don't notify changes to text-properties.
> >> Currently, things like `put-text-property` run the *-change-functions
> >> like any other buffer modification. In practice this is of dubious value:
> >> - It's already the case that most calls to `put-text-property` and
> >> friends don't cause any notification because they are wrapped within
> >> a `with-silent-modifications` or otherwise take place from code
> >> which always runs with `inhibit-modification-hooks` set
> >> (e.g. because it's run from a *-change-function).
> >> So *-change-functions can't reliably track changes to text-properties.
> >> - Most *-change-functions are *not* interested in text-property
> >> changes anyway.
> >> The above two points suggest maybe we could just refrain from
> >> running *-change-functions when changing the text-properties (just
> >> like we do for changes to overlay properties).
> >> Then again, this would be a backward-incompatible change, so there's
> >> a chance some packages out there would be negatively affected.
> >> Another option would be to allow packages to choose whether to receive
> >> notifications like now or only for changes to the text.
> >> E.g. just like we have `buffer-modified-tick` and
> >> `buffer-chars-modified-tick`, we could have `*-change-functions`
> >> and `*-chars-change-functions` (with some questions remaining about
> >> `first-change-hook` and the `modification-hooks` property).
> >> Or we could rely on a (symbol) property being set on the functions
> >> added to `*-change-functions` to tell whether they want to know about
> >> changes to text-properties or not.
> >> Or maybe a more crude way would be a buffer-local variable controlling
> >> whether `*-change-functions` are called for text-property changes.
> > I think it was a mistake in the beginning to have text property
> > modifications trigger before/after-c-f.
> +1
> > But seeing it's been that way for so long, I don't think it would be
> > a good idea to change it now.
> The more I look at it, the more I see it as a serious mistake, indeed.
> I still have not found a single *-change-function that needs to know
> about text-property changes.
I can't actually feel terribly strongly about it. I think it was a
mistake, but not all that serious.
> On the contrary, I see that most code that changes text-properties
> wraps those changes in `with-silent-modifications` to avoid the various
> undesirable side-effects of treating text-properties as being part of
> the text. Actually, the whole purpose of `with-silent-modifications` is
> to work around that historical mistake.
> Of all the code that touches text-properties I see that the majority is
> wrapped (directly or indirectly) in `with-silent-modifications`, and of
> the remaining ones, the majority would actually benefit from being
> wrapped as well (the authors just haven't bumped (yet) into the
> downsides).
> The only case I have found so far where we do want to record
> text-property changes (not to run *-change-functions, but to mark the
> buffer as modified and to record the changes in the undo-list) is the
> `enriched-mode`.
> For that single use case the rest of ELisp code has had to pay the
> complexity cost of `with-silent-modifications` (which is delicate to use
> since its effect is nasty if you do modify the buffer's text) plus the
> occasional performance cost of uselessly running the *-change-functions
> and wasting memory by recording those changes on the undo-list (not to
> mention the occasional breakage of promises of how *-change-functions
> are run).
> AFAICT, in the long term, ELisp code would benefit from fixing that
> historical mistake.
I think in the long term, you're right. But in the short and medium term
(up to ~15 years from now) ....
> I suggest we introduce a new boolean variable
> `inhibit-recording-text-property-changes`: if nil we get the current
> behavior, but if non-nil then all text-property modifications are
> implicitly wrapped in a `with-silent-modifications`: they don't change
> the modified-p flag, they don't change the undo list, they don't run any
> modification hooks.
....., I think the extra complexity will cause confusion. It will cause
bugs, too. The situation with text properties is already complicated
enough, and the extra flag will be adding to the already great weight of
Emacs complexity, something which impedes all of us, especially
beginners, in modifying Emacs.
So, on balance, I'm against this new mechanism. I don't feel at all
strongly about it, though.
> I'd expect it to default to nil (for obvious backward compatibility
> reasons), and major modes can set it buffer-locally to t. Eventually,
> I'd hope even `enriched-mode` will set it to t, and will instead record
> the text-property changes "by hand".
> Stefan
--
Alan Mackenzie (Nuremberg, Germany).
This bug report was last modified 1 day ago.
Previous Next
GNU bug tracking system
Copyright (C) 1999 Darren O. Benham,
1997,2003 nCipher Corporation Ltd,
1994-97 Ian Jackson.