Subject: bug#78658: 30.1; [PATCH] Dired feature suggestion: dired-on-marked-files-in-all-buffers

From: Drew Adams <[email-masked]>
Date: Wed, 4 Jun 2025 18:26:52 +0000

I wrote:

> (defun diredp-live-dired-buffers ()
>   "Return a list of the live Dired buffers."
>   (delq nil (mapcar (lambda (d.b)
>                       (and (buffer-live-p (cdr d.b))  (cdr d.b)))
>                     dired-buffers)))

I'm afraid I may have led you (and myself) astray, by suggesting to
use variable `dired-buffers' instead of testing all buffers.
(I see you adopted that in your latest code.)

It works fine, and it's much faster by not bothering with non-Dired
buffers.  The problem is that it doesn't work with commands
`find-dired' and  `find-lisp-find-dired*'.  They produce legitimate
Dired buffers, and they work fine with the feature we're discussing,
but they're excluded from `dired-buffers'.  They have this binding:

  (let ((dired-buffers dired-buffers))...)

_Should_ they be excluded from `dired-buffers'?  Maybe so, maybe not.
They support most Dired features, and their mode is `dired-mode', but
there are perhaps a few Dired features they don't support (dunno what,
offhand - they support WDired and everything else that occurs to me
offhand).  (I wish their code included a comment as to _why_ they have
that binding.)

Anyway, if we do want to support such buffers (which we should) then
we unfortunately need to check all buffers, not just those in variable
`dired-buffers'.

So my function `diredp-live-dired-buffers' needs to change from this:

(defun diredp-live-dired-buffers ()
  "Return a list of the live Dired buffers."
  (delq nil (mapcar (lambda (d.b)
                      (and (buffer-live-p (cdr d.b))  (cdr d.b)))
                    dired-buffers)))

to this:

(defun diredp-live-dired-buffers ()
  "Return a list of the live Dired buffers."
  (delq nil (mapcar (lambda (buf)
                      (and (buffer-live-p buf)
                           (with-current-buffer buf
                             (and (derived-mode-p 'dired-mode)  buf))))
                    (buffer-list))))

Or maybe make it more general, to handle either 100% Dired buffers
or (optionally) both those and the find-* Dired buffers:

(defun diredp-live-dired-buffers (&optional exclude-find-bufs-p)
  "Return a list of the live Dired buffers.
Non-nil EXCLUDE-FIND-BUFS-P means exclude Dired buffers that aren't
listed in variable `dired-buffers'.  Examples are the Dired buffers
from commands `find*-dired' and `find-lisp-find-dired*'."
  (delq nil
        (if exclude-find-bufs-p
            (mapcar (lambda (d.b)
                      (and (buffer-live-p (cdr d.b))  (cdr d.b)))
                    dired-buffers)
          (mapcar (lambda (buf)
                    (and (buffer-live-p buf)
                         (with-current-buffer buf
                           (and (derived-mode-p 'dired-mode)  buf))))
                  (buffer-list)))))

There's no need for that general version in the current scenario,
but it's maybe a better utility function that way.

BTW, do you find that using `(delete-consecutive-dups (sort...))'
is a whole lot faster than just using `delete-dups'.  I guess it
is, but it's ugly - had to read the source code to understand it.

[IMO, the doc should say something about its use cases, i.e., when
to use it instead of `delete-dups'.  The doc doesn't even mention
that it's for _sorted_ lists, or at least sorted enough that all
dups you might care about are consecutive.]