unofficial mirror of emacs-devel@gnu.org 
 help / color / mirror / code / Atom feed
* find-file-literally-at-point
@ 2009-11-06  0:13 Edward O'Connor
  2009-11-06  1:45 ` find-file-literally-at-point Juri Linkov
  2009-11-06 10:20 ` find-file-literally-at-point Eduard Wiebe
  0 siblings, 2 replies; 55+ messages in thread
From: Edward O'Connor @ 2009-11-06  0:13 UTC (permalink / raw)
  To: emacs-devel

Hi,

I recently found myself in need of such a function (I was going through
a bunch of files to strip out their UTF-8 BOMs, if you're curious), and
it was quick enough to put together:

(autoload 'ffap-guesser "ffap")
(defun find-file-literally-at-point ()
  "Open the file at point (like `ffap') with `find-file-literally'."
  (interactive)
  (find-file-literally (ffap-guesser)))

Is this something people might like to see added to ffap.el? I've signed
papers.


Thanks,
Ted




^ permalink raw reply	[flat|nested] 55+ messages in thread

* Re: find-file-literally-at-point
  2009-11-06  0:13 find-file-literally-at-point Edward O'Connor
@ 2009-11-06  1:45 ` Juri Linkov
  2009-11-06  4:20   ` FFAP (was: find-file-literally-at-point) Stefan Monnier
                     ` (2 more replies)
  2009-11-06 10:20 ` find-file-literally-at-point Eduard Wiebe
  1 sibling, 3 replies; 55+ messages in thread
From: Juri Linkov @ 2009-11-06  1:45 UTC (permalink / raw)
  To: Edward O'Connor; +Cc: emacs-devel

> I recently found myself in need of such a function (I was going through
> a bunch of files to strip out their UTF-8 BOMs, if you're curious),

Oh, I see.  That's what I regularly had to do on files produced
by Windows editors :)  Some time ago Emacs used to display BOMs,
so it was easy to see and delete BOMs, but now doesn't anymore,
since now the default coding system of files with the BOM is
`utf-8-with-signature'.  Forcing it to use `utf-8' with e.g.
`C-x RET c utf-8 RET C-x C-f' is a way to display BOMs
in an UTF-8 file.

> and it was quick enough to put together:
>
> (autoload 'ffap-guesser "ffap")
> (defun find-file-literally-at-point ()
>   "Open the file at point (like `ffap') with `find-file-literally'."
>   (interactive)
>   (find-file-literally (ffap-guesser)))
>
> Is this something people might like to see added to ffap.el?

When I added a few find-file related functions to ffap,
I don't remember why I missed `find-file-literally'.
Maybe because it has no keybinding (should we try to find one?).
So we definitely need such a function.

However, I wonder why you don't implement it using `ffap-file-finder'
and `call-interactively', like e.g. `ffap-alternate-file' does?
Like other ffap functions, it asks for a filename in the minibuffer,
and allows to get the default behavior with C-u.

-- 
Juri Linkov
http://www.jurta.org/emacs/




^ permalink raw reply	[flat|nested] 55+ messages in thread

* FFAP (was: find-file-literally-at-point)
  2009-11-06  1:45 ` find-file-literally-at-point Juri Linkov
@ 2009-11-06  4:20   ` Stefan Monnier
  2009-11-06  4:41     ` FFAP Miles Bader
  2009-11-06  4:45     ` FFAP Juri Linkov
  2009-11-09  0:44   ` find-file-literally-at-point Juri Linkov
  2009-11-09 10:01   ` utf-8-with-signature (was: find-file-literally-at-point) Juri Linkov
  2 siblings, 2 replies; 55+ messages in thread
From: Stefan Monnier @ 2009-11-06  4:20 UTC (permalink / raw)
  To: Juri Linkov; +Cc: Edward O'Connor, emacs-devel

> When I added a few find-file related functions to ffap,
> I don't remember why I missed `find-file-literally'.
> Maybe because it has no keybinding (should we try to find one?).
> So we definitely need such a function.

BTW, I'd be interested in trying to integrate the FFAP behavior into the
default find-file behavior.  If you people have ideas how such an
integration could take place, I'm all ears (of course, backward
compatibility with older users is very important).  Maybe we could have
an FFAP prefix, so <prefix> C-x C-f would `find-file-at-point'.
Or maybe we could have a keybinding in
minibuffer-local-filename-completion-map to bring in the
filename-at-point.


        Stefan




^ permalink raw reply	[flat|nested] 55+ messages in thread

* Re: FFAP
  2009-11-06  4:20   ` FFAP (was: find-file-literally-at-point) Stefan Monnier
@ 2009-11-06  4:41     ` Miles Bader
  2009-11-06 15:20       ` FFAP Stefan Monnier
  2009-11-06  4:45     ` FFAP Juri Linkov
  1 sibling, 1 reply; 55+ messages in thread
From: Miles Bader @ 2009-11-06  4:41 UTC (permalink / raw)
  To: Stefan Monnier; +Cc: Juri Linkov, Edward O'Connor, emacs-devel

Stefan Monnier <monnier@iro.umontreal.ca> writes:
> Or maybe we could have a keybinding in
> minibuffer-local-filename-completion-map to bring in the
> filename-at-point.

That sounds most useful to me -- it seems more flexible for users, and
it could immediately be used with (almost) all functions that want
filename entry.

-Miles

-- 
Hers, pron. His.




^ permalink raw reply	[flat|nested] 55+ messages in thread

* Re: FFAP
  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  4:45     ` Juri Linkov
  2009-11-06  8:50       ` FFAP Eli Zaretskii
  2009-11-06 15:18       ` FFAP Stefan Monnier
  1 sibling, 2 replies; 55+ messages in thread
From: Juri Linkov @ 2009-11-06  4:45 UTC (permalink / raw)
  To: Stefan Monnier; +Cc: Edward O'Connor, emacs-devel

>> When I added a few find-file related functions to ffap,
>> I don't remember why I missed `find-file-literally'.
>> Maybe because it has no keybinding (should we try to find one?).
>> So we definitely need such a function.
>
> BTW, I'd be interested in trying to integrate the FFAP behavior into the
> default find-file behavior.  If you people have ideas how such an
> integration could take place, I'm all ears (of course, backward
> compatibility with older users is very important).

I had an idea for a long time how to do such an integration, but
not implemented it yet because I currently don't see how to do this
without loading the whole ffap.el by default.  Perhaps we should
rewrite most of the ffap functionality and simplify it.

The idea is to put a file/URL from the text around the point into
the minibuffer's default values list.  So typing `C-x C-f M-n'
on a file name will bring in it from the current buffer into the
minibuffer.  This is useful for all prompts that read files or
directories.  For instance, `M-x mkdir RET M-n' will try to fetch
the directory name from the current buffer, and so on.

> Or maybe we could have a keybinding in
> minibuffer-local-filename-completion-map to bring in the
> filename-at-point.

`M-n' is such a binding that users are already familiar with.
If it turns out that it's unsuitable, we could invent a new one.

-- 
Juri Linkov
http://www.jurta.org/emacs/




^ permalink raw reply	[flat|nested] 55+ messages in thread

* Re: FFAP
  2009-11-06  4:45     ` FFAP Juri Linkov
@ 2009-11-06  8:50       ` Eli Zaretskii
  2009-11-06 10:37         ` FFAP Juri Linkov
  2009-11-06 15:18       ` FFAP Stefan Monnier
  1 sibling, 1 reply; 55+ messages in thread
From: Eli Zaretskii @ 2009-11-06  8:50 UTC (permalink / raw)
  To: Juri Linkov; +Cc: emacs-devel, monnier, hober0

> From: Juri Linkov <juri@jurta.org>
> Date: Fri, 06 Nov 2009 06:45:45 +0200
> Cc: Edward O'Connor <hober0@gmail.com>, emacs-devel@gnu.org
> 
> The idea is to put a file/URL from the text around the point into
> the minibuffer's default values list.  So typing `C-x C-f M-n'
> on a file name will bring in it from the current buffer into the
> minibuffer.

That's fine, but I don't think it should be the only possibility.  We
should also provide a special key binding just for ffap, and if
possible also an explicit prompt or tooltip for it.

The reason is that I think we already have too many unintuitive
features in minibuffer prompts, that may be working well for Emacs
veterans, but are entirely concealed (by virtue of their unintuitive
behavior) from the rest.  `M-n' is one such unintuitive feature.




^ permalink raw reply	[flat|nested] 55+ messages in thread

* Re: find-file-literally-at-point
  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 10:20 ` Eduard Wiebe
  2009-11-09  0:55   ` find-file-literally-at-point Juri Linkov
  1 sibling, 1 reply; 55+ messages in thread
From: Eduard Wiebe @ 2009-11-06 10:20 UTC (permalink / raw)
  To: emacs-devel

"Edward O'Connor" <hober0@gmail.com> writes:

> Hi,
>
> I recently found myself in need of such a function (I was going through
> a bunch of files to strip out their UTF-8 BOMs, if you're curious), and
> it was quick enough to put together:

I need/use `find-fil-literaly' often from dired. For this purpose i have

(define-key dired-mode-map (kbd "<C-return>")
  (lambda ()
    (interactive)
    (find-file-literally (dired-get-file-for-visit))))

in my .emacs.

-- 
Eduard Wiebe





^ permalink raw reply	[flat|nested] 55+ messages in thread

* Re: FFAP
  2009-11-06  8:50       ` FFAP Eli Zaretskii
@ 2009-11-06 10:37         ` Juri Linkov
  0 siblings, 0 replies; 55+ messages in thread
From: Juri Linkov @ 2009-11-06 10:37 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: emacs-devel, monnier, hober0

>> The idea is to put a file/URL from the text around the point into
>> the minibuffer's default values list.  So typing `C-x C-f M-n'
>> on a file name will bring in it from the current buffer into the
>> minibuffer.
>
> That's fine, but I don't think it should be the only possibility.  We
> should also provide a special key binding just for ffap, and if
> possible also an explicit prompt or tooltip for it.

We already have a special menu `Minibuf' for the minibuffer, so we
could add more minibuffer-related items to unconceal minibuffer
functionality.

-- 
Juri Linkov
http://www.jurta.org/emacs/




^ permalink raw reply	[flat|nested] 55+ messages in thread

* Re: FFAP
  2009-11-06  4:45     ` FFAP Juri Linkov
  2009-11-06  8:50       ` FFAP Eli Zaretskii
@ 2009-11-06 15:18       ` Stefan Monnier
  2009-11-06 21:19         ` FFAP Juri Linkov
  1 sibling, 1 reply; 55+ messages in thread
From: Stefan Monnier @ 2009-11-06 15:18 UTC (permalink / raw)
  To: Juri Linkov; +Cc: Edward O'Connor, emacs-devel

> I had an idea for a long time how to do such an integration, but
> not implemented it yet because I currently don't see how to do this
> without loading the whole ffap.el by default.  Perhaps we should
> rewrite most of the ffap functionality and simplify it.

By "integration" I mostly mean the functionality, not necessarily
the code.  But if it means preloading ffap.el, that's not necessarily
a bad thing, although I think that by integrating it, we can make it
a lot simpler, so I expect that a complete rewrite will be preferable
(especially since we probably wouldn't provide every single last detail
of ffap's functionality).

> The idea is to put a file/URL from the text around the point into
> the minibuffer's default values list.  So typing `C-x C-f M-n'
> on a file name will bring in it from the current buffer into the
> minibuffer.

I thought about it but M-n is already used in some file prompts for
other purposes, so the user would then have to hit M-n more than once to
get the file-at-point, which makes it cumbersome.  I think a dedicated
keybinding would be better.

BTW, another possibility is to do what complete.el does: use a special
file name (complete.el uses "<>" but we could choose something else,
like " ") to mean file-at-point.  I think it's a worse solution (both
because it may collide with a real file name, and more importantly
because it makes it impossible/difficult to edit the file-at-point), but
I throw it out, for completeness's sake.


        Stefan




^ permalink raw reply	[flat|nested] 55+ messages in thread

* Re: FFAP
  2009-11-06  4:41     ` FFAP Miles Bader
@ 2009-11-06 15:20       ` Stefan Monnier
  0 siblings, 0 replies; 55+ messages in thread
From: Stefan Monnier @ 2009-11-06 15:20 UTC (permalink / raw)
  To: Miles Bader; +Cc: Juri Linkov, Edward O'Connor, emacs-devel

>> Or maybe we could have a keybinding in
>> minibuffer-local-filename-completion-map to bring in the
>> filename-at-point.

> That sounds most useful to me -- it seems more flexible for users, and
> it could immediately be used with (almost) all functions that want
> filename entry.

Another advantage is that minibuffer-local-filename-completion-map is
not nearly as crowded as the global map.  But still, we'd have to come
up with a good binding.


        Stefan




^ permalink raw reply	[flat|nested] 55+ messages in thread

