GNU bug report logs - #70593
30.0.50; Dired: buffers of renamed dirs are broken

Previous Next

Package: emacs;

Reported by: Michael Heerdegen <michael_heerdegen <at> web.de>

Date: Fri, 26 Apr 2024 12:04:06 UTC

Severity: normal

Found in version 30.0.50

To reply to this bug, email your comments to 70593 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#70593; Package emacs. (Fri, 26 Apr 2024 12:04:09 GMT) Full text and rfc822 format available.

Acknowledgement sent to Michael Heerdegen <michael_heerdegen <at> web.de>:
New bug report received and forwarded. Copy sent to bug-gnu-emacs <at> gnu.org. (Fri, 26 Apr 2024 12:04:10 GMT) Full text and rfc822 format available.

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

From: Michael Heerdegen <michael_heerdegen <at> web.de>
To: bug-gnu-emacs <at> gnu.org
Subject: 30.0.50; Dired: buffers of renamed dirs are broken
Date: Fri, 26 Apr 2024 13:59:16 +0200
Hello,

I'm really, really happy that I finally nailed down this not
insignificant dired problem:

When you revert a dired buffer whose default-directory has been renamed,
the buffer is erased and an error message is displayed.  Marks and stuff
are permanently lost.  This even happens when the directory had been
renamed with means of dired.

It follows a recipe for emacs -Q; feel free to skip to the following
analysis of the problem... (we care about this case, but the code is
broken - see below)

[ Recipe:

I have two dired buffers, one showing "~", the other one a subdirectory
"~/test" in the other window.  You can put some trash files into that
directory and mark some of them.

Now I select the "~" dired buffer and enable wdired.  I rename "test"
to, say, "test1", and confirm.

Now select the other dired buffer.  The directory name in the first line
has even been updated.  But when I hit g, the buffer is erased and an
error is raised:

| insert-directory: Setting current directory: No such file or directory,
| /home/micha/test2/

Recipe end ]

The problem is that we partially fail to update the affected buffers.

The code wants to do this in `dired-rename-subdir-1':

    (if (equal dir default-directory)
	;; if top level directory was renamed, lots of things have to be
	;; updated:

DIR is the old directory name.  But the `equality' test fails simply
because default-directory is "~/test/" but DIR has the tilde expanded.


TIA,

Michael.






Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#70593; Package emacs. (Fri, 26 Apr 2024 14:57:04 GMT) Full text and rfc822 format available.

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

From: Eli Zaretskii <eliz <at> gnu.org>
To: Michael Heerdegen <michael_heerdegen <at> web.de>
Cc: 70593 <at> debbugs.gnu.org
Subject: Re: bug#70593: 30.0.50; Dired: buffers of renamed dirs are broken
Date: Fri, 26 Apr 2024 17:55:52 +0300
> Date: Fri, 26 Apr 2024 13:59:16 +0200
> From:  Michael Heerdegen via "Bug reports for GNU Emacs,
>  the Swiss army knife of text editors" <bug-gnu-emacs <at> gnu.org>
> 
> The problem is that we partially fail to update the affected buffers.
> 
> The code wants to do this in `dired-rename-subdir-1':
> 
>     (if (equal dir default-directory)
> 	;; if top level directory was renamed, lots of things have to be
> 	;; updated:
> 
> DIR is the old directory name.  But the `equality' test fails simply
> because default-directory is "~/test/" but DIR has the tilde expanded.

So all we need to do is call expand-file-name on both of them?  Or do
we need also to call file-truename?




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#70593; Package emacs. (Mon, 29 Apr 2024 14:43:02 GMT) Full text and rfc822 format available.

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

From: Michael Heerdegen <michael_heerdegen <at> web.de>
To: Eli Zaretskii <eliz <at> gnu.org>
Cc: 70593 <at> debbugs.gnu.org
Subject: Re: bug#70593: 30.0.50; Dired: buffers of renamed dirs are broken
Date: Mon, 29 Apr 2024 16:42:18 +0200
[Message part 1 (text/plain, inline)]
Eli Zaretskii <eliz <at> gnu.org> writes:

> > The code wants to do this in `dired-rename-subdir-1':
> >
> >     (if (equal dir default-directory)
> > 	;; if top level directory was renamed, lots of things have to be
> > 	;; updated:
> >
> > DIR is the old directory name.  But the `equality' test fails simply
> > because default-directory is "~/test/" but DIR has the tilde expanded.
>
> So all we need to do is call expand-file-name on both of them?  Or do
> we need also to call file-truename?

