GNU bug report logs - #38867
27.0.60; fileloop-initialize-replace misses occurrences to be replaced

Previous Next

Package: emacs;

Reported by: Eric Michael Timmons <etimmons <at> mit.edu>

Date: Thu, 2 Jan 2020 05:35:01 UTC

Severity: normal

Tags: fixed, patch

Found in version 27.0.60

Fixed in version 28.1

Done: Noam Postavsky <npostavs <at> gmail.com>

Bug is archived. No further changes may be made.

To add a comment to this bug, you must first unarchive it, by sending
a message to control AT debbugs.gnu.org, with unarchive 38867 in the body.
You can then email your comments to 38867 AT debbugs.gnu.org in the normal way.

Toggle the display of automated, internal messages from the tracker.

View this report as an mbox folder, status mbox, maintainer mbox


Report forwarded to bug-gnu-emacs <at> gnu.org:
bug#38867; Package emacs. (Thu, 02 Jan 2020 05:35:01 GMT) Full text and rfc822 format available.

Acknowledgement sent to Eric Michael Timmons <etimmons <at> mit.edu>:
New bug report received and forwarded. Copy sent to bug-gnu-emacs <at> gnu.org. (Thu, 02 Jan 2020 05:35:01 GMT) Full text and rfc822 format available.

Message #5 received at submit <at> debbugs.gnu.org (full text, mbox):

From: Eric Michael Timmons <etimmons <at> mit.edu>
To: "bug-gnu-emacs <at> gnu.org" <bug-gnu-emacs <at> gnu.org>
Subject: 27.0.60; fileloop-initialize-replace misses occurrences to be replaced
Date: Thu, 2 Jan 2020 05:08:25 +0000
[Message part 1 (text/plain, inline)]
Severity: normal
Tags: patch

When using fileloop-initialize-replace on files that already have open
buffers and points in arbitrary locations, occurrences of the regex to
replace can be missed. This appears to happen on my setup when
switch-to-buffer-preserve-window-point is non-nil. The call to
switch-buffer between the invocation of the scan- and operate-functions
can then cause the point to change to a different location than the
scan-function left it.

This can manifest itself by either missing occurrences of the regex in
the open files where point is beyond some occurrences or it can
completely miss files if some file early on in the iteration has its
point beyond all occurrences of the regex, causing the operate-function
to return nil, aborting the rest of the operation.

In GNU Emacs 27.0.60 (build 1, x86_64-pc-linux-gnu, GTK+ Version 3.24.13, cairo version 1.16.0)
 of 2019-12-27 built on rocinante
Repository revision: 8224ed7d406e8654a163b05c0c647a5d44c090ed
Repository branch: emacs-27
Windowing system distributor 'The X.Org Foundation', version 11.0.12006000
System Description: Gentoo/Linux

[0001-Fix-fileloop-initialize-replace-with-buffers-that-ar.patch (text/x-patch, attachment)]

Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#38867; Package emacs. (Tue, 24 Mar 2020 10:01:01 GMT) Full text and rfc822 format available.

Message #8 received at 38867 <at> debbugs.gnu.org (full text, mbox):

From: Noam Postavsky <npostavs <at> gmail.com>
To: Eric Michael Timmons <etimmons <at> mit.edu>
Cc: 38867 <at> debbugs.gnu.org
Subject: Re: bug#38867: 27.0.60; fileloop-initialize-replace misses
 occurrences to be replaced
Date: Tue, 24 Mar 2020 06:00:05 -0400
[Message part 1 (text/plain, inline)]
Eric Michael Timmons <etimmons <at> mit.edu> 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
> operate-function.

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...

[0001-Don-t-lose-point-during-fileloop-replace-Bug-38867.patch (text/x-diff, inline)]
From 033564127065e213868f034f08b32d14ad3d1c74 Mon Sep 17 00:00:00 2001
From: Noam Postavsky <npostavs <at> gmail.com>
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 <etimmons <at> mit.edu>.
* 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


Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#38867; Package emacs. (Tue, 24 Mar 2020 14:09:02 GMT) Full text and rfc822 format available.

Message #11 received at 38867 <at> debbugs.gnu.org (full text, mbox):

From: Eli Zaretskii <eliz <at> gnu.org>
To: Noam Postavsky <npostavs <at> gmail.com>
Cc: etimmons <at> mit.edu, 38867 <at> debbugs.gnu.org
Subject: Re: bug#38867: 27.0.60;
 fileloop-initialize-replace misses occurrences to be replaced
Date: Tue, 24 Mar 2020 16:08:28 +0200
> From: Noam Postavsky <npostavs <at> gmail.com>
> Date: Tue, 24 Mar 2020 06:00:05 -0400
> Cc: 38867 <at> debbugs.gnu.org
> 
> > 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
> > operate-function.
> 
> 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...

I think this can wait for Emacs 28, but if you disagree, please tell
why.

Thanks.




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#38867; Package emacs. (Tue, 31 Mar 2020 22:25:02 GMT) Full text and rfc822 format available.

Message #14 received at 38867 <at> debbugs.gnu.org (full text, mbox):

From: Noam Postavsky <npostavs <at> gmail.com>
To: Eli Zaretskii <eliz <at> gnu.org>
Cc: etimmons <at> mit.edu, 38867 <at> debbugs.gnu.org
Subject: Re: bug#38867: 27.0.60; fileloop-initialize-replace misses
 occurrences to be replaced
Date: Tue, 31 Mar 2020 18:23:54 -0400
tags 38867 fixed
close 38867 28.1
quit

Eli Zaretskii <eliz <at> gnu.org> writes:

>> 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...
>
> I think this can wait for Emacs 28, but if you disagree, please tell
> why.

I don't really feel strongly about it, so I've pushed to master.

[1: a477a7b86b]: 2020-03-31 18:17:53 -0400
  Don't lose point during fileloop replace (Bug#38867)
  https://git.savannah.gnu.org/cgit/emacs.git/commit/?id=a477a7b86ba7c59a90b18283cc86769c27de6c7c




Added tag(s) fixed. Request was from Noam Postavsky <npostavs <at> gmail.com> to control <at> debbugs.gnu.org. (Tue, 31 Mar 2020 22:25:02 GMT) Full text and rfc822 format available.

bug marked as fixed in version 28.1, send any further explanations to 38867 <at> debbugs.gnu.org and Eric Michael Timmons <etimmons <at> mit.edu> Request was from Noam Postavsky <npostavs <at> gmail.com> to control <at> debbugs.gnu.org. (Tue, 31 Mar 2020 22:25:03 GMT) Full text and rfc822 format available.

bug archived. Request was from Debbugs Internal Request <help-debbugs <at> gnu.org> to internal_control <at> debbugs.gnu.org. (Wed, 29 Apr 2020 11:24:06 GMT) Full text and rfc822 format available.

This bug report was last modified 3 years and 362 days ago.

Previous Next


GNU bug tracking system
Copyright (C) 1999 Darren O. Benham, 1997,2003 nCipher Corporation Ltd, 1994-97 Ian Jackson.