1
0
mirror of https://git.savannah.gnu.org/git/emacs.git synced 2025-01-05 11:45:45 +00:00

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.
This commit is contained in:
Tino Calancha 2018-05-23 18:20:36 +09:00
parent cc130d13d4
commit bab73230d1
2 changed files with 24 additions and 0 deletions

View File

@ -2214,6 +2214,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