A sign of life with intermediate results:

Turns out this is a difficult and not even the only question (see
below).  It looks to me like this branch of the code (after the always
failing test) was never in use, or only a very long time ago.  Because
that unreachable branch is broken in several ways.

I needed to add a `file-name-as-directory' wrapper, else dired wouldn't
recognize the new directory as a directory and treats the file name as a
wildcard instead.

I would also add `abbreviate-file-name' calls so that the format of the
file names is like before (abbreviated).  Finally I don't understand why
the existing code computes `default-directory' and `dired-directory'
differently, so I reduced that to one computation for now, but also see
below for more.

This took me to this first actually working version for the
simplest case:

[0001-WIP-Try-to-fix-70593.patch (text/x-diff, inline)]
From aa6146e69d8d9d97424ccaf4d69db9eea64d0011 Mon Sep 17 00:00:00 2001
From: Michael Heerdegen <michael_heerdegen <at> web.de>
Date: Mon, 29 Apr 2024 16:10:29 +0200
Subject: [PATCH] WIP: Try to fix #70593

---
 lisp/dired-aux.el | 19 +++++++++++--------
 1 file changed, 11 insertions(+), 8 deletions(-)

diff --git a/lisp/dired-aux.el b/lisp/dired-aux.el
index e340f98a551..60a0f16bfe4 100644
--- a/lisp/dired-aux.el
+++ b/lisp/dired-aux.el
@@ -2331,18 +2331,21 @@ dired-rename-subdir-1
       (if (dired-in-this-tree-p (car elt) expanded-dir)
 	  ;; ELT's subdir is affected by the rename
 	  (dired-rename-subdir-2 elt dir to)))
