[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
bug#38867: 27.0.60; fileloop-initialize-replace misses occurrences to be
bug#38867: 27.0.60; fileloop-initialize-replace misses occurrences to be replaced
Tue, 24 Mar 2020 06:00:05 -0400
Gnus/5.13 (Gnus v5.13) Emacs/27.0.90 (gnu/linux)
Eric Michael Timmons <address@hidden> writes:
> Fix by telling `perform-replace' to operate over the entire
> buffer. Could potentially be further be optimized by saving the point
> in the scan-function and using it as the start point in the
Since the current code is trying to save the point in the scan function,
it's better to keep that optimization. See patch below. Should this go
to emacs-27 or master? The assumption that point would be preserved
seems to be long-standing, but I guess the change in the default of
switch-to-buffer-preserve-window-point is what surfaces the bug and
makes it more recent...
>From 033564127065e213868f034f08b32d14ad3d1c74 Mon Sep 17 00:00:00 2001
From: Noam Postavsky <address@hidden>
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 <address@hidden>.
* 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
@@ -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.
- (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)))
+ (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))
;;; fileloop.el ends here
- bug#38867: 27.0.60; fileloop-initialize-replace misses occurrences to be replaced,
Noam Postavsky <=