Subject: Re: bug#58721: 28.2; dired with delete-by-moving-to-trash can't trash directory twice

From: Mike Kupfer <[email-masked]>
Date: Sat, 29 Oct 2022 17:09:06 -0700

Eli Zaretskii wrote:

> Yet another possibility is to refrain from calling rename-file when
> the moved file is a directory, and instead to do what rename-file
> does, with a twist, "by hand".  That is what I actually prefer, as
> nothing is really wrong with rename-file.

I'm afraid I don't understand your suggestion.

I've attached the proof-of-concept patch that I came up with, which just
modifies move-file-to-trash.  I've tested it with files and directories,
both same-filesystem and crossing filesystems.  Did you have in mind
something similar?

cheers,
mike
diff --git a/lisp/files.el b/lisp/files.el
index 1e1ec6127d..63786ec103 100644
--- a/lisp/files.el
+++ b/lisp/files.el
@@ -8565,10 +8565,29 @@ move-file-to-trash
 		    (setq files-base (substring (file-name-nondirectory info-fn)
                                                 0 (- (length ".trashinfo"))))
 		    (write-region nil nil info-fn nil 'quiet info-fn)))
-		 ;; Finally, try to move the file to the trashcan.
+		 ;; Finally, try to move the item to the trashcan.  If
+                 ;; it's a file, just move it.  If it's a directory,
+                 ;; there's no way to invoke rename-file to replace
+                 ;; new-fn with fn, so move everything in fn and then
+                 ;; delete it.
 		 (let ((delete-by-moving-to-trash nil)
 		       (new-fn (file-name-concat trash-files-dir files-base)))
-		   (rename-file fn new-fn overwrite)))))))))
+                   (if (not (file-directory-p fn))
+                       (rename-file fn new-fn overwrite)
+                     (make-directory new-fn)
+                     (mapc  
+                      (lambda (f1)
+                        (let ((src (file-name-concat fn f1))
+	                      (targ (file-name-concat new-fn f1)))
+                          (cond
+                           ((or (string= f1 ".")
+	                        (string= f1 ".."))
+                            t)
+                           (t
+                            (rename-file src targ)))))
+                      (directory-files fn))
+                     (delete-directory fn))))))))))
+
 
 
 (defsubst file-attribute-type (attributes)