From dc2bc29527d65f54704570c991e023cbb0723544 Mon Sep 17 00:00:00 2001 From: Juri Linkov Date: Sat, 2 Feb 2013 01:38:41 +0200 Subject: [PATCH] * lisp/replace.el (perform-replace): Move let-bindings of isearch-* variables deeper to the loop that searches for the next match. Add bindings for `isearch-nonincremental' and `isearch-adjusted'. Use `isearch-search-fun-default' instead of `isearch-search-fun'. * lisp/isearch.el (isearch-search-fun-default): Check for null first element of isearch-cmds as a precaution when it's used with inactive isearch. Fixes: debbugs:13579 --- lisp/ChangeLog | 12 ++++++ lisp/isearch.el | 1 + lisp/replace.el | 102 ++++++++++++++++++++++++++---------------------- 3 files changed, 69 insertions(+), 46 deletions(-) diff --git a/lisp/ChangeLog b/lisp/ChangeLog index df19277bb3a..a1d85b55c25 100644 --- a/lisp/ChangeLog +++ b/lisp/ChangeLog @@ -1,3 +1,15 @@ +2013-02-01 Juri Linkov + + * replace.el (perform-replace): Move let-bindings of isearch-* + variables deeper to the loop that searches for the next match. + Add bindings for `isearch-nonincremental' and `isearch-adjusted'. + Use `isearch-search-fun-default' instead of `isearch-search-fun'. + (Bug#13579) + + * isearch.el (isearch-search-fun-default): Check for null + first element of isearch-cmds as a precaution when it's used + with inactive isearch. + 2013-02-01 Andrew W. Nosenko (tiny change) * net/tramp.el (tramp-check-for-regexp): Avoid "Args out of range" diff --git a/lisp/isearch.el b/lisp/isearch.el index e8bcf7679ae..972fb0058d3 100644 --- a/lisp/isearch.el +++ b/lisp/isearch.el @@ -2495,6 +2495,7 @@ Can be changed via `isearch-search-fun-function' for special needs." ;; the user adds and removes characters in the search string ;; (or when using nonincremental word isearch) (let ((lax (not (or isearch-nonincremental + (null (car isearch-cmds)) (eq (length isearch-string) (length (isearch--state-string (car isearch-cmds)))))))) diff --git a/lisp/replace.el b/lisp/replace.el index fb251821445..7757426cf95 100644 --- a/lisp/replace.el +++ b/lisp/replace.el @@ -1819,19 +1819,6 @@ make, or the user didn't cancel the call." case-fold-search)) (nocasify (not (and case-replace case-fold-search))) (literal (or (not regexp-flag) (eq regexp-flag 'literal))) - (search-function - (or (if regexp-flag - replace-re-search-function - replace-search-function) - (let ((isearch-regexp regexp-flag) - (isearch-word delimited-flag) - (isearch-lax-whitespace - replace-lax-whitespace) - (isearch-regexp-lax-whitespace - replace-regexp-lax-whitespace) - (isearch-case-fold-search case-fold-search) - (isearch-forward t)) - (isearch-search-fun)))) (search-string from-string) (real-match-data nil) ; The match data for the current match. (next-replacement nil) @@ -1894,39 +1881,62 @@ make, or the user didn't cancel the call." ;; Loop finding occurrences that perhaps should be replaced. (while (and keep-going (not (or (eobp) (and limit (>= (point) limit)))) - ;; Use the next match if it is already known; - ;; otherwise, search for a match after moving forward - ;; one char if progress is required. - (setq real-match-data - (cond ((consp match-again) - (goto-char (nth 1 match-again)) - (replace-match-data - t real-match-data match-again)) - ;; MATCH-AGAIN non-nil means accept an - ;; adjacent match. - (match-again - (and - (funcall search-function search-string - limit t) - ;; For speed, use only integers and - ;; reuse the list used last time. - (replace-match-data t real-match-data))) - ((and (< (1+ (point)) (point-max)) - (or (null limit) - (< (1+ (point)) limit))) - ;; If not accepting adjacent matches, - ;; move one char to the right before - ;; searching again. Undo the motion - ;; if the search fails. - (let ((opoint (point))) - (forward-char 1) - (if (funcall - search-function search-string - limit t) - (replace-match-data - t real-match-data) - (goto-char opoint) - nil)))))) + ;; Let-bind global isearch-* variables to values used + ;; to search the next replacement. These let-bindings + ;; should be effective both at the time of calling + ;; `isearch-search-fun-default' and also at the + ;; time of funcalling `search-function'. + ;; These isearch-* bindings can't be placed higher + ;; outside of this loop because then another I-search + ;; used after `recursive-edit' might override them. + (let* ((isearch-regexp regexp-flag) + (isearch-word delimited-flag) + (isearch-lax-whitespace + replace-lax-whitespace) + (isearch-regexp-lax-whitespace + replace-regexp-lax-whitespace) + (isearch-case-fold-search case-fold-search) + (isearch-adjusted nil) + (isearch-nonincremental t) ; don't use lax word mode + (isearch-forward t) + (search-function + (or (if regexp-flag + replace-re-search-function + replace-search-function) + (isearch-search-fun-default)))) + ;; Use the next match if it is already known; + ;; otherwise, search for a match after moving forward + ;; one char if progress is required. + (setq real-match-data + (cond ((consp match-again) + (goto-char (nth 1 match-again)) + (replace-match-data + t real-match-data match-again)) + ;; MATCH-AGAIN non-nil means accept an + ;; adjacent match. + (match-again + (and + (funcall search-function search-string + limit t) + ;; For speed, use only integers and + ;; reuse the list used last time. + (replace-match-data t real-match-data))) + ((and (< (1+ (point)) (point-max)) + (or (null limit) + (< (1+ (point)) limit))) + ;; If not accepting adjacent matches, + ;; move one char to the right before + ;; searching again. Undo the motion + ;; if the search fails. + (let ((opoint (point))) + (forward-char 1) + (if (funcall + search-function search-string + limit t) + (replace-match-data + t real-match-data) + (goto-char opoint) + nil))))))) ;; Record whether the match is nonempty, to avoid an infinite loop ;; repeatedly matching the same empty string. -- 2.39.2