From: Juri Linkov <juri@jurta.org>
To: Stefan Monnier <monnier@IRO.UMontreal.CA>
Cc: martin rudalics <rudalics@gmx.at>, emacs-devel@gnu.org
Subject: Re: find-file-read-args
Date: Mon, 23 Nov 2009 23:17:36 +0200 [thread overview]
Message-ID: <87aaydrle7.fsf@mail.jurta.org> (raw)
In-Reply-To: <jwvbpithvd0.fsf-monnier+emacs@gnu.org> (Stefan Monnier's message of "Mon, 23 Nov 2009 15:17:57 -0500")
>>> so I'd like to understand how you reproduce it.
>
>> This can be reproduced by typing M-n in the minibuffer of commands
>> other than find-file-*, e.g. `insert-file', `append-to-file',
>> `write-file', `write-region', `load-file', `recode-file-name',
>> `make-directory', `delete-directory', `copy-directory'.
>
> I meant "how does your code reproduce the right behavior for C-x C-f".
Ah. It reproduces the right behavior for C-x C-f by moving the logic of
setting minibuffer-default from `find-file-read-args' to `read-file-name'.
> But I think I'm beginning to understand why it works.
>
>>>> + ((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)))))))
>>> This is ugly. Why does it have to be here rather than somewhere in dired?
>> I can't find a function in dired.el and dired-aux.el that uses
>> `abbreviate-file-name' necessary for the minibuffer reading a file name.
>
> We must be miscommunicating: I don't want to have dired-specific code
> (including no test for (eq major-mode 'dired-mode)) in read-file-name,
> because it's ugly. Can't the same behavior be obtained by changing some
> code in dired rather than in minibuffer.el?
I have no idea how to get rid of `dired-get-filename'.
Grepping for `dired-get-filename' in the source tree shows that
there are many packages not directly related to Dired that call
`dired-get-filename'.
>> OK, I'll create a new function that could later be bound to a dedicated key.
>
> Thanks. Tho it doesn't need to be a command (e.g. that function
> shouldn't want to insert anything into the buffer, so it'll probably be
> better to have a separate command, unless we want to rely on
> called-interactively-p).
Please see `minibuffer-insert-file-name-at-point' below.
>> I'll try to better detect this situation than checking for a cons.
>
> Yes, I think your solution is at least as good as the previous one.
> But please check explicitly for "default == initial input", that will
> make the code both safer and easier to understand.
Done below.
Index: lisp/files.el
===================================================================
RCS file: /sources/emacs/emacs/lisp/files.el,v
retrieving revision 1.1101
diff -c -r1.1101 files.el
*** lisp/files.el 13 Nov 2009 22:19:51 -0000 1.1101
--- lisp/files.el 23 Nov 2009 21:14:12 -0000
***************
*** 411,416 ****
--- 411,424 ----
:type '(hook :options (cvs-dired-noselect dired-noselect))
:group 'find-file)
+ (defcustom file-name-at-point-functions '(ffap-guess-file-name-at-point)
+ "List of functions to try in sequence to get the 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,1283 ****
;;(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.
--- 1283,1288 ----
***************
*** 1298,1309 ****
(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)))
t))
(defun find-file (filename &optional wildcards)
--- 1303,1309 ----
(remove-hook 'minibuffer-setup-hook ,hook)))))
(defun find-file-read-args (prompt mustmatch)
! (list (read-file-name prompt nil default-directory mustmatch)
t))
(defun find-file (filename &optional wildcards)
Index: lisp/ffap.el
===================================================================
RCS file: /sources/emacs/emacs/lisp/ffap.el,v
retrieving revision 1.87
diff -c -r1.87 ffap.el
*** lisp/ffap.el 12 Nov 2009 10:41:53 -0000 1.87
--- lisp/ffap.el 23 Nov 2009 21:15:00 -0000
***************
*** 1893,1898 ****
--- 1893,1921 ----
(call-interactively 'dired-at-point)))
\f
+ ;;; 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))))))
+
+ \f
;;; Offer default global bindings (`ffap-bindings'):
(defvar ffap-bindings
Index: lisp/minibuffer.el
===================================================================
RCS file: /sources/emacs/emacs/lisp/minibuffer.el,v
retrieving revision 1.99
diff -c -r1.99 minibuffer.el
*** lisp/minibuffer.el 19 Nov 2009 22:05:42 -0000 1.99
--- lisp/minibuffer.el 23 Nov 2009 21:15:32 -0000
***************
*** 1320,1325 ****
--- 1320,1359 ----
;; 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)))))))
+ (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.
***************
*** 1404,1410 ****
(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)))
--- 1438,1459 ----
(lexical-let ((dir (file-name-as-directory
(expand-file-name dir))))
(minibuffer-with-setup-hook
! (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 nil))
! ;; 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,2002 ****
--- 2046,2062 ----
(when newstr
(completion-pcm-try-completion newstr table pred (length newstr)))))
+ \f
+ ;; Miscellaneous
+
+ (defun minibuffer-insert-file-name-at-point ()
+ "Get a file name from original buffer and insert it to the 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)
--
Juri Linkov
http://www.jurta.org/emacs/
next prev parent reply other threads:[~2009-11-23 21:17 UTC|newest]
Thread overview: 55+ messages / expand[flat|nested] mbox.gz Atom feed top
2009-11-06 0:13 find-file-literally-at-point Edward O'Connor
2009-11-06 1:45 ` find-file-literally-at-point Juri Linkov
2009-11-06 4:20 ` FFAP (was: find-file-literally-at-point) Stefan Monnier
2009-11-06 4:41 ` FFAP Miles Bader
2009-11-06 15:20 ` FFAP Stefan Monnier
2009-11-06 4:45 ` FFAP Juri Linkov
2009-11-06 8:50 ` FFAP Eli Zaretskii
2009-11-06 10:37 ` FFAP Juri Linkov
2009-11-06 15:18 ` FFAP Stefan Monnier
2009-11-06 21:19 ` FFAP Juri Linkov
2009-11-07 1:32 ` FFAP Stefan Monnier
2009-11-09 0:52 ` FFAP Juri Linkov
2009-11-09 6:33 ` FFAP Stefan Monnier
2009-11-09 10:09 ` find-file-read-args (was: FFAP) Juri Linkov
2009-11-09 14:28 ` find-file-read-args Stefan Monnier
2009-11-10 0:57 ` find-file-read-args Juri Linkov
2009-11-12 9:56 ` find-file-read-args Juri Linkov
2009-11-12 10:45 ` find-file-read-args martin rudalics
2009-11-12 10:51 ` find-file-read-args Juri Linkov
2009-11-15 15:09 ` find-file-read-args Juri Linkov
2009-11-15 17:28 ` find-file-read-args martin rudalics
2009-11-16 1:23 ` find-file-read-args Stefan Monnier
2009-11-17 7:43 ` find-file-read-args martin rudalics
2009-11-17 9:59 ` find-file-read-args Juri Linkov
2009-11-17 17:42 ` dired-dwim-target-directory (was: find-file-read-args) Juri Linkov
2009-11-17 17:43 ` Juri Linkov
2009-11-23 4:19 ` find-file-read-args Stefan Monnier
2009-11-23 9:59 ` find-file-read-args Juri Linkov
2009-11-23 20:17 ` find-file-read-args Stefan Monnier
2009-11-23 21:17 ` Juri Linkov [this message]
2009-11-24 2:33 ` find-file-read-args Stefan Monnier
2009-11-24 17:08 ` find-file-read-args Juri Linkov
2009-11-24 19:40 ` find-file-read-args Stefan Monnier
2009-11-23 21:17 ` find-file-literally (was: find-file-read-args) Juri Linkov
2009-11-25 2:10 ` find-file-literally Stefan Monnier
2009-11-09 10:14 ` read-file-name (was: FFAP) Juri Linkov
2009-11-09 14:31 ` read-file-name Stefan Monnier
2009-11-10 0:55 ` read-file-name Juri Linkov
2009-11-10 17:25 ` read-file-name Stefan Monnier
2009-11-09 10:30 ` dired-read-dir-and-switches (was: FFAP) Juri Linkov
2009-11-09 10:36 ` M-! M-n should fetch filename (Re: FFAP) Juri Linkov
2009-11-09 14:35 ` Stefan Monnier
2009-11-10 0:59 ` Juri Linkov
2009-11-10 17:29 ` Stefan Monnier
2009-11-11 0:12 ` Juri Linkov
2009-11-15 15:12 ` dired-dwim-target (was: FFAP) Juri Linkov
2009-11-23 21:12 ` dired-dwim-target-defaults (was: dired-dwim-target) Juri Linkov
2009-11-09 0:44 ` find-file-literally-at-point Juri Linkov
2009-11-09 2:00 ` find-file-literally-at-point Miles Bader
2009-11-09 2:11 ` find-file-literally-at-point Juri Linkov
2009-11-10 0:49 ` find-file-literally-at-point Juri Linkov
2009-11-09 10:01 ` utf-8-with-signature (was: find-file-literally-at-point) Juri Linkov
2009-11-06 10:20 ` find-file-literally-at-point Eduard Wiebe
2009-11-09 0:55 ` find-file-literally-at-point Juri Linkov
2009-11-09 19:49 ` find-file-literally-at-point Eduard Wiebe
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=87aaydrle7.fsf@mail.jurta.org \
--to=juri@jurta.org \
--cc=emacs-devel@gnu.org \
--cc=monnier@IRO.UMontreal.CA \
--cc=rudalics@gmx.at \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
Code repositories for project(s) associated with this external index
https://git.savannah.gnu.org/cgit/emacs.git
https://git.savannah.gnu.org/cgit/emacs/org-mode.git
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.