[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
bug#35385: 27.0.50; Make dired-dwim-target aware of other frames
From: |
Juri Linkov |
Subject: |
bug#35385: 27.0.50; Make dired-dwim-target aware of other frames |
Date: |
Thu, 19 Sep 2019 23:43:37 +0300 |
User-agent: |
Gnus/5.13 (Gnus v5.13) Emacs/27.0.50 (x86_64-pc-linux-gnu) |
>> BTW, while looking at windows walking functions, I noticed
>> an opportunity for simplification.
>>
>> Martin, could you please confirm if I'm not mistaken with this patch:
>
> Removing the
>
> (when (framep all-frames)
> (select-window (frame-first-window all-frames) 'norecord))
>
> LGTM. Whether we should remove the
>
> (save-selected-window
>
> envelope is another question. If FUN changes the selected window,
> we'd now have a side effect we didn't have so far.
So I left a comment explaining why save-selected-window is still needed.
Now I prepared a patch for dired-dwim-target to DWIM most recently used
windows from all frames:
diff --git a/lisp/dired-aux.el b/lisp/dired-aux.el
index a321247b0b..7c477fa89d 100644
--- a/lisp/dired-aux.el
+++ b/lisp/dired-aux.el
@@ -1965,6 +1968,18 @@ dired-mark-read-file-name
#'read-file-name
(format prompt (dired-mark-prompt arg files)) dir default))
+(defun dired-dwim-target-directories ()
+ ;; Return directories from all visible windows with dired-mode buffers
+ ;; ordered by most-recently-used.
+ (mapcar #'cdr (sort (mapcan (lambda (w)
+ (with-current-buffer (window-buffer w)
+ (when (eq major-mode 'dired-mode)
+ (list (cons (window-use-time w)
+ (dired-current-directory))))))
+ (delq (selected-window)
+ (window-list-1 nil 'nomini 'visible)))
+ (lambda (a b) (> (car a) (car b))))))
+
(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,
@@ -1973,15 +1988,7 @@ dired-dwim-target-directory
(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))
+ (or (car (dired-dwim-target-directories)) this-dir)
this-dir)))
(defun dired-dwim-target-defaults (fn-list target-dir)
@@ -1999,15 +2006,11 @@ dired-dwim-target-defaults
(and (consp fn-list) (null (cdr fn-list)) (car fn-list)))
(current-dir (and (eq major-mode 'dired-mode)
(dired-current-directory)))
- dired-dirs)
- ;; Get a list of directories of visible buffers in dired-mode.
- (walk-windows (lambda (w)
- (with-current-buffer (window-buffer w)
- (and (eq major-mode 'dired-mode)
- (push (dired-current-directory) dired-dirs)))))
+ ;; Get a list of directories of visible buffers in dired-mode.
+ (dired-dirs (dired-dwim-target-directories)))
;; Force the current dir to be the first in the list.
(setq dired-dirs
- (delete-dups (delq nil (cons current-dir (nreverse dired-dirs)))))
+ (delete-dups (delq nil (cons current-dir dired-dirs))))
;; Remove the target dir (if specified) or the current dir from
;; default values, because it should be already in initial input.
(setq dired-dirs (delete (or target-dir current-dir) dired-dirs))
diff --git a/lisp/dired.el b/lisp/dired.el
index 854bc9f7d7..b0d40da57f 100644
--- a/lisp/dired.el
+++ b/lisp/dired.el
@@ -185,9 +185,9 @@ 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 one of recently
+selected windows, use its current directory, instead of this Dired
+buffer's current directory.
The target is used in the prompt for file copy, rename etc."
:type 'boolean