Skip to content

Commit 30c4f35

Browse files
committed
query-replace-regexp undo: Update next-replacement after undo
* lisp/replace.el (perform-replace): Rename the local binding to not shadow next-replacement. Update next-replacement after undo (Bug#37287). * test/lisp/replace-tests.el (query-replace-undo-bug37287): Add test. (query-replace-undo-bug37073): Tweak this test.
1 parent c596be0 commit 30c4f35

File tree

2 files changed

+25
-7
lines changed

2 files changed

+25
-7
lines changed

lisp/replace.el

+8-6
Original file line numberDiff line numberDiff line change
@@ -2584,7 +2584,7 @@ It must return a string."
25842584
(num-replacements 0)
25852585
(nocasify t) ; Undo must preserve case (Bug#31073).
25862586
search-string
2587-
next-replacement)
2587+
last-replacement)
25882588
(while (and (< stack-idx stack-len)
25892589
stack
25902590
(or (null replaced) last-was-act-and-show))
@@ -2595,9 +2595,9 @@ It must return a string."
25952595
;; Bind swapped values
25962596
;; (search-string <--> replacement)
25972597
search-string (nth (if replaced 4 3) elt)
2598-
next-replacement (nth (if replaced 3 4) elt)
2598+
last-replacement (nth (if replaced 3 4) elt)
25992599
search-string-replaced search-string
2600-
next-replacement-replaced next-replacement
2600+
last-replacement-replaced last-replacement
26012601
last-was-act-and-show nil)
26022602

26032603
(when (and (= stack-idx stack-len)
@@ -2619,16 +2619,18 @@ It must return a string."
26192619
(match-data t (nth 2 elt)))
26202620
noedit
26212621
(replace-match-maybe-edit
2622-
next-replacement nocasify literal
2622+
last-replacement nocasify literal
26232623
noedit real-match-data backward)
26242624
replace-count (1- replace-count)
26252625
real-match-data
26262626
(save-excursion
26272627
(goto-char (match-beginning 0))
26282628
(if regexp-flag
2629-
(looking-at next-replacement)
2630-
(looking-at (regexp-quote next-replacement)))
2629+
(looking-at last-replacement)
2630+
(looking-at (regexp-quote last-replacement)))
26312631
(match-data t (nth 2 elt))))
2632+
(when regexp-flag
2633+
(setq next-replacement (nth 4 elt)))
26322634
;; Set replaced nil to keep in loop
26332635
(when (eq def 'undo-all)
26342636
(setq replaced nil

test/lisp/replace-tests.el

+17-1
Original file line numberDiff line numberDiff line change
@@ -463,7 +463,9 @@ Return the last evalled form in BODY."
463463
(should
464464
(replace-tests-with-undo
465465
input "theorem \\([0-9]+\\)"
466-
"theorem \\\\ref{theo_\\1}"
466+
'(replace-eval-replacement
467+
replace-quote
468+
(format "theorem \\\\ref{theo_%d}" (1+ (string-to-number (match-string 1)))))
467469
((?\s . (1 2)) (?U . (3)))
468470
?q
469471
(string= input (buffer-string)))))
@@ -479,4 +481,18 @@ Return the last evalled form in BODY."
479481
?q
480482
(string= expected (buffer-string))))))
481483

484+
(ert-deftest query-replace-undo-bug37287 ()
485+
"Test for https://debbugs.gnu.org/37287 ."
486+
(let ((input "foo-1\nfoo-2\nfoo-3")
487+
(expected "foo-2\nfoo-2\nfoo-3"))
488+
(should
489+
(replace-tests-with-undo
490+
input "\\([0-9]\\)"
491+
'(replace-eval-replacement
492+
replace-quote
493+
(format "%d" (1+ (string-to-number (match-string 1)))))
494+
((?\s . (1 2 4)) (?U . (3)))
495+
?q
496+
(string= expected (buffer-string))))))
497+
482498
;;; replace-tests.el ends here

0 commit comments

Comments
 (0)