[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
dired-dwim-target (was: FFAP)
From: |
Juri Linkov |
Subject: |
dired-dwim-target (was: FFAP) |
Date: |
Sun, 15 Nov 2009 17:12:32 +0200 |
User-agent: |
Gnus/5.13 (Gnus v5.13) Emacs/23.1.50 (x86_64-pc-linux-gnu) |
The first thing I have to do when using Dired in pristine Emacs without
.emacs is to type `M-x set-variable RET dired-dwim-target RET t RET'
because without dired-dwim-target = t Dired is helpless to me.
By default Dired operations provide the following minibuffer
default values (0. means initial input, and 1. - minibuffer's
contents after one M-n):
0. current directory name
1. file name from the current Dired line
However, when there is another Dired window on the same frame, there is
no easy way to copy/rename a file to it. When `dired-dwim-target' is t,
then the default values are:
0. other directory name
1. file name from the other directory
This is better for copying/renaming to another directory, but still
inconvenient for copying/renaming in the current directory. This
requires deleting all other Dired windows to force it showing the
default with the current directory name.
The solution is simple: provide both the current and other
directory names as default values. The following patch keeps
the old behavior when there is one Dired window:
0. current directory name
1. file name from the current Dired line
but with more Dired windows it provides more default values:
0. current directory name
1. other directory name
2. file name from the other directory
3. file name from the current Dired line
When there are more than one marked file:
0. current directory name
1. other directory name
When `dired-dwim-target' is t (whose only purpose now will be
to show the other directory name as initial input, but with
`dired-dwim-target' = nil the same will be easily achievable via M-n):
0. other directory name
1. current directory name
2. file name from the current Dired line
3. file name from the other directory
When there are more than one marked file:
0. other directory name
1. current directory name
Actually in the following patch after reaching the end of the
aforementioned lists prepared in `dired-do-create-files-defaults',
the function `read-file-name-defaults' starts adding more items
guessed from the content of the Dired buffer. But perhaps this
is not too useful. If so, this can be easily disabled by
setting `minibuffer-default-add-function' to nil in
`dired-do-create-files' (currently commented out).
Index: lisp/dired-aux.el
===================================================================
RCS file: /sources/emacs/emacs/lisp/dired-aux.el,v
retrieving revision 1.197
diff -c -r1.197 dired-aux.el
*** lisp/dired-aux.el 13 Nov 2009 22:19:50 -0000 1.197
--- lisp/dired-aux.el 15 Nov 2009 15:12:05 -0000
***************
*** 1463,1471 ****
(expand-file-name (file-name-nondirectory (car fn-list))
target-dir)))
(target (expand-file-name ; fluid variable inside dired-create-files
! (dired-mark-read-file-name
! (concat (if dired-one-file op1 operation) " %s to: ")
! target-dir op-symbol arg rfn-list default)))
(into-dir (cond ((null how-to)
;; Allow DOS/Windows users to change the letter
;; case of a directory. If we don't test these
--- 1463,1477 ----
(expand-file-name (file-name-nondirectory (car fn-list))
target-dir)))
(target (expand-file-name ; fluid variable inside dired-create-files
! (minibuffer-with-setup-hook
! (lambda ()
! ;; (set (make-local-variable
'minibuffer-default-add-function) nil)
! (setq minibuffer-default
! (dired-do-create-files-defaults
! fn-list target-dir)))
! (dired-mark-read-file-name
! (concat (if dired-one-file op1 operation) " %s to: ")
! target-dir op-symbol arg rfn-list default))))
(into-dir (cond ((null how-to)
;; Allow DOS/Windows users to change the letter
;; case of a directory. If we don't test these
***************
*** 1520,1525 ****
--- 1526,1568 ----
(function read-file-name)
(format prompt (dired-mark-prompt arg files)) dir default))
+ (defun dired-do-create-files-defaults (fn-list target-dir)
+ ;; Return a list of default values for `dired-do-create-files-defaults'.
+ (let (target-dirs)
+ ;; Get a list of directories of visible buffers in dired-mode.
+ (walk-windows (lambda (w)
+ (with-current-buffer (window-buffer w)
+ (when (eq major-mode 'dired-mode)
+ (push default-directory target-dirs)))))
+ ;; Return default values.
+ (cond
+ (dired-dwim-target
+ (setq target-dirs (delete target-dir target-dirs))
+ (if dired-one-file
+ (append target-dirs
+ (mapcar (lambda (dir)
+ (expand-file-name
+ (file-name-nondirectory (car fn-list))
+ dir))
+ (reverse target-dirs))
+ (list (expand-file-name
+ (file-name-nondirectory (car fn-list))
+ dir)))
+ target-dirs))
+ (t
+ (setq target-dirs (delete default-directory target-dirs))
+ (if dired-one-file
+ (append target-dirs
+ (mapcar (lambda (dir)
+ (expand-file-name
+ (file-name-nondirectory (car fn-list))
+ dir))
+ (reverse target-dirs))
+ (list (expand-file-name
+ (file-name-nondirectory (car fn-list))
+ target-dir)))
+ target-dirs)))))
+
(defun dired-dwim-target-directory ()
;; Try to guess which target directory the user may want.
;; If there is a dired buffer displayed in the next window, use
Index: lisp/minibuffer.el
===================================================================
RCS file: /sources/emacs/emacs/lisp/minibuffer.el,v
retrieving revision 1.96
diff -c -r1.96 minibuffer.el
*** lisp/minibuffer.el 12 Nov 2009 23:10:06 -0000 1.96
--- lisp/minibuffer.el 15 Nov 2009 15:11:14 -0000
***************
*** 1253,1258 ****
--- 1253,1310 ----
;; Not always defined, but only called if next-read-file-uses-dialog-p says
so.
(declare-function x-file-dialog "xfns.c"
(prompt dir &optional default-filename mustmatch
only-dir-p))
+ (declare-function dired-get-filename "dired" (&optional localp
no-error-if-not-filep))
+
+ (defun read-file-name-defaults (&optional dir initial)
+ (let ((default
+ (cond
+ ;; With non-nil `initial', use `dir' as the first default.
+ ;; Essentially, this mean reversing the normal order of the
+ ;; current directory name and the current file name, i.e.
+ ;; 1. with normal file reading:
+ ;; 1.1. initial input is the current directory
+ ;; 1.2. the first default is the current file name
+ ;; 2. with non-nil `initial' (for `find-alternate-file'):
+ ;; 2.2. initial input is the current file name
+ ;; 2.1. the first default is the current directory
+ (initial (abbreviate-file-name dir))
+ ;; In file buffers, try to get the current file name
+ (buffer-file-name
+ (abbreviate-file-name buffer-file-name))
+ ;; In Dired, get file name from the current line.
+ ((eq major-mode 'dired-mode)
+ (let ((filename (dired-get-filename nil t)))
+ (when filename
+ (if (file-directory-p filename)
+ (file-name-as-directory (abbreviate-file-name filename))
+ (abbreviate-file-name filename)))))))
+ (filename-at-point
+ (cond
+ ((fboundp 'ffap-guesser)
+ ;; Logic from `ffap-read-file-or-url' and `dired-at-point-prompter'
+ (let ((guess (ffap-guesser)))
+ (setq guess
+ (if (or (not guess)
+ (and (fboundp 'ffap-url-p)
+ (ffap-url-p guess))
+ (and (fboundp 'ffap-file-remote-p)
+ (ffap-file-remote-p guess)))
+ guess
+ (abbreviate-file-name (expand-file-name guess))))
+ (when guess
+ (if (file-directory-p guess)
+ (file-name-as-directory guess)
+ guess))))
+ ;; ((fboundp 'thing-at-point)
+ ;; (thing-at-point 'filename))
+ )))
+ (when filename-at-point
+ (setq default (delete-dups
+ (delete "" (delq nil (list filename-at-point default))))))
+ ;; Append new default values to the end of existing `minibuffer-default'
+ (append
+ (if (listp minibuffer-default) minibuffer-default (list
minibuffer-default))
+ (if (listp default) default (list default)))))
(defun read-file-name (prompt &optional dir default-filename mustmatch
initial predicate)
"Read file name, prompting with PROMPT and completing in directory DIR.
***************
*** 1337,1343 ****
(lexical-let ((dir (file-name-as-directory
(expand-file-name dir))))
(minibuffer-with-setup-hook
! (lambda () (setq default-directory dir))
(completing-read prompt 'read-file-name-internal
pred mustmatch insdef
'file-name-history
default-filename)))
--- 1389,1409 ----
(lexical-let ((dir (file-name-as-directory
(expand-file-name dir))))
(minibuffer-with-setup-hook
! (lambda ()
! (setq default-directory dir)
! ;; Unless a list of default values is provided,
! ;; reset `minibuffer-default' to nil and on the
! ;; first request on `M-n' fill it with a list of
! ;; default values relevant for file-name reading.
! (unless (consp default-filename)
! (setq minibuffer-default nil)
! (set (make-local-variable
'minibuffer-default-add-function)
! (lambda ()
! (message "Original buffer: %S"
! (window-buffer
(minibuffer-selected-window)))
! (with-current-buffer
! (window-buffer
(minibuffer-selected-window))
! (read-file-name-defaults dir
initial))))))
(completing-read prompt 'read-file-name-internal
pred mustmatch insdef
'file-name-history
default-filename)))
--
Juri Linkov
http://www.jurta.org/emacs/
- Re: find-file-read-args, (continued)
- find-file-literally (was: find-file-read-args), Juri Linkov, 2009/11/23
- Re: find-file-literally, Stefan Monnier, 2009/11/24
- M-! M-n should fetch filename (Re: FFAP), Juri Linkov, 2009/11/09
- Re: M-! M-n should fetch filename (Re: FFAP), Stefan Monnier, 2009/11/09
- Re: M-! M-n should fetch filename (Re: FFAP), Juri Linkov, 2009/11/09
- Re: M-! M-n should fetch filename (Re: FFAP), Stefan Monnier, 2009/11/10
- Re: M-! M-n should fetch filename (Re: FFAP), Juri Linkov, 2009/11/10
- dired-dwim-target (was: FFAP),
Juri Linkov <=
- dired-dwim-target-defaults (was: dired-dwim-target), Juri Linkov, 2009/11/23
Re: find-file-literally-at-point, Juri Linkov, 2009/11/08
utf-8-with-signature (was: find-file-literally-at-point), Juri Linkov, 2009/11/09
Re: find-file-literally-at-point, Eduard Wiebe, 2009/11/06