From: Noam Postavsky Date: Tue, 24 Mar 2020 09:39:03 +0000 (-0400) Subject: Don't lose point during fileloop replace (Bug#38867) X-Git-Tag: emacs-28.0.90~7683 X-Git-Url: http://git.eshelyaron.com/gitweb/?a=commitdiff_plain;h=a477a7b86ba7c59a90b18283cc86769c27de6c7c;p=emacs.git 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. --- diff --git a/lisp/fileloop.el b/lisp/fileloop.el index 543963feafe..8f4911638e9 100644 --- a/lisp/fileloop.el +++ b/lisp/fileloop.el @@ -200,18 +200,22 @@ the default setting of `case-fold-search'. 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