Subject: Re: bug#31492: 26.1; query-replace-regexp undo fails in regexps w/o printable chars

From: Eli Zaretskii <[email-masked]>
Date: Sun, 20 May 2018 12:29:07 +0300

> From: Tino Calancha <[email-masked]>
> Cc: [email-masked]
> Date: Sat, 19 May 2018 23:28:35 +0900
> 
> > The relevant
> > element of the replacement stack (whose structure, btw, seems not to
> > be documented anywhere), is (4 4 *scratch*), whereas I'd expect to see
> > (1 4 *scratch) instead, because the replacement was at position 1;
> > then setting match-data from this would DTRT.
> Yes, that is the logic.  The thing is, for some unknown reason to me,
> the reported match-data is inexact when there are no printable chars
> in the regexp (maybe it's expected and I am wrong on my assumptions).

The reason for that is that match-data is recorded as markers, and so
the positions move if text is inserted.  In your example, the position
of $ moved due to insertion, so the marker's position was updated as
part of the replacement.

> (with-temp-buffer
>   (insert "foo")
>   (goto-char 1)
>   (progn (re-search-forward "$" nil t)
> 	 (save-match-data (replace-match "ZZZ"))
> 	 (list (point) (match-beginning 0) (match-end 0))))
> => (7 7 7)
> ;; If this would be (7 4 7), then we could use `looking-at'; we are to
> ;; the right of the replacement, then we use `looking-back'.
>   
> 
> ;; But the match was at 4 not at 7
> (with-temp-buffer
>   (insert "foo")
>   (goto-char 1)
>   (progn (re-search-forward "$" nil t)
> 	 (list (point) (match-beginning 0) (match-end 0))))
> => (4 4 4)

Right, and so I submit that the problem is where the replacement stack
is updated: it should account for these subtleties and adjust the
stack positions accordingly, since it has the opportunity to look at
the match position before the matched text is replaced.  It is IMO
suboptimal to make these adjustments where the stack is used, because
you've lost the information about the actual match point, and you are
deducing it using heuristics, which I'm not sure is 100% reliable.

Thanks.