GNU bug report logs - #79310
[PATCH] Filter out selected buffers in multi-occur

Previous Next

Package: emacs;

Reported by: Gabriel do Nascimento Ribeiro <gabriel376 <at> hotmail.com>

Date: Mon, 25 Aug 2025 16:00:02 UTC

Severity: normal

Tags: patch

To reply to this bug, email your comments to 79310 AT debbugs.gnu.org.

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#79310; Package emacs. (Mon, 25 Aug 2025 16:00:02 GMT) Full text and rfc822 format available.

Acknowledgement sent to Gabriel do Nascimento Ribeiro <gabriel376 <at> hotmail.com>:
New bug report received and forwarded. Copy sent to bug-gnu-emacs <at> gnu.org. (Mon, 25 Aug 2025 16:00:02 GMT) Full text and rfc822 format available.

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

From: Gabriel do Nascimento Ribeiro <gabriel376 <at> hotmail.com>
To: "bug-gnu-emacs <at> gnu.org" <bug-gnu-emacs <at> gnu.org>
Subject: [PATCH] Filter out selected buffers in multi-occur
Date: Mon, 25 Aug 2025 15:53:51 +0000
The proposed patch below adds a predicate function to read-buffer in multi-occur
to filter out previous selected buffers.  The current behavior does not have
such filter, allowing users to select the same buffer over and over, which can
be confusing when selecting multiple buffers, since users should keep in memory
what they have already selected, and shows duplicated results in the *Occur*
buffer.  I don't see a reason for the current behavior, so I propose the patch
below.

Potential improvements:

1) When the buffer list is empty (user has selected all the buffers), it could
skip the read-buffer and go directly to next step (ask 'List lines matching
regexp').  Not sure how to implement it, since internal-complete-buffer does
some filtering of Vbuffer_alist to remove internal buffers, and I could not find
an easy way to get the length of this filtered buffer list.

2) I believe multi-occur--prompt is not very accurate in case an user changes or
remaps related functions in minibuffer.  For instance, I use
icomplete-vertical-mode with different keybindings, but it always show '(RET to
end)'.  We could make it smarter, or change the prompt to indicate that an empty
string terminates the buffer selection instead of trying to guess the
keybinding.


From e3c2932ee551db6a008f078579ae6550356647fb Mon Sep 17 00:00:00 2001
From: Gabriel Ribeiro <gabriel376 <at> hotmail.com>
Date: Mon, 25 Aug 2025 12:38:12 -0300
Subject: [PATCH] Filter out already selected buffers in multi-occur

* lisp/replace.el (multi-occur): Add predicate to
read-buffer to filter out previous selected buffers.
---
 lisp/replace.el | 20 +++++++++++++-------
 1 file changed, 13 insertions(+), 7 deletions(-)

diff --git a/lisp/replace.el b/lisp/replace.el
index 8227056e012..03b274c59af 100644
--- a/lisp/replace.el
+++ b/lisp/replace.el
@@ -1853,14 +1853,20 @@ multi-occur
   (interactive
    (cons
     (let* ((bufs (list (read-buffer "First buffer to search: "
-				    (current-buffer) t)))
-	   (buf nil)
-	   (ido-ignore-item-temp-list bufs))
+                                    (current-buffer))))
+           (ido-ignore-item-temp-list bufs)
+           (buf nil))
       (while (not (string-equal
-		   (setq buf (read-buffer (multi-occur--prompt) nil t))
-		   ""))
-	(cl-pushnew buf bufs)
-	(setq ido-ignore-item-temp-list bufs))
+                   (setq buf (read-buffer
+                              (multi-occur--prompt)
+                              nil t
+                              (lambda (b)
+                                (not (member
+                                      (if (stringp b) b (car b))
+                                      ido-ignore-item-temp-list)))))
+                   ""))
+        (cl-pushnew buf bufs)
+        (setq ido-ignore-item-temp-list bufs))
       (nreverse (mapcar #'get-buffer bufs)))
     (occur-read-primary-args)))
   (occur-1 regexp nlines bufs))
-- 
2.34.1


---
Gabriel



Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#79310; Package emacs. (Wed, 27 Aug 2025 17:17:02 GMT) Full text and rfc822 format available.

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

From: Juri Linkov <juri <at> linkov.net>
To: Gabriel do Nascimento Ribeiro <gabriel376 <at> hotmail.com>
Cc: 79310 <at> debbugs.gnu.org
Subject: Re: bug#79310: [PATCH] Filter out selected buffers in multi-occur
Date: Wed, 27 Aug 2025 20:14:07 +0300
> The proposed patch below adds a predicate function to read-buffer in multi-occur
> to filter out previous selected buffers.  The current behavior does not have
> such filter, allowing users to select the same buffer over and over, which can
> be confusing when selecting multiple buffers, since users should keep in memory
> what they have already selected, and shows duplicated results in the *Occur*
> buffer.  I don't see a reason for the current behavior, so I propose the patch
> below.

Thanks, good idea.

> Potential improvements:
>
> 1) When the buffer list is empty (user has selected all the buffers), it could
> skip the read-buffer and go directly to next step (ask 'List lines matching
> regexp').  Not sure how to implement it, since internal-complete-buffer does
> some filtering of Vbuffer_alist to remove internal buffers, and I could not find
> an easy way to get the length of this filtered buffer list.

Makes sense.  Can you do the same filtering as in internal-complete-buffer?
For example:

  (seq-filter (lambda (b) (/= (aref (buffer-name b) 0) ?\s)) (buffer-list))

> 2) I believe multi-occur--prompt is not very accurate in case an user changes or
> remaps related functions in minibuffer.  For instance, I use
> icomplete-vertical-mode with different keybindings, but it always show '(RET to
> end)'.  We could make it smarter, or change the prompt to indicate that an empty
> string terminates the buffer selection instead of trying to guess the
> keybinding.

