Subject: bug#70593: 30.0.50; Dired: buffers of renamed dirs are broken

From: Drew Adams <[email-masked]>
Date: Fri, 10 May 2024 16:51:50 +0000

> > But the car of a cons `dired-directory' isn't
> > necessarily a directory name or any file name.
> > It's just a string used as the Dired buffer
> > name.  (Often it is a directory name, but it
> > need not be.)
> 
> That's exactly the kind of problem why I have CC'd you.
> 
> Is this a documented feature, however?

No, I don't think so.  But very little is said
in any doc about Dired listings of arbitrary
files (i.e., the cons `dired-directory' case).

Even in the code very little is said about it.

> Heard about it (from you).  But
> `dired-noselect' doesn't seem to handle or support this case at all, at
> least not specifically, although the code doesn't error in this case.

Dunno much about that, or I don't recall what
I might have known about it; sorry.

But note this comment in the code for
`dired-internal-noselect' (in dired.el):

;; We can do this unconditionally
;; because dired-noselect ensures that the name
;; is passed in directory name syntax
;; if it was the name of a directory at all.
   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Whether doc'd or commented or not, it's pretty
clear to me that the any-string (i.e., non-dir)
case for the car of `dired-directory' was
expected/intended from the outset, even if it's
not always respected (taken into account).

Someone (maybe Sebastian Kremer) provided for
it, from the outset. 

And even if that weren't the case, that's the
behavior.

To me, it makes sense.  If a listing can list
files and dirs from anywhere - not even the
same file-system hierarchy, then clearly the
name of the Dired buffer isn't necessarily a
directory name.

Or, put differently, whatever its name, the
listed files and dirs don't necessarily "belong"
to any particular directory - they need not even
have a common ancestor (at least in Dired+ - see
my other reply to you today).

I agree that the cons case isn't as fully
supported or fleshed out as the straightforward
single-directory case.

In particular, there's no _interactive_ support
for it, i.e., no way for users to interactively
create a Dired buffer listing arbitrary files
and dirs.  (Dired+ does let users do that, in
multiple ways.)

> I can only find places in the documentation where the
> car is described or referred to as "directory name".

Yes, I know.  As I say, AFAIK the cons case was
never fully developed, especially at the user
level (e.g. interactive use).

> Could you please briefly refresh my knowledge about this use
> case?  Does Vanilla Emacs somewhere make use of this case?

No, not that I know of.  I think I discovered it
by accident.  This isn't the only thing in Dired
that's not particularly well-known/advertised,
but it might be the main such thing that wasn't
ever fully exploited/developed.

Apart from WDired, I don't think much in the way
of _features_ has been added to Dired since its
beginning.  I think most work on the code has
been essentially maintenance.

I have no doubt that there are hidden/unknown
corners concerning the use of arbitrary Dired
listings.  Someday maybe someone will dig in and
develop it more thoroughly.
___

FWIW, this is my take (for Dired+) on how a Dired
listing of arbitrary files and dirs can be used,
including caveats about side-band modifications
(e.g. renaming, addition, and deletion of files
originally listed).  It's from the dired+.el
Commentary.  HTH.
_________________

Dired Snapshot Listings: Arbitrary Files and Dirs From Anywhere
---------------------------------------------------------------

Suppose you use a command such as `find-name-dired', to generate a
Dired buffer that lists files from various places.  The search
part of that operation might take a long time.

And suppose that you later want to get back to such a listing,
even if that buffer no longer exists.  In particular, maybe you
want to get to it in another Emacs session.

And suppose that you don't want to pay the penalty of performing
the `find' search again, and you're content with the set of file
names found by the original search.  That is, you don't care
whether that set of names is still 100% up-to-date.

In such a context you want, in effect, to create a Dired buffer
snapshot of some sort - you want to record the set of names that
your search found, and later use them again in Dired.

Dired+ gives you two ways to do this.  Both involve first creating
a Dired buffer that's produced from an explicit set of file names,
from anywhere, rather than one that's produced using `ls' or
similar, and then saving that set of file names for re-creating
such a Dired buffer later.

1. Use `C-M-*' (`diredp-marked-other-window') or `diredp-marked',
   to create a snapshot Dired buffer.  Then bookmark that buffer.
   Just jump to the bookmark to restore the snapshot buffer.

