diff options
| author | Juri Linkov | 2019-07-12 00:35:21 +0300 |
|---|---|---|
| committer | Juri Linkov | 2019-07-12 00:35:21 +0300 |
| commit | 53fb021acc9cae6dcfc3cbe2004a070036e5c4e7 (patch) | |
| tree | e1ac27bab58e9d4229467ef64758c6e555a35b9e | |
| parent | 0b0ed31df9c7c1b74b9f1ac75223ad5158c2b408 (diff) | |
| download | emacs-53fb021acc9cae6dcfc3cbe2004a070036e5c4e7.tar.gz emacs-53fb021acc9cae6dcfc3cbe2004a070036e5c4e7.zip | |
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.el | 39 |
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." | |||
| 285 | (string-match "\\(\\`\\|[^\\]\\)\\(\\\\\\\\\\)*\\\\[,#]" to))) | 285 | (string-match "\\(\\`\\|[^\\]\\)\\(\\\\\\\\\\)*\\\\[,#]" to))) |
| 286 | (setq to (nreverse (delete "" (cons to list)))) | 286 | (setq to (nreverse (delete "" (cons to list)))) |
| 287 | (replace-match-string-symbols to) | 287 | (replace-match-string-symbols to) |
| 288 | (cons 'replace-eval-replacement | 288 | (cons #'replace-eval-replacement |
| 289 | (if (cdr to) | 289 | (if (cdr to) |
| 290 | (cons 'concat to) | 290 | (cons 'concat to) |
| 291 | (car to)))) | 291 | (car to)))) |
| @@ -543,7 +543,7 @@ for Lisp calls." "22.1")) | |||
| 543 | (if (use-region-p) (region-beginning)) | 543 | (if (use-region-p) (region-beginning)) |
| 544 | (if (use-region-p) (region-end)) | 544 | (if (use-region-p) (region-end)) |
| 545 | (if (use-region-p) (region-noncontiguous-p)))))) | 545 | (if (use-region-p) (region-noncontiguous-p)))))) |
| 546 | (perform-replace regexp (cons 'replace-eval-replacement to-expr) | 546 | (perform-replace regexp (cons #'replace-eval-replacement to-expr) |
| 547 | t 'literal delimited nil nil start end nil region-noncontiguous-p)) | 547 | t 'literal delimited nil nil start end nil region-noncontiguous-p)) |
| 548 | 548 | ||
| 549 | (defun map-query-replace-regexp (regexp to-strings &optional n start end region-noncontiguous-p) | 549 | (defun map-query-replace-regexp (regexp to-strings &optional n start end region-noncontiguous-p) |
| @@ -2471,7 +2471,8 @@ characters." | |||
| 2471 | replacements nil)) | 2471 | replacements nil)) |
| 2472 | ((stringp (car replacements)) ; If it isn't a string, it must be a cons | 2472 | ((stringp (car replacements)) ; If it isn't a string, it must be a cons |
| 2473 | (or repeat-count (setq repeat-count 1)) | 2473 | (or repeat-count (setq repeat-count 1)) |
| 2474 | (setq replacements (cons 'replace-loop-through-replacements | 2474 | ;; This is a hand-made `iterator'. |
| 2475 | (setq replacements (cons #'replace-loop-through-replacements | ||
| 2475 | (vector repeat-count repeat-count | 2476 | (vector repeat-count repeat-count |
| 2476 | replacements replacements))))) | 2477 | replacements replacements))))) |
| 2477 | 2478 | ||
| @@ -2578,14 +2579,10 @@ characters." | |||
| 2578 | (if (not query-flag) | 2579 | (if (not query-flag) |
| 2579 | (progn | 2580 | (progn |
| 2580 | (unless (or literal noedit) | 2581 | (unless (or literal noedit) |
| 2581 | (save-match-data | 2582 | (replace-highlight |
| 2582 | ;; replace-highlight calls isearch-lazy-highlight-new-loop | 2583 | (nth 0 real-match-data) (nth 1 real-match-data) |
| 2583 | ;; and `sit-for' whose redisplay might clobber match data. | 2584 | start end search-string |
| 2584 | ;; (Bug#36328) | 2585 | regexp-flag delimited-flag case-fold-search backward)) |
| 2585 | (replace-highlight | ||
| 2586 | (nth 0 real-match-data) (nth 1 real-match-data) | ||
| 2587 | start end search-string | ||
| 2588 | regexp-flag delimited-flag case-fold-search backward))) | ||
| 2589 | (setq noedit | 2586 | (setq noedit |
| 2590 | (replace-match-maybe-edit | 2587 | (replace-match-maybe-edit |
| 2591 | next-replacement nocasify literal | 2588 | next-replacement nocasify literal |
| @@ -2600,27 +2597,31 @@ characters." | |||
| 2600 | ;; Commands not setting `done' need to adjust | 2597 | ;; Commands not setting `done' need to adjust |
| 2601 | ;; `real-match-data'. | 2598 | ;; `real-match-data'. |
| 2602 | (while (not done) | 2599 | (while (not done) |
| 2600 | ;; This sets match-data only for the next hook and | ||
| 2601 | ;; replace-highlight that calls `sit-for' from | ||
| 2602 | ;; isearch-lazy-highlight-new-loop whose redisplay | ||
| 2603 | ;; might clobber match-data. So subsequent code should | ||
| 2604 | ;; use only real-match-data, not match-data (bug#36328). | ||
| 2603 | (set-match-data real-match-data) | 2605 | (set-match-data real-match-data) |
| 2604 | (run-hooks 'replace-update-post-hook) ; Before `replace-highlight'. | 2606 | (run-hooks 'replace-update-post-hook) ; Before `replace-highlight'. |
| 2605 | (save-match-data | 2607 | (replace-highlight |
| 2606 | (replace-highlight | 2608 | (match-beginning 0) (match-end 0) |
| 2607 | (match-beginning 0) (match-end 0) | 2609 | start end search-string |
| 2608 | start end search-string | 2610 | regexp-flag delimited-flag case-fold-search backward) |
| 2609 | regexp-flag delimited-flag case-fold-search backward)) | ||
| 2610 | ;; Obtain the matched groups: needed only when | 2611 | ;; Obtain the matched groups: needed only when |
| 2611 | ;; regexp-flag non nil. | 2612 | ;; regexp-flag non nil. |
| 2612 | (when (and last-was-undo regexp-flag) | 2613 | (when (and last-was-undo regexp-flag) |
| 2613 | (setq last-was-undo nil | 2614 | (setq last-was-undo nil |
| 2614 | real-match-data | 2615 | real-match-data |
| 2615 | (save-excursion | 2616 | (save-excursion |
| 2616 | (goto-char (match-beginning 0)) | 2617 | (goto-char (nth 0 real-match-data)) |
| 2617 | (looking-at search-string) | 2618 | (looking-at search-string) |
| 2618 | (match-data t real-match-data)))) | 2619 | (match-data t real-match-data)))) |
| 2619 | ;; Matched string and next-replacement-replaced | 2620 | ;; Matched string and next-replacement-replaced |
| 2620 | ;; stored in stack. | 2621 | ;; stored in stack. |
| 2621 | (setq search-string-replaced (buffer-substring-no-properties | 2622 | (setq search-string-replaced (buffer-substring-no-properties |
| 2622 | (match-beginning 0) | 2623 | (nth 0 real-match-data) |
| 2623 | (match-end 0)) | 2624 | (nth 1 real-match-data)) |
| 2624 | next-replacement-replaced | 2625 | next-replacement-replaced |
| 2625 | (query-replace-descr | 2626 | (query-replace-descr |
| 2626 | (save-match-data | 2627 | (save-match-data |