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

From: Drew Adams <[email-masked]>
Date: Sat, 7 Jun 2025 16:52:14 +0000

> > When `dired-mode' is invoked it calls `dired-advertise',
> > which adds the Dired buffer to the value of global variable
> > `dired-buffers'.  A couple commands remove a buffer name from
> > this list, by calling `dired-unadvertise'.  In particular,
> > `wdired-change-to-wdired-mode' does this, because it changes
> > the major mode from `dired-mode' to `wdired-mode'.
> >
> > The value of var `dired-buffers' is thus generally a list of
> > all buffers in `dired-mode'.  (This can include buffers that
> > have been killed, so filtering with `buffer-live-p' is also
> > needed.)
> >
> > The only exceptions are (1) commands `find-dired' and its
> > derivatives such as `find-name-dired', and (2) commands
> > `find-lisp-dired*'.  They're exceptions because they bind
> > `dired-buffers' around their work (see above), so as not to
> > add their resulting Dired buffers to `dired-buffers'.
> >
> > This means that code can't just examine `dired-buffers' to
> > find the set of Dired buffers (buffers advertised to be in
> > `dired-mode').  Instead, it needs to filter `buffer-list',
> > to gather the buffers with modes derived from `dired-mode'.
> > That's unfortunate - it's much more costly, in general.
> >
> > The question is whether there's a good reason why find*
> > buffers, which are in `dired-mode', should be excluded from
> > being "advertised" as such, i.e., whether they should really
> > be excluded from `dired-buffers'.  And if so, why?
> >
> > It was apparently a 1998 commit by Richard that added the
> > protective binding to `find-dired', but with no comment as
> > to why.
> >
> > In the Emacs sources, at least, there are no other places
> > that exclude `dired-mode' buffers from `dired-buffers'.
> > And grepping for `find-dired' shows that there are no places
> > that rely on such exclusion for `find-dired' buffers.  Same
> > for `find-lisp-find-dired-internal' (which binds
> > `dired-buffers' for `find-lisp*').
> 
> Thanks.
> 
> If we allow find-dired to add its buffers to the list in
> dired-buffers, we need to make sure they are removed from the list.
> We also need to make sure that functions which scan the list and
> operate on its buffers will DTRT with find-dired buffers found in the
> list.  Is all of this reasonable to do, and if so, is it planned to be
> done as part of the changes you are discussing?

I'm afraid I don't understand.

1. What do you mean by making sure they're removed from the list?  The only reason to remove a file/dir from the list is, as is the case with WDired, if the mode is changed from `dired-mode' to something else. (WDired removes its buffer from the list, for that reason.)

As I said, there are no uses of `dired-buffers' in the Emacs source code, apart from what I mentioned - no function that accesses `dired-buffers' at all.

2. What do you mean by a function operating on Dired buffers doing the right thing? What can that possibly mean, independent from any particular such function?

Again, no Emacs source code accesses (in order to operate) on its buffers.
___

There's no way to know what might exist in the wild, of course - code that might use `dired-buffers' somehow.  (I would guess zero such use, but I could be wrong.)

We could certainly add to the `dired-buffers' doc string, pointing out that `dired-buffers' can include Dired buffers with "listings" created by find* or from an arbitrary list of files&dirs, i.e., the files&dirs listed aren't necessarily the result of `ls'.

I don't think it's necessary to do that, but it wouldn't hurt.
___

The other thing that code should be aware of, and which is not documented AFAIK, is that an entry in `dired-buffers can include buffers that have been killed.  Any code that might want to operate on the buffers (there is none, so far, AFAIK) needs to be aware of this.  E.g., it will likely want to filter out killed-buffer entries.

I do think it might be good to mention this in the `dired-buffers' doc string.
___

We already "allow" buffers with arbitrary files & dirs to be added to `dired-buffers' (via `dired' with a cons DIRNAME arg).  I really don't see how also allowing the Dired buffers with find* files & dirs is different.  We don't say or do anything special if you use a Dired buffer with an arbitrary list of files&dirs.  I don't see anything different/special about the Dired buffers from find*.

I do understand that historically we've prevented this, so we should think about it.  But so far, I don't see any reason for it.  I'm generally conservative on such things, but in this case I'd suggest we just do it.

We could also add a defvar that controls whether to do this, to be more conservative.  If we do that, I'd suggest that by default it allows find* Dired buffers.   Any code that finds their inclusion problematic could change the variable value, by binding or assigning.
___

I suspect that the prohibition for `find*' was overengineering, for lack of full understanding of Dired.  There's a lot of stuff in Dired, some of which has never seen a lot of use.

In particular, Dired buffers with lists of arbitrary files&dirs (not from `ls').  That feature was (apparently) provided from the get-go, but I doubt that it's been used much.  I feel like I might have been the first to take advantage of it, but I don't know.

I mention this as a possible reason why `dired-buffers' was made off-limits for find*: maybe we just weren't clear enough about what might be involved or what might happen with a non-`ls' buffer.  If so, that's kinda where we are today too.  It'd be great if Richard happened to recall something about why he made it off-limits, but I don't expect he would 27 years later - I certainly wouldn't.

HTH.