* bug#25111: @ 2016-12-04 20:53 Phillip Lord 2016-12-05 15:33 ` bug#25111: Eli Zaretskii ` (2 more replies) 0 siblings, 3 replies; 26+ messages in thread From: Phillip Lord @ 2016-12-04 20:53 UTC (permalink / raw) To: 25111 The documentation for "modification-hooks" on overlays says: If these functions modify the buffer, they should bind ‘inhibit-modification-hooks’ to ‘t’ around doing so, to avoid confusing the internal mechanism that calls these hooks. But as far as I can see, the only place these gets called "signal_after_change" and "signal_before_change", inhibit-modification-hooks is already specbound to t, so this advice is unnecessary. Also, the documentation for inhibit-modification-hooks says: If you do want modification hooks to be run in a particular piece of code that is itself run from a modification hook, then rebind locally ‘inhibit-modification-hooks’ to ‘nil’. which suggests that, in fact, it is possible to call the modification hooks from inside another call to these functions. This is true for both emacs-25 and master. ^ permalink raw reply [flat|nested] 26+ messages in thread
* bug#25111: 2016-12-04 20:53 bug#25111: Phillip Lord @ 2016-12-05 15:33 ` Eli Zaretskii [not found] ` <87wpfbpual.fsf@russet.org.uk> 2016-12-05 17:39 ` bug#25111: How modification-hooks let-bind inhibit-modification-hooks? Noam Postavsky 2017-03-09 19:34 ` Noam Postavsky 2 siblings, 1 reply; 26+ messages in thread From: Eli Zaretskii @ 2016-12-05 15:33 UTC (permalink / raw) To: Phillip Lord; +Cc: 25111 > Date: Sun, 4 Dec 2016 20:53:24 -0000 > From: "Phillip Lord" <phillip.lord@russet.org.uk> > > The documentation for "modification-hooks" on overlays says: > > If these functions modify the buffer, they should bind > ‘inhibit-modification-hooks’ to ‘t’ around doing so, to avoid > confusing the internal mechanism that calls these hooks. > > But as far as I can see, the only place these gets called > "signal_after_change" > and "signal_before_change", inhibit-modification-hooks is already specbound > to t, so this advice is unnecessary. > > Also, the documentation for inhibit-modification-hooks says: > > If you do want modification hooks to be run in a particular > piece of code that is itself run from a modification hook, then > rebind locally ‘inhibit-modification-hooks’ to ‘nil’. > > which suggests that, in fact, it is possible to call the modification > hooks from inside another call to these functions. Given these two excerpts, it seems to me that there's no inaccuracies in the manual, perhaps we just need to tell both stories in the same place or something? Or do you still think there's something incorrect in these two fragments? Thanks. ^ permalink raw reply [flat|nested] 26+ messages in thread
[parent not found: <87wpfbpual.fsf@russet.org.uk>]
* bug#25111: [not found] ` <87wpfbpual.fsf@russet.org.uk> @ 2016-12-07 16:40 ` Phillip Lord [not found] ` <WM!2f8d5bad87de09a0621b1f025704a97dd719ed1ae7d08e03f6b419e215cd51bc54917b522795d7421de3533c07950608!@mailhub-mx1> 1 sibling, 0 replies; 26+ messages in thread From: Phillip Lord @ 2016-12-07 16:40 UTC (permalink / raw) To: Eli Zaretskii; +Cc: 25111 Eli Zaretskii <eliz@gnu.org> writes: >> Date: Sun, 4 Dec 2016 20:53:24 -0000 >> From: "Phillip Lord" <phillip.lord@russet.org.uk> >> >> The documentation for "modification-hooks" on overlays says: >> >> If these functions modify the buffer, they should bind >> ‘inhibit-modification-hooks’ to ‘t’ around doing so, to avoid >> confusing the internal mechanism that calls these hooks. >> >> But as far as I can see, the only place these gets called >> "signal_after_change" >> and "signal_before_change", inhibit-modification-hooks is already specbound >> to t, so this advice is unnecessary. >> >> Also, the documentation for inhibit-modification-hooks says: >> >> If you do want modification hooks to be run in a particular >> piece of code that is itself run from a modification hook, then >> rebind locally ‘inhibit-modification-hooks’ to ‘nil’. >> >> which suggests that, in fact, it is possible to call the modification >> hooks from inside another call to these functions. > > Given these two excerpts, it seems to me that there's no inaccuracies > in the manual, perhaps we just need to tell both stories in the same > place or something? Or do you still think there's something incorrect > in these two fragments? I think that the first of these is incorrect. There is no need to bind `inhibit-modification-hooks' to `t'. More over, there may be reasons by bind `inhibit-modification-hooks' to `nil' (i.e. "If you do want modification hooks to be run..."). I am unclear whether this will "confuse the internal mechanism", since I don't know exactly what this means. It possible that the documentation should say "Mostly, you should avoid modifying the buffer on these hooks, any other functionality using these modification-hooks will not be called." The reason I ask all of this as a result of a concrete use case. yasnippet modifies the buffer in these hooks, in turn breaks my own package, lentic, which uses these hooks to respond to changes. https://github.com/joaotavora/yasnippet/issues/756 https://github.com/phillord/lentic/issues/51 Phil ^ permalink raw reply [flat|nested] 26+ messages in thread
[parent not found: <WM!2f8d5bad87de09a0621b1f025704a97dd719ed1ae7d08e03f6b419e215cd51bc54917b522795d7421de3533c07950608!@mailhub-mx1>]
* bug#25111: [not found] ` <WM!2f8d5bad87de09a0621b1f025704a97dd719ed1ae7d08e03f6b419e215cd51bc54917b522795d7421de3533c07950608!@mailhub-mx1> @ 2016-12-08 15:55 ` Eli Zaretskii 2016-12-09 17:17 ` bug#25111: Phillip Lord 0 siblings, 1 reply; 26+ messages in thread From: Eli Zaretskii @ 2016-12-08 15:55 UTC (permalink / raw) To: Phillip Lord; +Cc: 25111 > From: phillip.lord@russet.org.uk (Phillip Lord) > Cc: 25111@debbugs.gnu.org > Date: Wed, 07 Dec 2016 16:40:02 +0000 > > I think that the first of these is incorrect. There is no need to bind > `inhibit-modification-hooks' to `t'. More over, there may be reasons by > bind `inhibit-modification-hooks' to `nil' (i.e. "If you do want > modification hooks to be run..."). So if we envision that some hook will bind inhibit-modification-hooks to nil, then that is the reason to bind it to t in a hokk which doesn't want such hooks to be run. > It possible that the documentation should say "Mostly, you should avoid > modifying the buffer on these hooks, any other functionality using these > modification-hooks will not be called." You mean, not mention the variable at all? That'd be loss of useful information, I think. > The reason I ask all of this as a result of a concrete use > case. yasnippet modifies the buffer in these hooks, in turn breaks my > own package, lentic, which uses these hooks to respond to changes. So how would you want the manual to help avert such calamities? ^ permalink raw reply [flat|nested] 26+ messages in thread
* bug#25111: 2016-12-08 15:55 ` bug#25111: Eli Zaretskii @ 2016-12-09 17:17 ` Phillip Lord 2016-12-09 17:26 ` bug#25111: Eli Zaretskii 0 siblings, 1 reply; 26+ messages in thread From: Phillip Lord @ 2016-12-09 17:17 UTC (permalink / raw) To: Eli Zaretskii; +Cc: 25111 Eli Zaretskii <eliz@gnu.org> writes: >> From: phillip.lord@russet.org.uk (Phillip Lord) >> Cc: 25111@debbugs.gnu.org >> Date: Wed, 07 Dec 2016 16:40:02 +0000 >> >> I think that the first of these is incorrect. There is no need to bind >> `inhibit-modification-hooks' to `t'. More over, there may be reasons by >> bind `inhibit-modification-hooks' to `nil' (i.e. "If you do want >> modification hooks to be run..."). > > So if we envision that some hook will bind inhibit-modification-hooks > to nil, then that is the reason to bind it to t in a hokk which > doesn't want such hooks to be run. Indeed, this is true, and it's a difficulty with the hook. I mean, it is *meant* to run when the buffer is modified and yet here is an example of where we cannot be sure that it will. >> It possible that the documentation should say "Mostly, you should avoid >> modifying the buffer on these hooks, any other functionality using these >> modification-hooks will not be called." > > You mean, not mention the variable at all? That'd be loss of useful > information, I think. > >> The reason I ask all of this as a result of a concrete use >> case. yasnippet modifies the buffer in these hooks, in turn breaks my >> own package, lentic, which uses these hooks to respond to changes. > > So how would you want the manual to help avert such calamities? My own feeling is that "inhibit-modification-hooks" should *only* be for modifications that really should not be detected by anything else. I can think of examples of this (I used to change the buffer to display a completion string to the user for instance, although I now use an "after-string" overlay property). The simplest advice makes calls to the modification hooks consistent is to say "You should not modify the buffer on these hooks". The potential solution, for instance, for yasnippet is to record the changes on after-change-function, and then change the buffer on post-command-hook. I think this would work? Is this what the manual should say? Phil ^ permalink raw reply [flat|nested] 26+ messages in thread
* bug#25111: 2016-12-09 17:17 ` bug#25111: Phillip Lord @ 2016-12-09 17:26 ` Eli Zaretskii 2016-12-11 22:11 ` bug#25111: Phillip Lord 0 siblings, 1 reply; 26+ messages in thread From: Eli Zaretskii @ 2016-12-09 17:26 UTC (permalink / raw) To: Phillip Lord; +Cc: 25111 > From: phillip.lord@russet.org.uk (Phillip Lord) > Cc: 25111@debbugs.gnu.org > Date: Fri, 09 Dec 2016 17:17:51 +0000 > > > So how would you want the manual to help avert such calamities? > > > My own feeling is that "inhibit-modification-hooks" should *only* be for > modifications that really should not be detected by anything else. I can > think of examples of this (I used to change the buffer to display a > completion string to the user for instance, although I now use an > "after-string" overlay property). > > The simplest advice makes calls to the modification hooks consistent is > to say "You should not modify the buffer on these hooks". The potential > solution, for instance, for yasnippet is to record the changes on > after-change-function, and then change the buffer on > post-command-hook. I think this would work? Is this what the manual > should say? IMO, the manual should advise the safe practices, and then tell how to behave if the code really needs to play it less safe. The former would be what you say above, I think. But since we know there are packages out there that don't choose the safe approach, we should cover those as well. ^ permalink raw reply [flat|nested] 26+ messages in thread
* bug#25111: 2016-12-09 17:26 ` bug#25111: Eli Zaretskii @ 2016-12-11 22:11 ` Phillip Lord 2016-12-12 16:06 ` bug#25111: Eli Zaretskii 0 siblings, 1 reply; 26+ messages in thread From: Phillip Lord @ 2016-12-11 22:11 UTC (permalink / raw) To: Eli Zaretskii; +Cc: 25111 Eli Zaretskii <eliz@gnu.org> writes: >> From: phillip.lord@russet.org.uk (Phillip Lord) >> Cc: 25111@debbugs.gnu.org >> Date: Fri, 09 Dec 2016 17:17:51 +0000 >> >> My own feeling is that "inhibit-modification-hooks" should *only* be for >> modifications that really should not be detected by anything else. I can >> think of examples of this (I used to change the buffer to display a >> completion string to the user for instance, although I now use an >> "after-string" overlay property). >> >> The simplest advice makes calls to the modification hooks consistent is >> to say "You should not modify the buffer on these hooks". The potential >> solution, for instance, for yasnippet is to record the changes on >> after-change-function, and then change the buffer on >> post-command-hook. I think this would work? Is this what the manual >> should say? > > IMO, the manual should advise the safe practices, and then tell how to > behave if the code really needs to play it less safe. The former > would be what you say above, I think. But since we know there are > packages out there that don't choose the safe approach, we should > cover those as well. So, instead of this: If these functions modify the buffer, they should bind ‘inhibit-modification-hooks’ to ‘t’ around doing so, to avoid confusing the internal mechanism that calls these hooks. We could have: These functions should avoid unnecessarily modifying the buffer. Emacs binds 'inhibit-modification-hooks' to `t' during their evaluation, which means that any modifications will not be signalled to other hook functions listening for them. Perhaps a better solution would be: These functions should avoid unnecessarily modifying the buffer; see Change Hooks for further details. Then a new paragraph can be added to the Change Hooks section talking about the complexity of modifying buffers on these hooks, with alternatives. I am happy to draft something if you wish. Phil ^ permalink raw reply [flat|nested] 26+ messages in thread
* bug#25111: 2016-12-11 22:11 ` bug#25111: Phillip Lord @ 2016-12-12 16:06 ` Eli Zaretskii 2019-05-19 20:31 ` bug#25111: (Inaccurate documentation of inhibit-modification-hooks) Alan Mackenzie 0 siblings, 1 reply; 26+ messages in thread From: Eli Zaretskii @ 2016-12-12 16:06 UTC (permalink / raw) To: Phillip Lord; +Cc: 25111 > From: phillip.lord@russet.org.uk (Phillip Lord) > Cc: 25111@debbugs.gnu.org > Date: Sun, 11 Dec 2016 22:11:14 +0000 > > So, instead of this: > > If these functions modify the buffer, they should bind > ‘inhibit-modification-hooks’ to ‘t’ around doing so, to avoid > confusing the internal mechanism that calls these hooks. > > > We could have: > > These functions should avoid unnecessarily modifying the buffer. > Emacs binds 'inhibit-modification-hooks' to `t' during their > evaluation, which means that any modifications will not be signalled > to other hook functions listening for them. > > > Perhaps a better solution would be: > > > These functions should avoid unnecessarily modifying the buffer; see > Change Hooks for further details. > > > Then a new paragraph can be added to the Change Hooks section talking > about the complexity of modifying buffers on these hooks, with > alternatives. > > I am happy to draft something if you wish. Sure, please do. Thanks. ^ permalink raw reply [flat|nested] 26+ messages in thread
* bug#25111: (Inaccurate documentation of inhibit-modification-hooks) 2016-12-12 16:06 ` bug#25111: Eli Zaretskii @ 2019-05-19 20:31 ` Alan Mackenzie 2019-05-25 12:39 ` Noam Postavsky 0 siblings, 1 reply; 26+ messages in thread From: Alan Mackenzie @ 2019-05-19 20:31 UTC (permalink / raw) To: Eli Zaretskii, Noam Postavsky; +Cc: 25111, Phillip Lord Hello, Eli and Noam. On Mon, Dec 12, 2016 at 18:06:34 +0200, Eli Zaretskii wrote: > > From: phillip.lord@russet.org.uk (Phillip Lord) > > Cc: 25111@debbugs.gnu.org > > Date: Sun, 11 Dec 2016 22:11:14 +0000 > > So, instead of this: > > If these functions modify the buffer, they should bind > > ‘inhibit-modification-hooks’ to ‘t’ around doing so, to avoid > > confusing the internal mechanism that calls these hooks. > > We could have: > > These functions should avoid unnecessarily modifying the buffer. > > Emacs binds 'inhibit-modification-hooks' to `t' during their > > evaluation, which means that any modifications will not be signalled > > to other hook functions listening for them. > > Perhaps a better solution would be: > > These functions should avoid unnecessarily modifying the buffer; see > > Change Hooks for further details. > > Then a new paragraph can be added to the Change Hooks section talking > > about the complexity of modifying buffers on these hooks, with > > alternatives. > > I am happy to draft something if you wish. > Sure, please do. > Thanks. OK, it was a while ago, and I'm not Phillip, but I recently got caught out with the inaccurate documentation of inhibit-modification-hooks, so I suggest the following, to get the discussion rolling again: diff --git a/doc/lispref/display.texi b/doc/lispref/display.texi index a2ed4b3891..b88702f2a2 100644 --- a/doc/lispref/display.texi +++ b/doc/lispref/display.texi @@ -1743,9 +1743,17 @@ Overlay Properties length is the number of characters deleted, and the post-change beginning and end are equal.) -If these functions modify the buffer, they should bind -@code{inhibit-modification-hooks} to @code{t} around doing so, to -avoid confusing the internal mechanism that calls these hooks. +@c If these functions modify the buffer, they should bind +@c @code{inhibit-modification-hooks} to @code{t} around doing so, to +@c avoid confusing the internal mechanism that calls these hooks. + +When these functions are called, @code{inhibit-modification-hooks} is +bound to non-@code{nil}. If the functions modify the buffer, you +might want to bind @code{inhibit-modification-hooks} to nil, so as to +cause the change hooks to run for these modifications. @xref{Change +Hooks}. However, doing this can sometimes confuse the internal +mechanism that calls all these hooks, leading, for example, to calling +them recursively, which is usually unwanted. Text properties also support the @code{modification-hooks} property, but the details are somewhat different (@pxref{Special Properties}). diff --git a/doc/lispref/text.texi b/doc/lispref/text.texi index 278bc3c268..fd4338ecdb 100644 --- a/doc/lispref/text.texi +++ b/doc/lispref/text.texi @@ -3621,9 +3621,14 @@ Special Properties hook will only be run when removing some characters, replacing them with others, or changing their text-properties. -If these functions modify the buffer, they should bind -@code{inhibit-modification-hooks} to @code{t} around doing so, to -avoid confusing the internal mechanism that calls these hooks. +@c If these functions modify the buffer, they should bind +@c @code{inhibit-modification-hooks} to @code{t} around doing so, to +@c avoid confusing the internal mechanism that calls these hooks. + +When Emacs calls these functions, @code{inhibit-modification-hooks} is +set to @code{nil}. If the functions modify the buffer, you should +consider binding this variable to non-@code{nil}, to avoid confusing +the internal mechanism that calls these hooks. @xref{Change Hooks}. Overlays also support the @code{modification-hooks} property, but the details are somewhat different (@pxref{Overlay Properties}). -- Alan Mackenzie (Nuremberg, Germany). ^ permalink raw reply related [flat|nested] 26+ messages in thread
* bug#25111: (Inaccurate documentation of inhibit-modification-hooks) 2019-05-19 20:31 ` bug#25111: (Inaccurate documentation of inhibit-modification-hooks) Alan Mackenzie @ 2019-05-25 12:39 ` Noam Postavsky 2019-05-25 13:44 ` Alan Mackenzie 2019-05-25 13:49 ` Eli Zaretskii 0 siblings, 2 replies; 26+ messages in thread From: Noam Postavsky @ 2019-05-25 12:39 UTC (permalink / raw) To: Alan Mackenzie; +Cc: 25111, Phillip Lord [-- Attachment #1: Type: text/plain, Size: 749 bytes --] Alan Mackenzie <acm@muc.de> writes: > @@ -1743,9 +1743,17 @@ Overlay Properties > However, doing this can sometimes confuse the internal > +mechanism that calls all these hooks, leading, for example, to calling > +them recursively, which is usually unwanted. > @@ -3621,9 +3621,14 @@ Special Properties > +When Emacs calls these functions, @code{inhibit-modification-hooks} is > +set to @code{nil}. As Phillip mentioned in the OP, Emacs in fact binds it to t. > If the functions modify the buffer, you should > +consider binding this variable to non-@code{nil}, to avoid confusing > +the internal mechanism that calls these hooks. @xref{Change Hooks}. I find this "confusing the internal mechanism" thing unhelpful, how about this instead: [-- Warning: decoded text below may be mangled, UTF-8 assumed --] [-- Attachment #2: patch --] [-- Type: text/x-diff, Size: 3188 bytes --] From 568e640f962cd9a59d695351ded11c4a8e781f06 Mon Sep 17 00:00:00 2001 From: Alan Mackenzie <acm@muc.de> Date: Sun, 19 May 2019 20:31:19 +0000 Subject: [PATCH] Clarify elisp ref for inhibit-modification-hooks (Bug#25111) * doc/lispref/display.texi (Overlay Properties): * doc/lispref/text.texi (Special Properties) (Change Hooks): Explain that inhibit-modification-hooks is bound to t while executing change hooks, and suggest binding to nil with suitable precautions when modifying buffer from a change hook. Co-authored-by: Noam Postavsky <npostavs@gmail.com> --- doc/lispref/display.texi | 9 ++++++--- doc/lispref/text.texi | 12 ++++++++---- 2 files changed, 14 insertions(+), 7 deletions(-) diff --git a/doc/lispref/display.texi b/doc/lispref/display.texi index b07999432c..f7140f444e 100644 --- a/doc/lispref/display.texi +++ b/doc/lispref/display.texi @@ -1708,9 +1708,12 @@ Overlay Properties length is the number of characters deleted, and the post-change beginning and end are equal.) -If these functions modify the buffer, they should bind -@code{inhibit-modification-hooks} to @code{t} around doing so, to -avoid confusing the internal mechanism that calls these hooks. +When these functions are called, @code{inhibit-modification-hooks} is +bound to non-@code{nil}. If the functions modify the buffer, you +might want to bind @code{inhibit-modification-hooks} to nil, so as to +cause the change hooks to run for these modifications. However, doing +this may call your own change hook recursively, so be sure to prepare +for that. @xref{Change Hooks}. Text properties also support the @code{modification-hooks} property, but the details are somewhat different (@pxref{Special Properties}). diff --git a/doc/lispref/text.texi b/doc/lispref/text.texi index f3d222b708..5954161fcf 100644 --- a/doc/lispref/text.texi +++ b/doc/lispref/text.texi @@ -3514,9 +3514,10 @@ Special Properties hook will only be run when removing some characters, replacing them with others, or changing their text-properties. -If these functions modify the buffer, they should bind -@code{inhibit-modification-hooks} to @code{t} around doing so, to -avoid confusing the internal mechanism that calls these hooks. +When Emacs calls these functions, @code{inhibit-modification-hooks} is +set to non-@code{nil}. If the functions modify the buffer, you should +consider binding this variable to @code{nil}, but in that case you +must be prepared for recursive calls. @xref{Change Hooks}. Overlays also support the @code{modification-hooks} property, but the details are somewhat different (@pxref{Overlay Properties}). @@ -5093,5 +5094,8 @@ Change Hooks a modification hook does not cause other modification hooks to be run. If you do want modification hooks to be run in a particular piece of code that is itself run from a modification hook, then rebind locally -@code{inhibit-modification-hooks} to @code{nil}. +@code{inhibit-modification-hooks} to @code{nil}. However, doing this +may cause recursive calls to the modification hooks, so be sure to +prepare for that (for example, by binding some variable which tells +your hook to do nothing). @end defvar -- 2.11.0 ^ permalink raw reply related [flat|nested] 26+ messages in thread
* bug#25111: (Inaccurate documentation of inhibit-modification-hooks) 2019-05-25 12:39 ` Noam Postavsky @ 2019-05-25 13:44 ` Alan Mackenzie 2019-05-25 14:36 ` Noam Postavsky 2019-05-25 13:49 ` Eli Zaretskii 1 sibling, 1 reply; 26+ messages in thread From: Alan Mackenzie @ 2019-05-25 13:44 UTC (permalink / raw) To: Noam Postavsky; +Cc: 25111, Phillip Lord Hello, Noam. On Sat, May 25, 2019 at 08:39:39 -0400, Noam Postavsky wrote: > Alan Mackenzie <acm@muc.de> writes: > > @@ -1743,9 +1743,17 @@ Overlay Properties > > However, doing this can sometimes confuse the internal > > +mechanism that calls all these hooks, leading, for example, to calling > > +them recursively, which is usually unwanted. > > @@ -3621,9 +3621,14 @@ Special Properties > > +When Emacs calls these functions, @code{inhibit-modification-hooks} is > > +set to @code{nil}. > As Phillip mentioned in the OP, Emacs in fact binds it to t. Are you sure? We're talking here about the text property (in which I think inhibit-modification-hooks IS at nil) as opposed to the overlay property (where inhibit-modification-hooks is bound to t). I admit just to having examined the source code rather than actually trying it out. But in verify_interval_modification in textprop.c, near the end, we have: if (!inhibit_modification_hooks) { hooks = Fnreverse (hooks); while (! NILP (hooks)) { call_mod_hooks (Fcar (hooks), make_fixnum (start), make_fixnum (end)); hooks = Fcdr (hooks); } } . Here, mod_hooks is a list of modification-hooks combined with positions. call_mod_hooks only gets called when inhibit-modification-hooks is nil. call_mod_hooks just calls the hooks, without binding i-m-h. Are you really sure? I'll answer the rest of your post later, I've got a lot on in Real Life at the moment. [ .... ] -- Alan Mackenzie (Nuremberg, Germany). ^ permalink raw reply [flat|nested] 26+ messages in thread
* bug#25111: (Inaccurate documentation of inhibit-modification-hooks) 2019-05-25 13:44 ` Alan Mackenzie @ 2019-05-25 14:36 ` Noam Postavsky 2019-05-27 14:31 ` Alan Mackenzie 0 siblings, 1 reply; 26+ messages in thread From: Noam Postavsky @ 2019-05-25 14:36 UTC (permalink / raw) To: Alan Mackenzie; +Cc: 25111, Phillip Lord [-- Attachment #1: Type: text/plain, Size: 508 bytes --] Alan Mackenzie <acm@muc.de> writes: >>> @@ -3621,9 +3621,14 @@ Special Properties > >>> +When Emacs calls these functions, @code{inhibit-modification-hooks} is >>> +set to @code{nil}. > >> As Phillip mentioned in the OP, Emacs in fact binds it to t. > > Are you sure? We're talking here about the text property (in which I > think inhibit-modification-hooks IS at nil) as opposed to the overlay > property (where inhibit-modification-hooks is bound to t). Oh, you're quite right. Here's some test code: [-- Attachment #2: testing inhibit-modification-hooks binding --] [-- Type: text/plain, Size: 788 bytes --] (defun mod-hook-text-prop (&rest args) (message "mod-hook-text-prop %S, inhibit? %S" args inhibit-modification-hooks)) (defun mod-hook-ov-prop (&rest args) (message "mod-hook-ov-prop %S, inhibit? %S" args inhibit-modification-hooks)) (defun mod-hook-change-fun (&rest args) (message "mod-hook-change-fun %S, inhibit? %S" args inhibit-modification-hooks)) (with-current-buffer (get-buffer-create "*test*") (insert (propertize "foo\n" 'modification-hooks '(mod-hook-text-prop))) (let ((ov (make-overlay (point-min) (point-max) ))) (overlay-put ov 'modification-hooks '(mod-hook-ov-prop))) (setq-local before-change-functions '(mod-hook-change-fun)) (setq-local after-change-functions '(mod-hook-change-fun)) (goto-char (point-min)) (delete-char 3) (insert "bar")) [-- Attachment #3: Type: text/plain, Size: 605 bytes --] Which produces this: mod-hook-text-prop (1 4), inhibit? nil mod-hook-change-fun (1 4), inhibit? t mod-hook-ov-prop (#<overlay from 1 to 5 in *test*> nil 1 4), inhibit? t mod-hook-change-fun (1 1 3), inhibit? t mod-hook-ov-prop (#<overlay from 1 to 2 in *test*> t 1 1 3), inhibit? t mod-hook-change-fun (1 1), inhibit? t mod-hook-change-fun (1 4 0), inhibit? t I think we need to emphasize the difference in this case, it's rather confusing. > I'll answer the rest of your post later, I've got a lot on in Real Life > at the moment. No rush. I've updated the patch based on your and Eli's feedback. [-- Warning: decoded text below may be mangled, UTF-8 assumed --] [-- Attachment #4: patch --] [-- Type: text/x-diff, Size: 3019 bytes --] From 7f6453596b7753af7704eaac7f27ebba8d03cfc4 Mon Sep 17 00:00:00 2001 From: Alan Mackenzie <acm@muc.de> Date: Sun, 19 May 2019 20:31:19 +0000 Subject: [PATCH] Clarify elisp ref for inhibit-modification-hooks (Bug#25111) * doc/lispref/display.texi (Overlay Properties): * doc/lispref/text.texi (Change Hooks): Explain that inhibit-modification-hooks is bound to t while executing change hooks, and suggest binding to nil with suitable precautions when modifying buffer from a change hook. (Special Properties): Emphasize that inhibit-modification-hooks is left set to nil when executing text property change hooks. Co-authored-by: Noam Postavsky <npostavs@gmail.com> --- doc/lispref/display.texi | 6 +++--- doc/lispref/text.texi | 12 ++++++++---- 2 files changed, 11 insertions(+), 7 deletions(-) diff --git a/doc/lispref/display.texi b/doc/lispref/display.texi index b07999432c..59d02d540a 100644 --- a/doc/lispref/display.texi +++ b/doc/lispref/display.texi @@ -1708,9 +1708,9 @@ Overlay Properties length is the number of characters deleted, and the post-change beginning and end are equal.) -If these functions modify the buffer, they should bind -@code{inhibit-modification-hooks} to @code{t} around doing so, to -avoid confusing the internal mechanism that calls these hooks. +Similar to change hooks, when these functions are called, +@code{inhibit-modification-hooks} is bound to @code{t}. @xref{Change +Hooks}. Text properties also support the @code{modification-hooks} property, but the details are somewhat different (@pxref{Special Properties}). diff --git a/doc/lispref/text.texi b/doc/lispref/text.texi index f3d222b708..c935cfe49b 100644 --- a/doc/lispref/text.texi +++ b/doc/lispref/text.texi @@ -3514,9 +3514,10 @@ Special Properties hook will only be run when removing some characters, replacing them with others, or changing their text-properties. -If these functions modify the buffer, they should bind -@code{inhibit-modification-hooks} to @code{t} around doing so, to -avoid confusing the internal mechanism that calls these hooks. +When Emacs calls these functions, @code{inhibit-modification-hooks} is +set to @code{nil}, unlike for change hooks. When writing a function +which modifies the buffer, consider binding it @code{t}, to avoid +recursive calls. @xref{Change Hooks}. Overlays also support the @code{modification-hooks} property, but the details are somewhat different (@pxref{Overlay Properties}). @@ -5093,5 +5094,8 @@ Change Hooks a modification hook does not cause other modification hooks to be run. If you do want modification hooks to be run in a particular piece of code that is itself run from a modification hook, then rebind locally -@code{inhibit-modification-hooks} to @code{nil}. +@code{inhibit-modification-hooks} to @code{nil}. However, doing this +may cause recursive calls to the modification hooks, so be sure to +prepare for that (for example, by binding some variable which tells +your hook to do nothing). @end defvar -- 2.11.0 ^ permalink raw reply related [flat|nested] 26+ messages in thread
* bug#25111: (Inaccurate documentation of inhibit-modification-hooks) 2019-05-25 14:36 ` Noam Postavsky @ 2019-05-27 14:31 ` Alan Mackenzie 2019-06-03 19:15 ` Alan Mackenzie 0 siblings, 1 reply; 26+ messages in thread From: Alan Mackenzie @ 2019-05-27 14:31 UTC (permalink / raw) To: Noam Postavsky; +Cc: 25111, Phillip Lord Hello, Noam. On Sat, May 25, 2019 at 10:36:55 -0400, Noam Postavsky wrote: > Alan Mackenzie <acm@muc.de> writes: > >>> @@ -3621,9 +3621,14 @@ Special Properties > >>> +When Emacs calls these functions, @code{inhibit-modification-hooks} is > >>> +set to @code{nil}. > >> As Phillip mentioned in the OP, Emacs in fact binds it to t. > > Are you sure? We're talking here about the text property (in which I > > think inhibit-modification-hooks IS at nil) as opposed to the overlay > > property (where inhibit-modification-hooks is bound to t). > Oh, you're quite right. Here's some test code: [ .... ] > Which produces this: > mod-hook-text-prop (1 4), inhibit? nil > mod-hook-change-fun (1 4), inhibit? t > mod-hook-ov-prop (#<overlay from 1 to 5 in *test*> nil 1 4), inhibit? t > mod-hook-change-fun (1 1 3), inhibit? t > mod-hook-ov-prop (#<overlay from 1 to 2 in *test*> t 1 1 3), inhibit? t > mod-hook-change-fun (1 1), inhibit? t > mod-hook-change-fun (1 4 0), inhibit? t > I think we need to emphasize the difference in this case, it's rather > confusing. Alternatively, we could perhaps regard the first of these results (for modification-hooks) as a bug in the code, which seems like it ought to be binding inhibit-modification-hooks to non-nil like the others. Maybe we should amend the code, even though this would be a jarring incompatibility with previous Emacs versions. Eli? [ .... ] > I've updated the patch based on your and Eli's feedback. Yes, I agree that "confusing the internal mechanism" is unhelpful here. Thanks for getting rid of it. [ .... ] -- Alan Mackenzie (Nuremberg, Germany). ^ permalink raw reply [flat|nested] 26+ messages in thread
* bug#25111: (Inaccurate documentation of inhibit-modification-hooks) 2019-05-27 14:31 ` Alan Mackenzie @ 2019-06-03 19:15 ` Alan Mackenzie 2019-06-03 19:26 ` npostavs 0 siblings, 1 reply; 26+ messages in thread From: Alan Mackenzie @ 2019-06-03 19:15 UTC (permalink / raw) To: Eli Zaretskii; +Cc: 25111, Noam Postavsky, Phillip Lord Hello, Eli. To recap, the problem we were talking about was the modification-hooks overlay property, whose value is a function which gets called before and after modification of the text under an overlay. When such a function gets called, inhibit-modification-hooks is left at nil. When the other four similar overlay/text-property "change functions" get called, inhibit-modification-hooks gets bound to t. This is difficult to document coherently. My proposal of last week was to fix the code, also to bin inhibit-modification-hooks to t for the modification-hooks overlay property, even though this would be an incompatibility in Lisp. Ping? ----------------------------->----------------------------------- | On Mon, May 27, 2019 at 14:31:09 +0000, Alan Mackenzie wrote: | > Hello, Noam. | | > On Sat, May 25, 2019 at 10:36:55 -0400, Noam Postavsky wrote: | > > Alan Mackenzie <acm@muc.de> writes: | | > > >>> @@ -3621,9 +3621,14 @@ Special Properties | | > > >>> +When Emacs calls these functions, @code{inhibit-modification-hooks} is > > >>> +set to @code{nil}. | v > > >> As Phillip mentioned in the OP, Emacs in fact binds it to t. | | > > > Are you sure? We're talking here about the text property (in which I > > > think inhibit-modification-hooks IS at nil) as opposed to the overlay > > > property (where inhibit-modification-hooks is bound to t). | | > > Oh, you're quite right. Here's some test code: | | > [ .... ] | | | > > Which produces this: | | > > mod-hook-text-prop (1 4), inhibit? nil | > > mod-hook-change-fun (1 4), inhibit? t | > > mod-hook-ov-prop (#<overlay from 1 to 5 in *test*> nil 1 4), inhibit? t > > mod-hook-change-fun (1 1 3), inhibit? t | > > mod-hook-ov-prop (#<overlay from 1 to 2 in *test*> t 1 1 3), inhibit? t > > mod-hook-change-fun (1 1), inhibit? t | > > mod-hook-change-fun (1 4 0), inhibit? t | | > > I think we need to emphasize the difference in this case, it's rather > > confusing. | V > Alternatively, we could perhaps regard the first of these results (for > modification-hooks) as a bug in the code, which seems like it ought to be > binding inhibit-modification-hooks to non-nil like the others. Maybe we > should amend the code, even though this would be a jarring > incompatibility with previous Emacs versions. Eli? > [ .... ] > > I've updated the patch based on your and Eli's feedback. > Yes, I agree that "confusing the internal mechanism" is unhelpful here. > Thanks for getting rid of it. > [ .... ] -- Alan Mackenzie (Nuremberg, Germany). ^ permalink raw reply [flat|nested] 26+ messages in thread
* bug#25111: (Inaccurate documentation of inhibit-modification-hooks) 2019-06-03 19:15 ` Alan Mackenzie @ 2019-06-03 19:26 ` npostavs 2019-06-04 9:32 ` Alan Mackenzie 0 siblings, 1 reply; 26+ messages in thread From: npostavs @ 2019-06-03 19:26 UTC (permalink / raw) To: Alan Mackenzie; +Cc: Phillip Lord, 25111, Noam Postavsky Alan Mackenzie <acm@muc.de> writes: > Hello, Eli. > > To recap, the problem we were talking about was the modification-hooks > overlay property, whose value is a function which gets called before and > after modification of the text under an overlay. > > When such a function gets called, inhibit-modification-hooks is left at > nil. When the other four similar overlay/text-property "change > functions" get called, inhibit-modification-hooks gets bound to t. Minor correction: it's the modification-hooks text property which have inhibit-modification-hooks left at nil, when the overlay property modification-hooks get called inhibit-modification-hooks is bound to t, just like in the after/before-change-functions case. > This is difficult to document coherently. And confusing, as evidenced by the fact that we both got confused about it in this very thread :) > My proposal of last week was to fix the code, also to bin > inhibit-modification-hooks to t for the modification-hooks overlay > property, even though this would be an incompatibility in Lisp. ^ permalink raw reply [flat|nested] 26+ messages in thread
* bug#25111: (Inaccurate documentation of inhibit-modification-hooks) 2019-06-03 19:26 ` npostavs @ 2019-06-04 9:32 ` Alan Mackenzie 2019-06-04 14:36 ` Eli Zaretskii 0 siblings, 1 reply; 26+ messages in thread From: Alan Mackenzie @ 2019-06-04 9:32 UTC (permalink / raw) To: npostavs; +Cc: 25111, Phillip Lord Hello, Noam. On Mon, Jun 03, 2019 at 15:26:38 -0400, npostavs@gmail.com wrote: > Alan Mackenzie <acm@muc.de> writes: > > Hello, Eli. > > To recap, the problem we were talking about was the modification-hooks > > overlay property, whose value is a function which gets called before and > > after modification of the text under an overlay. > > When such a function gets called, inhibit-modification-hooks is left at > > nil. When the other four similar overlay/text-property "change > > functions" get called, inhibit-modification-hooks gets bound to t. > Minor correction: it's the modification-hooks text property which have > inhibit-modification-hooks left at nil, when the overlay property > modification-hooks get called inhibit-modification-hooks is bound to t, > just like in the after/before-change-functions case. Oh, bother. ;-) > > This is difficult to document coherently. > And confusing, as evidenced by the fact that we both got confused about > it in this very thread :) > > My proposal of last week was to fix the code, also to bind > > inhibit-modification-hooks to t for the modification-hooks overlay > > property, even though this would be an incompatibility in Lisp. How about this? diff --git a/src/textprop.c b/src/textprop.c index ae42c44185..607bd40676 100644 --- a/src/textprop.c +++ b/src/textprop.c @@ -2247,6 +2247,8 @@ verify_interval_modification (struct buffer *buf, if (!inhibit_modification_hooks) { + int count = SPECPDL_INDEX (); + specbind (Qinhibit_modification_hooks, Qt); hooks = Fnreverse (hooks); while (! NILP (hooks)) { @@ -2254,6 +2256,7 @@ verify_interval_modification (struct buffer *buf, make_fixnum (end)); hooks = Fcdr (hooks); } + unbind_to (count, Qnil); } } } -- Alan Mackenzie (Nuremberg, Germany). ^ permalink raw reply related [flat|nested] 26+ messages in thread
* bug#25111: (Inaccurate documentation of inhibit-modification-hooks) 2019-06-04 9:32 ` Alan Mackenzie @ 2019-06-04 14:36 ` Eli Zaretskii 2019-06-09 12:00 ` Eli Zaretskii 0 siblings, 1 reply; 26+ messages in thread From: Eli Zaretskii @ 2019-06-04 14:36 UTC (permalink / raw) To: Alan Mackenzie; +Cc: phillip.lord, 25111, npostavs > Date: Tue, 4 Jun 2019 09:32:41 +0000 > Cc: Eli Zaretskii <eliz@gnu.org>, Phillip Lord <phillip.lord@russet.org.uk>, > 25111@debbugs.gnu.org > From: Alan Mackenzie <acm@muc.de> > > > > This is difficult to document coherently. > > > And confusing, as evidenced by the fact that we both got confused about > > it in this very thread :) > > > > My proposal of last week was to fix the code, also to bind > > > inhibit-modification-hooks to t for the modification-hooks overlay > > > property, even though this would be an incompatibility in Lisp. > > How about this? Please wait with this for a few days. I must refresh my memory about this old issue, and re-read the code, and I'm currently busy with more urgent issues, like the harfbuzz branch and a couple of display bugs. TIA, and sorry for being unable to respond quickly. ^ permalink raw reply [flat|nested] 26+ messages in thread
* bug#25111: (Inaccurate documentation of inhibit-modification-hooks) 2019-06-04 14:36 ` Eli Zaretskii @ 2019-06-09 12:00 ` Eli Zaretskii 2019-06-09 20:45 ` Alan Mackenzie 2019-06-24 12:52 ` Alan Mackenzie 0 siblings, 2 replies; 26+ messages in thread From: Eli Zaretskii @ 2019-06-09 12:00 UTC (permalink / raw) To: acm, phillip.lord; +Cc: 25111, npostavs > Date: Tue, 04 Jun 2019 17:36:12 +0300 > From: Eli Zaretskii <eliz@gnu.org> > Cc: phillip.lord@russet.org.uk, 25111@debbugs.gnu.org, npostavs@gmail.com > > > Date: Tue, 4 Jun 2019 09:32:41 +0000 > > Cc: Eli Zaretskii <eliz@gnu.org>, Phillip Lord <phillip.lord@russet.org.uk>, > > 25111@debbugs.gnu.org > > From: Alan Mackenzie <acm@muc.de> > > > > > > This is difficult to document coherently. > > > > > And confusing, as evidenced by the fact that we both got confused about > > > it in this very thread :) > > > > > > My proposal of last week was to fix the code, also to bind > > > > inhibit-modification-hooks to t for the modification-hooks overlay > > > > property, even though this would be an incompatibility in Lisp. > > > > How about this? > > Please wait with this for a few days. OK, after re-reading the discussions and the code, I don't think we should make the incompatible change suggested by Alan. We haven't bound inhibit-modification-hooks to t in the text-property hooks since the day the code was written, 24 years ago, so it makes no sense to me to do that now. Let's document the exception and move on. Noam's last patch LGTM, with the single minor gotcha: > +When Emacs calls these functions, @code{inhibit-modification-hooks} is > +set to @code{nil}, unlike for change hooks. This is from the part that changes the "Special Properties" node, and it's inaccurate: we don't bind inhibit-modification-hooks to nil, we just leave it at its previous binding. This distinction is important in recursive calls, when the caller caused inhibit-modification-hooks to be bound to non-nil. Another minor comment, although not to the proposed text, is that the fact that inhibit-modification-hooks is bound to t when the hook specified by the overlay properties are called is because those hooks are called from within signal_before_change and signal_after_change, which perform these bindings, and the bindings stay in effect both for before/after-change-functions and for hooks specified by overlay properties. By contrast, the hooks specified by text properties are called before that binding becomes in effect (which is why we need a separate check whether inhibit_modification_hooks are non-nil inside verify_interval_modification, which calls the text-property hooks). Thanks. ^ permalink raw reply [flat|nested] 26+ messages in thread
* bug#25111: (Inaccurate documentation of inhibit-modification-hooks) 2019-06-09 12:00 ` Eli Zaretskii @ 2019-06-09 20:45 ` Alan Mackenzie 2019-06-24 12:52 ` Alan Mackenzie 1 sibling, 0 replies; 26+ messages in thread From: Alan Mackenzie @ 2019-06-09 20:45 UTC (permalink / raw) To: Eli Zaretskii; +Cc: phillip.lord, npostavs, 25111 Hello, Eli. On Sun, Jun 09, 2019 at 15:00:16 +0300, Eli Zaretskii wrote: > > Date: Tue, 04 Jun 2019 17:36:12 +0300 > > From: Eli Zaretskii <eliz@gnu.org> > > Cc: phillip.lord@russet.org.uk, 25111@debbugs.gnu.org, npostavs@gmail.com > > > Date: Tue, 4 Jun 2019 09:32:41 +0000 > > > Cc: Eli Zaretskii <eliz@gnu.org>, Phillip Lord <phillip.lord@russet.org.uk>, > > > 25111@debbugs.gnu.org > > > From: Alan Mackenzie <acm@muc.de> > > > > > This is difficult to document coherently. > > > > And confusing, as evidenced by the fact that we both got confused about > > > > it in this very thread :) > > > > > My proposal of last week was to fix the code, also to bind > > > > > inhibit-modification-hooks to t for the modification-hooks overlay > > > > > property, even though this would be an incompatibility in Lisp. > > > How about this? > > Please wait with this for a few days. > OK, after re-reading the discussions and the code, I don't think we > should make the incompatible change suggested by Alan. We haven't > bound inhibit-modification-hooks to t in the text-property hooks since > the day the code was written, 24 years ago, so it makes no sense to me > to do that now. Let's document the exception and move on. Thanks for looking at this and taking the decision. > Noam's last patch LGTM, with the single minor gotcha: > > +When Emacs calls these functions, @code{inhibit-modification-hooks} is > > +set to @code{nil}, unlike for change hooks. > This is from the part that changes the "Special Properties" node, and > it's inaccurate: we don't bind inhibit-modification-hooks to nil, we > just leave it at its previous binding. This distinction is important > in recursive calls, when the caller caused inhibit-modification-hooks > to be bound to non-nil. Yes. The "is set" formulation is ambiguous. It could mean "gets set (bound)", which is how you read it; it could also mean "happens to be set to (at the time)", which was how I intended it. Ambiguous writing isn't good, so I suggest: "When Emacs calls this function, @code{inhibit-modification-hooks} is left at its current value; unlike for change hooks, it does not get bound to non-@code{nil}. > Another minor comment, although not to the proposed text, is that the > fact that inhibit-modification-hooks is bound to t when the hook > specified by the overlay properties are called is because those hooks > are called from within signal_before_change and signal_after_change, > which perform these bindings, and the bindings stay in effect both for > before/after-change-functions and for hooks specified by overlay > properties. By contrast, the hooks specified by text properties are > called before that binding becomes in effect (which is why we need a > separate check whether inhibit_modification_hooks are non-nil inside > verify_interval_modification, which calls the text-property hooks). Thanks, that's helpful. > Thanks. -- Alan Mackenzie (Nuremberg, Germany). ^ permalink raw reply [flat|nested] 26+ messages in thread
* bug#25111: (Inaccurate documentation of inhibit-modification-hooks) 2019-06-09 12:00 ` Eli Zaretskii 2019-06-09 20:45 ` Alan Mackenzie @ 2019-06-24 12:52 ` Alan Mackenzie 2019-06-24 22:48 ` Noam Postavsky 1 sibling, 1 reply; 26+ messages in thread From: Alan Mackenzie @ 2019-06-24 12:52 UTC (permalink / raw) To: Eli Zaretskii, npostavs; +Cc: 25111, phillip.lord Hello, Eli and Noam (but mainly Noam). It's about time we finally got this matter tidied up, so... On Sun, Jun 09, 2019 at 15:00:16 +0300, Eli Zaretskii wrote: > OK, after re-reading the discussions and the code, I don't think we > should make the incompatible change suggested by Alan. We haven't > bound inhibit-modification-hooks to t in the text-property hooks since > the day the code was written, 24 years ago, so it makes no sense to me > to do that now. Let's document the exception and move on. > Noam's last patch LGTM, with the single minor gotcha: > > +When Emacs calls these functions, @code{inhibit-modification-hooks} is > > +set to @code{nil}, unlike for change hooks. > This is from the part that changes the "Special Properties" node, and > it's inaccurate: we don't bind inhibit-modification-hooks to nil, we > just leave it at its previous binding. This distinction is important > in recursive calls, when the caller caused inhibit-modification-hooks > to be bound to non-nil. I've corrected this bit by saying that "Unlike with other similar hooks, when Emacs calls these functions, `inhibit-modification-hooks' does _not_ get bound to non-`nil'". I've also added bits to the descriptions of insert-{in-front,behind}-hooks, the text property version of them, documenting that inhibit-modification-hooks gets bound to non-nil. [ .... ] I think the changes as now formulated are right. Perhaps one or both of you might like to give the following patch a quick review. Thanks! diff --git a/doc/lispref/display.texi b/doc/lispref/display.texi index 7e8abb0440..68f40b55d8 100644 --- a/doc/lispref/display.texi +++ b/doc/lispref/display.texi @@ -1752,9 +1752,12 @@ Overlay Properties length is the number of characters deleted, and the post-change beginning and end are equal.) -If these functions modify the buffer, they should bind -@code{inhibit-modification-hooks} to @code{t} around doing so, to -avoid confusing the internal mechanism that calls these hooks. +When these functions are called, @code{inhibit-modification-hooks} is +bound to non-@code{nil}. If the functions modify the buffer, you +might want to bind @code{inhibit-modification-hooks} to nil, so as to +cause the change hooks to run for these modifications. However, doing +this may call your own change hook recursively, so be sure to prepare +for that. @xref{Change Hooks}. Text properties also support the @code{modification-hooks} property, but the details are somewhat different (@pxref{Special Properties}). diff --git a/doc/lispref/text.texi b/doc/lispref/text.texi index 2e7c497f57..95ed758914 100644 --- a/doc/lispref/text.texi +++ b/doc/lispref/text.texi @@ -3621,9 +3621,12 @@ Special Properties hook will only be run when removing some characters, replacing them with others, or changing their text-properties. -If these functions modify the buffer, they should bind -@code{inhibit-modification-hooks} to @code{t} around doing so, to -avoid confusing the internal mechanism that calls these hooks. +Unlike with other similar hooks, when Emacs calls these functions, +@code{inhibit-modification-hooks} does @emph{not} get bound to +non-@code{nil}. If the functions modify the buffer, you should +consider binding this variable to non-@code{nil} to prevent any buffer +changes running the change hooks. Otherwise, you must be prepared for +recursive calls. @xref{Change Hooks}. Overlays also support the @code{modification-hooks} property, but the details are somewhat different (@pxref{Overlay Properties}). @@ -3639,6 +3642,13 @@ Special Properties beginning and end of the inserted text. The functions are called @emph{after} the actual insertion takes place. +When these functions are called, @code{inhibit-modification-hooks} is +bound to non-@code{nil}. If the functions modify the buffer, you +might want to bind @code{inhibit-modification-hooks} to nil, so as to +cause the change hooks to run for these modifications. However, doing +this may call your own change hook recursively, so be sure to prepare +for that. + See also @ref{Change Hooks}, for other hooks that are called when you change text in a buffer. @@ -5650,5 +5660,8 @@ Change Hooks a modification hook does not cause other modification hooks to be run. If you do want modification hooks to be run in a particular piece of code that is itself run from a modification hook, then rebind locally -@code{inhibit-modification-hooks} to @code{nil}. +@code{inhibit-modification-hooks} to @code{nil}. However, doing this +may cause recursive calls to the modification hooks, so be sure to +prepare for that (for example, by binding some variable which tells +your hook to do nothing). @end defvar -- Alan Mackenzie (Nuremberg, Germany). ^ permalink raw reply related [flat|nested] 26+ messages in thread
* bug#25111: (Inaccurate documentation of inhibit-modification-hooks) 2019-06-24 12:52 ` Alan Mackenzie @ 2019-06-24 22:48 ` Noam Postavsky 2019-06-25 9:17 ` Alan Mackenzie 0 siblings, 1 reply; 26+ messages in thread From: Noam Postavsky @ 2019-06-24 22:48 UTC (permalink / raw) To: Alan Mackenzie; +Cc: 25111, phillip.lord Alan Mackenzie <acm@muc.de> writes: > Hello, Eli and Noam (but mainly Noam). > > It's about time we finally got this matter tidied up, so... Yeah, sorry I dropped the ball on this. > I think the changes as now formulated are right. Perhaps one or both of > you might like to give the following patch a quick review. Thanks! Minor formatting nitpick: > +++ b/doc/lispref/display.texi > @@ -1752,9 +1752,12 @@ Overlay Properties > +When these functions are called, @code{inhibit-modification-hooks} is > +bound to non-@code{nil}. If the functions modify the buffer, you > +might want to bind @code{inhibit-modification-hooks} to nil, so as to ^^^ > +cause the change hooks to run for these modifications. However, doing > +this may call your own change hook recursively, so be sure to prepare > +for that. @xref{Change Hooks}. > +++ b/doc/lispref/text.texi > @@ -3639,6 +3642,13 @@ Special Properties > beginning and end of the inserted text. The functions are called > @emph{after} the actual insertion takes place. > > +When these functions are called, @code{inhibit-modification-hooks} is > +bound to non-@code{nil}. If the functions modify the buffer, you > +might want to bind @code{inhibit-modification-hooks} to nil, so as to ^^^ @code{nil} for both of these, right? Otherwise looks good to me. ^ permalink raw reply [flat|nested] 26+ messages in thread
* bug#25111: (Inaccurate documentation of inhibit-modification-hooks) 2019-06-24 22:48 ` Noam Postavsky @ 2019-06-25 9:17 ` Alan Mackenzie 0 siblings, 0 replies; 26+ messages in thread From: Alan Mackenzie @ 2019-06-25 9:17 UTC (permalink / raw) To: Noam Postavsky; +Cc: 25111-done, phillip.lord Hello, Noam. On Mon, Jun 24, 2019 at 18:48:14 -0400, Noam Postavsky wrote: > Alan Mackenzie <acm@muc.de> writes: [ .... ] > > I think the changes as now formulated are right. Perhaps one or > > both of you might like to give the following patch a quick review. > > Thanks! > Minor formatting nitpick: > > +++ b/doc/lispref/display.texi > > @@ -1752,9 +1752,12 @@ Overlay Properties > > +When these functions are called, @code{inhibit-modification-hooks} is > > +bound to non-@code{nil}. If the functions modify the buffer, you > > +might want to bind @code{inhibit-modification-hooks} to nil, so as to > ^^^ > > +cause the change hooks to run for these modifications. However, doing > > +this may call your own change hook recursively, so be sure to prepare > > +for that. @xref{Change Hooks}. > > +++ b/doc/lispref/text.texi > > @@ -3639,6 +3642,13 @@ Special Properties > > beginning and end of the inserted text. The functions are called > > @emph{after} the actual insertion takes place. > > +When these functions are called, @code{inhibit-modification-hooks} is > > +bound to non-@code{nil}. If the functions modify the buffer, you > > +might want to bind @code{inhibit-modification-hooks} to nil, so as to > ^^^ > @code{nil} for both of these, right? Otherwise looks good to me. Whoops! Thanks for spotting these. I've fixed them and committed the changes. I'm closing the bug with this post. -- Alan Mackenzie (Nuremberg, Germany). ^ permalink raw reply [flat|nested] 26+ messages in thread
* bug#25111: (Inaccurate documentation of inhibit-modification-hooks) 2019-05-25 12:39 ` Noam Postavsky 2019-05-25 13:44 ` Alan Mackenzie @ 2019-05-25 13:49 ` Eli Zaretskii 1 sibling, 0 replies; 26+ messages in thread From: Eli Zaretskii @ 2019-05-25 13:49 UTC (permalink / raw) To: Noam Postavsky; +Cc: acm, 25111, phillip.lord > From: Noam Postavsky <npostavs@gmail.com> > Cc: Eli Zaretskii <eliz@gnu.org>, 25111@debbugs.gnu.org, Phillip Lord <phillip.lord@russet.org.uk> > Date: Sat, 25 May 2019 08:39:39 -0400 > > I find this "confusing the internal mechanism" thing unhelpful, how > about this instead: Fine with me (although I'm not Alan), but please avoid saying the same thing more than once. It is better to describe the issue in one place, and then have the N-1 other places have a cross-reference to that one place. Thanks. ^ permalink raw reply [flat|nested] 26+ messages in thread
* bug#25111: How modification-hooks let-bind inhibit-modification-hooks? 2016-12-04 20:53 bug#25111: Phillip Lord 2016-12-05 15:33 ` bug#25111: Eli Zaretskii @ 2016-12-05 17:39 ` Noam Postavsky 2016-12-05 18:37 ` Eli Zaretskii 2017-03-09 19:34 ` Noam Postavsky 2 siblings, 1 reply; 26+ messages in thread From: Noam Postavsky @ 2016-12-05 17:39 UTC (permalink / raw) To: Eli Zaretskii; +Cc: 25111, Phillip Lord On Mon, Dec 5, 2016 at 10:33 AM, Eli Zaretskii <eliz@gnu.org> wrote: >> Date: Sun, 4 Dec 2016 20:53:24 -0000 >> From: "Phillip Lord" <phillip.lord@russet.org.uk> >> >> The documentation for "modification-hooks" on overlays says: >> >> If these functions modify the buffer, they should bind >> ‘inhibit-modification-hooks’ to ‘t’ around doing so, to avoid >> confusing the internal mechanism that calls these hooks. >> >> But as far as I can see, the only place these gets called >> "signal_after_change" >> and "signal_before_change", inhibit-modification-hooks is already specbound >> to t, so this advice is unnecessary. >> >> Also, the documentation for inhibit-modification-hooks says: >> >> If you do want modification hooks to be run in a particular >> piece of code that is itself run from a modification hook, then >> rebind locally ‘inhibit-modification-hooks’ to ‘nil’. >> >> which suggests that, in fact, it is possible to call the modification >> hooks from inside another call to these functions. > > Given these two excerpts, it seems to me that there's no inaccuracies > in the manual, perhaps we just need to tell both stories in the same > place or something? Or do you still think there's something incorrect > in these two fragments? Would following the advice in the second fragment confuse the "internal mechanism" (as suggested in the first fragment) or not? ^ permalink raw reply [flat|nested] 26+ messages in thread
* bug#25111: How modification-hooks let-bind inhibit-modification-hooks? 2016-12-05 17:39 ` bug#25111: How modification-hooks let-bind inhibit-modification-hooks? Noam Postavsky @ 2016-12-05 18:37 ` Eli Zaretskii 0 siblings, 0 replies; 26+ messages in thread From: Eli Zaretskii @ 2016-12-05 18:37 UTC (permalink / raw) To: Noam Postavsky; +Cc: 25111, phillip.lord > From: Noam Postavsky <npostavs@users.sourceforge.net> > Date: Mon, 5 Dec 2016 12:39:29 -0500 > Cc: Phillip Lord <phillip.lord@russet.org.uk>, 25111@debbugs.gnu.org > > >> The documentation for "modification-hooks" on overlays says: > >> > >> If these functions modify the buffer, they should bind > >> ‘inhibit-modification-hooks’ to ‘t’ around doing so, to avoid > >> confusing the internal mechanism that calls these hooks. > >> > >> But as far as I can see, the only place these gets called > >> "signal_after_change" > >> and "signal_before_change", inhibit-modification-hooks is already specbound > >> to t, so this advice is unnecessary. > >> > >> Also, the documentation for inhibit-modification-hooks says: > >> > >> If you do want modification hooks to be run in a particular > >> piece of code that is itself run from a modification hook, then > >> rebind locally ‘inhibit-modification-hooks’ to ‘nil’. > >> > >> which suggests that, in fact, it is possible to call the modification > >> hooks from inside another call to these functions. > > > > Given these two excerpts, it seems to me that there's no inaccuracies > > in the manual, perhaps we just need to tell both stories in the same > > place or something? Or do you still think there's something incorrect > > in these two fragments? > > Would following the advice in the second fragment confuse the > "internal mechanism" (as suggested in the first fragment) or not? Only if the other hooks that modify buffer, and do NOT want hooks to be run, don't bind inhibit-modification-hooks to t. AFAIU, at least. ^ permalink raw reply [flat|nested] 26+ messages in thread
* bug#25111: How modification-hooks let-bind inhibit-modification-hooks? 2016-12-04 20:53 bug#25111: Phillip Lord 2016-12-05 15:33 ` bug#25111: Eli Zaretskii 2016-12-05 17:39 ` bug#25111: How modification-hooks let-bind inhibit-modification-hooks? Noam Postavsky @ 2017-03-09 19:34 ` Noam Postavsky 2 siblings, 0 replies; 26+ messages in thread From: Noam Postavsky @ 2017-03-09 19:34 UTC (permalink / raw) To: Phillip Lord; +Cc: 25111 On Wed, Dec 7, 2016 at 11:40 AM, Phillip Lord <phillip.lord@russet.org.uk> wrote: > > The reason I ask all of this as a result of a concrete use > case. yasnippet modifies the buffer in these hooks, in turn breaks my > own package, lentic, which uses these hooks to respond to changes. > > > https://github.com/joaotavora/yasnippet/issues/756 > https://github.com/phillord/lentic/issues/51 By the way, text-clone--maintain in subr.el seems to have the same problem. ^ permalink raw reply [flat|nested] 26+ messages in thread
end of thread, other threads:[~2019-06-25 9:17 UTC | newest] Thread overview: 26+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2016-12-04 20:53 bug#25111: Phillip Lord 2016-12-05 15:33 ` bug#25111: Eli Zaretskii [not found] ` <87wpfbpual.fsf@russet.org.uk> 2016-12-07 16:40 ` bug#25111: Phillip Lord [not found] ` <WM!2f8d5bad87de09a0621b1f025704a97dd719ed1ae7d08e03f6b419e215cd51bc54917b522795d7421de3533c07950608!@mailhub-mx1> 2016-12-08 15:55 ` bug#25111: Eli Zaretskii 2016-12-09 17:17 ` bug#25111: Phillip Lord 2016-12-09 17:26 ` bug#25111: Eli Zaretskii 2016-12-11 22:11 ` bug#25111: Phillip Lord 2016-12-12 16:06 ` bug#25111: Eli Zaretskii 2019-05-19 20:31 ` bug#25111: (Inaccurate documentation of inhibit-modification-hooks) Alan Mackenzie 2019-05-25 12:39 ` Noam Postavsky 2019-05-25 13:44 ` Alan Mackenzie 2019-05-25 14:36 ` Noam Postavsky 2019-05-27 14:31 ` Alan Mackenzie 2019-06-03 19:15 ` Alan Mackenzie 2019-06-03 19:26 ` npostavs 2019-06-04 9:32 ` Alan Mackenzie 2019-06-04 14:36 ` Eli Zaretskii 2019-06-09 12:00 ` Eli Zaretskii 2019-06-09 20:45 ` Alan Mackenzie 2019-06-24 12:52 ` Alan Mackenzie 2019-06-24 22:48 ` Noam Postavsky 2019-06-25 9:17 ` Alan Mackenzie 2019-05-25 13:49 ` Eli Zaretskii 2016-12-05 17:39 ` bug#25111: How modification-hooks let-bind inhibit-modification-hooks? Noam Postavsky 2016-12-05 18:37 ` Eli Zaretskii 2017-03-09 19:34 ` Noam Postavsky
Code repositories for project(s) associated with this public inbox https://git.savannah.gnu.org/cgit/emacs.git This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).