summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJuri Linkov <juri@linkov.net>2019-07-12 00:35:21 +0300
committerJuri Linkov <juri@linkov.net>2019-07-12 00:35:21 +0300
commit53fb021acc9cae6dcfc3cbe2004a070036e5c4e7 (patch)
treee1ac27bab58e9d4229467ef64758c6e555a35b9e
parent0b0ed31df9c7c1b74b9f1ac75223ad5158c2b408 (diff)
downloademacs-53fb021acc9cae6dcfc3cbe2004a070036e5c4e7.tar.gz
Better match-data handling in perform-replace
* lisp/replace.el (perform-replace): Don't wrap replace-highlight in save-match-data. Use `(nth 0 real-match-data)' instead of `(match-beginning 0)' after replace-highlight. (Bug#36328)
-rw-r--r--lisp/replace.el39
1 files changed, 20 insertions, 19 deletions
diff --git a/lisp/replace.el b/lisp/replace.el
index ab1ff327f6c..7839bed7fb5 100644
--- a/lisp/replace.el
+++ b/lisp/replace.el
@@ -285,7 +285,7 @@ the original string if not."
(string-match "\\(\\`\\|[^\\]\\)\\(\\\\\\\\\\)*\\\\[,#]" to)))
(setq to (nreverse (delete "" (cons to list))))
(replace-match-string-symbols to)
- (cons 'replace-eval-replacement
+ (cons #'replace-eval-replacement
(if (cdr to)
(cons 'concat to)
(car to))))
@@ -543,7 +543,7 @@ for Lisp calls." "22.1"))
(if (use-region-p) (region-beginning))
(if (use-region-p) (region-end))
(if (use-region-p) (region-noncontiguous-p))))))
- (perform-replace regexp (cons 'replace-eval-replacement to-expr)
+ (perform-replace regexp (cons #'replace-eval-replacement to-expr)
t 'literal delimited nil nil start end nil region-noncontiguous-p))
(defun map-query-replace-regexp (regexp to-strings &optional n start end region-noncontiguous-p)
@@ -2471,7 +2471,8 @@ characters."
replacements nil))
((stringp (car replacements)) ; If it isn't a string, it must be a cons
(or repeat-count (setq repeat-count 1))
- (setq replacements (cons 'replace-loop-through-replacements
+ ;; This is a hand-made `iterator'.
+ (setq replacements (cons #'replace-loop-through-replacements
(vector repeat-count repeat-count
replacements replacements)))))
@@ -2578,14 +2579,10 @@ characters."
(if (not query-flag)
(progn
(unless (or literal noedit)
- (save-match-data
- ;; replace-highlight calls isearch-lazy-highlight-new-loop
- ;; and `sit-for' whose redisplay might clobber match data.
- ;; (Bug#36328)
- (replace-highlight
- (nth 0 real-match-data) (nth 1 real-match-data)
- start end search-string
- regexp-flag delimited-flag case-fold-search backward)))
+ (replace-highlight
+ (nth 0 real-match-data) (nth 1 real-match-data)
+ start end search-string
+ regexp-flag delimited-flag case-fold-search backward))
(setq noedit
(replace-match-maybe-edit
next-replacement nocasify literal
@@ -2600,27 +2597,31 @@ characters."
;; Commands not setting `done' need to adjust
;; `real-match-data'.
(while (not done)
+ ;; This sets match-data only for the next hook and
+ ;; replace-highlight that calls `sit-for' from
+ ;; isearch-lazy-highlight-new-loop whose redisplay
+ ;; might clobber match-data. So subsequent code should
+ ;; use only real-match-data, not match-data (bug#36328).
(set-match-data real-match-data)
(run-hooks 'replace-update-post-hook) ; Before `replace-highlight'.
- (save-match-data
- (replace-highlight
- (match-beginning 0) (match-end 0)
- start end search-string
- regexp-flag delimited-flag case-fold-search backward))
+ (replace-highlight
+ (match-beginning 0) (match-end 0)
+ start end search-string
+ regexp-flag delimited-flag case-fold-search backward)
;; Obtain the matched groups: needed only when
;; regexp-flag non nil.
(when (and last-was-undo regexp-flag)
(setq last-was-undo nil
real-match-data
(save-excursion
- (goto-char (match-beginning 0))
+ (goto-char (nth 0 real-match-data))
(looking-at search-string)
(match-data t real-match-data))))
;; Matched string and next-replacement-replaced
;; stored in stack.
(setq search-string-replaced (buffer-substring-no-properties
- (match-beginning 0)
- (match-end 0))
+ (nth 0 real-match-data)
+ (nth 1 real-match-data))
next-replacement-replaced
(query-replace-descr
(save-match-data