Subject: Re: bug#76313: New function `replace-region`

From: Eli Zaretskii <[email-masked]>
Date: Sun, 30 Mar 2025 08:12:13 +0300

> From: Stefan Monnier <[email-masked]>
> Cc: [email-masked],  [email-masked],  [email-masked],
>   [email-masked]
> Date: Sat, 29 Mar 2025 18:20:15 -0400
> 
> > I'd prefer a completely backward-compatible change of passing a
> > special value of MAX-SECS to indicate that the potentially costly
> > algorithm is to be bypassed.
> 
> We already have that: pass a 0 for MAX-SECS.

So we should probably mention this in the documentation?

> But I've changed my mind: I don't think we should unify
> `replace-region-contents` and my proposed `replace-region`.
> 
> When I sent the patches there were still some tests failing, and
> I assumed these were just the result of idiotic errors on my part which
> I'd fix the next day (it was late).
> 
> While that was partly true, some of the problems were a lot more
> delicate: while `replace-region` is "easy" to use to do what I would
> describe as "edits", `replace-region-contents` is a good bit more
> delicate because its effect on point is less predictable.
> 
> When point is "in the middle" of the modified text, all is fine callers
> usually don't expect any specific position for point after wards, in
> that case.  But if point is at the beginning (resp. at the end) of the text
> being replaced, most callers expect it to still be at the beginning
> (resp. the end) of the new text afterwards.
> 
> This does hold when point is at the beginning of the text but *not* when
> it's at the end.  So in a typical loop scanning a buffer with
> `re-search-forward` and then calling `replace-region-contents`, it's
> easy to get bitten by it when occasionally we'll end up finding a match
> in the text we just inserted because the "careful" version of
> `replace-region-contents` moved point back somewhat.
> 
> IOW, if you have code that uses
> 
>     (replace-region-contents BEG END SOURCE 0)
> 
> and you change it to:
> 
>     (replace-region-contents BEG END SOURCE 0.1)
> 
> thinking "oh, I can afford to spend a bit more time here, let's
> enable the fancy diff algorithm", you may end up breaking your code.

So maybe these subtleties should be described in the manual?  And if
the caller doesn't care, or has point in a place that won't bump into
these issues, then replace-region-contents can still be used as a Lisp
API to replace_region?  For example, a loop like you describe above
could carefully place point before each call to re-search-forward, to
avoid the problems, no?