* Re: FFAP
  2009-11-06 15:18       ` FFAP Stefan Monnier
@ 2009-11-06 21:19         ` Juri Linkov
  2009-11-07  1:32           ` FFAP Stefan Monnier
                             ` (5 more replies)
  0 siblings, 6 replies; 55+ messages in thread
From: Juri Linkov @ 2009-11-06 21:19 UTC (permalink / raw)
  To: Stefan Monnier; +Cc: Edward O'Connor, emacs-devel

> By "integration" I mostly mean the functionality, not necessarily
> the code.  But if it means preloading ffap.el, that's not necessarily
> a bad thing, although I think that by integrating it, we can make it
> a lot simpler, so I expect that a complete rewrite will be preferable
> (especially since we probably wouldn't provide every single last detail
> of ffap's functionality).

I forgot that we already have a clean and small counterpart of ffap
that can be preloaded instead of ffap.el.  It is thingatpt.el.
With (thing-at-point 'filename) it returns the filename at point,
and with (thing-at-point 'url) it returns the URL at point.

>> The idea is to put a file/URL from the text around the point into
>> the minibuffer's default values list.  So typing `C-x C-f M-n'
>> on a file name will bring in it from the current buffer into the
>> minibuffer.
>
> I thought about it but M-n is already used in some file prompts for
> other purposes,

Let's see what currently M-n does in file prompts (0. means the default
input, and 1. - the minibuffer's content after one M-n):

`C-x C-f' in a non-file buffer:
0. current directory name

`C-x C-f' in a file buffer:
0. current directory name
1. file name of the current buffer

`C-x C-v' in a file buffer:
0. file name of the current buffer
1. file name of the current buffer
(the last case has duplicates)

> so the user would then have to hit M-n more than once to get the
> file-at-point, which makes it cumbersome.

After adding a file name at point:

`C-x C-f' in a non-file buffer:
0. current directory name
1. file name at point

`C-x C-f' in a file buffer:
0. current directory name
1. file name of the current buffer
2. file name at point

`C-x C-v' in a file buffer:
0. file name of the current buffer
1. file name at point

So M-n more than once is only in a file buffer,
where we could add a file name at point before
the file name of the current buffer:

`C-x C-f' in a file buffer:
0. current directory name
1. file name at point
2. file name of the current buffer

> I think a dedicated keybinding would be better.

Of course, a dedicated keybinding would be good as well.
IIRC, the last time this has been discussed where Drew
proposed `M-.' to yank text at point into the minibuffer in:
http://thread.gmane.org/gmane.emacs.devel/50372

-- 
Juri Linkov
http://www.jurta.org/emacs/




^ permalink raw reply	[flat|nested] 55+ messages in thread

* Re: FFAP
  2009-11-06 21:19         ` FFAP Juri Linkov
@ 2009-11-07  1:32           ` Stefan Monnier
  2009-11-09  0:52             ` FFAP Juri Linkov
  2009-11-09 10:09           ` find-file-read-args (was: FFAP) Juri Linkov
                             ` (4 subsequent siblings)
  5 siblings, 1 reply; 55+ messages in thread
From: Stefan Monnier @ 2009-11-07  1:32 UTC (permalink / raw)
  To: Juri Linkov; +Cc: Edward O'Connor, emacs-devel

>> By "integration" I mostly mean the functionality, not necessarily
>> the code.  But if it means preloading ffap.el, that's not necessarily
>> a bad thing, although I think that by integrating it, we can make it
>> a lot simpler, so I expect that a complete rewrite will be preferable
>> (especially since we probably wouldn't provide every single last detail
>> of ffap's functionality).
> I forgot that we already have a clean and small counterpart of ffap
> that can be preloaded instead of ffap.el.  It is thingatpt.el.
> With (thing-at-point 'filename) it returns the filename at point,
> and with (thing-at-point 'url) it returns the URL at point.

I think it'd be important to make it mode-aware, so that when you're on
a (require 'foo) or on a #include "bar", it can find the relevant file.
So (thing-at-point 'filename) wouldn't quite cut it as it stands.


        Stefan




^ permalink raw reply	[flat|nested] 55+ messages in thread

* Re: find-file-literally-at-point
  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-09  0:44   ` Juri Linkov
  2009-11-09  2:00     ` find-file-literally-at-point Miles Bader
  2009-11-09 10:01   ` utf-8-with-signature (was: find-file-literally-at-point) Juri Linkov
  2 siblings, 1 reply; 55+ messages in thread
From: Juri Linkov @ 2009-11-09  0:44 UTC (permalink / raw)
  To: Edward O'Connor; +Cc: emacs-devel

> When I added a few find-file related functions to ffap,
> I don't remember why I missed `find-file-literally'.
> Maybe because it has no keybinding (should we try to find one?).
> So we definitely need such a function.

Below is a patch that implements `ffap-literally' using
`ffap-file-finder' and `call-interactively' like other similar
functions do.  It also adds `ffap-alternate-file-other-window' -
the remaining missing find-file related function that has
no keybinding.

Index: lisp/ffap.el
===================================================================
RCS file: /sources/emacs/emacs/lisp/ffap.el,v
retrieving revision 1.86
diff -c -r1.86 ffap.el
*** lisp/ffap.el	2 Oct 2009 03:48:40 -0000	1.86
--- lisp/ffap.el	9 Nov 2009 00:39:51 -0000
***************
*** 1435,1441 ****
  	   (string-match ffap-dired-wildcards filename)
  	   find-file-wildcards
  	   ;; Check if it's find-file that supports wildcards arg
! 	   (memq ffap-file-finder '(find-file find-alternate-file)))
        (funcall ffap-file-finder (expand-file-name filename) t))
       ((or (not ffap-newfile-prompt)
  	  (file-exists-p filename)
--- 1435,1443 ----
  	   (string-match ffap-dired-wildcards filename)
  	   find-file-wildcards
  	   ;; Check if it's find-file that supports wildcards arg
! 	   (memq ffap-file-finder '(find-file
! 				    find-alternate-file
! 				    find-alternate-file-other-window)))
        (funcall ffap-file-finder (expand-file-name filename) t))
       ((or (not ffap-newfile-prompt)
  	  (file-exists-p filename)
***************
*** 1708,1713 ****
--- 1710,1729 ----
    (let ((ffap-file-finder 'find-alternate-file))
      (call-interactively 'ffap)))
  
+ (defun ffap-alternate-file-other-window ()
+   "Like `ffap' and `find-alternate-file-other-window'.
+ Only intended for interactive use."
+   (interactive)
+   (let ((ffap-file-finder 'find-alternate-file-other-window))
+     (call-interactively 'ffap)))
+ 
+ (defun ffap-literally ()
+   "Like `ffap' and `find-file-literally'.
+ Only intended for interactive use."
+   (interactive)
+   (let ((ffap-file-finder 'find-file-literally))
+     (call-interactively 'ffap)))
+ 
  \f
  ;;; Bug Reporter:

-- 
Juri Linkov
http://www.jurta.org/emacs/




^ permalink raw reply	[flat|nested] 55+ messages in thread

* Re: FFAP
  2009-11-07  1:32           ` FFAP Stefan Monnier
@ 2009-11-09  0:52             ` Juri Linkov
  2009-11-09  6:33               ` FFAP Stefan Monnier
  0 siblings, 1 reply; 55+ messages in thread
From: Juri Linkov @ 2009-11-09  0:52 UTC (permalink / raw)
  To: Stefan Monnier; +Cc: Edward O'Connor, emacs-devel

>> I forgot that we already have a clean and small counterpart of ffap
>> that can be preloaded instead of ffap.el.  It is thingatpt.el.
>> With (thing-at-point 'filename) it returns the filename at point,
>> and with (thing-at-point 'url) it returns the URL at point.
>
> I think it'd be important to make it mode-aware, so that when you're on
> a (require 'foo) or on a #include "bar", it can find the relevant file.
> So (thing-at-point 'filename) wouldn't quite cut it as it stands.

FFAP is already mode-aware, but IMHO its code is ugly.  It puts
all supported modes into `ffap-alist'.  Maybe we should reimplement
this in `thing-at-point' exposing a generic interface for modes
to be able to add their mode-specific settings (like e.g. imenu does
with `imenu-generic-expression').

-- 
Juri Linkov
http://www.jurta.org/emacs/




^ permalink raw reply	[flat|nested] 55+ messages in thread

* Re: find-file-literally-at-point
  2009-11-06 10:20 ` find-file-literally-at-point Eduard Wiebe
@ 2009-11-09  0:55   ` Juri Linkov
  2009-11-09 19:49     ` find-file-literally-at-point Eduard Wiebe
  0 siblings, 1 reply; 55+ messages in thread
From: Juri Linkov @ 2009-11-09  0:55 UTC (permalink / raw)
  To: Eduard Wiebe; +Cc: emacs-devel

> I need/use `find-fil-literaly' often from dired. For this purpose i have
>
> (define-key dired-mode-map (kbd "<C-return>")
>   (lambda ()
>     (interactive)
>     (find-file-literally (dired-get-file-for-visit))))
>
> in my .emacs.

Maybe a prefix argument of `find-file' and `dired-find-file'
could be used to request `find-file-literally'.

-- 
Juri Linkov
http://www.jurta.org/emacs/




^ permalink raw reply	[flat|nested] 55+ messages in thread

* Re: find-file-literally-at-point
  2009-11-09  0:44   ` find-file-literally-at-point Juri Linkov
@ 2009-11-09  2:00     ` Miles Bader
  2009-11-09  2:11       ` find-file-literally-at-point Juri Linkov
  0 siblings, 1 reply; 55+ messages in thread
From: Miles Bader @ 2009-11-09  2:00 UTC (permalink / raw)
  To: Juri Linkov; +Cc: Edward O'Connor, emacs-devel

Juri Linkov <juri@jurta.org> writes:
> Below is a patch that implements `ffap-literally' using

`ffap-literally' seems like the most horrible name ever tho...

-Miles

-- 
The automobile has not merely taken over the street, it has dissolved the
living tissue of the city.  Its appetite for space is absolutely insatiable;
moving and parked, it devours urban land, leaving the buildings as mere
islands of habitable space in a sea of dangerous and ugly traffic.
[James Marston Fitch, New York Times, 1 May 1960]




^ permalink raw reply	[flat|nested] 55+ messages in thread

* Re: find-file-literally-at-point
  2009-11-09  2:00     ` find-file-literally-at-point Miles Bader
@ 2009-11-09  2:11       ` Juri Linkov
  2009-11-10  0:49         ` find-file-literally-at-point Juri Linkov
  0 siblings, 1 reply; 55+ messages in thread
From: Juri Linkov @ 2009-11-09  2:11 UTC (permalink / raw)
  To: Miles Bader; +Cc: Edward O'Connor, emacs-devel

>> Below is a patch that implements `ffap-literally' using
>
> `ffap-literally' seems like the most horrible name ever tho...

There are two naming conventions in ffap.el: one where the function name
ends with the `-at-point' suffix, and another where the function name
begins with the `ffap-' prefix.

The problem with adding the `-at-point' suffix is that it will create
more horrible names than using the `ffap-' prefix.  Currently
the `-at-point' suffix is used only for relatively short names like
`find-file-at-point' and `dired-at-point'.  But using it for other
names will create names like `find-file-read-only-other-window-at-point'
(41 characters!) instead of the current `ffap-read-only-other-window'
(27 characters).

That's because the name `ffap' compresses 18 characters of
`find-file-at-point' into 4 characters of `ffap'.


-- 
Juri Linkov
http://www.jurta.org/emacs/




^ permalink raw reply	[flat|nested] 55+ messages in thread

* Re: FFAP
  2009-11-09  0:52             ` FFAP Juri Linkov
@ 2009-11-09  6:33               ` Stefan Monnier
  0 siblings, 0 replies; 55+ messages in thread
From: Stefan Monnier @ 2009-11-09  6:33 UTC (permalink / raw)
  To: Juri Linkov; +Cc: Edward O'Connor, emacs-devel

> FFAP is already mode-aware, but IMHO its code is ugly.  It puts
> all supported modes into `ffap-alist'.  Maybe we should reimplement
> this in `thing-at-point' exposing a generic interface for modes
> to be able to add their mode-specific settings (like e.g. imenu does
> with `imenu-generic-expression').

That sounds like a good way to attack the problem, yes.


        Stefan




^ permalink raw reply	[flat|nested] 55+ messages in thread

* utf-8-with-signature (was: find-file-literally-at-point)
  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-09  0:44   ` find-file-literally-at-point Juri Linkov
@ 2009-11-09 10:01   ` Juri Linkov
  2 siblings, 0 replies; 55+ messages in thread
From: Juri Linkov @ 2009-11-09 10:01 UTC (permalink / raw)
  To: Edward O'Connor; +Cc: emacs-devel

>> I recently found myself in need of such a function (I was going through
>> a bunch of files to strip out their UTF-8 BOMs, if you're curious),
>
> Oh, I see.  That's what I regularly had to do on files produced
> by Windows editors :)  Some time ago Emacs used to display BOMs,
> so it was easy to see and delete BOMs, but now doesn't anymore,
> since now the default coding system of files with the BOM is
> `utf-8-with-signature'.  Forcing it to use `utf-8' with e.g.
> `C-x RET c utf-8 RET C-x C-f' is a way to display BOMs
> in an UTF-8 file.

BTW, after removing `("\\`\xEF\xBB\xBF" . utf-8-with-signature)'
from `auto-coding-regexp-alist' BOMs will be always displayed
without the need to visit files literally.

-- 
Juri Linkov
http://www.jurta.org/emacs/




^ permalink raw reply	[flat|nested] 55+ messages in thread

* find-file-read-args (was: FFAP)
  2009-11-06 21:19         ` FFAP Juri Linkov
  2009-11-07  1:32           ` FFAP Stefan Monnier
@ 2009-11-09 10:09           ` Juri Linkov
  2009-11-09 14:28             ` find-file-read-args Stefan Monnier
  2009-11-09 10:14           ` read-file-name (was: FFAP) Juri Linkov
                             ` (3 subsequent siblings)
  5 siblings, 1 reply; 55+ messages in thread
From: Juri Linkov @ 2009-11-09 10:09 UTC (permalink / raw)
  To: Stefan Monnier; +Cc: emacs-devel

> Let's see what currently M-n does in file prompts (0. means the default
> input, and 1. - the minibuffer's content after one M-n):
>
> `C-x C-f' in a non-file buffer:
> 0. current directory name
>
> `C-x C-f' in a file buffer:
> 0. current directory name
> 1. file name of the current buffer
>
> `C-x C-v' in a file buffer:
> 0. file name of the current buffer
> 1. file name of the current buffer
> (the last case has duplicates)
>
> After adding a file name at point:
>
> `C-x C-f' in a non-file buffer:
> 0. current directory name
> 1. file name at point
>
> `C-x C-f' in a file buffer:
> 0. current directory name
> 1. file name of the current buffer
> 2. file name at point
>
> `C-x C-v' in a file buffer:
> 0. file name of the current buffer
> 1. file name at point
>
> So M-n more than once is only in a file buffer,
> where we could add a file name at point before
> the file name of the current buffer:
>
> `C-x C-f' in a file buffer:
> 0. current directory name
> 1. file name at point
> 2. file name of the current buffer

The patch below implements this scheme, and additionally
includes an approved but not installed change proposed
by Drew in http://thread.gmane.org/gmane.emacs.devel/74534
that allows `M-n' with `C-x C-f' to get the file at point
in Dired mode.

Other changes are:

1. When `ffap-guesser' is available, use it to provide
   an additional default value.  Since currently its
   guesses are much better than from `thing-at-point',
   it makes sense to load ffap.el in .emacs but without
   rebinding file-related keys to their equivalents
   by `ffap-bindings'.  This way standard keys will remain
   bound to default functions that will use `ffap-guesser' to
   get the file name at point and provide it as default.

2. When ffap.el is not loaded, then use `thing-at-point'
   to provide an additional default value.  But currently
   this code is commented out in the patch below,
   because in the current state, `thing-at-point' is useless
   since it doesn't check if the file at point exists.
   It blindly proposes any word at point as a file name.
   Perhaps a new scheme should be implemented like e.g.
   (thing-at-point 'existing-filename).

3. Added two new optional arguments `dir' and `initial'
   for `find-file-read-args' to allow `find-alternate-file'
   to use features of `find-file-read-args' shared among
   all filename-reading functions.

4. For the same reason, `find-file-literally' now relies on
   `find-file-read-args' as well.

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	9 Nov 2009 10:04:57 -0000
***************
*** 1297,1309 ****
  	     ,@body)
  	 (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)
--- 1297,1332 ----
  	     ,@body)
  	 (remove-hook 'minibuffer-setup-hook ,hook)))))
  
! (defun find-file-read-args (prompt mustmatch &optional dir initial)
    (list (let ((find-file-default
! 	       (cond
! 		(initial nil) ; don't duplicate initial and default values
! 		((eq major-mode 'dired-mode)
! 		 (and (dired-get-filename nil t)
! 		      (abbreviate-file-name (dired-get-filename nil t))))
! 		(buffer-file-name
! 		 (abbreviate-file-name buffer-file-name))))
! 	      (file-at-point
! 	       (cond ((fboundp 'ffap-guesser)
! 		      (let ((guess (ffap-guesser)))
! 			(if (or (not (stringp 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)))))
! 		     ;; ((fboundp 'thing-at-point)
! 		     ;;  (thing-at-point 'filename))
! 		     )))
! 	  (when file-at-point
! 	    (setq find-file-default
! 		  (delq nil (delete "" (delete-dups
! 					(list file-at-point
! 					      find-file-default))))))
  	  (minibuffer-with-setup-hook
  	      (lambda () (setq minibuffer-default find-file-default))
! 	    (read-file-name prompt dir default-directory mustmatch initial)))
  	t))
  
  (defun find-file (filename &optional wildcards)
***************
*** 1460,1469 ****
         (and file
  	    (setq file-name (file-name-nondirectory file)
  		  file-dir (file-name-directory file)))
!        (list (read-file-name
! 	      "Find alternate file: " file-dir nil
!               (confirm-nonexistent-file-or-buffer) file-name)
! 	     t))))
    (if (one-window-p)
        (find-file-other-window filename wildcards)
      (save-selected-window
--- 1483,1491 ----
         (and file
  	    (setq file-name (file-name-nondirectory file)
  		  file-dir (file-name-directory file)))
!        (find-file-read-args "Find alternate file: "
! 			    (confirm-nonexistent-file-or-buffer)
! 			    file-dir file-name))))
    (if (one-window-p)
        (find-file-other-window filename wildcards)
      (save-selected-window
***************
*** 1490,1499 ****
       (and file
  	  (setq file-name (file-name-nondirectory file)
  		file-dir (file-name-directory file)))
!      (list (read-file-name
! 	    "Find alternate file: " file-dir nil
!             (confirm-nonexistent-file-or-buffer) file-name)
! 	   t)))
    (unless (run-hook-with-args-until-failure 'kill-buffer-query-functions)
      (error "Aborted"))
    (when (and (buffer-modified-p) buffer-file-name)
--- 1512,1520 ----
       (and file
  	  (setq file-name (file-name-nondirectory file)
  		file-dir (file-name-directory file)))
!      (find-file-read-args "Find alternate file: "
! 			  (confirm-nonexistent-file-or-buffer)
! 			  file-dir file-name)))
    (unless (run-hook-with-args-until-failure 'kill-buffer-query-functions)
      (error "Aborted"))
    (when (and (buffer-modified-p) buffer-file-name)
***************
*** 2020,2026 ****
  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: ")
    (switch-to-buffer (find-file-noselect filename nil t)))
  \f
  (defvar after-find-file-from-revert-buffer nil)
--- 2041,2050 ----
  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
!    (nbutlast				; remove the `wildcards' arg
!     (find-file-read-args "Find file literally: "
! 			 (confirm-nonexistent-file-or-buffer))))
    (switch-to-buffer (find-file-noselect filename nil t)))
  \f
  (defvar after-find-file-from-revert-buffer nil)

-- 
Juri Linkov
http://www.jurta.org/emacs/




^ permalink raw reply	[flat|nested] 55+ messages in thread

* read-file-name (was: FFAP)
  2009-11-06 21:19         ` FFAP Juri Linkov
  2009-11-07  1:32           ` FFAP Stefan Monnier
  2009-11-09 10:09           ` find-file-read-args (was: FFAP) Juri Linkov
@ 2009-11-09 10:14           ` Juri Linkov
  2009-11-09 14:31             ` read-file-name Stefan Monnier
  2009-11-09 10:30           ` dired-read-dir-and-switches (was: FFAP) Juri Linkov
                             ` (2 subsequent siblings)
  5 siblings, 1 reply; 55+ messages in thread
From: Juri Linkov @ 2009-11-09 10:14 UTC (permalink / raw)
  To: Stefan Monnier; +Cc: emacs-devel

All completion functions support a list of default values
except `read-file-name'.  The following patch fills this hole.

Index: lisp/minibuffer.el
===================================================================
RCS file: /sources/emacs/emacs/lisp/minibuffer.el,v
retrieving revision 1.93
diff -c -r1.93 minibuffer.el
*** lisp/minibuffer.el	2 Nov 2009 02:06:40 -0000	1.93
--- lisp/minibuffer.el	9 Nov 2009 10:12:38 -0000
***************
*** 1265,1271 ****
  Default name to DEFAULT-FILENAME if user exits the minibuffer with
  the same non-empty string that was inserted by this function.
   (If DEFAULT-FILENAME is omitted, the visited file name is used,
!   except that if INITIAL is specified, that combined with DIR is used.)
  If the user exits with an empty minibuffer, this function returns
  an empty string.  (This can only happen if the user erased the
  pre-inserted contents or if `insert-default-directory' is nil.)
--- 1265,1272 ----
  Default name to DEFAULT-FILENAME if user exits the minibuffer with
  the same non-empty string that was inserted by this function.
   (If DEFAULT-FILENAME is omitted, the visited file name is used,
!   except that if INITIAL is specified, that combined with DIR is used.
!   If DEFAULT-FILENAME is a list of file names, the first file name is used.)
  If the user exits with an empty minibuffer, this function returns
  an empty string.  (This can only happen if the user erased the
  pre-inserted contents or if `insert-default-directory' is nil.)
***************
*** 1308,1314 ****
    (setq dir (abbreviate-file-name dir))
    ;; Likewise for default-filename.
    (if default-filename
!       (setq default-filename (abbreviate-file-name default-filename)))
    (let ((insdef (cond
                   ((and insert-default-directory (stringp dir))
                    (if initial
--- 1309,1317 ----
    (setq dir (abbreviate-file-name dir))
    ;; Likewise for default-filename.
    (if default-filename
!       (if (consp default-filename)
! 	  (setq default-filename (mapcar 'abbreviate-file-name default-filename))
! 	(setq default-filename (abbreviate-file-name default-filename))))
    (let ((insdef (cond
                   ((and insert-default-directory (stringp dir))
                    (if initial
***************
*** 1357,1365 ****
  			       (not (zerop (length file))))
                        (setq default-filename file)
                        (setq dir (file-name-directory dir)))
!                     (if default-filename
!                         (setq default-filename
!                               (expand-file-name default-filename dir)))
                      (setq add-to-history t)
                      (x-file-dialog prompt dir default-filename
  				   dialog-mustmatch
--- 1360,1371 ----
  			       (not (zerop (length file))))
                        (setq default-filename file)
                        (setq dir (file-name-directory dir)))
!                     (when default-filename
! 		      (setq default-filename
! 			    (expand-file-name (if (consp default-filename)
! 						  (car default-filename)
! 						default-filename)
! 					      dir)))
                      (setq add-to-history t)
                      (x-file-dialog prompt dir default-filename
  				   dialog-mustmatch
***************
*** 1371,1376 ****
--- 1377,1384 ----
            ;; it has to mean that the user typed RET with the minibuffer empty.
            ;; In that case, we really want to return ""
            ;; so that commands such as set-visited-file-name can distinguish.
+ 	  (when (consp default-filename)
+ 	    (setq default-filename (car default-filename)))
            (when (eq val default-filename)
              ;; In this case, completing-read has not added an element
              ;; to the history.  Maybe we should.

-- 
Juri Linkov
http://www.jurta.org/emacs/




^ permalink raw reply	[flat|nested] 55+ messages in thread

* dired-read-dir-and-switches (was: FFAP)
  2009-11-06 21:19         ` FFAP Juri Linkov
                             ` (2 preceding siblings ...)
  2009-11-09 10:14           ` read-file-name (was: FFAP) Juri Linkov
@ 2009-11-09 10:30           ` Juri Linkov
  2009-11-09 10:36           ` M-! M-n should fetch filename (Re: FFAP) Juri Linkov
  2009-11-15 15:12           ` dired-dwim-target (was: FFAP) Juri Linkov
  5 siblings, 0 replies; 55+ messages in thread
From: Juri Linkov @ 2009-11-09 10:30 UTC (permalink / raw)
  To: Stefan Monnier; +Cc: emacs-devel

Similar to `find-file-read-args' for file-reading functions,
the following patch does the same for directory-reading functions.
It modifies `dired-read-dir-and-switches' to allow it guessing
the default value.

Index: lisp/dired.el
===================================================================
RCS file: /sources/emacs/emacs/lisp/dired.el,v
retrieving revision 1.437
diff -c -r1.437 dired.el
*** lisp/dired.el	8 Nov 2009 00:32:22 -0000	1.437
--- lisp/dired.el	9 Nov 2009 10:29:09 -0000
***************
*** 598,605 ****
  	    (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)
--- 598,639 ----
  	    (if (next-read-file-uses-dialog-p)
  		(read-directory-name (format "Dired %s(directory): " str)
  				     nil default-directory nil)
! 	      (let ((default
! 		      (cond
! 		       ((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)))))
! 		       (buffer-file-name
! 			(abbreviate-file-name buffer-file-name))))
! 		    (file-at-point
! 		     (cond ((fboundp 'ffap-guesser)
! 			    ;; Most code from `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 file-at-point
! 		  (setq default
! 			(delq nil (delete "" (delete-dups
! 					      (list file-at-point
! 						    default))))))
  		(minibuffer-with-setup-hook
  		    (lambda () (setq minibuffer-default default))
  		  (read-file-name (format "Dired %s(directory): " str)

-- 
Juri Linkov
http://www.jurta.org/emacs/




^ permalink raw reply	[flat|nested] 55+ messages in thread

* M-! M-n should fetch filename (Re: FFAP)
  2009-11-06 21:19         ` FFAP Juri Linkov
                             ` (3 preceding siblings ...)
  2009-11-09 10:30           ` dired-read-dir-and-switches (was: FFAP) Juri Linkov
@ 2009-11-09 10:36           ` Juri Linkov
  2009-11-09 14:35             ` Stefan Monnier
  2009-11-15 15:12           ` dired-dwim-target (was: FFAP) Juri Linkov
  5 siblings, 1 reply; 55+ messages in thread
From: Juri Linkov @ 2009-11-09 10:36 UTC (permalink / raw)
  To: Stefan Monnier; +Cc: emacs-devel

There is the following etc/TODO item:

  ** M-! M-n should fetch the buffer-file-name as the default.

However, it seems it's already implemented.  What is missing
is an ability of M-! M-n to fetch the filename as the default
in Dired mode using `dired-get-filename'.  The patch below
implements this.

Please note that it doesn't use a guesser based on the
filename at point when not in Dired mode.  I'm not sure
whether it makes sense to get the filename at point as the
base for building a command line for `shell-command'.

Index: lisp/simple.el
===================================================================
RCS file: /sources/emacs/emacs/lisp/simple.el,v
retrieving revision 1.1022
diff -c -r1.1022 simple.el
*** lisp/simple.el	30 Oct 2009 02:00:30 -0000	1.1022
--- lisp/simple.el	9 Nov 2009 10:31:21 -0000
***************
*** 2136,2143 ****
    (interactive
     (list
      (read-shell-command "Shell command: " nil nil
! 			(and buffer-file-name
! 			     (file-relative-name buffer-file-name)))
      current-prefix-arg
      shell-command-default-error-buffer))
    ;; Look for a handler in case default-directory is a remote file name.
--- 2152,2163 ----
    (interactive
     (list
      (read-shell-command "Shell command: " nil nil
! 			(cond
! 			 ((eq major-mode 'dired-mode)
! 			  (let ((filename (dired-get-filename nil t)))
! 			    (and filename (file-relative-name filename))))
! 			 (buffer-file-name
! 			  (file-relative-name buffer-file-name))))
      current-prefix-arg
      shell-command-default-error-buffer))
    ;; Look for a handler in case default-directory is a remote file name.

-- 
Juri Linkov
http://www.jurta.org/emacs/




^ permalink raw reply	[flat|nested] 55+ messages in thread

* Re: find-file-read-args
  2009-11-09 10:09           ` find-file-read-args (was: FFAP) Juri Linkov
@ 2009-11-09 14:28             ` Stefan Monnier
  2009-11-10  0:57               ` find-file-read-args Juri Linkov
  2009-11-12  9:56               ` find-file-read-args Juri Linkov
  0 siblings, 2 replies; 55+ messages in thread
From: Stefan Monnier @ 2009-11-09 14:28 UTC (permalink / raw)
  To: Juri Linkov; +Cc: emacs-devel

>> Let's see what currently M-n does in file prompts (0. means the default
>> input, and 1. - the minibuffer's content after one M-n):

> The patch below implements this scheme, and additionally
> includes an approved but not installed change proposed
> by Drew in http://thread.gmane.org/gmane.emacs.devel/74534
> that allows `M-n' with `C-x C-f' to get the file at point
> in Dired mode.

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.


        Stefan




^ permalink raw reply	[flat|nested] 55+ messages in thread

* Re: read-file-name
  2009-11-09 10:14           ` read-file-name (was: FFAP) Juri Linkov
@ 2009-11-09 14:31             ` Stefan Monnier
  2009-11-10  0:55               ` read-file-name Juri Linkov
  0 siblings, 1 reply; 55+ messages in thread
From: Stefan Monnier @ 2009-11-09 14:31 UTC (permalink / raw)
  To: Juri Linkov; +Cc: emacs-devel

> All completion functions support a list of default values
> except `read-file-name'.  The following patch fills this hole.

Looks OK, feel free to install it.

> !       (if (consp default-filename)
> ! 	  (setq default-filename (mapcar 'abbreviate-file-name default-filename))
> ! 	(setq default-filename (abbreviate-file-name default-filename))))

That should be

       (setq default-filename
             (if (consp default-filename)
                 (mapcar 'abbreviate-file-name default-filename)
               (abbreviate-file-name default-filename))))


-- Stefan




^ permalink raw reply	[flat|nested] 55+ messages in thread

* Re: M-! M-n should fetch filename (Re: FFAP)
  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
  0 siblings, 1 reply; 55+ messages in thread
From: Stefan Monnier @ 2009-11-09 14:35 UTC (permalink / raw)
  To: Juri Linkov; +Cc: emacs-devel

> There is the following etc/TODO item:
>   ** M-! M-n should fetch the buffer-file-name as the default.

> However, it seems it's already implemented.

Then please remove it from etc/TODO.

> What is missing is an ability of M-! M-n to fetch the filename as the
> default in Dired mode using `dired-get-filename'.

I don't have an opinion on whether that's good/bad/useful/...
If people find it to be a good feature, please rework the patch so
there's only one call to file-relative-name, rather than one in each
branch of the test.


        Stefan




^ permalink raw reply	[flat|nested] 55+ messages in thread

* Re: find-file-literally-at-point
  2009-11-09  0:55   ` find-file-literally-at-point Juri Linkov
@ 2009-11-09 19:49     ` Eduard Wiebe
  0 siblings, 0 replies; 55+ messages in thread
From: Eduard Wiebe @ 2009-11-09 19:49 UTC (permalink / raw)
  To: emacs-devel

Juri Linkov <juri@jurta.org> writes:

>> I need/use `find-fil-literaly' often from dired. For this purpose i have
>>
>> (define-key dired-mode-map (kbd "<C-return>")
>>   (lambda ()
>>     (interactive)
>>     (find-file-literally (dired-get-file-for-visit))))
>>
>> in my .emacs.
>
> Maybe a prefix argument of `find-file' and `dired-find-file'
> could be used to request `find-file-literally'.

 Indeed, that would be great.

-- 
Eduard Wiebe





^ permalink raw reply	[flat|nested] 55+ messages in thread

* Re: find-file-literally-at-point
  2009-11-09  2:11       ` find-file-literally-at-point Juri Linkov
@ 2009-11-10  0:49         ` Juri Linkov
  0 siblings, 0 replies; 55+ messages in thread
From: Juri Linkov @ 2009-11-10  0:49 UTC (permalink / raw)
  To: Miles Bader; +Cc: Edward O'Connor, emacs-devel

>>> Below is a patch that implements `ffap-literally' using
>>
>> `ffap-literally' seems like the most horrible name ever tho...
>
> There are two naming conventions in ffap.el: one where the function name
> ends with the `-at-point' suffix, and another where the function name
> begins with the `ffap-' prefix.
>
> The problem with adding the `-at-point' suffix is that it will create
> more horrible names than using the `ffap-' prefix.  Currently
> the `-at-point' suffix is used only for relatively short names like
> `find-file-at-point' and `dired-at-point'.  But using it for other
> names will create names like `find-file-read-only-other-window-at-point'
> (41 characters!) instead of the current `ffap-read-only-other-window'
> (27 characters).
>
> That's because the name `ffap' compresses 18 characters of
> `find-file-at-point' into 4 characters of `ffap'.

Since `ffap' is an alias of `find-file-at-point', perhaps we should
add abbreviated versions that begin with the `ffap-' prefix as
aliases of full versions with long names:

                                            ALIAS
find-file-at-point                          ffap
dired-at-point                              ffap-dired
list-directory-at-point                     ffap-list-directory

find-file-read-only-at-point                ffap-read-only
find-alternate-file-at-point                ffap-alternate
find-file-literally-at-point                ffap-literally

find-file-other-window-at-point             ffap-other-window
find-file-read-only-other-window-at-point   ffap-read-only-other-window
dired-other-window-at-point                 ffap-dired-other-window
find-alternate-file-other-window-at-point   ffap-alternate-other-window

find-file-other-frame-at-point              ffap-other-frame
find-file-read-only-other-frame-at-point    ffap-read-only-other-frame
dired-other-frame-at-point                  ffap-dired-other-frame

-- 
Juri Linkov
http://www.jurta.org/emacs/




^ permalink raw reply	[flat|nested] 55+ messages in thread

* Re: read-file-name
  2009-11-09 14:31             ` read-file-name Stefan Monnier
@ 2009-11-10  0:55               ` Juri Linkov
  2009-11-10 17:25                 ` read-file-name Stefan Monnier
  0 siblings, 1 reply; 55+ messages in thread
From: Juri Linkov @ 2009-11-10  0:55 UTC (permalink / raw)
  To: Stefan Monnier; +Cc: emacs-devel

>> All completion functions support a list of default values
>> except `read-file-name'.  The following patch fills this hole.
>
> Looks OK, feel free to install it.
>
>> !       (if (consp default-filename)
>> ! 	  (setq default-filename (mapcar 'abbreviate-file-name default-filename))
>> ! 	(setq default-filename (abbreviate-file-name default-filename))))
>
> That should be
>
>        (setq default-filename
>              (if (consp default-filename)
>                  (mapcar 'abbreviate-file-name default-filename)
>                (abbreviate-file-name default-filename))))

Done.

BTW, do you know an Emacs function that does such
common subexpression elimination?

-- 
Juri Linkov
http://www.jurta.org/emacs/




^ permalink raw reply	[flat|nested] 55+ messages in thread

* Re: find-file-read-args
  2009-11-09 14:28             ` find-file-read-args Stefan Monnier
@ 2009-11-10  0:57               ` Juri Linkov
  2009-11-12  9:56               ` find-file-read-args Juri Linkov
  1 sibling, 0 replies; 55+ messages in thread
From: Juri Linkov @ 2009-11-10  0:57 UTC (permalink / raw)
  To: Stefan Monnier; +Cc: emacs-devel

>> The patch below implements this scheme, and additionally
>> includes an approved but not installed change proposed
>> by Drew in http://thread.gmane.org/gmane.emacs.devel/74534
>> that allows `M-n' with `C-x C-f' to get the file at point
>> in Dired mode.
>
> 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.

I had the same doubts whether to do this in read-file-name or find-file
since read-file-name is too general.  But I'll try to move the
"file-at-point" feature to read-file-name and see how well it really
works with other file and directory reading functions.

-- 
Juri Linkov
http://www.jurta.org/emacs/




^ permalink raw reply	[flat|nested] 55+ messages in thread

* Re: M-! M-n should fetch filename (Re: FFAP)
  2009-11-09 14:35             ` Stefan Monnier
@ 2009-11-10  0:59               ` Juri Linkov
  2009-11-10 17:29                 ` Stefan Monnier
  0 siblings, 1 reply; 55+ messages in thread
From: Juri Linkov @ 2009-11-10  0:59 UTC (permalink / raw)
  To: Stefan Monnier; +Cc: emacs-devel

>> What is missing is an ability of M-! M-n to fetch the filename as the
>> default in Dired mode using `dired-get-filename'.
>
> I don't have an opinion on whether that's good/bad/useful/...

It is useful when there is a need to prepare and run a command
from Dired with a file name in the middle of the command line,
i.e. instead of fiddling with `*' and `?' surrounded by whitespace
and hoping to get the right result with the `!' command,
it is easier just to type `M-! M-n' and build the explicit
command line based on the file name at point.

> If people find it to be a good feature, please rework the patch so
> there's only one call to file-relative-name, rather than one in each
> branch of the test.

Below is a version with only one call to file-relative-name:

Index: lisp/simple.el
===================================================================
RCS file: /sources/emacs/emacs/lisp/simple.el,v
retrieving revision 1.1022
diff -c -r1.1022 simple.el
*** lisp/simple.el	30 Oct 2009 02:00:30 -0000	1.1022
--- lisp/simple.el	10 Nov 2009 00:57:27 -0000
***************
*** 2136,2143 ****
    (interactive
     (list
      (read-shell-command "Shell command: " nil nil
! 			(and buffer-file-name
! 			     (file-relative-name buffer-file-name)))
      current-prefix-arg
      shell-command-default-error-buffer))
    ;; Look for a handler in case default-directory is a remote file name.
--- 2152,2163 ----
    (interactive
     (list
      (read-shell-command "Shell command: " nil nil
! 			(let ((filename
! 			       (cond
! 				((eq major-mode 'dired-mode)
! 				 (dired-get-filename nil t))
! 				(buffer-file-name))))
! 			  (and filename (file-relative-name filename))))
      current-prefix-arg
      shell-command-default-error-buffer))
    ;; Look for a handler in case default-directory is a remote file name.

-- 
Juri Linkov
http://www.jurta.org/emacs/




^ permalink raw reply	[flat|nested] 55+ messages in thread

* Re: read-file-name
  2009-11-10  0:55               ` read-file-name Juri Linkov
@ 2009-11-10 17:25                 ` Stefan Monnier
  0 siblings, 0 replies; 55+ messages in thread
From: Stefan Monnier @ 2009-11-10 17:25 UTC (permalink / raw)
  To: Juri Linkov; +Cc: emacs-devel

> BTW, do you know an Emacs function that does such
> common subexpression elimination?

No,


        Stefan




^ permalink raw reply	[flat|nested] 55+ messages in thread

* Re: M-! M-n should fetch filename (Re: FFAP)
  2009-11-10  0:59               ` Juri Linkov
@ 2009-11-10 17:29                 ` Stefan Monnier
  2009-11-11  0:12                   ` Juri Linkov
  0 siblings, 1 reply; 55+ messages in thread
From: Stefan Monnier @ 2009-11-10 17:29 UTC (permalink / raw)
  To: Juri Linkov; +Cc: emacs-devel

> ***************
> *** 2136,2143 ****
>     (interactive
>      (list
>       (read-shell-command "Shell command: " nil nil
> ! 			(and buffer-file-name
> ! 			     (file-relative-name buffer-file-name)))
>       current-prefix-arg
>       shell-command-default-error-buffer))
>     ;; Look for a handler in case default-directory is a remote file name.
> --- 2152,2163 ----
>     (interactive
>      (list
>       (read-shell-command "Shell command: " nil nil
> ! 			(let ((filename
> ! 			       (cond
> ! 				((eq major-mode 'dired-mode)
> ! 				 (dired-get-filename nil t))
> ! 				(buffer-file-name))))
> ! 			  (and filename (file-relative-name filename))))
>       current-prefix-arg
>       shell-command-default-error-buffer))
>     ;; Look for a handler in case default-directory is a remote file name.

I think if you rewrite it to

			(let ((filename
			       (cond
				(buffer-file-name)
				((eq major-mode 'dired-mode)
				 (dired-get-filename nil t)))))
			  (and filename (file-relative-name filename))))

it's a lot more clear why it's useful (it adds data, rather than just
changing one data for another).


        Stefan




^ permalink raw reply	[flat|nested] 55+ messages in thread

* Re: M-! M-n should fetch filename (Re: FFAP)
  2009-11-10 17:29                 ` Stefan Monnier
@ 2009-11-11  0:12                   ` Juri Linkov
  0 siblings, 0 replies; 55+ messages in thread
From: Juri Linkov @ 2009-11-11  0:12 UTC (permalink / raw)
  To: Stefan Monnier; +Cc: emacs-devel

> I think if you rewrite it to
>
> 			(let ((filename
> 			       (cond
> 				(buffer-file-name)
> 				((eq major-mode 'dired-mode)
> 				 (dired-get-filename nil t)))))
> 			  (and filename (file-relative-name filename))))
>
> it's a lot more clear why it's useful (it adds data, rather than just
> changing one data for another).

Done.

-- 
Juri Linkov
http://www.jurta.org/emacs/




^ permalink raw reply	[flat|nested] 55+ messages in thread

* Re: find-file-read-args
  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               ` Juri Linkov
  2009-11-12 10:45                 ` find-file-read-args martin rudalics
  1 sibling, 1 reply; 55+ messages in thread
From: Juri Linkov @ 2009-11-12  9:56 UTC (permalink / raw)
  To: Stefan Monnier; +Cc: emacs-devel

> 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/




^ permalink raw reply	[flat|nested] 55+ messages in thread

* Re: find-file-read-args
  2009-11-12  9:56               ` find-file-read-args Juri Linkov
@ 2009-11-12 10:45                 ` martin rudalics
  2009-11-12 10:51                   ` find-file-read-args Juri Linkov
  0 siblings, 1 reply; 55+ messages in thread
From: martin rudalics @ 2009-11-12 10:45 UTC (permalink / raw)
  To: Juri Linkov; +Cc: Stefan Monnier, emacs-devel

 > 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?

Isn't that the buffer shown in `minibuffer-selected-window'?

martin




^ permalink raw reply	[flat|nested] 55+ messages in thread

* Re: find-file-read-args
  2009-11-12 10:45                 ` find-file-read-args martin rudalics
@ 2009-11-12 10:51                   ` Juri Linkov
  2009-11-15 15:09                     ` find-file-read-args Juri Linkov
  0 siblings, 1 reply; 55+ messages in thread
From: Juri Linkov @ 2009-11-12 10:51 UTC (permalink / raw)
  To: martin rudalics; +Cc: Stefan Monnier, emacs-devel

>> 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?
>
> Isn't that the buffer shown in `minibuffer-selected-window'?

Thank you, I'll try to use this.

-- 
Juri Linkov
http://www.jurta.org/emacs/




^ permalink raw reply	[flat|nested] 55+ messages in thread

* Re: find-file-read-args
  2009-11-12 10:51                   ` find-file-read-args Juri Linkov
@ 2009-11-15 15:09                     ` Juri Linkov
  2009-11-15 17:28                       ` find-file-read-args martin rudalics
  0 siblings, 1 reply; 55+ messages in thread
From: Juri Linkov @ 2009-11-15 15:09 UTC (permalink / raw)
  To: martin rudalics; +Cc: Stefan Monnier, emacs-devel

>>> 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?
>>
>> Isn't that the buffer shown in `minibuffer-selected-window'?
>
> Thank you, I'll try to use this.

Unfortunately, `minibuffer-selected-window' is useless for Dired.
It returns the wrong window.  Instead of returning the original Dired
buffer's window it returns " *Marked Files*".

How this can be reproduced:
1. emacs -Q
2. (setq enable-recursive-minibuffers t)
3. `C-x d'
4. Mark more than 1 file
5. Type `C'
6. Type `M-: (window-buffer (minibuffer-selected-window)) RET'

Result: #<buffer  *Marked Files*>

-- 
Juri Linkov
http://www.jurta.org/emacs/




^ permalink raw reply	[flat|nested] 55+ messages in thread

* dired-dwim-target (was: FFAP)
  2009-11-06 21:19         ` FFAP Juri Linkov
                             ` (4 preceding siblings ...)
  2009-11-09 10:36           ` M-! M-n should fetch filename (Re: FFAP) Juri Linkov
@ 2009-11-15 15:12           ` Juri Linkov
  2009-11-23 21:12             ` dired-dwim-target-defaults (was: dired-dwim-target) Juri Linkov
  5 siblings, 1 reply; 55+ messages in thread
From: Juri Linkov @ 2009-11-15 15:12 UTC (permalink / raw)
  To: Stefan Monnier; +Cc: emacs-devel

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/




^ permalink raw reply	[flat|nested] 55+ messages in thread

* Re: find-file-read-args
  2009-11-15 15:09                     ` find-file-read-args Juri Linkov
@ 2009-11-15 17:28                       ` martin rudalics
  2009-11-16  1:23                         ` find-file-read-args Stefan Monnier
  0 siblings, 1 reply; 55+ messages in thread
From: martin rudalics @ 2009-11-15 17:28 UTC (permalink / raw)
  To: Juri Linkov; +Cc: Stefan Monnier, emacs-devel

 > Unfortunately, `minibuffer-selected-window' is useless for Dired.
 > It returns the wrong window.  Instead of returning the original Dired
 > buffer's window it returns " *Marked Files*".

Then the *Marked Files* buffer needs a buffer-local back reference to
the Dired window selected at the time the buffer was created.  The
assignment could be made directly before the `dired-pop-to-buffer' call
in `dired-mark-pop-up'.

martin




^ permalink raw reply	[flat|nested] 55+ messages in thread

* Re: find-file-read-args
  2009-11-15 17:28                       ` find-file-read-args martin rudalics
@ 2009-11-16  1:23                         ` Stefan Monnier
  2009-11-17  7:43                           ` find-file-read-args martin rudalics
  0 siblings, 1 reply; 55+ messages in thread
From: Stefan Monnier @ 2009-11-16  1:23 UTC (permalink / raw)
  To: martin rudalics; +Cc: Juri Linkov, emacs-devel

>> Unfortunately, `minibuffer-selected-window' is useless for Dired.
>> It returns the wrong window.  Instead of returning the original Dired
>> buffer's window it returns " *Marked Files*".

> Then the *Marked Files* buffer needs a buffer-local back reference to
> the Dired window selected at the time the buffer was created.  The
> assignment could be made directly before the `dired-pop-to-buffer' call
> in `dired-mark-pop-up'.

Or more simply, maybe dired should be changed such that the dired window
is selected instead of the *Marked Files* window when the minibuffer
is invoked.


        Stefan




^ permalink raw reply	[flat|nested] 55+ messages in thread

* Re: find-file-read-args
  2009-11-16  1:23                         ` find-file-read-args Stefan Monnier
@ 2009-11-17  7:43                           ` martin rudalics
  2009-11-17  9:59                             ` find-file-read-args Juri Linkov
  0 siblings, 1 reply; 55+ messages in thread
From: martin rudalics @ 2009-11-17  7:43 UTC (permalink / raw)
  To: Stefan Monnier; +Cc: Juri Linkov, emacs-devel

 > Or more simply, maybe dired should be changed such that the dired window
 > is selected instead of the *Marked Files* window when the minibuffer
 > is invoked.

I'm afraid this might affect `minibuffer-scroll-window' and thus the
behavior of C-M-v in a quite non-intuitive manner.

martin




^ permalink raw reply	[flat|nested] 55+ messages in thread

* Re: find-file-read-args
  2009-11-17  7:43                           ` find-file-read-args martin rudalics
@ 2009-11-17  9:59                             ` Juri Linkov
  2009-11-17 17:42                               ` dired-dwim-target-directory (was: find-file-read-args) Juri Linkov
                                                 ` (2 more replies)
  0 siblings, 3 replies; 55+ messages in thread
From: Juri Linkov @ 2009-11-17  9:59 UTC (permalink / raw)
  To: martin rudalics; +Cc: Stefan Monnier, emacs-devel

>> Or more simply, maybe dired should be changed such that the dired window
>> is selected instead of the *Marked Files* window when the minibuffer
>> is invoked.
>
> I'm afraid this might affect `minibuffer-scroll-window' and thus the
> behavior of C-M-v in a quite non-intuitive manner.

Don't worry, I think it's quite useless to get the filename at point
from the Dired buffer when copying multiple files (i.e. when it shows
the *Marked files* window).  A list of directories would be enough.
The complete patch below avoids this problem by setting
`minibuffer-default-add-function' to nil in `dired-do-create-files'
and thus not using the filename guessing.

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	17 Nov 2009 09:56:31 -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)
***************
*** 2020,2026 ****
  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: ")
    (switch-to-buffer (find-file-noselect filename nil t)))
  \f
  (defvar after-find-file-from-revert-buffer nil)
--- 2012,2021 ----
  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
!    (list (read-file-name
! 	  "Find file literally: " nil default-directory
! 	  (confirm-nonexistent-file-or-buffer))))
    (switch-to-buffer (find-file-noselect filename nil t)))
  \f
  (defvar after-find-file-from-revert-buffer nil)

Index: lisp/dired.el
===================================================================
RCS file: /sources/emacs/emacs/lisp/dired.el,v
retrieving revision 1.443
diff -c -r1.443 dired.el
*** lisp/dired.el	15 Nov 2009 16:23:11 -0000	1.443
--- lisp/dired.el	17 Nov 2009 09:57:27 -0000
***************
*** 599,610 ****
  	    (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
--- 599,606 ----
  	    (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.96
diff -c -r1.96 minibuffer.el
*** lisp/minibuffer.el	12 Nov 2009 23:10:06 -0000	1.96
--- lisp/minibuffer.el	17 Nov 2009 09:57:32 -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 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.
***************
*** 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,1407 ----
                      (lexical-let ((dir (file-name-as-directory
                                          (expand-file-name dir))))
                        (minibuffer-with-setup-hook
!                           (lambda ()
! 			    (setq default-directory dir)
! 			    ;; Unless a list of defaults in `minibuffer-default'
! 			    ;; is provided, reset it to nil and on the
! 			    ;; first request on `M-n' fill it with a list
! 			    ;; of defaults relevant for file-name reading.
! 			    (unless (consp minibuffer-default)
! 			      (setq minibuffer-default nil)
! 			      (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)))

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	17 Nov 2009 09:57:57 -0000
***************
*** 1462,1471 ****
  	 (default (and dired-one-file
  		       (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
--- 1462,1477 ----
  	 (default (and dired-one-file
  		       (expand-file-name (file-name-nondirectory (car fn-list))
  					 target-dir)))
+ 	 (defaults (dired-do-create-files-defaults
+ 		    dired-one-file 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 defaults))
! 		    (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,1537 ****
     (function read-file-name)
     (format prompt (dired-mark-prompt arg files)) dir default))
  
+ (defun dired-do-create-files-defaults (dired-one-file fn-list target-dir)
+   ;; Return a list of default values for `dired-do-create-files'.
+   (let ((current-dir (and (eq major-mode 'dired-mode)
+ 			  (dired-current-directory)))
+ 	dired-dirs)
+     ;; Get a list of directories of visible buffers in dired-mode.
+     (walk-windows (lambda (w)
+ 		    (with-current-buffer (window-buffer w)
+ 		      (and (eq major-mode 'dired-mode)
+ 			   (push (dired-current-directory) dired-dirs)))))
+     ;; Force the current dir to be the first in the list.
+     (setq dired-dirs
+ 	  (delete-dups (delq nil (cons current-dir (nreverse dired-dirs)))))
+     ;; Return default values.
+     (cond
+      (dired-dwim-target
+       ;; For non-nil `dired-dwim-target', remove the target dir from
+       ;; default values, because it should be already in initial input.
+       (setq dired-dirs (delete target-dir dired-dirs))
+       (if dired-one-file
+ 	  ;; For one file operation, provide a list that contains
+ 	  ;; other directories, other directories with the appended filename
+ 	  ;; and the target directory with the appended filename, e.g.
+ 	  ;; 1. /CURRENT-DIR/
+ 	  ;; 2. /CURRENT-DIR/FILENAME
+ 	  ;; 3. /TARGET-DIR/FILENAME
+ 	  (append dired-dirs
+ 		  (mapcar (lambda (dir)
+ 			    (expand-file-name
+ 			     (file-name-nondirectory (car fn-list)) dir))
+ 			  (reverse dired-dirs))
+ 		  (list (expand-file-name
+ 			 (file-name-nondirectory (car fn-list)) target-dir)))
+ 	;; For multi-file operation, provide a list of other directories.
+ 	dired-dirs))
+      (t
+       ;; For nil `dired-dwim-target', remove the current dir from
+       ;; default values, because it should be already in initial input.
+       (setq dired-dirs (delete current-dir dired-dirs))
+       (if dired-one-file
+ 	  ;; For one file operation, provide a list that contains
+ 	  ;; other directories, other directories with the appended filename
+ 	  ;; and the current directory with the appended filename, e.g.
+ 	  ;; 1. /TARGET-DIR/
+ 	  ;; 2. /TARGET-DIR/FILENAME
+ 	  ;; 3. /CURRENT-DIR/FILENAME
+ 	  (append dired-dirs
+ 		  (mapcar (lambda (dir)
+ 			    (expand-file-name
+ 			     (file-name-nondirectory (car fn-list)) dir))
+ 			  (reverse dired-dirs))
+ 		  (list (expand-file-name
+ 			 (file-name-nondirectory (car fn-list)) current-dir)))
+ 	;; For multi-file operation, provide a list of other directories.
+ 	dired-dirs)))))
+ 
  (defun dired-dwim-target-directory ()
    ;; Try to guess which target directory the user may want.

-- 
Juri Linkov
http://www.jurta.org/emacs/




^ permalink raw reply	[flat|nested] 55+ messages in thread

* dired-dwim-target-directory (was: find-file-read-args)
  2009-11-17  9:59                             ` find-file-read-args Juri Linkov
@ 2009-11-17 17:42                               ` Juri Linkov
  2009-11-17 17:43                               ` Juri Linkov
  2009-11-23  4:19                               ` find-file-read-args Stefan Monnier
  2 siblings, 0 replies; 55+ messages in thread
From: Juri Linkov @ 2009-11-17 17:42 UTC (permalink / raw)
  To: emacs-devel

There is one limitation of `dired-dwim-target-directory'.
It tries to get a Dired buffer displayed in the next window,
So when, for instance, there are two windows with Dired buffers
on the same frame and one non-Dired window, it can fail.

The following patch makes `dired-dwim-target-directory' more useful
by allowing it to find the next window that displays a Dired buffer.

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	17 Nov 2009 17:42:07 -0000
***************
*** 1520,1537 ****
     (function read-file-name)
     (format prompt (dired-mark-prompt arg files)) dir default))
  
  (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
!   ;; its current subdir, else use current subdir of this dired buffer.
    (let ((this-dir (and (eq major-mode 'dired-mode)
  		       (dired-current-directory))))
      ;; non-dired buffer may want to profit from this function, e.g. vm-uudecode
      (if dired-dwim-target
! 	(let* ((other-buf (window-buffer (next-window)))
! 	       (other-dir (with-current-buffer other-buf
! 			    (and (eq major-mode 'dired-mode)
! 				 (dired-current-directory)))))
  	  (or other-dir this-dir))
        this-dir)))
  \f
--- 1528,1546 ----
  (defun dired-dwim-target-directory ()
    ;; Try to guess which target directory the user may want.
!   ;; If there is a dired buffer displayed in one of the next windows,
!   ;; use its current subdir, else use current subdir of this dired buffer.
    (let ((this-dir (and (eq major-mode 'dired-mode)
  		       (dired-current-directory))))
      ;; non-dired buffer may want to profit from this function, e.g. vm-uudecode
      (if dired-dwim-target
! 	(let* ((other-win (get-window-with-predicate
! 			   (lambda (window)
! 			     (with-current-buffer (window-buffer window)
! 			       (eq major-mode 'dired-mode)))))
! 	       (other-dir (and other-win
! 			       (with-current-buffer (window-buffer other-win)
! 				 (and (eq major-mode 'dired-mode)
! 				      (dired-current-directory))))))
  	  (or other-dir this-dir))
        this-dir)))
  \f

-- 
Juri Linkov
http://www.jurta.org/emacs/




^ permalink raw reply	[flat|nested] 55+ messages in thread

* dired-dwim-target-directory (was: find-file-read-args)
  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
  2 siblings, 0 replies; 55+ messages in thread
From: Juri Linkov @ 2009-11-17 17:43 UTC (permalink / raw)
  To: emacs-devel

There are some other minibuffer prompts that suffer from the lack
of the directory names of other Dired windows in the default values.

Trying to compare files in Dired with a directory in another Dired
window on the same frame using `ediff-files', `dired-diff',
`dired-compare-directories' was troublesome until now.  The following
patch adds directories from other Dired windows to the default values.

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	17 Nov 2009 17:43:00 -0000
***************
*** 59,88 ****
  With prefix arg, prompt for second argument SWITCHES,
  which is options for `diff'."
    (interactive
!    (let ((current (dired-get-filename t))
! 	 (default (if (mark t)
! 		      (save-excursion (goto-char (mark t))
! 				      (dired-get-filename t t)))))
!      (if (or (equal default current)
! 	     (and (not (equal (dired-dwim-target-directory)
! 			      (dired-current-directory)))
! 		  (not mark-active)))
! 	 (setq default nil))
       (require 'diff)
!      (list (read-file-name (format "Diff %s with%s: "
! 				   current
! 				   (if default
! 				       (concat " (default " default ")")
! 				     ""))
! 			   (if default
! 			       (dired-current-directory)
! 			     (dired-dwim-target-directory))
! 			   default t)
! 	   (if current-prefix-arg
! 	       (read-string "Options for diff: "
! 			    (if (stringp diff-switches)
! 				diff-switches
! 			      (mapconcat 'identity diff-switches " ")))))))
    (diff file (dired-get-filename t) switches))
  
  ;;;###autoload
--- 59,85 ----
  With prefix arg, prompt for second argument SWITCHES,
  which is options for `diff'."
    (interactive
!    (let* ((current (dired-get-filename t))
! 	  (target-dir (dired-dwim-target-directory))
! 	  (marked (and (mark t) (save-excursion
! 				  (goto-char (mark t))
! 				  (dired-get-filename nil t))))
! 	  (defaults
! 	    (append (dired-do-create-files-defaults nil target-dir)
! 		    ;; Additional file with the mark.
! 		    (and marked (list marked)))))
       (require 'diff)
!      (list
!       (minibuffer-with-setup-hook
! 	  (lambda ()
! 	    (set (make-local-variable 'minibuffer-default-add-function) nil)
! 	    (setq minibuffer-default defaults))
! 	(read-file-name (format "Diff %s with: " current) target-dir nil t))
!       (if current-prefix-arg
! 	  (read-string "Options for diff: "
! 		       (if (stringp diff-switches)
! 			   diff-switches
! 			 (mapconcat 'identity diff-switches " ")))))))
    (diff file (dired-get-filename t) switches))
  
  ;;;###autoload
***************
*** 128,138 ****
      (not (and (= (nth 2 fa1) (nth 2 fa2))   - mark files with different UID
                (= (nth 3 fa1) (nth 3 fa2))))   and GID."
    (interactive
!    (list (read-directory-name (format "Compare %s with: "
! 				      (dired-current-directory))
! 			      (dired-dwim-target-directory)
! 			      (dired-dwim-target-directory))
!          (read-from-minibuffer "Mark if (lisp expr or RET): " nil nil t nil "nil")))
    (let* ((dir1 (dired-current-directory))
           (file-alist1 (dired-files-attributes dir1))
           (file-alist2 (dired-files-attributes dir2))
--- 125,141 ----
      (not (and (= (nth 2 fa1) (nth 2 fa2))   - mark files with different UID
                (= (nth 3 fa1) (nth 3 fa2))))   and GID."
    (interactive
!    (list
!     (let* ((target-dir (dired-dwim-target-directory))
! 	   (defaults (dired-do-create-files-defaults nil target-dir)))
!       (minibuffer-with-setup-hook
! 	  (lambda ()
! 	    (set (make-local-variable 'minibuffer-default-add-function) nil)
! 	    (setq minibuffer-default defaults))
! 	(read-directory-name (format "Compare %s with: "
! 				     (dired-current-directory))
! 			     target-dir target-dir t)))
!     (read-from-minibuffer "Mark if (lisp expr or RET): " nil nil t nil "nil")))
    (let* ((dir1 (dired-current-directory))
           (file-alist1 (dired-files-attributes dir1))
           (file-alist2 (dired-files-attributes dir2))

Index: lisp/ediff-util.el
===================================================================
RCS file: /sources/emacs/emacs/lisp/ediff-util.el,v
retrieving revision 1.99
diff -c -r1.99 ediff-util.el
*** lisp/ediff-util.el	13 Nov 2009 22:19:50 -0000	1.99
--- lisp/ediff-util.el	17 Nov 2009 17:43:23 -0000
***************
*** 3113,3133 ****
    (if (string= default-file "")
        (setq default-file nil))
  
!   (let (f)
!     (setq f (expand-file-name
! 	     (read-file-name
! 	      (format "%s%s "
! 		      prompt
! 		      (cond (default-file
! 			      (concat " (default " default-file "):"))
! 			    (t (concat " (default " default-dir "):"))))
! 	      default-dir
! 	      (or default-file default-dir)
! 	      t  ; must match, no-confirm
! 	      (if default-file (file-name-directory default-file))
! 	      )
! 	     default-dir
! 	     ))
      ;; If user entered a directory name, expand the default file in that
      ;; directory.  This allows the user to enter a directory name for the
      ;; B-file and diff against the default-file in that directory instead
--- 3113,3134 ----
    (if (string= default-file "")
        (setq default-file nil))
  
!   (let ((defaults (dired-do-create-files-defaults
! 		   nil (dired-dwim-target-directory)))
! 	f)
!     (setq f (minibuffer-with-setup-hook
! 		(lambda () (setq minibuffer-default defaults))
! 	      (read-file-name
! 	       (format "%s%s "
! 		       prompt
! 		       (cond (default-file
! 			       (concat " (default " default-file "):"))
! 			     (t (concat " (default " default-dir "):"))))
! 	       default-dir
! 	       (or default-file default-dir)
! 	       t			; must match, no-confirm
! 	       (if default-file (file-name-directory default-file)))))
!     (setq f (expand-file-name f default-dir))
      ;; If user entered a directory name, expand the default file in that
      ;; directory.  This allows the user to enter a directory name for the
      ;; B-file and diff against the default-file in that directory instead

-- 
Juri Linkov
http://www.jurta.org/emacs/




^ permalink raw reply	[flat|nested] 55+ messages in thread

* Re: find-file-read-args
  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                               ` Stefan Monnier
  2009-11-23  9:59                                 ` find-file-read-args Juri Linkov
  2009-11-23 21:17                                 ` find-file-literally (was: find-file-read-args) Juri Linkov
  2 siblings, 2 replies; 55+ messages in thread
From: Stefan Monnier @ 2009-11-23  4:19 UTC (permalink / raw)
  To: Juri Linkov; +Cc: martin rudalics, emacs-devel

> Don't worry, I think it's quite useless to get the filename at point
> from the Dired buffer when copying multiple files (i.e. when it shows
> the *Marked files* window).  A list of directories would be enough.
> The complete patch below avoids this problem by setting
> `minibuffer-default-add-function' to nil in `dired-do-create-files'
> and thus not using the filename guessing.

I think this is a useful feature.  I'm not yet 100% sure this is the
best way to provide it (I think a dedicated key would be at least as
good), but it saves us from figuring out which key to use: it's
very unintrusive.

So, I like it.  But I have some more questions:

> --- 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)

Can you explain this hunk?  This is a fairly delicate part of the
behavior of C-x C-f, so I'd like to understand how you reproduce it.

> ***************
> *** 2020,2026 ****
>   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: ")
>     (switch-to-buffer (find-file-noselect filename nil t)))
>   \f
>   (defvar after-find-file-from-revert-buffer nil)
> --- 2012,2021 ----
>   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
> !    (list (read-file-name
> ! 	  "Find file literally: " nil default-directory
> ! 	  (confirm-nonexistent-file-or-buffer))))
>     (switch-to-buffer (find-file-noselect filename nil t)))
>   \f
>   (defvar after-find-file-from-revert-buffer nil)

Good change, thank you.

> + 	   ((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?

> + 	(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))
> + 	  )))

I think this should be moved to a separate function (e.g. so it can be
used by a separate key-binding) in file.el.  That function could/should
obey a new hook file-name-at-point-functions hook which we'd run with
run-hook-with-args-until-success.

> ! 			    ;; Unless a list of defaults in `minibuffer-default'
> ! 			    ;; is provided, reset it to nil and on the
> ! 			    ;; first request on `M-n' fill it with a list
> ! 			    ;; of defaults relevant for file-name reading.
> ! 			    (unless (consp minibuffer-default)
> ! 			      (setq minibuffer-default nil)
> ! 			      (set (make-local-variable 'minibuffer-default-add-function)
> ! 				   (lambda ()
> ! 				     (with-current-buffer
> ! 					 (window-buffer (minibuffer-selected-window))
> ! 				       (read-file-name-defaults dir initial))))))

Is it really necessary to throw away the minibuffer-default if it's not
a cons?  I'd rather keep it and just add file-name-at-point.  That would
make the change a lot more "obviously safe".

> Index: lisp/dired-aux.el

Am I right that this part of the change is not strictly necessary?


        Stefan




^ permalink raw reply	[flat|nested] 55+ messages in thread

* Re: find-file-read-args
  2009-11-23  4:19                               ` find-file-read-args Stefan Monnier
@ 2009-11-23  9:59                                 ` Juri Linkov
  2009-11-23 20:17                                   ` find-file-read-args Stefan Monnier
  2009-11-23 21:17                                 ` find-file-literally (was: find-file-read-args) Juri Linkov
  1 sibling, 1 reply; 55+ messages in thread
From: Juri Linkov @ 2009-11-23  9:59 UTC (permalink / raw)
  To: Stefan Monnier; +Cc: martin rudalics, emacs-devel

> I think this is a useful feature.  I'm not yet 100% sure this is the
> best way to provide it (I think a dedicated key would be at least as
> good), but it saves us from figuring out which key to use: it's
> very unintrusive.
>
> So, I like it.  But I have some more questions:
>
>> --- 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)
>
> Can you explain this hunk?  This is a fairly delicate part of the
> behavior of C-x C-f,

The patch just moves the `minibuffer-with-setup-hook' from
`find-file-read-args' to `read-file-name', thus providing the logic of
setting of `minibuffer-default' to a wider set of file-reading
functions than only find-file-*.

> 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'.

>> + 	   ((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.

>> + 	(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))
>> + 	  )))
>
> I think this should be moved to a separate function (e.g. so it can be
> used by a separate key-binding) in file.el.  That function could/should
> obey a new hook file-name-at-point-functions hook which we'd run with
> run-hook-with-args-until-success.

OK, I'll create a new function that could later be bound to a dedicated key.

>> ! 			    ;; Unless a list of defaults in `minibuffer-default'
>> ! 			    ;; is provided, reset it to nil and on the
>> ! 			    ;; first request on `M-n' fill it with a list
>> ! 			    ;; of defaults relevant for file-name reading.
>> ! 			    (unless (consp minibuffer-default)
>> ! 			      (setq minibuffer-default nil)
>> ! 			      (set (make-local-variable 'minibuffer-default-add-function)
>> ! 				   (lambda ()
>> ! 				     (with-current-buffer
>> ! 					 (window-buffer (minibuffer-selected-window))
>> ! 				       (read-file-name-defaults dir initial))))))
>
> Is it really necessary to throw away the minibuffer-default if it's not
> a cons?  I'd rather keep it and just add file-name-at-point.  That would
> make the change a lot more "obviously safe".

For most file/directory reading functions the minibuffer-default
duplicates the initial input, so the first typing M-n is useless since
it doesn't change the minibuffer's contents.  I'll try to better detect
this situation than checking for a cons.

>> Index: lisp/dired-aux.el
>
> Am I right that this part of the change is not strictly necessary?

dired-aux.el is from other threads with the subject "dired-dwim-target"
and "dired-dwim-target-directory" that has separate reasonings for separate
but related changes.  I'll send a new patch for dired-aux.el in another message.

-- 
Juri Linkov
http://www.jurta.org/emacs/




^ permalink raw reply	[flat|nested] 55+ messages in thread

* Re: find-file-read-args
  2009-11-23  9:59                                 ` find-file-read-args Juri Linkov
@ 2009-11-23 20:17                                   ` Stefan Monnier
  2009-11-23 21:17                                     ` find-file-read-args Juri Linkov
  0 siblings, 1 reply; 55+ messages in thread
From: Stefan Monnier @ 2009-11-23 20:17 UTC (permalink / raw)
  To: Juri Linkov; +Cc: martin rudalics, emacs-devel

>> 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".
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?

>>> + 	(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))
>>> + 	  )))
>> 
>> I think this should be moved to a separate function (e.g. so it can be
>> used by a separate key-binding) in file.el.  That function could/should
>> obey a new hook file-name-at-point-functions hook which we'd run with
>> run-hook-with-args-until-success.

> 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).

>> Is it really necessary to throw away the minibuffer-default if it's not
>> a cons?  I'd rather keep it and just add file-name-at-point.  That would
>> make the change a lot more "obviously safe".
> For most file/directory reading functions the minibuffer-default
> duplicates the initial input, so the first typing M-n is useless since
> it doesn't change the minibuffer's contents.

Right, and that's what the minibuffer-setup-hook thingy in
find-file-read-args was trying to do.

> 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.

>>> Index: lisp/dired-aux.el
>> Am I right that this part of the change is not strictly necessary?

> dired-aux.el is from other threads with the subject
> "dired-dwim-target" and "dired-dwim-target-directory" that has
> separate reasonings for separate but related changes.  I'll send a new
> patch for dired-aux.el in another message.

That was my impression as well.  Thank you for separating them.


        Stefan




^ permalink raw reply	[flat|nested] 55+ messages in thread

* dired-dwim-target-defaults (was: dired-dwim-target)
  2009-11-15 15:12           ` dired-dwim-target (was: FFAP) Juri Linkov
@ 2009-11-23 21:12             ` Juri Linkov
  0 siblings, 0 replies; 55+ messages in thread
From: Juri Linkov @ 2009-11-23 21:12 UTC (permalink / raw)
  To: Stefan Monnier; +Cc: emacs-devel

> 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 `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

Below is a complete patch that implements this scheme for
`dired-do-create-files' related commands (copy, rename, etc.),
`dired-diff', `dired-compare-directories' and `ediff-read-file-name'.

(This is a separate issue not depending on `find-file-read-args'.)

Index: lisp/dired-aux.el
===================================================================
RCS file: /sources/emacs/emacs/lisp/dired-aux.el,v
retrieving revision 1.198
diff -c -r1.198 dired-aux.el
*** lisp/dired-aux.el	19 Nov 2009 07:42:24 -0000	1.198
--- lisp/dired-aux.el	23 Nov 2009 21:11:16 -0000
***************
*** 59,88 ****
  With prefix arg, prompt for second argument SWITCHES,
  which is options for `diff'."
    (interactive
!    (let ((current (dired-get-filename t))
! 	 (default (if (mark t)
! 		      (save-excursion (goto-char (mark t))
! 				      (dired-get-filename t t)))))
!      (if (or (equal default current)
! 	     (and (not (equal (dired-dwim-target-directory)
! 			      (dired-current-directory)))
! 		  (not mark-active)))
! 	 (setq default nil))
       (require 'diff)
!      (list (read-file-name (format "Diff %s with%s: "
! 				   current
! 				   (if default
! 				       (concat " (default " default ")")
! 				     ""))
! 			   (if default
! 			       (dired-current-directory)
! 			     (dired-dwim-target-directory))
! 			   default t)
! 	   (if current-prefix-arg
! 	       (read-string "Options for diff: "
! 			    (if (stringp diff-switches)
! 				diff-switches
! 			      (mapconcat 'identity diff-switches " ")))))))
    (diff file (dired-get-filename t) switches))
  
  ;;;###autoload
--- 59,85 ----
  With prefix arg, prompt for second argument SWITCHES,
  which is options for `diff'."
    (interactive
!    (let* ((current (dired-get-filename t))
! 	  (target-dir (dired-dwim-target-directory))
! 	  (marked (and (mark t) (save-excursion
! 				  (goto-char (mark t))
! 				  (dired-get-filename nil t))))
! 	  (defaults
! 	    (append (dired-dwim-target-defaults nil target-dir)
! 		    ;; Additional file with the mark.
! 		    (and marked (list marked)))))
       (require 'diff)
!      (list
!       (minibuffer-with-setup-hook
! 	  (lambda ()
! 	    (set (make-local-variable 'minibuffer-default-add-function) nil)
! 	    (setq minibuffer-default defaults))
! 	(read-file-name (format "Diff %s with: " current) target-dir nil t))
!       (if current-prefix-arg
! 	  (read-string "Options for diff: "
! 		       (if (stringp diff-switches)
! 			   diff-switches
! 			 (mapconcat 'identity diff-switches " ")))))))
    (diff file (dired-get-filename t) switches))
  
  ;;;###autoload
***************
*** 128,138 ****
      (not (and (= (nth 2 fa1) (nth 2 fa2))   - mark files with different UID
                (= (nth 3 fa1) (nth 3 fa2))))   and GID."
    (interactive
!    (list (read-directory-name (format "Compare %s with: "
! 				      (dired-current-directory))
! 			      (dired-dwim-target-directory)
! 			      (dired-dwim-target-directory))
!          (read-from-minibuffer "Mark if (lisp expr or RET): " nil nil t nil "nil")))
    (let* ((dir1 (dired-current-directory))
           (file-alist1 (dired-files-attributes dir1))
           (file-alist2 (dired-files-attributes dir2))
--- 125,141 ----
      (not (and (= (nth 2 fa1) (nth 2 fa2))   - mark files with different UID
                (= (nth 3 fa1) (nth 3 fa2))))   and GID."
    (interactive
!    (list
!     (let* ((target-dir (dired-dwim-target-directory))
! 	   (defaults (dired-dwim-target-defaults nil target-dir)))
!       (minibuffer-with-setup-hook
! 	  (lambda ()
! 	    (set (make-local-variable 'minibuffer-default-add-function) nil)
! 	    (setq minibuffer-default defaults))
! 	(read-directory-name (format "Compare %s with: "
! 				     (dired-current-directory))
! 			     target-dir target-dir t)))
!     (read-from-minibuffer "Mark if (lisp expr or RET): " nil nil t nil "nil")))
    (let* ((dir1 (dired-current-directory))
           (file-alist1 (dired-files-attributes dir1))
           (file-alist2 (dired-files-attributes dir2))
***************
*** 1463,1472 ****
  	 (default (and dired-one-file
  		       (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
--- 1466,1480 ----
  	 (default (and dired-one-file
  		       (expand-file-name (file-name-nondirectory (car fn-list))
  					 target-dir)))
+ 	 (defaults (dired-dwim-target-defaults 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 defaults))
! 		    (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
***************
*** 1523,1540 ****
  	  (or other-dir this-dir))
        this-dir)))
+ 
+ (defun dired-dwim-target-defaults (fn-list target-dir)
+   ;; Return a list of default values for file-reading functions in Dired.
+   ;; This list may contain directories from Dired buffers in other windows.
+   ;; `fn-list' is a list of file names used to build a list of defaults.
+   ;; When nil, a list of defaults will contain only directory names.
+   ;; `target-dir' is a directory name to exclude from the returned list,
+   ;; when this directory name is already presented in initial input.
+   ;; For Dired operations that support `dired-dwim-target', the argument
+   ;; `target-dir' should have the value returned from `dired-dwim-target-directory'.
+   (let ((dired-one-file
+ 	 (and (consp fn-list) (null (cdr fn-list)) (car fn-list)))
+ 	(current-dir (and (eq major-mode 'dired-mode)
+ 			  (dired-current-directory)))
+ 	dired-dirs)
+     ;; Get a list of directories of visible buffers in dired-mode.
+     (walk-windows (lambda (w)
+ 		    (with-current-buffer (window-buffer w)
+ 		      (and (eq major-mode 'dired-mode)
+ 			   (push (dired-current-directory) dired-dirs)))))
+     ;; Force the current dir to be the first in the list.
+     (setq dired-dirs
+ 	  (delete-dups (delq nil (cons current-dir (nreverse dired-dirs)))))
+     ;; Return default values.
+     ;; For nil `dired-dwim-target', remove the current dir from
+     ;; default values, because it should be already in initial input.
+     (setq dired-dirs (delete (or target-dir current-dir) dired-dirs))
+     (if dired-one-file
+ 	;; For one file operation, provide a list that contains
+ 	;; other directories, other directories with the appended filename
+ 	;; and the current directory with the appended filename, e.g.
+ 	;; 1. /TARGET-DIR/
+ 	;; 2. /TARGET-DIR/FILENAME
+ 	;; 3. /CURRENT-DIR/FILENAME
+ 	(append dired-dirs
+ 		(mapcar (lambda (dir)
+ 			  (expand-file-name
+ 			   (file-name-nondirectory (car fn-list)) dir))
+ 			(reverse dired-dirs))
+ 		(list (expand-file-name
+ 		       (file-name-nondirectory (car fn-list))
+ 		       (or target-dir current-dir))))
+       ;; For multi-file operation, provide a list of other directories.
+       dired-dirs)))
  \f
  ;;;###autoload
  (defun dired-create-directory (directory)

Index: lisp/ediff-util.el
===================================================================
RCS file: /sources/emacs/emacs/lisp/ediff-util.el,v
retrieving revision 1.100
diff -c -r1.100 ediff-util.el
*** lisp/ediff-util.el	22 Nov 2009 03:14:15 -0000	1.100
--- lisp/ediff-util.el	23 Nov 2009 21:12:23 -0000
***************
*** 3090,3095 ****
--- 3090,3096 ----
    (ediff-unhighlight-diffs-totally-in-one-buffer 'Ancestor)
    )
  
+ (declare-function dired-dwim-target-defaults "dired-aux" (fn-list target-dir))
  
  ;; This is adapted from a similar function in `emerge.el'.
  ;; PROMPT should not have a trailing ': ', so that it can be modified
***************
*** 3113,3133 ****
    (if (string= default-file "")
        (setq default-file nil))
  
!   (let (f)
!     (setq f (expand-file-name
! 	     (read-file-name
! 	      (format "%s%s "
! 		      prompt
! 		      (cond (default-file
! 			      (concat " (default " default-file "):"))
! 			    (t (concat " (default " default-dir "):"))))
! 	      default-dir
! 	      (or default-file default-dir)
! 	      t  ; must match, no-confirm
! 	      (if default-file (file-name-directory default-file))
! 	      )
! 	     default-dir
! 	     ))
      ;; If user entered a directory name, expand the default file in that
      ;; directory.  This allows the user to enter a directory name for the
      ;; B-file and diff against the default-file in that directory instead
--- 3114,3136 ----
    (if (string= default-file "")
        (setq default-file nil))
  
!   (let ((defaults (dired-dwim-target-defaults
! 		   (and default-file (list default-file))
! 		   default-dir))
! 	f)
!     (setq f (minibuffer-with-setup-hook
! 		(lambda () (setq minibuffer-default defaults))
! 	      (read-file-name
! 	       (format "%s%s "
! 		       prompt
! 		       (cond (default-file
! 			       (concat " (default " default-file "):"))
! 			     (t (concat " (default " default-dir "):"))))
! 	       default-dir
! 	       (or default-file default-dir)
! 	       t			; must match, no-confirm
! 	       (if default-file (file-name-directory default-file)))))
!     (setq f (expand-file-name f default-dir))
      ;; If user entered a directory name, expand the default file in that
      ;; directory.  This allows the user to enter a directory name for the
      ;; B-file and diff against the default-file in that directory instead

-- 
Juri Linkov
http://www.jurta.org/emacs/




^ permalink raw reply	[flat|nested] 55+ messages in thread

* find-file-literally (was: find-file-read-args)
  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 21:17                                 ` Juri Linkov
  2009-11-25  2:10                                   ` find-file-literally Stefan Monnier
  1 sibling, 1 reply; 55+ messages in thread
From: Juri Linkov @ 2009-11-23 21:17 UTC (permalink / raw)
  To: Stefan Monnier; +Cc: martin rudalics, emacs-devel

> So, I like it.  But I have some more questions:
>
>> ***************
>> *** 2020,2026 ****
>>   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: ")
>>     (switch-to-buffer (find-file-noselect filename nil t)))
>>   \f
>>   (defvar after-find-file-from-revert-buffer nil)
>> --- 2012,2021 ----
>>   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
>> !    (list (read-file-name
>> ! 	  "Find file literally: " nil default-directory
>> ! 	  (confirm-nonexistent-file-or-buffer))))
>>     (switch-to-buffer (find-file-noselect filename nil t)))
>>   \f
>>   (defvar after-find-file-from-revert-buffer nil)
>
> Good change, thank you.

Please note that this change would be unnecessary if following lines
were removed from `read-file-name':

  (unless default-filename
    (setq default-filename (if initial (expand-file-name initial dir)
                             buffer-file-name)))

That's because (interactive "FFind file literally: ") calls
`read-file-name' with `default-filename' = nil:

	case 'F':		/* Possibly nonexistent file name. */
	  args[i] = Fread_file_name (callint_message,
				     Qnil, Qnil, Qnil, Qnil, Qnil);

and `read-file-name' sets `default-filename' to `buffer-file-name'.

IMHO, it's dangerous when the user types RET on the directory name
(in the initial input) not expecting that buffer-file-name will be
really used as the default.

Fortunately, there are not many places where that call `read-file-name'
with `default-filename' = nil.  Most commands call `read-file-name'
with `default-filename' = default directory.

-- 
Juri Linkov
http://www.jurta.org/emacs/




^ permalink raw reply	[flat|nested] 55+ messages in thread

* Re: find-file-read-args
  2009-11-23 20:17                                   ` find-file-read-args Stefan Monnier
@ 2009-11-23 21:17                                     ` Juri Linkov
  2009-11-24  2:33                                       ` find-file-read-args Stefan Monnier
  0 siblings, 1 reply; 55+ messages in thread
From: Juri Linkov @ 2009-11-23 21:17 UTC (permalink / raw)
  To: Stefan Monnier; +Cc: martin rudalics, emacs-devel

>>> 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/




^ permalink raw reply	[flat|nested] 55+ messages in thread

* Re: find-file-read-args
  2009-11-23 21:17                                     ` find-file-read-args Juri Linkov
@ 2009-11-24  2:33                                       ` Stefan Monnier
  2009-11-24 17:08                                         ` find-file-read-args Juri Linkov
  0 siblings, 1 reply; 55+ messages in thread
From: Stefan Monnier @ 2009-11-24  2:33 UTC (permalink / raw)
  To: Juri Linkov; +Cc: martin rudalics, emacs-devel

>> 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'.

Now I wonder: is that code necessary at all?  If dired sets
file-name-at-point-functions, the dired-get-filename would get in the
minibuffer-defaults via file-name-at-point-functions, wouldn't it?

The idea with "no dired-specific code" is that if it's useful for dired
it's also useful for VC-Dir, PCL-CVS, etc...
So it looks like file-name-at-point-functions would be a good way to get
what we want.
WDYT?

> Done below.

Other than the dired issue discussed above, it looks good now, thank you.

> ! 			    (when (equal (or (car-safe insdef) insdef)
> ! 					 (or (car-safe minibuffer-default)
> ! 					     minibuffer-default))
> ! 			      (setq minibuffer-default nil))

I guess this nil should be something like

   (cdr-safe minibuffer-default)


-- Stefan




^ permalink raw reply	[flat|nested] 55+ messages in thread

* Re: find-file-read-args
  2009-11-24  2:33                                       ` find-file-read-args Stefan Monnier
@ 2009-11-24 17:08                                         ` Juri Linkov
  2009-11-24 19:40                                           ` find-file-read-args Stefan Monnier
  0 siblings, 1 reply; 55+ messages in thread
From: Juri Linkov @ 2009-11-24 17:08 UTC (permalink / raw)
  To: Stefan Monnier; +Cc: martin rudalics, emacs-devel

> Now I wonder: is that code necessary at all?  If dired sets
> file-name-at-point-functions, the dired-get-filename would get in the
> minibuffer-defaults via file-name-at-point-functions, wouldn't it?
>
> The idea with "no dired-specific code" is that if it's useful for dired
> it's also useful for VC-Dir, PCL-CVS, etc...
> So it looks like file-name-at-point-functions would be a good way to get
> what we want.
> WDYT?

This works correctly with this patch that adds `dired-file-name-at-point'.
(Only relevant changes included, omitting unchanged parts of the whole
patch from the previous message).

Index: lisp/dired.el
===================================================================
RCS file: /sources/emacs/emacs/lisp/dired.el,v
retrieving revision 1.444
diff -c -r1.444 dired.el
*** lisp/dired.el	19 Nov 2009 16:49:24 -0000	1.444
--- lisp/dired.el	24 Nov 2009 17:08:33 -0000
***************
*** 587,592 ****
--- 587,603 ----
  \f
  ;; The dired command
  
+ ;;;###autoload
+ (progn (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'."
+   (when (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)))))))
+ 
  (defun dired-read-dir-and-switches (str)
    ;; For use in interactive.
    (reverse (list

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	24 Nov 2009 17:08:20 -0000
***************
*** 411,416 ****
--- 411,426 ----
    :type '(hook :options (cvs-dired-noselect dired-noselect))
    :group 'find-file)
  
+ (defcustom file-name-at-point-functions '(dired-file-name-at-point
+ 					  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 (dired-file-name-at-point
+ 			 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

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	24 Nov 2009 17:08:28 -0000
***************
*** 1320,1325 ****
--- 1320,1352 ----
  ;; 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))))
+ 	(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.

-- 
Juri Linkov
http://www.jurta.org/emacs/




^ permalink raw reply	[flat|nested] 55+ messages in thread

* Re: find-file-read-args
  2009-11-24 17:08                                         ` find-file-read-args Juri Linkov
@ 2009-11-24 19:40                                           ` Stefan Monnier
  0 siblings, 0 replies; 55+ messages in thread
From: Stefan Monnier @ 2009-11-24 19:40 UTC (permalink / raw)
  To: Juri Linkov; +Cc: martin rudalics, emacs-devel

> + ;;;###autoload
> + (progn (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'."
> +   (when (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)))))))
[...]
> + (defcustom file-name-at-point-functions '(dired-file-name-at-point
> + 					  ffap-guess-file-name-at-point)

Almost right: don't put dired-file-name-at-point in the default value.
Instead use `add-hook' in dired-mode to add it buffer-locally.
That will also get you rid of the ugly (eq major-mode 'dired-mode).
After that, please install your patch (and advertise it well in
etc/NEWS).  And thank you very much for working on it.


        Stefan




^ permalink raw reply	[flat|nested] 55+ messages in thread

* Re: find-file-literally
  2009-11-23 21:17                                 ` find-file-literally (was: find-file-read-args) Juri Linkov
@ 2009-11-25  2:10                                   ` Stefan Monnier
  0 siblings, 0 replies; 55+ messages in thread
From: Stefan Monnier @ 2009-11-25  2:10 UTC (permalink / raw)
  To: Juri Linkov; +Cc: martin rudalics, emacs-devel

>>> !   (interactive
>>> !    (list (read-file-name
>>> ! 	  "Find file literally: " nil default-directory
>>> ! 	  (confirm-nonexistent-file-or-buffer))))
>> Good change, thank you.
> Please note that this change would be unnecessary if following lines
> were removed from `read-file-name':

>   (unless default-filename
>     (setq default-filename (if initial (expand-file-name initial dir)
>                              buffer-file-name)))

The part I like is (confirm-nonexistent-file-or-buffer) which wouldn't
be solved by removing those lines, right?


        Stefan




^ permalink raw reply	[flat|nested] 55+ messages in thread

end of thread, other threads:[~2009-11-25  2:10 UTC | newest]

Thread overview: 55+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
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                                     ` find-file-read-args Juri Linkov
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

Code repositories for project(s) associated with this public inbox

	https://git.savannah.gnu.org/cgit/emacs.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).