From 033564127065e213868f034f08b32d14ad3d1c74 Mon Sep 17 00:00:00 2001 From: Noam Postavsky Date: Tue, 24 Mar 2020 05:39:03 -0400 Subject: [PATCH] Don't lose point during fileloop replace (Bug#38867) Suggested by Eric Michael Timmons . * lisp/fileloop.el (fileloop-initialize-replace): Save the match-beginning position in a variable instead of the buffer's point. The point may be changed by the time perform-replace is called, e.g., due to switch-to-buffer-preserve-window-point. --- lisp/fileloop.el | 28 ++++++++++++++++------------ 1 file changed, 16 insertions(+), 12 deletions(-) diff --git a/lisp/fileloop.el b/lisp/fileloop.el index 543963feaf..8f4911638e 100644 --- a/lisp/fileloop.el +++ b/lisp/fileloop.el @@ -200,18 +200,22 @@ fileloop-initialize-replace DELIMITED if non-nil means replace only word-delimited matches." ;; FIXME: Not sure how the delimited-flag interacts with the regexp-flag in ;; `perform-replace', so I just try to mimic the old code. - (fileloop-initialize - files - (lambda () - (let ((case-fold-search - (if (memql case-fold '(nil t)) case-fold case-fold-search))) - (if (re-search-forward from nil t) - ;; When we find a match, move back - ;; to the beginning of it so perform-replace - ;; will see it. - (goto-char (match-beginning 0))))) - (lambda () - (perform-replace from to t t delimited nil multi-query-replace-map)))) + (let ((mstart (make-hash-table :test 'eq))) + (fileloop-initialize + files + (lambda () + (let ((case-fold-search + (if (memql case-fold '(nil t)) case-fold case-fold-search))) + (when (re-search-forward from nil t) + ;; When we find a match, save its beginning for + ;; `perform-replace' (we used to just set point, but this + ;; is unreliable in the face of + ;; `switch-to-buffer-preserve-window-point'). + (puthash (current-buffer) (match-beginning 0) mstart)))) + (lambda () + (perform-replace from to t t delimited nil multi-query-replace-map + (gethash (current-buffer) mstart (point-min)) + (point-max)))))) (provide 'fileloop) ;;; fileloop.el ends here -- 2.11.0