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

From: "Basil L. Contovounesios" <[email-masked]>
Date: Mon, 22 Apr 2019 23:11:28 +0100

tags 35385 patch
quit

>From 463ccbe8ba96aee0a2cdfd49342270a33e161db2 Mon Sep 17 00:00:00 2001
From: "Basil L. Contovounesios" <[email-masked]>
Date: Mon, 22 Apr 2019 14:33:38 +0100
Subject: [PATCH] Make dired-dwim-target aware of other frames

* lisp/dired.el (dired-dwim-target-frames): New user
option. (bug#35385)
(dired-dwim-target): Mention it in docstring.
* lisp/dired-aux.el (dired-dwim-target-directory): Use it.
* doc/emacs/dired.texi (Operating on Files): Document it.
* etc/NEWS: Announce it.  Merge duplicate Dired outlines.
* test/lisp/dired-tests.el: Remove unnecessary require and pacify
byte-compiler.
---
 doc/emacs/dired.texi     | 23 ++++++++++++++++++++---
 etc/NEWS                 | 16 +++++++++-------
 lisp/dired-aux.el        | 34 +++++++++++++++++-----------------
 lisp/dired.el            | 20 +++++++++++++++++---
 test/lisp/dired-tests.el |  3 +--
 5 files changed, 64 insertions(+), 32 deletions(-)

diff --git a/doc/emacs/dired.texi b/doc/emacs/dired.texi
index 9f454ea2ad..b8b1d73d8f 100644
--- a/doc/emacs/dired.texi
+++ b/doc/emacs/dired.texi
@@ -644,13 +644,30 @@ Operating on Files
 commands, use the same conventions to decide which files to work on.
 
 @vindex dired-dwim-target
+@vindex dired-dwim-target-frames
 @cindex two directories (in Dired)
   Commands which ask for a destination directory, such as those which
 copy and rename files or create links for them, try to guess the default
 target directory for the operation.  Normally, they suggest the Dired
-buffer's default directory, but if the variable @code{dired-dwim-target}
-is non-@code{nil}, and if there is another Dired buffer displayed in the
-next window, that other buffer's directory is suggested instead.
+buffer's default directory, but if the option @code{dired-dwim-target}
+is non-@code{nil}, and if there is another Dired buffer displayed in
+another window, that other buffer's directory is suggested instead.  The
+option @code{dired-dwim-target-frames} controls which windows to
+consider:
+
+@itemize @bullet
+@item @code{nil}
+means to consider windows on the selected frame.
+
+@item @code{t}
+means to consider windows on all existing frames.
+
+@item @code{visible}
+means to consider windows on all visible frames.
+
+@item 0
+means to consider windows on all frames on the current terminal.
+@end itemize
 
   Here are the file-manipulating Dired commands that operate on files.
 
diff --git a/etc/NEWS b/etc/NEWS
index b13ab47768..d1761c6415 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -507,6 +507,15 @@ remapped to these, respectively.
 +++
 *** New command 'dired-create-empty-file'.
 
++++
+*** The new user option 'dired-create-destination-dirs' controls whether
+'dired-do-copy' and 'dired-rename-file' should create non-existent
+directories in the destination.
+
++++
+*** New user option 'dired-dwim-target-frames'.
+This option controls which frames 'dired-dwim-target' applies to.
+
 ** Change Logs and VC
 
 *** Recording ChangeLog entries doesn't require an actual file.
@@ -857,13 +866,6 @@ unescaping text.
 The maximum level is used by default; customize
 'font-lock-maximum-decoration' to tone down the decoration.
 
-** Dired
-
-+++
-*** The new user option 'dired-create-destination-dirs' controls whether
-'dired-do-copy' and 'dired-rename-file' should create non-existent
-directories in the destination.
-
 ** Help
 
 ---
diff --git a/lisp/dired-aux.el b/lisp/dired-aux.el
index b81c0d1a4f..c3df5c982b 100644
--- a/lisp/dired-aux.el
+++ b/lisp/dired-aux.el
@@ -1937,23 +1937,21 @@ dired-mark-read-file-name
    (format prompt (dired-mark-prompt arg files)) dir default))
 
 (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,
-  ;; use its current subdir, else use current subdir of this dired buffer.
-  (let ((this-dir (and (eq major-mode 'dired-mode)
-		       (dired-current-directory))))
-    ;; non-dired buffer may want to profit from this function, e.g. vm-uudecode
-    (if dired-dwim-target
-	(let* ((other-win (get-window-with-predicate
-			   (lambda (window)
-			     (with-current-buffer (window-buffer window)
-			       (eq major-mode 'dired-mode)))))
-	       (other-dir (and other-win
-			       (with-current-buffer (window-buffer other-win)
-				 (and (eq major-mode 'dired-mode)
-				      (dired-current-directory))))))
-	  (or other-dir this-dir))
-      this-dir)))
+  "Try to guess which target directory the user may want.
+If there is a Dired buffer displayed in another window (subject
+to `dired-dwim-target' and `dired-dwim-target-frames'), return
+its current subdirectory, otherwise return that of the current
+Dired buffer."
+  (let ((win (if dired-dwim-target
+                 (get-window-with-predicate
+                  (lambda (window)
+                    (with-current-buffer (window-buffer window)
+                      (eq major-mode 'dired-mode)))
+                  nil dired-dwim-target-frames (selected-window))
+               (selected-window))))
+    (with-current-buffer (window-buffer win)
+      (and (eq major-mode 'dired-mode)
+           (dired-current-directory)))))
 
 (defun dired-dwim-target-defaults (fn-list target-dir)
   ;; Return a list of default values for file-reading functions in Dired.
@@ -2839,6 +2837,8 @@ dired-do-isearch-regexp
   (multi-isearch-files-regexp
    (dired-get-marked-files nil nil 'dired-nondirectory-p nil t)))
 
+(declare-function fileloop-continue "fileloop" ())
+
 ;;;###autoload
 (defun dired-do-search (regexp)
   "Search through all marked files for a match for REGEXP.
diff --git a/lisp/dired.el b/lisp/dired.el
index 63082fe392..710fcfc0f4 100644
--- a/lisp/dired.el
+++ b/lisp/dired.el
@@ -185,14 +185,28 @@ dired-keep-marker-symlink
 
 (defcustom dired-dwim-target nil
   "If non-nil, Dired tries to guess a default target directory.
-This means: if there is a Dired buffer displayed in the next
-window, use its current directory, instead of this Dired buffer's
-current directory.
+This means: if there is a Dired buffer displayed in some window,
+use its current directory, instead of this Dired buffer's current
+directory.  See `dired-dwim-target-frames' for which frames to
+consider when looking for a target window.
 
 The target is used in the prompt for file copy, rename etc."
   :type 'boolean
   :group 'dired)
 
+(defcustom dired-dwim-target-frames nil
+  "Determines which frames to consider for `dired-dwim-target'.
+It has a similar meaning to the ALL-FRAMES argument of
+`next-window'.  nil means consider windows on only the selected
+frame; t on all existing frames; `visible' on all visible frames;
+and 0 on all frames on the current terminal."
+  :type '(choice (const :tag "Selected frame only" nil)
+                 (const :tag "All existing frames" t)
+                 (const :tag "All visible frames" visible)
+                 (const :tag "All frames on current terminal" 0))
+  :version "27.1"
+  :group 'dired)
+
 (defcustom dired-copy-preserve-time t
   "If non-nil, Dired preserves the last-modified time in a file copy.
 \(This works on only some systems.)"
diff --git a/test/lisp/dired-tests.el b/test/lisp/dired-tests.el
index 71ffcdd545..c4728e7a06 100644
--- a/test/lisp/dired-tests.el
+++ b/test/lisp/dired-tests.el
@@ -20,7 +20,6 @@
 ;;; Code:
 (require 'ert)
 (require 'dired)
-(require 'nadvice)
 
 (ert-deftest dired-autoload ()
   "Tests to see whether dired-x has been autoloaded"
@@ -54,7 +53,7 @@
         (when (buffer-live-p buf) (kill-buffer buf)))
       (delete-directory dir 'recursive))))
 
-(defvar dired-dwim-target)
+(defvar dired-query)
 (ert-deftest dired-test-bug25609 ()
   "Test for https://debbugs.gnu.org/25609 ."
   (let* ((from (make-temp-file "foo" 'dir))
-- 
2.20.1

"Basil L. Contovounesios" <[email-masked]> writes:

> Patch implementing this to follow.

Now attached.  WDYT?

Thanks,

-- 
Basil