Subject: bug#76108: Call `modify_text' only on the text being replaced in `subst-char-in-region'

From: Thuna <[email-masked]>
Date: Wed, 12 Feb 2025 01:37:18 +0100

>> I thought it might have been because `subst-char-in-region' calls
>> `signal_after_change' from the first to the last change (and that is
>> likely not unrelated) but even if that were the case the first and last
>> change in the above situation is the sole newline at the middle, so it
>> shouldn't have reached the overlay regardless.  Maybe
>> `report_overlay_modification' calls everything called in the before call
>> as well, but I honestly can't tell.
>
> It turns out that, indeed, the C code makes extra efforts to call the
> same `modification-hooks` functions from overlays before and after
> the change, hence the weird behavior (from `editfns.c`):
>
>     /* Lisp vector holding overlay hook functions to call.
>        Vector elements come in pairs.
>        Each even-index element is a list of hook functions.
>        The following odd-index element is the overlay they came from.
>     
>        Before the buffer change, we fill in this vector
>        as we call overlay hook functions.
>        After the buffer change, we get the functions to call from this vector.
>        This way we always call the same functions before and after the change.  */
>     static Lisp_Object last_overlay_modification_hooks;
>     
>     /* Number of elements actually used in last_overlay_modification_hooks.  */
>     static ptrdiff_t last_overlay_modification_hooks_used;
>
> so, while it looks like a bug to me, it's very much done on purpose.
> Not sure whether we should fix it or document it.
>
> And I guess we could use the same approach to run the
> `modification-hooks` from text properties also *after* the modification.

I'm still not happy with the loose way in which these hooks are called.
I imagine that any modification hook that's useful will essentially be
implementing a half-working version of what calling them strictly would
achieve.  My biggest problem is that I don't have a reference for how
significant the performance issues are, so the limitations end up
feeling much more impactful.

At the very least, the documentation of precisely when these functions
are called and what sort of guarantees they give should be updated,
since it currently reads
> ‘modification-hooks’
>      This property's value is a list of functions to be called if any
>      character within the overlay is changed or if text is inserted
>      strictly within the overlay.
in (info "(elisp) Overlay Properties").