1
Fork 0
mirror of git://git.sv.gnu.org/emacs.git synced 2026-01-30 04:10:54 -08:00

Backport: Fix corner case in query-replace-regexp undo

This commit fixes Bug#31492.
* lisp/replace.el (replace-match-maybe-edit): Preserve match data.

* test/lisp/replace-tests.el (query-replace-undo-bug31492): Add test.

(cherry picked from commit bab73230d1)
This commit is contained in:
Tino Calancha 2018-06-03 23:28:24 +09:00
parent 50c0624b2a
commit 031004e81b
2 changed files with 24 additions and 0 deletions

View file

@ -2147,6 +2147,10 @@ passed in. If LITERAL is set, no checking is done, anyway."
noedit nil)))
(set-match-data match-data)
(replace-match newtext fixedcase literal)
;; `query-replace' undo feature needs the beginning of the match position,
;; but `replace-match' may change it, for instance, with a regexp like "^".
;; Ensure that this function preserves the match data (Bug#31492).
(set-match-data match-data)
;; `replace-match' leaves point at the end of the replacement text,
;; so move point to the beginning when replacing backward.
(when backward (goto-char (nth 0 match-data)))

View file

@ -399,5 +399,25 @@ Each element has the format:
;; After undo text must be the same.
(should (string= text (buffer-string))))))
(ert-deftest query-replace-undo-bug31492 ()
"Test for https://debbugs.gnu.org/31492 ."
(let ((text "a\nb\nc\n")
(count 0)
(inhibit-message t))
(with-temp-buffer
(insert text)
(goto-char 1)
(cl-letf (((symbol-function 'read-event)
(lambda (&rest args)
(cl-incf count)
(let ((val (pcase count
((or 1 2) ?\s) ; replace current and go next
(3 ?U) ; undo-all
(_ ?q)))) ; exit
val))))
(perform-replace "^\\|\b\\|$" "foo" t t nil))
;; After undo text must be the same.
(should (string= text (buffer-string))))))
;;; replace-tests.el ends here