Changing the default text to not mention RET would be nice.

> @@ -1853,14 +1853,20 @@ multi-occur
>    (interactive
>     (cons
>      (let* ((bufs (list (read-buffer "First buffer to search: "
> -				    (current-buffer) t)))
> +                                    (current-buffer))))

I wonder why you removed t from the REQUIRE-MATCH arg of read-buffer?
This allows the user to enter an non-existent buffer name.

>        (while (not (string-equal
> -		   (setq buf (read-buffer (multi-occur--prompt) nil t))
> -		   ""))
> -	(cl-pushnew buf bufs)
> -	(setq ido-ignore-item-temp-list bufs))
> +                   (setq buf (read-buffer
> +                              (multi-occur--prompt)
> +                              nil t
> +                              (lambda (b)
> +                                (not (member
> +                                      (if (stringp b) b (car b))
> +                                      ido-ignore-item-temp-list)))))

Wouldn't it be more clear here to use 'bufs' instead of 'ido-ignore-item-temp-list'?




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#79310; Package emacs. (Wed, 27 Aug 2025 18:15:02 GMT) Full text and rfc822 format available.

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

From: Gabriel do Nascimento Ribeiro <gabriel376 <at> hotmail.com>
To: Juri Linkov <juri <at> linkov.net>
Cc: "79310 <at> debbugs.gnu.org" <79310 <at> debbugs.gnu.org>
Subject: Re: bug#79310: [PATCH] Filter out selected buffers in multi-occur
Date: Wed, 27 Aug 2025 18:14:41 +0000
> Makes sense.  Can you do the same filtering as in internal-complete-buffer?
> For example:
>
> (seq-filter (lambda (b) (/= (aref (buffer-name b) 0) ?\s)) (buffer-list))

I'll give that a try, thanks for the suggestion.
Of course, if someone wants to install a different patch, that’s fine too; mine was
just meant as a starting point for discussion.

> I wonder why you removed t from the REQUIRE-MATCH arg of read-buffer?
> This allows the user to enter an non-existent buffer name.

That was a mistake on my part, thanks for catching it.  It should definitely remain t.

> Wouldn't it be more clear here to use 'bufs' instead of 'ido-ignore-item-temp-list'?

From what I saw, ido-ignore-item-temp-list (declared in ido.el) seems related to an
older implementation for ido-mode, but I didn’t look into it in detail.

---
Gabriel

________________________________________
From: Juri Linkov <juri <at> linkov.net>
Sent: Wednesday, August 27, 2025 2:14 PM
To: Gabriel do Nascimento Ribeiro
Cc: 79310 <at> debbugs.gnu.org
Subject: Re: bug#79310: [PATCH] Filter out selected buffers in multi-occur

> The proposed patch below adds a predicate function to read-buffer in multi-occur
> to filter out previous selected buffers.  The current behavior does not have
> such filter, allowing users to select the same buffer over and over, which can
> be confusing when selecting multiple buffers, since users should keep in memory
> what they have already selected, and shows duplicated results in the *Occur*
> buffer.  I don't see a reason for the current behavior, so I propose the patch
> below.

Thanks, good idea.

> Potential improvements:
>
> 1) When the buffer list is empty (user has selected all the buffers), it could
> skip the read-buffer and go directly to next step (ask 'List lines matching
> regexp').  Not sure how to implement it, since internal-complete-buffer does
> some filtering of Vbuffer_alist to remove internal buffers, and I could not find
> an easy way to get the length of this filtered buffer list.

Makes sense.  Can you do the same filtering as in internal-complete-buffer?
For example:

  (seq-filter (lambda (b) (/= (aref (buffer-name b) 0) ?\s)) (buffer-list))

> 2) I believe multi-occur--prompt is not very accurate in case an user changes or
> remaps related functions in minibuffer.  For instance, I use
> icomplete-vertical-mode with different keybindings, but it always show '(RET to
> end)'.  We could make it smarter, or change the prompt to indicate that an empty
> string terminates the buffer selection instead of trying to guess the
> keybinding.

Changing the default text to not mention RET would be nice.

> @@ -1853,14 +1853,20 @@ multi-occur
>    (interactive
>     (cons
>      (let* ((bufs (list (read-buffer "First buffer to search: "
> -                                 (current-buffer) t)))
> +                                    (current-buffer))))

I wonder why you removed t from the REQUIRE-MATCH arg of read-buffer?
This allows the user to enter an non-existent buffer name.

>        (while (not (string-equal
> -                (setq buf (read-buffer (multi-occur--prompt) nil t))
> -                ""))
> -     (cl-pushnew buf bufs)
> -     (setq ido-ignore-item-temp-list bufs))
> +                   (setq buf (read-buffer
> +                              (multi-occur--prompt)
> +                              nil t
> +                              (lambda (b)
> +                                (not (member
> +                                      (if (stringp b) b (car b))
> +                                      ido-ignore-item-temp-list)))))

Wouldn't it be more clear here to use 'bufs' instead of 'ido-ignore-item-temp-list'?




This bug report was last modified 9 days ago.

Previous Next


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