mirror of
https://git.savannah.gnu.org/git/emacs.git
synced 2024-11-27 07:37:33 +00:00
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'.
This commit is contained in:
parent
04ae543a28
commit
7d371eac64
4
etc/NEWS
4
etc/NEWS
@ -150,6 +150,10 @@ For instance, this can complete M-x lch to list-command-history.
|
||||
** Completions in the *Completions* buffer are sorted vertically
|
||||
when the value of the new variable `completions-format' is `vertical'.
|
||||
|
||||
** M-n provides more default values in the minibuffer of commands that
|
||||
read a file and directory name: a file name at point (when ffap is loaded
|
||||
without ffap-bindings), a file name on the current line in the Dired buffer.
|
||||
|
||||
** M-r is bound to the new `move-to-window-line-top-bottom'
|
||||
to mirror the new behavior of C-l in Emacs-23.1.
|
||||
|
||||
|
@ -1,3 +1,32 @@
|
||||
2009-11-25 Juri Linkov <juri@jurta.org>
|
||||
|
||||
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'.
|
||||
|
||||
2009-11-25 Stefan Monnier <monnier@iro.umontreal.ca>
|
||||
|
||||
Really make the *Completions* window soft-dedicated (bug#5030).
|
||||
|
@ -599,12 +599,8 @@ Don't use that together with FILTER."
|
||||
(if (next-read-file-uses-dialog-p)
|
||||
(read-directory-name (format "Dired %s(directory): " str)
|
||||
nil default-directory nil)
|
||||
(let ((default (and buffer-file-name
|
||||
(abbreviate-file-name buffer-file-name))))
|
||||
(minibuffer-with-setup-hook
|
||||
(lambda () (setq minibuffer-default default))
|
||||
(read-file-name (format "Dired %s(directory): " str)
|
||||
nil default-directory nil)))))))
|
||||
(read-file-name (format "Dired %s(directory): " str)
|
||||
nil default-directory nil)))))
|
||||
|
||||
;; We want to switch to a more sophisticated version of
|
||||
;; dired-read-dir-and-switches like the following, if there is a way
|
||||
@ -659,6 +655,15 @@ Don't use that together with FILTER."
|
||||
;; (read-file-name (format "Dired %s(directory): " str)
|
||||
;; nil default-directory nil))))))))
|
||||
|
||||
(defun dired-file-name-at-point ()
|
||||
"Try to get a file name at point in the current dired buffer.
|
||||
This hook is inteneded to be put in `file-name-at-point-functions'."
|
||||
(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)))))
|
||||
|
||||
;;;###autoload (define-key ctl-x-map "d" 'dired)
|
||||
;;;###autoload
|
||||
(defun dired (dirname &optional switches)
|
||||
@ -1772,6 +1777,7 @@ Keybindings:
|
||||
(when (featurep 'dnd)
|
||||
(set (make-local-variable 'dnd-protocol-alist)
|
||||
(append dired-dnd-protocol-alist dnd-protocol-alist)))
|
||||
(add-hook 'file-name-at-point-functions 'dired-file-name-at-point nil t)
|
||||
(add-hook 'isearch-mode-hook 'dired-isearch-filenames-setup nil t)
|
||||
(run-mode-hooks 'dired-mode-hook))
|
||||
|
||||
|
23
lisp/ffap.el
23
lisp/ffap.el
@ -1892,6 +1892,29 @@ Only intended for interactive use."
|
||||
(let ((ffap-directory-finder 'list-directory))
|
||||
(call-interactively 'dired-at-point)))
|
||||
|
||||
|
||||
;;; Hooks to put in `file-name-at-point-functions':
|
||||
|
||||
;;;###autoload
|
||||
(progn (defun ffap-guess-file-name-at-point ()
|
||||
"Try to get a file name at point.
|
||||
This hook is inteneded to be put in `file-name-at-point-functions'."
|
||||
(when (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))))))
|
||||
|
||||
|
||||
;;; Offer default global bindings (`ffap-bindings'):
|
||||
|
||||
|
@ -411,6 +411,14 @@ and should return either a buffer or nil."
|
||||
:type '(hook :options (cvs-dired-noselect dired-noselect))
|
||||
:group 'find-file)
|
||||
|
||||
;; FIXME: also add a hook for `(thing-at-point 'filename)'
|
||||
(defcustom file-name-at-point-functions '(ffap-guess-file-name-at-point)
|
||||
"List of functions to try in sequence to get a file name at point.
|
||||
Each function should return either nil or a file name found at the
|
||||
location of point in the current buffer."
|
||||
:type '(hook :options (ffap-guess-file-name-at-point))
|
||||
:group 'find-file)
|
||||
|
||||
;;;It is not useful to make this a local variable.
|
||||
;;;(put 'find-file-not-found-hooks 'permanent-local t)
|
||||
(defvar find-file-not-found-functions nil
|
||||
@ -1275,9 +1283,6 @@ its documentation for additional customization information."
|
||||
;;(make-frame-visible (window-frame old-window))
|
||||
))
|
||||
|
||||
(defvar find-file-default nil
|
||||
"Used within `find-file-read-args'.")
|
||||
|
||||
(defmacro minibuffer-with-setup-hook (fun &rest body)
|
||||
"Add FUN to `minibuffer-setup-hook' while executing BODY.
|
||||
BODY should use the minibuffer at most once.
|
||||
@ -1298,12 +1303,7 @@ Recursive uses of the minibuffer will not be affected."
|
||||
(remove-hook 'minibuffer-setup-hook ,hook)))))
|
||||
|
||||
(defun find-file-read-args (prompt mustmatch)
|
||||
(list (let ((find-file-default
|
||||
(and buffer-file-name
|
||||
(abbreviate-file-name buffer-file-name))))
|
||||
(minibuffer-with-setup-hook
|
||||
(lambda () (setq minibuffer-default find-file-default))
|
||||
(read-file-name prompt nil default-directory mustmatch)))
|
||||
(list (read-file-name prompt nil default-directory mustmatch)
|
||||
t))
|
||||
|
||||
(defun find-file (filename &optional wildcards)
|
||||
@ -2020,7 +2020,10 @@ regardless of whether it was created literally or not.
|
||||
In a Lisp program, if you want to be sure of accessing a file's
|
||||
contents literally, you should create a temporary buffer and then read
|
||||
the file contents into it using `insert-file-contents-literally'."
|
||||
(interactive "FFind file literally: ")
|
||||
(interactive
|
||||
(list (read-file-name
|
||||
"Find file literally: " nil default-directory
|
||||
(confirm-nonexistent-file-or-buffer))))
|
||||
(switch-to-buffer (find-file-noselect filename nil t)))
|
||||
|
||||
(defvar after-find-file-from-revert-buffer nil)
|
||||
|
@ -1321,6 +1321,32 @@ such as making the current buffer visit no file in the case of
|
||||
(declare-function x-file-dialog "xfns.c"
|
||||
(prompt dir &optional default-filename mustmatch only-dir-p))
|
||||
|
||||
(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' (e.g. 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))))
|
||||
(file-name-at-point
|
||||
(run-hook-with-args-until-success 'file-name-at-point-functions)))
|
||||
(when file-name-at-point
|
||||
(setq default (delete-dups
|
||||
(delete "" (delq nil (list file-name-at-point default))))))
|
||||
;; Append new defaults 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.
|
||||
Value is not expanded---you must call `expand-file-name' yourself.
|
||||
@ -1404,7 +1430,24 @@ and `read-file-name-function'."
|
||||
(lexical-let ((dir (file-name-as-directory
|
||||
(expand-file-name dir))))
|
||||
(minibuffer-with-setup-hook
|
||||
(lambda () (setq default-directory dir))
|
||||
(lambda ()
|
||||
(setq default-directory dir)
|
||||
;; When the first default in `minibuffer-default'
|
||||
;; duplicates initial input `insdef',
|
||||
;; reset `minibuffer-default' to nil.
|
||||
(when (equal (or (car-safe insdef) insdef)
|
||||
(or (car-safe minibuffer-default)
|
||||
minibuffer-default))
|
||||
(setq minibuffer-default
|
||||
(cdr-safe minibuffer-default)))
|
||||
;; On the first request on `M-n' fill
|
||||
;; `minibuffer-default' with a list of defaults
|
||||
;; relevant for file-name reading.
|
||||
(set (make-local-variable 'minibuffer-default-add-function)
|
||||
(lambda ()
|
||||
(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)))
|
||||
@ -1997,6 +2040,17 @@ filter out additional entries (because TABLE migth not obey PRED)."
|
||||
(when newstr
|
||||
(completion-pcm-try-completion newstr table pred (length newstr)))))
|
||||
|
||||
|
||||
;; Miscellaneous
|
||||
|
||||
(defun minibuffer-insert-file-name-at-point ()
|
||||
"Get a file name at point in original buffer and insert it to minibuffer."
|
||||
(interactive)
|
||||
(let ((file-name-at-point
|
||||
(with-current-buffer (window-buffer (minibuffer-selected-window))
|
||||
(run-hook-with-args-until-success 'file-name-at-point-functions))))
|
||||
(when file-name-at-point
|
||||
(insert file-name-at-point))))
|
||||
|
||||
(provide 'minibuffer)
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user