From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.org!not-for-mail From: Juri Linkov Newsgroups: gmane.emacs.devel Subject: Re: find-file-read-args Date: Thu, 12 Nov 2009 11:56:35 +0200 Organization: JURTA Message-ID: <87ocn8ayrw.fsf@mail.jurta.org> References: <3b31caf90911051613w80af4cu61352a29ce5dcd77@mail.gmail.com> <87vdhoe73d.fsf@mail.jurta.org> <87y6mkb6qr.fsf@mail.jurta.org> <87bpjfiark.fsf@mail.jurta.org> <871vk8uo0q.fsf@mail.jurta.org> NNTP-Posting-Host: lo.gmane.org Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii X-Trace: ger.gmane.org 1258020530 26659 80.91.229.12 (12 Nov 2009 10:08:50 GMT) X-Complaints-To: usenet@ger.gmane.org NNTP-Posting-Date: Thu, 12 Nov 2009 10:08:50 +0000 (UTC) Cc: emacs-devel@gnu.org To: Stefan Monnier Original-X-From: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Thu Nov 12 11:08:43 2009 Return-path: Envelope-to: ged-emacs-devel@m.gmane.org Original-Received: from lists.gnu.org ([199.232.76.165]) by lo.gmane.org with esmtp (Exim 4.50) id 1N8WbM-0001xu-3q for ged-emacs-devel@m.gmane.org; Thu, 12 Nov 2009 11:08:28 +0100 Original-Received: from localhost ([127.0.0.1]:34780 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1N8WbL-00076T-IX for ged-emacs-devel@m.gmane.org; Thu, 12 Nov 2009 05:08:27 -0500 Original-Received: from mailman by lists.gnu.org with tmda-scanned (Exim 4.43) id 1N8WYg-0005LT-F0 for emacs-devel@gnu.org; Thu, 12 Nov 2009 05:05:42 -0500 Original-Received: from exim by lists.gnu.org with spam-scanned (Exim 4.43) id 1N8WYb-0005Gl-Sw for emacs-devel@gnu.org; Thu, 12 Nov 2009 05:05:41 -0500 Original-Received: from [199.232.76.173] (port=57913 helo=monty-python.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1N8WYb-0005Gi-EV for emacs-devel@gnu.org; Thu, 12 Nov 2009 05:05:37 -0500 Original-Received: from smtp-out1.starman.ee ([85.253.0.3]:42604 helo=mx1.starman.ee) by monty-python.gnu.org with esmtp (Exim 4.60) (envelope-from ) id 1N8WYa-0006De-KR for emacs-devel@gnu.org; Thu, 12 Nov 2009 05:05:37 -0500 X-Virus-Scanned: by Amavisd-New at mx1.starman.ee Original-Received: from mail.starman.ee (82.131.30.134.cable.starman.ee [82.131.30.134]) by mx1.starman.ee (Postfix) with ESMTP id 306D73F41D6; Thu, 12 Nov 2009 12:05:28 +0200 (EET) In-Reply-To: (Stefan Monnier's message of "Mon, 09 Nov 2009 09:28:19 -0500") User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/23.1.50 (x86_64-pc-linux-gnu) X-detected-operating-system: by monty-python.gnu.org: GNU/Linux 2.6, seldom 2.4 (older, 4) X-BeenThere: emacs-devel@gnu.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "Emacs development discussions." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Original-Sender: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Errors-To: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Xref: news.gmane.org gmane.emacs.devel:116871 Archived-At: > Thanks for working this out. Looking at the patch I wonder if the > "file-at-point" feature shouldn't be implemented in read-file-name rather > than in find-file. In the following patch I moved the code that sets `minibuffer-default' from functions `find-file-read-args' and `dired-read-dir-and-switches' to `read-file-name' where the list of default values gets filled dynamically with the help of `minibuffer-default-add-function' that tries to guess additional default values only when the user types M-n. There is still one problem. Due to the dynamical nature of M-n, it needs to visit the original buffer to get file names at point at the time when the current buffer if the minibuffer. I tried to find the original buffer with the help of `(with-current-buffer (window-buffer (next-window)) ...' but it often finds the wrong buffer when there are more than one window on the frame. Could you suggest a method for finding the original buffer, from which the minibuffer was activated. Maybe we should add a new variable to hold the value of the original buffer set during minibuffer setup? Index: lisp/files.el =================================================================== RCS file: /sources/emacs/emacs/lisp/files.el,v retrieving revision 1.1098 diff -c -r1.1098 files.el *** lisp/files.el 6 Nov 2009 05:16:27 -0000 1.1098 --- lisp/files.el 12 Nov 2009 09:54:28 -0000 *************** *** 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. --- 1275,1280 ---- *************** *** 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) --- 1295,1301 ---- (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/dired.el =================================================================== RCS file: /sources/emacs/emacs/lisp/dired.el,v retrieving revision 1.438 diff -c -r1.438 dired.el *** lisp/dired.el 10 Nov 2009 08:11:51 -0000 1.438 --- lisp/dired.el 12 Nov 2009 09:52:56 -0000 *************** *** 598,609 **** (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))))))) ;; We want to switch to a more sophisticated version of ;; dired-read-dir-and-switches like the following, if there is a way --- 598,605 ---- (if (next-read-file-uses-dialog-p) (read-directory-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 Index: lisp/minibuffer.el =================================================================== RCS file: /sources/emacs/emacs/lisp/minibuffer.el,v retrieving revision 1.94 diff -c -r1.94 minibuffer.el *** lisp/minibuffer.el 10 Nov 2009 00:54:48 -0000 1.94 --- lisp/minibuffer.el 12 Nov 2009 09:54:59 -0000 *************** *** 1258,1263 **** --- 1258,1315 ---- ;; 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 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)))))) + ;; Delistify the default list containing only 1 element + (if (and (consp default) (null (cdr default))) + (car default) + default))) (defun read-file-name (prompt &optional dir default-filename mustmatch initial predicate) "Read file name, prompting with PROMPT and completing in directory DIR. *************** *** 1342,1348 **** (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))) --- 1394,1411 ---- (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 () ! (with-current-buffer (window-buffer (next-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/