-    (if (equal dir default-directory)
+    (if (string= dir (expand-file-name default-directory))
 	;; if top level directory was renamed, lots of things have to be
 	;; updated:
 	(progn
 	  (dired-unadvertise dir)	; we no longer dired DIR...
-	  (setq default-directory to
-		dired-directory (expand-file-name;; this is correct
-				 ;; with and without wildcards
-				 (file-name-nondirectory (if (stringp dired-directory)
-                                                             dired-directory
-                                                           (car dired-directory)))
-				 to))
+	  (setq dired-directory
+                (abbreviate-file-name
+                 (file-name-as-directory
+                  (expand-file-name ;; this is correct
+		   ;; with and without wildcards
+		   (file-name-nondirectory (if (stringp dired-directory)
+                                               dired-directory
+                                             (car dired-directory)))
+		   to)))
+                default-directory dired-directory)
 	  (let ((new-name (file-name-nondirectory
 			   (directory-file-name (if (stringp dired-directory)
                                                     dired-directory
--
2.39.2

[Message part 3 (text/plain, inline)]

Open questions:

(1) What do we need to do we do when `dired-directory' is a cons
(i.e. dir along with a file list)?  The existing code just threw away
the file list (that's why I unified the cases for now - the code didn't
make sense to me).

(2) What to do when symlinks are involved?  This question is also not
trivial.  It might be necessary to handle different cases and change
more than one part of the code.

Just calling `file-truename' before comparing as you (Eli) suggested
might fix more valid cases but will also resolve symlinks as side
effect: the dired buffer will afterwards visit a directory behind a
(probably unrelated) symlink when the visited directory name had not
been unresolved before.  This is not what we want.  Hope it's
understandable what I mean.

Another tricky case is when the user accidentally broke a symlink
and a dired buffer we handle visits a directory with a name that can't
be resolved any more.


Michael.

Information forwarded to drew.adams <at> oracle.com, bug-gnu-emacs <at> gnu.org:
bug#70593; Package emacs. (Thu, 09 May 2024 13:47:01 GMT) Full text and rfc822 format available.

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

From: Michael Heerdegen <michael_heerdegen <at> web.de>
To: Eli Zaretskii <eliz <at> gnu.org>
Cc: 70593 <at> debbugs.gnu.org
Subject: Re: bug#70593: 30.0.50; Dired: buffers of renamed dirs are broken
Date: Thu, 09 May 2024 15:46:18 +0200
Hello,

I'm CC'ing Drew.  Drew, do you happen to have any experience with this
case case (in general)?


In the meantime I've though about this particular question:

> (1) What do we need to do we do when `dired-directory' is a cons
> (i.e. dir along with a file list)?  The existing code just threw away
> the file list (that's why I unified the cases for now - the code didn't
> make sense to me).

I continue thinking like that.  But what should we do instead?  The file
list can contain anything - relative or absolute names.  And there can
be names affected by the renaming operation in the list even when the
`dired-directory' is not affected.  Would we want to exchange affected
file names in the list silently, or leave them as they are?


Michael.




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#70593; Package emacs. (Thu, 09 May 2024 14:06:02 GMT) Full text and rfc822 format available.

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

From: Michael Heerdegen <michael_heerdegen <at> web.de>
To: Michael Heerdegen via "Bug reports for GNU Emacs, the Swiss army knife
 of text editors" <bug-gnu-emacs <at> gnu.org>
Cc: 70593 <at> debbugs.gnu.org, Eli Zaretskii <eliz <at> gnu.org>,
 Drew Adams <drew.adams <at> oracle.com>
Subject: Re: bug#70593: 30.0.50; Dired: buffers of renamed dirs are broken
Date: Thu, 09 May 2024 16:05:11 +0200
[Message part 1 (text/plain, inline)]
Michael Heerdegen via "Bug reports for GNU Emacs, the Swiss army knife
of text editors" <bug-gnu-emacs <at> gnu.org> writes:

> > (1) What do we need to do we do when `dired-directory' is a cons
> > (i.e. dir along with a file list)?

Here is an update of the former patch doing the minimum in that case:
update only the car of a consp `dired-directory' when the car is
affected by the renaming, and leave the rest untouched:

[0001-WIP-Try-to-fix-70593.patch (text/x-diff, inline)]
From 30d1546d30a75f5ff52a7aad10063c49a5e76789 Mon Sep 17 00:00:00 2001
From: Michael Heerdegen <michael_heerdegen <at> web.de>
Date: Mon, 29 Apr 2024 16:10:29 +0200
Subject: [PATCH] WIP: Try to fix #70593

---
 lisp/dired-aux.el | 23 +++++++++++++++--------
 1 file changed, 15 insertions(+), 8 deletions(-)

diff --git a/lisp/dired-aux.el b/lisp/dired-aux.el
index e340f98a551..9c7cd8aa1f4 100644
--- a/lisp/dired-aux.el
+++ b/lisp/dired-aux.el
@@ -2331,18 +2331,25 @@ dired-rename-subdir-1
       (if (dired-in-this-tree-p (car elt) expanded-dir)
 	  ;; ELT's subdir is affected by the rename
 	  (dired-rename-subdir-2 elt dir to)))
-    (if (equal dir default-directory)
+    (if (string= dir (expand-file-name default-directory))
 	;; if top level directory was renamed, lots of things have to be
 	;; updated:
 	(progn
 	  (dired-unadvertise dir)	; we no longer dired DIR...
-	  (setq default-directory to
-		dired-directory (expand-file-name;; this is correct
-				 ;; with and without wildcards
-				 (file-name-nondirectory (if (stringp dired-directory)
-                                                             dired-directory
-                                                           (car dired-directory)))
-				 to))
+	  (let* ((dired-dir (if (stringp dired-directory)
+                                dired-directory
+                              (car dired-directory)))
+                 (dired-dir-new
+                  (abbreviate-file-name
+                   (file-name-as-directory
+                    (expand-file-name ;; this is correct
+		     ;; with and without wildcards
+		     (file-name-nondirectory dired-dir)
+		     to)))))
+            (if (stringp dired-directory)
+                (setq dired-directory dired-dir-new)
+              (setcar dired-directory dired-dir-new))
+            (setq default-directory dired-dir-new))
 	  (let ((new-name (file-name-nondirectory
 			   (directory-file-name (if (stringp dired-directory)
                                                     dired-directory
--
2.39.2

[Message part 3 (text/plain, inline)]

Michael.

Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#70593; Package emacs. (Thu, 09 May 2024 14:06:02 GMT) Full text and rfc822 format available.

Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#70593; Package emacs. (Thu, 09 May 2024 16:43:02 GMT) Full text and rfc822 format available.

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

From: Drew Adams <drew.adams <at> oracle.com>
To: Michael Heerdegen <michael_heerdegen <at> web.de>, Eli Zaretskii <eliz <at> gnu.org>
Cc: "70593 <at> debbugs.gnu.org" <70593 <at> debbugs.gnu.org>
Subject: RE: [External] : bug#70593: 30.0.50; Dired: buffers of renamed dirs
 are broken
Date: Thu, 9 May 2024 16:30:18 +0000
> I'm CC'ing Drew.  Drew, do you happen to have any experience with this
> case case (in general)?

Thanks for cc'ing me.

No, I have no particular experience with the
`dired-rename-subdir' code, other than using it in
typical ways.

In general, the support for a cons value of
`dired-directory' is not 100% wonderful.  I'm not
surprised when some uses of `dired-directory' don't
really handle the cons case or don't handle it well.

IMO the cons case is an important Dired feature,
but it's not taken into account well everywhere.

This is maybe partly the result of it being ignored
when changes have been made over the years to some
of the underlying basic functions.  IOW, use of a
cons `dired-directory' might not get tested after
some basic-level code change.

A Dired listing of arbitrary files (the cons case)
can be complicated, especially when it comes to
reverting the listing and in the face of changes
such as renamings.  Some of the basic plumbing
functions can be involved, and that's where some
of the complication lies.

Dunno whether it helps or would waste your time,
but in dired+.el I redefined some if the basic
functions to support a cons `dired-directory'.
E.g., you might look at `dired-buffers-for-dir'.
This is the comment for it in dired+.el:

;; REPLACE ORIGINAL in `dired.el'.
;;
;; 1. Allow for consp `dired-directory' too.
;; 2. Updated for Emacs 28: Added optional arg SUBDIRS-P.
;; 3. Fix for Emacs bug #52395.  Expand DIR with
;;    `default-directory', so `file-name-as-directory'
;;    gets applied to absolute name.  Otherwise,
;;    (dired-buffers-for-dir "~/some/dir/") returns nil,
;;    because the element in `dired-subdir-alist' is
;;    ("/the/home/dir/some/dir/" . #<buffer dir>), not
;;    ("~/some/dir/" . #<buffer dir>).

> In the meantime I've though about this particular question:
> 
> > (1) What do we need to do we do when `dired-directory' is a cons
> > (i.e. dir along with a file list)?  The existing code just threw away
> > the file list (that's why I unified the cases for now - the code didn't
> > make sense to me).

`dired-directory' is a buffer-local variable.
I don't think there's any support for subdir
listings that are of arbitrary files (i.e., cons
`dired-directory').  I don't recall, but I think
that's the case - in which case it shouldn't
matter that such a list of arbitrary files is
discarded here.  But it should be checked first.
And maybe there's a need for an error message
somewhere if things aren't as expected (?).

However, the explicit list of files can of course
include (arbitrary) directory names.  And in the
Dired buffer you can use `i' to insert a "subdir"
listing (which really means you can insert a
listing of any of the directories that are listed).

If you do that to insert a directory that's one of
the arbitrary files listed in `dired-directory',
then the files and dirs listed in that inserted
directory listing are not included in the
`dired-directory' cons value - it defines only the
main listing, not any inserted "subdir" listings.

So I think there's no problem with discarding the
explicit list of files in the case you raise.  But
I don't really know.

> I continue thinking like that.  But what should we do instead?  The file
> list can contain anything - relative or absolute names. 

Yes, the top-level listing (i.e., the value of
`dired-directory') can.

> And there can
> be names affected by the renaming operation in the list even when the
> `dired-directory' is not affected.  Would we want to exchange affected
> file names in the list silently, or leave them as they are?

Not sure I follow completely, but I think yes,
rename them in `dired-directory' also.  Maybe
if you showed some examples it would be clearer.

HTH somehow, though I doubt it.

Overall, I'd say that it's good to at least try
to test a bit with the cons `dired-directory'
case, whatever changes/fixes you might make.




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#70593; Package emacs. (Thu, 09 May 2024 19:27:03 GMT) Full text and rfc822 format available.

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

From: Michael Heerdegen <michael_heerdegen <at> web.de>
To: Drew Adams via "Bug reports for GNU Emacs, the Swiss army knife of text
 editors" <bug-gnu-emacs <at> gnu.org>
Cc: "70593 <at> debbugs.gnu.org" <70593 <at> debbugs.gnu.org>,
 Eli Zaretskii <eliz <at> gnu.org>, Drew Adams <drew.adams <at> oracle.com>
Subject: Re: bug#70593: 30.0.50; Dired: buffers of renamed dirs are broken
Date: Thu, 09 May 2024 21:27:14 +0200
Drew Adams via "Bug reports for GNU Emacs, the Swiss army knife of text
editors" <bug-gnu-emacs <at> gnu.org> writes:

> `dired-directory' is a buffer-local variable.
> I don't think there's any support for subdir
> listings that are of arbitrary files (i.e., cons
> `dired-directory').  I don't recall, but I think
> that's the case - in which case it shouldn't
> matter that such a list of arbitrary files is
> discarded here.  But it should be checked first.

Not sure whether I can follow.

When I call dired with a cons DIRNAME, `dired-directory' will be bound
to that cons.  And it is consulted for reverting.

When I overwrite it with just `default-directory' and revert, the result
will be a "normal" dired buffer showing this directory - the explicit
listing is lost.

In the scenario of the bug this surely makes a difference.  My latest
patch seems to work as expected.  Any comment about the patch btw?


Subdir insertion in cons value `dired-directory' buffers are not really
supported currently it seems so I took this complication aside for now.
The code does handle the subdir alists, though.


Thanks for your comments so far Drew,

Michael.




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#70593; Package emacs. (Thu, 09 May 2024 19:27:03 GMT) Full text and rfc822 format available.

Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#70593; Package emacs. (Thu, 09 May 2024 21:21:01 GMT) Full text and rfc822 format available.

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

From: Drew Adams <drew.adams <at> oracle.com>
To: Michael Heerdegen <michael_heerdegen <at> web.de>, "Drew Adams via Bug reports
 for GNU Emacs, the Swiss army knife of text editors" <bug-gnu-emacs <at> gnu.org>
Cc: "70593 <at> debbugs.gnu.org" <70593 <at> debbugs.gnu.org>,
 Eli Zaretskii <eliz <at> gnu.org>
Subject: RE: [External] : Re: bug#70593: 30.0.50; Dired: buffers of renamed
 dirs are broken
Date: Thu, 9 May 2024 21:20:09 +0000
> When I call dired with a cons DIRNAME, `dired-directory' will be bound
> to that cons.  And it is consulted for reverting.
> 
> When I overwrite it with just `default-directory' and revert, the result
> will be a "normal" dired buffer showing this directory - the explicit
> listing is lost.

Right.

> In the scenario of the bug this surely makes a difference.

OK; sounds right.

> My latest patch seems to work as expected.
> Any comment about the patch btw?

I can't really judge.  Eyeballing it, it looks
reasonable.

What I see is that when `dired-directory' is a
cons you replace its car, DIRED-DIR, applying this to that car:

 (abbreviate-file-name
   (file-name-as-directory DIRED-DIR))

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

If it's a directory name then what you're doing
looks right to me.  If it's not then I think
it's probably still OK - that code would
generally just append a `/' to the string.

But if the string has some particular file-name
syntax then maybe there could be some other 
resulting behavior; dunno.
 
> Subdir insertion in cons value `dired-directory' buffers 
> are not really supported currently it seems

Not sure what you mean.  Even in vanilla Emacs,
I think subdir insertion is supported.  E.g.:

M-: (dired (list "foobar" "/tata/file.txt"
                 "/toto/dir/" "/titi/"))

You get a Dired listing in buffer `foobar' with
those 3 filename entries.  Hitting `i' when on
the second entry inserts a listing of directory 
/toto/dir.  Hitting `i' on the third entry
inserts a listing of directory /titi.  That's
what I see, at least.

But maybe you meant something else?

> so I took this complication aside for now.
> The code does handle the subdir alists, though.

By "the subdir alists" I guess you mean
`dired-subdir-alist'.

___

What I think you've done seems reasonable.  It
should probably be checked in various scenarios,
however - at least a sanity check.




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#70593; Package emacs. (Thu, 09 May 2024 21:21:02 GMT) Full text and rfc822 format available.

Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#70593; Package emacs. (Fri, 10 May 2024 12:56:02 GMT) Full text and rfc822 format available.

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

From: Michael Heerdegen <michael_heerdegen <at> web.de>
To: Drew Adams <drew.adams <at> oracle.com>
Cc: "70593 <at> debbugs.gnu.org" <70593 <at> debbugs.gnu.org>,
 "Drew Adams via Bug reports for GNU Emacs, the Swiss army knife of text
 editors" <bug-gnu-emacs <at> gnu.org>, Eli Zaretskii <eliz <at> gnu.org>
Subject: Re: [External] : Re: bug#70593: 30.0.50; Dired: buffers of renamed
 dirs are broken
Date: Fri, 10 May 2024 14:56:08 +0200
Drew Adams <drew.adams <at> oracle.com> writes:

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

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

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


> > Subdir insertion in cons value `dired-directory' buffers
> > are not really supported currently it seems
>
> Not sure what you mean.  Even in vanilla Emacs,
> I think subdir insertion is supported.  E.g.:
>
> M-: (dired (list "foobar" "/tata/file.txt"
>                  "/toto/dir/" "/titi/"))

Hmm, indeed, this works in -Q.  Seems one of my local hacks broke this
case.


Thx,

Michael.




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#70593; Package emacs. (Fri, 10 May 2024 12:56:02 GMT) Full text and rfc822 format available.

Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#70593; Package emacs. (Fri, 10 May 2024 13:08:01 GMT) Full text and rfc822 format available.

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

From: Michael Heerdegen <michael_heerdegen <at> web.de>
To: Michael Heerdegen via "Bug reports for GNU Emacs, the Swiss army knife
 of text editors" <bug-gnu-emacs <at> gnu.org>
Cc: 70593 <at> debbugs.gnu.org, eliz <at> gnu.org, Drew Adams <drew.adams <at> oracle.com>
Subject: Re: bug#70593: 30.0.50; Dired: buffers of renamed dirs are broken
Date: Fri, 10 May 2024 15:08:10 +0200
Michael Heerdegen via "Bug reports for GNU Emacs, the Swiss army knife
of text editors" <bug-gnu-emacs <at> gnu.org> writes:

> > Not sure what you mean.  Even in vanilla Emacs,
> > I think subdir insertion is supported.  E.g.:
> >
> > M-: (dired (list "foobar" "/tata/file.txt"
> >                  "/toto/dir/" "/titi/"))
>
> Hmm, indeed, this works in -Q.  Seems one of my local hacks broke this
> case.

No no... not my fault: this does only work when starting from a buffer
whose `default-directory' is a parent of the listed directories.  Else I
get (in master emacs -Q) a buffer looking like

 /home/micha/.config:
  drwxr-xr-x 24 micha micha 4096 Nov 22 14:27 /home/micha/Treasure
  drwxr-xr-x  4 micha micha 4096 Mai  7 17:38 /home/micha/bin

and hitting i gives me the error "dired-insert-subdir-validate:
/home/micha/Treasure/: Not in this directory tree".


Michael.




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#70593; Package emacs. (Fri, 10 May 2024 13:11:01 GMT) Full text and rfc822 format available.

Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#70593; Package emacs. (Fri, 10 May 2024 16:52:02 GMT) Full text and rfc822 format available.

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

From: Drew Adams <drew.adams <at> oracle.com>
To: Michael Heerdegen <michael_heerdegen <at> web.de>
Cc: "70593 <at> debbugs.gnu.org" <70593 <at> debbugs.gnu.org>,
 "Drew Adams via Bug reports for GNU Emacs, the Swiss army knife of text
 editors" <bug-gnu-emacs <at> gnu.org>, Eli Zaretskii <eliz <at> gnu.org>
Subject: RE: [External] : Re: bug#70593: 30.0.50; Dired: buffers of renamed
 dirs are broken
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.)
___________________________




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#70593; Package emacs. (Fri, 10 May 2024 16:53:02 GMT) Full text and rfc822 format available.

Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#70593; Package emacs. (Fri, 10 May 2024 16:53:02 GMT) Full text and rfc822 format available.

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

From: Drew Adams <drew.adams <at> oracle.com>
To: Michael Heerdegen <michael_heerdegen <at> web.de>, "Michael Heerdegen via Bug
 reports for GNU Emacs, the Swiss army knife of text editors"
 <bug-gnu-emacs <at> gnu.org>
Cc: "70593 <at> debbugs.gnu.org" <70593 <at> debbugs.gnu.org>,
 "eliz <at> gnu.org" <eliz <at> gnu.org>
Subject: RE: [External] : Re: bug#70593: 30.0.50; Dired: buffers of renamed
 dirs are broken
Date: Fri, 10 May 2024 16:52:04 +0000
> > > Not sure what you mean.  Even in vanilla Emacs,
> > > I think subdir insertion is supported.  E.g.:
> > >
> > > M-: (dired (list "foobar" "/tata/file.txt"
> > >                  "/toto/dir/" "/titi/"))
> >
> > Hmm, indeed, this works in -Q.  Seems one of my local hacks broke this
> > case.
> 
> No no... not my fault: this does only work when starting from a buffer
> whose `default-directory' is a parent of the listed directories.  Else I
> get (in master emacs -Q) a buffer looking like
> 
>  /home/micha/.config:
>   drwxr-xr-x 24 micha micha 4096 Nov 22 14:27 /home/micha/Treasure
>   drwxr-xr-x  4 micha micha 4096 Mai  7 17:38 /home/micha/bin
> 
> and hitting i gives me the error "dired-insert-subdir-validate:
> /home/micha/Treasure/: Not in this directory tree".

Sorry, you're right; good point.

Dired+ redefines `dired-insert-subdir-validate'
to be a no-op, to allow inserting dirs that
aren't under `default-directory'.

And it redefines `dired-insert-subdir-newpos'
so that if arg NEW-DIR isn't a descendant of a
directory in the buffer then the new position
is at eob.

So if you load dired+.el in `emacs -Q' I think
you'll see that `i' on a directory line (any
directory line) will insert a listing of that
directory.

Or just evaluate the Dired+ definitions of
`dired-maybe-insert-subdir',
`dired-insert-subdir-validate', and
`dired-insert-subdir-newpos'.
___

However, including a nondirectory file (e.g.
"/tata/file.txt" in my example) does raise the
error, because `ls-lisp-insert-directory' tries
to insert it as a directory.  (I'm on Windows,
so ls-lisp is used.)

(file-error "Reading directory"
  "Directory doesn't exist or is inaccessible"
  "z:/path/to/the/file.txt")

(Something in my setup (but not Dired+) shows
the error message in *Messages* but doesn't
open the debugger for it.)

HTH.




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#70593; Package emacs. (Fri, 10 May 2024 16:53:03 GMT) Full text and rfc822 format available.

Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#70593; Package emacs. (Fri, 10 May 2024 17:02:01 GMT) Full text and rfc822 format available.

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

From: Michael Heerdegen <michael_heerdegen <at> web.de>
To: Drew Adams <drew.adams <at> oracle.com>
Cc: "70593 <at> debbugs.gnu.org" <70593 <at> debbugs.gnu.org>,
 "Drew Adams via Bug reports for GNU Emacs, the Swiss army knife of text
 editors" <bug-gnu-emacs <at> gnu.org>, Eli Zaretskii <eliz <at> gnu.org>
Subject: Re: [External] : Re: bug#70593: 30.0.50; Dired: buffers of renamed
 dirs are broken
Date: Fri, 10 May 2024 19:02:25 +0200
Drew Adams <drew.adams <at> oracle.com> writes:

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

Hmm - but this this could also speak about the wildcard case.


Michael.




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#70593; Package emacs. (Fri, 10 May 2024 17:03:02 GMT) Full text and rfc822 format available.

Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#70593; Package emacs. (Fri, 10 May 2024 18:33:02 GMT) Full text and rfc822 format available.

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

From: Drew Adams <drew.adams <at> oracle.com>
To: Michael Heerdegen <michael_heerdegen <at> web.de>
Cc: "70593 <at> debbugs.gnu.org" <70593 <at> debbugs.gnu.org>,
 "Drew Adams via Bug reports for GNU Emacs, the Swiss army knife of text
 editors" <bug-gnu-emacs <at> gnu.org>, Eli Zaretskii <eliz <at> gnu.org>
Subject: RE: [External] : Re: bug#70593: 30.0.50; Dired: buffers of renamed
 dirs are broken
Date: Fri, 10 May 2024 18:32:33 +0000
> > 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.
> >    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
> 
> Hmm - but this this could also speak about
> the wildcard case.

Yes, maybe so.  In any case, it alone isn't
proof of an expectation that the car can be
an arbitrary string.




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#70593; Package emacs. (Fri, 10 May 2024 18:33:02 GMT) Full text and rfc822 format available.

This bug report was last modified 5 days ago.

Previous Next


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