2. Use command `diredp-define-snapshot-dired-commands', to create
   two commands (for same-window and other-window) that will
   create a snapshot Dired buffer.  Save the `defun's of those
   commands to your init file, for persistent access.

The saved set of files, whether embedded in a bookmark or in a
special Dired command, is a snapshot of the files available at a
particular time.

When you later use Dired with that explicit set of file names,
only those files are listed - if a name no longer corresponds to
an existing file then it is ignored.  The resulting Dired buffer
represents the current state of the file system, but only as far
as the files it lists are concerned.

I think the first approach is generally preferable, but you might
prefer the second.

If you use approach #1 then you also need my library Bookmark+:

  https://www.emacswiki.org/emacs/BookmarkPlus

If you bookmark a Dired buffer without using Bookmark+ then the
bookmark records only the Dired directory name.  It doesn't record
the snapshot information - the explicit list of files to be
restored.  (It also doesn't record the `ls' switches or which
files were marked in the bookmarked snapshot listing, so you can't
restore them.)

Both approaches, #1 and #2, use the marked files and dirs as the
set to snapshot.  More precisely, they use the Dired+ version of
function `dired-get-marked-files'.  That means that you can use a
prefix arg to get a different set of files to snapshot, instead of
those that are explicitly marked.  See the doc strings.

Note too that it is the full content of the original Dired buffer
that's used to define the files to snapshot.  In particular,
inserted subdir listings are included.

Snapshot listings are composed of arbitrary files and directories.
Such a listing might result from a program such as `find', or from
a particular set of Dired markings, of from some other way of
selecting files - any way at all.  What makes them different from
the usual Dired listings is that they're not the output of `ls'.

You can persist any snapshot listing, as just mentioned, but in
most cases you won't.  The case of not wanting to recompute a
`find' result is a bit of an exception.

You can create snapshot listings in the following additional ways.

You can use the regular `dired' commands (`C-x d', `C-x 4 d', `C-x
5 d').  Just use a non-positive prefix arg (e.g., `C--') when
invoking them.

You're then prompted for the Dired buffer name (anything you like,
not necessarily a directory name) and for the individual files and
directories that you want listed.  (Use `C-g' to stop selecting.)

A non-negative prefix arg still prompts you for the `ls' switches
to use.  (So `C-0' does both: prompts for `ls' switches and for
the Dired buffer name and the files to list.)

`Dired+' provides these snapshot-producing commands for combining
and augmenting existing Dired listings.

 * `diredp-add-to-dired-buffer', bound globally to `C-x D A', lets
   you add arbitrary file and directory names to those in an
   existing Dired buffer.

 * `diredp-dired-union', bound globally to `C-x D U', lets you
   take the union of multiple Dired listings, or convert an
   ordinary Dired listing to an explicit list of absolute file
   names.  With a non-positive prefix arg, you can add extra file
   and directory names, just as for `diredp-add-to-dired-buffer'.

You can use `C-x D S' or `C-x 4 D S' to open an Emacs fileset as a
Dired (snapshot) listing.  See the Emacs manual, node Filesets, or
https://www.emacswiki.org/emacs/FileSets, for info about filesets.

You can visit your recent files or directories as a (snapshot)
listing, using `C-x D R' or `C-x D r'.

You can revert (using `g') or sort any Dired snapshot listing.

You can also sort such a listing in various ways, but you need to
use `C-M-L' (aka `C-M-S-l') to do so - you can't use the ordinary
Dired sort commands, such as `s'.  You're prompted for the sort
order.  The default sort order for such buffers is determined by
option `diredp-default-sort-arbitrary-function'.

When using a Dired snapshot listing other than one composed of
recent files, be aware that any operation that reverts the buffer
relists the same file names, and only those that still correspond
to currently existing files.  This means that:

1. If any of the files no longer exist then they will no longer be
   listed (which is likely what you would expect).

2. If any of the files has been renamed then it will no longer be
   listed (which is likely not what you would expect).  This
   applies to the use of WDired to rename files: the renamed files
   are not listed when you return to Dired from WDired.  It
   applies also to the use of `R' (`dired-do-rename').  (A renamed
   file is listed with its new name in any ordinary Dired buffer.)

(With Emacs prior to version 28 you can't use WDired on a
recent-files buffer at all, because such a buffer uses a
`revert-buffer-function' that updates the file list to show the
currently recent files, and older versions of WDired hard-code the
function used to revert back to Dired mode when you exit WDired.)
___________________________