unofficial mirror of bug-gnu-emacs@gnu.org 
 help / color / mirror / code / Atom feed
* 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

* 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:
       [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

* 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: 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

* 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 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: (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

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).