aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJuri Linkov2009-11-25 17:11:29 +0000
committerJuri Linkov2009-11-25 17:11:29 +0000
commit7d371eac644665cdc4afcac57e7a09560e010a31 (patch)
tree668947c7530c04603a2a5372cc13156c4f96ad0e
parent04ae543a28153fda0c084a5d56f59e2f7b12510d (diff)
downloademacs-7d371eac644665cdc4afcac57e7a09560e010a31.tar.gz
emacs-7d371eac644665cdc4afcac57e7a09560e010a31.zip
Provide additional default values (file name at point or at the
current Dired line) via M-n for file reading minibuffers. (Bug#5010) * minibuffer.el (read-file-name-defaults): New function. (read-file-name): Reset `minibuffer-default' to nil when it duplicates initial input `insdef'. Bind `minibuffer-default-add-function' to lambda that calls `read-file-name-defaults' in `minibuffer-selected-window'. (minibuffer-insert-file-name-at-point): New command. * files.el (file-name-at-point-functions): New defcustom. (find-file-default): Remove defvar. (find-file-read-args): Don't use `find-file-default'. Move `minibuffer-with-setup-hook' that sets `minibuffer-default' to `read-file-name'. (find-file-literally): Use `read-file-name' with `confirm-nonexistent-file-or-buffer'. * ffap.el (ffap-guess-file-name-at-point): New autoloaded function. * dired.el (dired-read-dir-and-switches): Move `minibuffer-with-setup-hook' that sets `minibuffer-default' to `read-file-name'. (dired-file-name-at-point): New function. (dired-mode): Add hook `dired-file-name-at-point' to `file-name-at-point-functions'.
-rw-r--r--etc/NEWS4
-rw-r--r--lisp/ChangeLog29
-rw-r--r--lisp/dired.el18
-rw-r--r--lisp/ffap.el23
-rw-r--r--lisp/files.el23
-rw-r--r--lisp/minibuffer.el56
6 files changed, 136 insertions, 17 deletions
diff --git a/etc/NEWS b/etc/NEWS
index 51c3ee62a60..58ff7c6705f 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -150,6 +150,10 @@ For instance, this can complete M-x lch to list-command-history.
150** Completions in the *Completions* buffer are sorted vertically 150** Completions in the *Completions* buffer are sorted vertically
151when the value of the new variable `completions-format' is `vertical'. 151when the value of the new variable `completions-format' is `vertical'.
152 152
153** M-n provides more default values in the minibuffer of commands that
154read a file and directory name: a file name at point (when ffap is loaded
155without ffap-bindings), a file name on the current line in the Dired buffer.
156
153** M-r is bound to the new `move-to-window-line-top-bottom' 157** M-r is bound to the new `move-to-window-line-top-bottom'
154to mirror the new behavior of C-l in Emacs-23.1. 158to mirror the new behavior of C-l in Emacs-23.1.
155 159
diff --git a/lisp/ChangeLog b/lisp/ChangeLog
index 3f392f8183e..5c7d0a1e25d 100644
--- a/lisp/ChangeLog
+++ b/lisp/ChangeLog
@@ -1,3 +1,32 @@
12009-11-25 Juri Linkov <juri@jurta.org>
2
3 Provide additional default values (file name at point or at the
4 current Dired line) via M-n for file reading minibuffers. (Bug#5010)
5
6 * minibuffer.el (read-file-name-defaults): New function.
7 (read-file-name): Reset `minibuffer-default' to nil when
8 it duplicates initial input `insdef'.
9 Bind `minibuffer-default-add-function' to lambda that
10 calls `read-file-name-defaults' in `minibuffer-selected-window'.
11 (minibuffer-insert-file-name-at-point): New command.
12
13 * files.el (file-name-at-point-functions): New defcustom.
14 (find-file-default): Remove defvar.
15 (find-file-read-args): Don't use `find-file-default'.
16 Move `minibuffer-with-setup-hook' that sets `minibuffer-default'
17 to `read-file-name'.
18 (find-file-literally): Use `read-file-name' with
19 `confirm-nonexistent-file-or-buffer'.
20
21 * ffap.el (ffap-guess-file-name-at-point): New autoloaded function.
22
23 * dired.el (dired-read-dir-and-switches):
24 Move `minibuffer-with-setup-hook' that sets `minibuffer-default'
25 to `read-file-name'.
26 (dired-file-name-at-point): New function.
27 (dired-mode): Add hook `dired-file-name-at-point' to
28 `file-name-at-point-functions'.
29
12009-11-25 Stefan Monnier <monnier@iro.umontreal.ca> 302009-11-25 Stefan Monnier <monnier@iro.umontreal.ca>
2 31
3 Really make the *Completions* window soft-dedicated (bug#5030). 32 Really make the *Completions* window soft-dedicated (bug#5030).
diff --git a/lisp/dired.el b/lisp/dired.el
index 788c5be3289..17bb3449da9 100644
--- a/lisp/dired.el
+++ b/lisp/dired.el
@@ -599,12 +599,8 @@ Don't use that together with FILTER."
599 (if (next-read-file-uses-dialog-p) 599 (if (next-read-file-uses-dialog-p)
600 (read-directory-name (format "Dired %s(directory): " str) 600 (read-directory-name (format "Dired %s(directory): " str)
601 nil default-directory nil) 601 nil default-directory nil)
602 (let ((default (and buffer-file-name 602 (read-file-name (format "Dired %s(directory): " str)
603 (abbreviate-file-name buffer-file-name)))) 603 nil default-directory nil)))))
604 (minibuffer-with-setup-hook
605 (lambda () (setq minibuffer-default default))
606 (read-file-name (format "Dired %s(directory): " str)
607 nil default-directory nil)))))))
608 604
609;; We want to switch to a more sophisticated version of 605;; We want to switch to a more sophisticated version of
610;; dired-read-dir-and-switches like the following, if there is a way 606;; dired-read-dir-and-switches like the following, if there is a way
@@ -659,6 +655,15 @@ Don't use that together with FILTER."
659;; (read-file-name (format "Dired %s(directory): " str) 655;; (read-file-name (format "Dired %s(directory): " str)
660;; nil default-directory nil)))))))) 656;; nil default-directory nil))))))))
661 657
658(defun dired-file-name-at-point ()
659 "Try to get a file name at point in the current dired buffer.
660This hook is inteneded to be put in `file-name-at-point-functions'."
661 (let ((filename (dired-get-filename nil t)))
662 (when filename
663 (if (file-directory-p filename)
664 (file-name-as-directory (abbreviate-file-name filename))
665 (abbreviate-file-name filename)))))
666
662;;;###autoload (define-key ctl-x-map "d" 'dired) 667;;;###autoload (define-key ctl-x-map "d" 'dired)
663;;;###autoload 668;;;###autoload
664(defun dired (dirname &optional switches) 669(defun dired (dirname &optional switches)
@@ -1772,6 +1777,7 @@ Keybindings:
1772 (when (featurep 'dnd) 1777 (when (featurep 'dnd)
1773 (set (make-local-variable 'dnd-protocol-alist) 1778 (set (make-local-variable 'dnd-protocol-alist)
1774 (append dired-dnd-protocol-alist dnd-protocol-alist))) 1779 (append dired-dnd-protocol-alist dnd-protocol-alist)))
1780 (add-hook 'file-name-at-point-functions 'dired-file-name-at-point nil t)
1775 (add-hook 'isearch-mode-hook 'dired-isearch-filenames-setup nil t) 1781 (add-hook 'isearch-mode-hook 'dired-isearch-filenames-setup nil t)
1776 (run-mode-hooks 'dired-mode-hook)) 1782 (run-mode-hooks 'dired-mode-hook))
1777 1783
diff --git a/lisp/ffap.el b/lisp/ffap.el
index a0e0d411206..7d3f279f724 100644
--- a/lisp/ffap.el
+++ b/lisp/ffap.el
@@ -1893,6 +1893,29 @@ Only intended for interactive use."
1893 (call-interactively 'dired-at-point))) 1893 (call-interactively 'dired-at-point)))
1894 1894
1895 1895
1896;;; Hooks to put in `file-name-at-point-functions':
1897
1898;;;###autoload
1899(progn (defun ffap-guess-file-name-at-point ()
1900 "Try to get a file name at point.
1901This hook is inteneded to be put in `file-name-at-point-functions'."
1902 (when (fboundp 'ffap-guesser)
1903 ;; Logic from `ffap-read-file-or-url' and `dired-at-point-prompter'.
1904 (let ((guess (ffap-guesser)))
1905 (setq guess
1906 (if (or (not guess)
1907 (and (fboundp 'ffap-url-p)
1908 (ffap-url-p guess))
1909 (and (fboundp 'ffap-file-remote-p)
1910 (ffap-file-remote-p guess)))
1911 guess
1912 (abbreviate-file-name (expand-file-name guess))))
1913 (when guess
1914 (if (file-directory-p guess)
1915 (file-name-as-directory guess)
1916 guess))))))
1917
1918
1896;;; Offer default global bindings (`ffap-bindings'): 1919;;; Offer default global bindings (`ffap-bindings'):
1897 1920
1898(defvar ffap-bindings 1921(defvar ffap-bindings
diff --git a/lisp/files.el b/lisp/files.el
index 1bde2be0ef0..8478151cf78 100644
--- a/lisp/files.el
+++ b/lisp/files.el
@@ -411,6 +411,14 @@ and should return either a buffer or nil."
411 :type '(hook :options (cvs-dired-noselect dired-noselect)) 411 :type '(hook :options (cvs-dired-noselect dired-noselect))
412 :group 'find-file) 412 :group 'find-file)
413 413
414;; FIXME: also add a hook for `(thing-at-point 'filename)'
415(defcustom file-name-at-point-functions '(ffap-guess-file-name-at-point)
416 "List of functions to try in sequence to get a file name at point.
417Each function should return either nil or a file name found at the
418location of point in the current buffer."
419 :type '(hook :options (ffap-guess-file-name-at-point))
420 :group 'find-file)
421
414;;;It is not useful to make this a local variable. 422;;;It is not useful to make this a local variable.
415;;;(put 'find-file-not-found-hooks 'permanent-local t) 423;;;(put 'find-file-not-found-hooks 'permanent-local t)
416(defvar find-file-not-found-functions nil 424(defvar find-file-not-found-functions nil
@@ -1275,9 +1283,6 @@ its documentation for additional customization information."
1275 ;;(make-frame-visible (window-frame old-window)) 1283 ;;(make-frame-visible (window-frame old-window))
1276 )) 1284 ))
1277 1285
1278(defvar find-file-default nil
1279 "Used within `find-file-read-args'.")
1280
1281(defmacro minibuffer-with-setup-hook (fun &rest body) 1286(defmacro minibuffer-with-setup-hook (fun &rest body)
1282 "Add FUN to `minibuffer-setup-hook' while executing BODY. 1287 "Add FUN to `minibuffer-setup-hook' while executing BODY.
1283BODY should use the minibuffer at most once. 1288BODY should use the minibuffer at most once.
@@ -1298,12 +1303,7 @@ Recursive uses of the minibuffer will not be affected."
1298 (remove-hook 'minibuffer-setup-hook ,hook))))) 1303 (remove-hook 'minibuffer-setup-hook ,hook)))))
1299 1304
1300(defun find-file-read-args (prompt mustmatch) 1305(defun find-file-read-args (prompt mustmatch)
1301 (list (let ((find-file-default 1306 (list (read-file-name prompt nil default-directory mustmatch)
1302 (and buffer-file-name
1303 (abbreviate-file-name buffer-file-name))))
1304 (minibuffer-with-setup-hook
1305 (lambda () (setq minibuffer-default find-file-default))
1306 (read-file-name prompt nil default-directory mustmatch)))
1307 t)) 1307 t))
1308 1308
1309(defun find-file (filename &optional wildcards) 1309(defun find-file (filename &optional wildcards)
@@ -2020,7 +2020,10 @@ regardless of whether it was created literally or not.
2020In a Lisp program, if you want to be sure of accessing a file's 2020In a Lisp program, if you want to be sure of accessing a file's
2021contents literally, you should create a temporary buffer and then read 2021contents literally, you should create a temporary buffer and then read
2022the file contents into it using `insert-file-contents-literally'." 2022the file contents into it using `insert-file-contents-literally'."
2023 (interactive "FFind file literally: ") 2023 (interactive
2024 (list (read-file-name
2025 "Find file literally: " nil default-directory
2026 (confirm-nonexistent-file-or-buffer))))
2024 (switch-to-buffer (find-file-noselect filename nil t))) 2027 (switch-to-buffer (find-file-noselect filename nil t)))
2025 2028
2026(defvar after-find-file-from-revert-buffer nil) 2029(defvar after-find-file-from-revert-buffer nil)
diff --git a/lisp/minibuffer.el b/lisp/minibuffer.el
index fdf57f9a2f8..cfe4d6f90de 100644
--- a/lisp/minibuffer.el
+++ b/lisp/minibuffer.el
@@ -1321,6 +1321,32 @@ such as making the current buffer visit no file in the case of
1321(declare-function x-file-dialog "xfns.c" 1321(declare-function x-file-dialog "xfns.c"
1322 (prompt dir &optional default-filename mustmatch only-dir-p)) 1322 (prompt dir &optional default-filename mustmatch only-dir-p))
1323 1323
1324(defun read-file-name-defaults (&optional dir initial)
1325 (let ((default
1326 (cond
1327 ;; With non-nil `initial', use `dir' as the first default.
1328 ;; Essentially, this mean reversing the normal order of the
1329 ;; current directory name and the current file name, i.e.
1330 ;; 1. with normal file reading:
1331 ;; 1.1. initial input is the current directory
1332 ;; 1.2. the first default is the current file name
1333 ;; 2. with non-nil `initial' (e.g. for `find-alternate-file'):
1334 ;; 2.2. initial input is the current file name
1335 ;; 2.1. the first default is the current directory
1336 (initial (abbreviate-file-name dir))
1337 ;; In file buffers, try to get the current file name
1338 (buffer-file-name
1339 (abbreviate-file-name buffer-file-name))))
1340 (file-name-at-point
1341 (run-hook-with-args-until-success 'file-name-at-point-functions)))
1342 (when file-name-at-point
1343 (setq default (delete-dups
1344 (delete "" (delq nil (list file-name-at-point default))))))
1345 ;; Append new defaults to the end of existing `minibuffer-default'.
1346 (append
1347 (if (listp minibuffer-default) minibuffer-default (list minibuffer-default))
1348 (if (listp default) default (list default)))))
1349
1324(defun read-file-name (prompt &optional dir default-filename mustmatch initial predicate) 1350(defun read-file-name (prompt &optional dir default-filename mustmatch initial predicate)
1325 "Read file name, prompting with PROMPT and completing in directory DIR. 1351 "Read file name, prompting with PROMPT and completing in directory DIR.
1326Value is not expanded---you must call `expand-file-name' yourself. 1352Value is not expanded---you must call `expand-file-name' yourself.
@@ -1404,7 +1430,24 @@ and `read-file-name-function'."
1404 (lexical-let ((dir (file-name-as-directory 1430 (lexical-let ((dir (file-name-as-directory
1405 (expand-file-name dir)))) 1431 (expand-file-name dir))))
1406 (minibuffer-with-setup-hook 1432 (minibuffer-with-setup-hook
1407 (lambda () (setq default-directory dir)) 1433 (lambda ()
1434 (setq default-directory dir)
1435 ;; When the first default in `minibuffer-default'
1436 ;; duplicates initial input `insdef',
1437 ;; reset `minibuffer-default' to nil.
1438 (when (equal (or (car-safe insdef) insdef)
1439 (or (car-safe minibuffer-default)
1440 minibuffer-default))
1441 (setq minibuffer-default
1442 (cdr-safe minibuffer-default)))
1443 ;; On the first request on `M-n' fill
1444 ;; `minibuffer-default' with a list of defaults
1445 ;; relevant for file-name reading.
1446 (set (make-local-variable 'minibuffer-default-add-function)
1447 (lambda ()
1448 (with-current-buffer
1449 (window-buffer (minibuffer-selected-window))
1450 (read-file-name-defaults dir initial)))))
1408 (completing-read prompt 'read-file-name-internal 1451 (completing-read prompt 'read-file-name-internal
1409 pred mustmatch insdef 1452 pred mustmatch insdef
1410 'file-name-history default-filename))) 1453 'file-name-history default-filename)))
@@ -1997,6 +2040,17 @@ filter out additional entries (because TABLE migth not obey PRED)."
1997 (when newstr 2040 (when newstr
1998 (completion-pcm-try-completion newstr table pred (length newstr))))) 2041 (completion-pcm-try-completion newstr table pred (length newstr)))))
1999 2042
2043
2044;; Miscellaneous
2045
2046(defun minibuffer-insert-file-name-at-point ()
2047 "Get a file name at point in original buffer and insert it to minibuffer."
2048 (interactive)
2049 (let ((file-name-at-point
2050 (with-current-buffer (window-buffer (minibuffer-selected-window))
2051 (run-hook-with-args-until-success 'file-name-at-point-functions))))
2052 (when file-name-at-point
2053 (insert file-name-at-point))))
2000 2054
2001(provide 'minibuffer) 2055(provide 'minibuffer)
2002 2056