Subject: Re: bug#35385: 27.0.50; Make dired-dwim-target aware of other frames

From: Juri Linkov <[email-masked]>
Date: Sun, 10 Nov 2019 22:38:38 +0200

>> So dired-dwim-target could have a similar defcustom
>> with choices for recent/next window.
>
> There are lots of imaginable user preferences, so I would prefer a
> solution where one can specify a function.  Would you want to use
> `dired-dwim-target' for that?

This would be a natural choice, indeed.

Please try this patch:

diff --git a/lisp/dired.el b/lisp/dired.el
index 05789a3516..cfee990a74 100644
--- a/lisp/dired.el
+++ b/lisp/dired.el
@@ -190,8 +190,16 @@ dired-dwim-target
 Dired buffer's current directory.
 
 The target is used in the prompt for file copy, rename etc."
-  :type 'boolean
-  :group 'dired)
+  :type '(choice
+          (const :tag "No guess" nil)
+          (function-item :tag "Prefer most recently used windows"
+                         dired-dwim-target-recent)
+          (function-item :tag "Prefer next windows"
+                         dired-dwim-target-next)
+          (function :tag "Your function")
+          (other :tag "Try to guess" t))
+  :group 'dired
+  :version "27.1")
 
 (defcustom dired-copy-preserve-time t
   "If non-nil, Dired preserves the last-modified time in a file copy.
diff --git a/lisp/dired-aux.el b/lisp/dired-aux.el
index 722d036e3f..a3d0ad61dd 100644
--- a/lisp/dired-aux.el
+++ b/lisp/dired-aux.el
@@ -1993,6 +1993,12 @@ dired-mark-read-file-name
    (format prompt (dired-mark-prompt arg files)) dir default))
 
 (defun dired-dwim-target-directories ()
+  (cond ((functionp dired-dwim-target)
+         (funcall dired-dwim-target))
+        (dired-dwim-target
+         (dired-dwim-target-recent))))
+
+(defun dired-dwim-target-recent ()
   ;; Return directories from all visible windows with dired-mode buffers
   ;; ordered by most-recently-used.
   (mapcar #'cdr (sort (mapcan (lambda (w)
@@ -2004,6 +2010,15 @@ dired-dwim-target-directories
                                     (window-list-1 nil 'nomini 'visible)))
                       (lambda (a b) (> (car a) (car b))))))
 
+(defun dired-dwim-target-next ()
+  (mapcan (lambda (w)
+            (with-current-buffer (window-buffer w)
+              (when (eq major-mode 'dired-mode)
+                (list (dired-current-directory)))))
+          (delq (selected-window) (window-list-1
+                                   (next-window nil 'nomini 'visible)
+                                   'nomini 'visible))))
+
 (defun dired-dwim-target-directory ()
   ;; Try to guess which target directory the user may want.
   ;; If there is a dired buffer displayed in one of the next windows,