* substitute-in-file-name is not distributive
@ 2012-10-10 5:36 Daniel Colascione
2012-10-10 6:39 ` Andreas Schwab
` (2 more replies)
0 siblings, 3 replies; 19+ messages in thread
From: Daniel Colascione @ 2012-10-10 5:36 UTC (permalink / raw
To: Emacs development discussions
[-- Attachment #1: Type: text/plain, Size: 1392 bytes --]
I wrote a bit of code to handle Windows paths in being given to
read-file-name in a Cygwin Emacs --- it's just a simple
file-name-handler-alist entry that overrides substitute-in-file-name
for Windows paths to yield the corresponding Cygwin path. Why not view
Windows path syntax as a funky way to "quote" Cygwin paths? This
approach works fine, except for completion.
The trouble is that the core completion code makes unwarranted
assumptions about the behavior of expand-in-file-name. Specifically,
completion--tqw-all assumes that (equal (unquote (concat (qnew foo)
(qnew bar)) (unquote (quote (concat foo bar))). Why should that be the
case?
In my mockup, I'm trying to complete 'c:\'. I have a 'c:\bin';
converting the path 'c:\bin' to Cygwin yields "/usr/bin" on my
machine. The trouble is that when we try to get all the completions
for 'c:\', which "unquoted" is '/' on my machine. completion--tqw-all
wants to paste '/' and 'bin' together to yield '/bin', but my s-i-f-n
handler returns '/usr/bin', so completion--qw-all's last cl-assert fails.
I don't think it's fair to assume that substitute-in-file-name
distributes over all components of a path. Unfortunately, simply
removing the assertion causes mysterious failures elsewhere. The
assumption of a distributing s-i-f-n seems baked into the code.
Is there another way to do what I want here?
[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 235 bytes --]
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: substitute-in-file-name is not distributive
2012-10-10 5:36 substitute-in-file-name is not distributive Daniel Colascione
@ 2012-10-10 6:39 ` Andreas Schwab
2012-10-10 15:31 ` Eli Zaretskii
2012-10-25 3:20 ` Stefan Monnier
2 siblings, 0 replies; 19+ messages in thread
From: Andreas Schwab @ 2012-10-10 6:39 UTC (permalink / raw
To: Daniel Colascione; +Cc: Emacs development discussions
Daniel Colascione <dancol@dancol.org> writes:
> In my mockup, I'm trying to complete 'c:\'. I have a 'c:\bin';
> converting the path 'c:\bin' to Cygwin yields "/usr/bin" on my
> machine. The trouble is that when we try to get all the completions
> for 'c:\', which "unquoted" is '/' on my machine. completion--tqw-all
> wants to paste '/' and 'bin' together to yield '/bin', but my s-i-f-n
> handler returns '/usr/bin', so completion--qw-all's last cl-assert fails.
That looks more like c:/bin being a symlink to /usr/bin.
Andreas.
--
Andreas Schwab, schwab@linux-m68k.org
GPG Key fingerprint = 58CA 54C7 6D53 942B 1756 01D3 44D5 214B 8276 4ED5
"And now for something completely different."
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: substitute-in-file-name is not distributive
2012-10-10 5:36 substitute-in-file-name is not distributive Daniel Colascione
2012-10-10 6:39 ` Andreas Schwab
@ 2012-10-10 15:31 ` Eli Zaretskii
2012-10-10 16:48 ` Daniel Colascione
2012-10-11 3:25 ` Stephen Leake
2012-10-25 3:20 ` Stefan Monnier
2 siblings, 2 replies; 19+ messages in thread
From: Eli Zaretskii @ 2012-10-10 15:31 UTC (permalink / raw
To: Daniel Colascione; +Cc: emacs-devel
> Date: Tue, 09 Oct 2012 22:36:21 -0700
> From: Daniel Colascione <dancol@dancol.org>
>
> I wrote a bit of code to handle Windows paths in being given to
> read-file-name in a Cygwin Emacs --- it's just a simple
> file-name-handler-alist entry that overrides substitute-in-file-name
> for Windows paths to yield the corresponding Cygwin path.
I'm not sure I understand the use case. Are you talking about a user
who wants to feed a Cygwin Emacs with a native Windows style file
name? Why would she want to do that?
I could understand a different use case: when a native Windows program
invoked by a Cygwin Emacs returns Windows style file names. But for
that, read-file-name is not the place to add support for this.
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: substitute-in-file-name is not distributive
2012-10-10 15:31 ` Eli Zaretskii
@ 2012-10-10 16:48 ` Daniel Colascione
2012-10-10 17:18 ` Eli Zaretskii
2012-10-11 3:25 ` Stephen Leake
1 sibling, 1 reply; 19+ messages in thread
From: Daniel Colascione @ 2012-10-10 16:48 UTC (permalink / raw
To: Eli Zaretskii; +Cc: emacs-devel
[-- Attachment #1: Type: text/plain, Size: 1065 bytes --]
On 10/10/12 8:31 AM, Eli Zaretskii wrote:
>> Date: Tue, 09 Oct 2012 22:36:21 -0700
>> From: Daniel Colascione <dancol@dancol.org>
>>
>> I wrote a bit of code to handle Windows paths in being given to
>> read-file-name in a Cygwin Emacs --- it's just a simple
>> file-name-handler-alist entry that overrides substitute-in-file-name
>> for Windows paths to yield the corresponding Cygwin path.
>
> I'm not sure I understand the use case. Are you talking about a user
> who wants to feed a Cygwin Emacs with a native Windows style file
> name? Why would she want to do that?
Copy and paste from the clipboard comes to mind. Cygwin itself deals
adequately with being given Windows paths --- it's Emacs that could
handle them more elegantly.
> I could understand a different use case: when a native Windows program
> invoked by a Cygwin Emacs returns Windows style file names. But for
> that, read-file-name is not the place to add support for this.
That's why I made it a substitute-in-file-name hander. Where would you
put the code?
[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 235 bytes --]
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: substitute-in-file-name is not distributive
2012-10-10 16:48 ` Daniel Colascione
@ 2012-10-10 17:18 ` Eli Zaretskii
2012-10-10 17:40 ` Daniel Colascione
0 siblings, 1 reply; 19+ messages in thread
From: Eli Zaretskii @ 2012-10-10 17:18 UTC (permalink / raw
To: Daniel Colascione; +Cc: emacs-devel
> Date: Wed, 10 Oct 2012 09:48:21 -0700
> From: Daniel Colascione <dancol@dancol.org>
> CC: emacs-devel@gnu.org
>
> Cygwin itself deals adequately with being given Windows paths ---
> it's Emacs that could handle them more elegantly.
If Cygwin can handle these file names (which is what I thought was the
case), why not change expand-file-name so that the DOS_NT parts there
are also compiled in for Cygwin?
Hmm... but then typing "C-x C-f /foo/bar TAB" will prepend a drive
letter, perhaps, which is not what you want.
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: substitute-in-file-name is not distributive
2012-10-10 17:18 ` Eli Zaretskii
@ 2012-10-10 17:40 ` Daniel Colascione
0 siblings, 0 replies; 19+ messages in thread
From: Daniel Colascione @ 2012-10-10 17:40 UTC (permalink / raw
To: Eli Zaretskii; +Cc: emacs-devel
[-- Attachment #1: Type: text/plain, Size: 2573 bytes --]
On 10/10/12 10:18 AM, Eli Zaretskii wrote:
>> Date: Wed, 10 Oct 2012 09:48:21 -0700
>> From: Daniel Colascione <dancol@dancol.org>
>> CC: emacs-devel@gnu.org
>>
>> Cygwin itself deals adequately with being given Windows paths ---
>> it's Emacs that could handle them more elegantly.
It's important to note that the Cygwin and Windows path trees can be
completely disjoint. Cygwin has its own mount table. I have my system
configured so that there's a close resemblance between the two
hierarchies, but it doesn't have to be so. c:\foo could map to
/qux/bar/spam/blah.
> If Cygwin can handle these file names (which is what I thought was the
> case), why not change expand-file-name so that the DOS_NT parts there
> are also compiled in for Cygwin?
>
> Hmm... but then typing "C-x C-f /foo/bar TAB" will prepend a drive
> letter, perhaps, which is not what you want.
Right. I suppose I could change the code so that we understand both
kinds of path but prefer POSIX ones, but the approach I have in mind
feels more elegant. What happens with my s-i-f-n handler is that
read-file-name accepts Windows paths and (when completion works)
completes them, but as soon as the user accepts a path, it's converted
to a Cygwin path and remains as a Cygwin path through the rest of
Emacs. It's pretty elegant in practice.
If we do nothing, Emacs treats Windows paths as opaque blobs. From
Emacs' point of view, if you try to find-file c:\etc\passwd when
default-directory is "/etc", you're asking Emacs to find the file
"/etc/c:\\etc\\passwd". That's not right.
There are three approaches to solving the problem:
1) Modify the DOS_NT code so that Cygwin Emacs can parse Windows
paths. Pass all paths to Cygwin and let Cygwin sort them out. This
approach will configure the hell out of other bits of code that assume
that we have Windows paths IFF (memq system-time '(windowsnt dos)).
It also complicates file-directory-name and friends.
2) Explicitly reject Windows paths and provide a way for the user to
trigger path conversion. This approach strikes me as inconvenient.
3) Use a s-i-f-n hook to convert paths to Cygwin ones. This approach
works well enough aside from the completion breakage. One way to deal
with the completion problem would be to build completions based on the
*Windows* path, not the Cygwin path, but it wasn't apparent to me how
you could convince the code to do that. There's no
file-name-handler-alist handler for "build me a set of completions,
but before you call substitute-in-file-name."
[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 235 bytes --]
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: substitute-in-file-name is not distributive
2012-10-10 15:31 ` Eli Zaretskii
2012-10-10 16:48 ` Daniel Colascione
@ 2012-10-11 3:25 ` Stephen Leake
1 sibling, 0 replies; 19+ messages in thread
From: Stephen Leake @ 2012-10-11 3:25 UTC (permalink / raw
To: emacs-devel
Eli Zaretskii <eliz@gnu.org> writes:
> I'm not sure I understand the use case. Are you talking about a user
> who wants to feed a Cygwin Emacs with a native Windows style file
> name? Why would she want to do that?
Because usually it Just Works :).
I run Cygwin Emacs for Gnus at work, because it handles the secure
connection properly. But I just pretend it's native most of the time,
and it's fine. Whenever it isn't, I use the Cygwin path.
--
-- Stephe
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: substitute-in-file-name is not distributive
2012-10-10 5:36 substitute-in-file-name is not distributive Daniel Colascione
2012-10-10 6:39 ` Andreas Schwab
2012-10-10 15:31 ` Eli Zaretskii
@ 2012-10-25 3:20 ` Stefan Monnier
2012-10-25 3:28 ` Daniel Colascione
2 siblings, 1 reply; 19+ messages in thread
From: Stefan Monnier @ 2012-10-25 3:20 UTC (permalink / raw
To: Daniel Colascione; +Cc: Emacs development discussions
> The trouble is that the core completion code makes unwarranted
> assumptions about the behavior of expand-in-file-name. Specifically,
> completion--tqw-all assumes that (equal (unquote (concat (qnew foo)
> (qnew bar)) (unquote (quote (concat foo bar))). Why should that be
> the case?
Long story. For typical escaping/quoting this does hold.
Of course, for more general rewrites, it doesn't.
Can you give me your file-name-handler code so I can play with it (I
don't have Cygwin at hand, but I should be able to make up the
difference).
I think the problem is in completion--sifn-requote, which is definitely
not prepared for the kind of rewrites you're doing.
Stefan
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: substitute-in-file-name is not distributive
2012-10-25 3:20 ` Stefan Monnier
@ 2012-10-25 3:28 ` Daniel Colascione
2012-10-27 16:08 ` Stefan Monnier
2012-10-28 19:09 ` Stefan Monnier
0 siblings, 2 replies; 19+ messages in thread
From: Daniel Colascione @ 2012-10-25 3:28 UTC (permalink / raw
To: Stefan Monnier; +Cc: Emacs development discussions
[-- Attachment #1: Type: text/plain, Size: 2280 bytes --]
On 10/24/2012 8:20 PM, Stefan Monnier wrote:
>> The trouble is that the core completion code makes unwarranted
>> assumptions about the behavior of expand-in-file-name. Specifically,
>> completion--tqw-all assumes that (equal (unquote (concat (qnew foo)
>> (qnew bar)) (unquote (quote (concat foo bar))). Why should that be
>> the case?
>
> Long story. For typical escaping/quoting this does hold.
> Of course, for more general rewrites, it doesn't.
>
> Can you give me your file-name-handler code so I can play with it (I
> don't have Cygwin at hand, but I should be able to make up the
> difference).
> I think the problem is in completion--sifn-requote, which is definitely
> not prepared for the kind of rewrites you're doing.
Here's what I threw together to try to get this working. I took a look at
minibuffer.el and other pieces of code seem to make the same assumption. Maybe
the requote operation needs a a file-name-handler?
(defun cygwin-handler (operation &rest args)
(when (eq operation 'substitute-in-file-name)
;;
;; Convert Windows paths to Cygwin paths. Take care to preserve
;; trailing "." and ".." suffixes so that completion doesn't
;; break. Punt to the regular substitute-in-file-name once we've
;; converted the path to a Cygwin one.
;;
(let* ((path (car args))
(orig-path path)
(suffix ""))
(when (string-match (rx bos
(group (* any) (or "/" "\\"))
(group "." (? ".") "/")
eos)
path)
(setf suffix (match-string 2 path))
(setf path (match-string 1 path)))
(let ((posix-path
(concat (cygwin-convert-path-from-windows path)
suffix)))
(message "CYG: %S -> %S" orig-path posix-path)
(setf args (list posix-path)))))
(let ((inhibit-file-name-handlers
(cons 'cygwin-handler
(and (eq inhibit-file-name-operation operation)
inhibit-file-name-handlers)))
(inhibit-file-name-operation operation))
(apply operation args)))
(add-to-list 'file-name-handler-alist '("\\\\" . cygwin-handler))
[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 256 bytes --]
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: substitute-in-file-name is not distributive
2012-10-25 3:28 ` Daniel Colascione
@ 2012-10-27 16:08 ` Stefan Monnier
2012-10-28 19:09 ` Stefan Monnier
1 sibling, 0 replies; 19+ messages in thread
From: Stefan Monnier @ 2012-10-27 16:08 UTC (permalink / raw
To: Daniel Colascione; +Cc: Emacs development discussions
> Here's what I threw together to try to get this working. I took
> a look at minibuffer.el and other pieces of code seem to make the
> same assumption.
Thanks, I'll try and see what I can come up with.
> Maybe the requote operation needs a file-name-handler?
I hesitated to do that, and am still hesitating. It might be useful for
the Tramp handler, but for your case I don't think it would help,
because your unquote operation is a black box (at least, you'd rather
treat it like that), so your requote operation should basically be
"generic".
Stefan
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: substitute-in-file-name is not distributive
2012-10-25 3:28 ` Daniel Colascione
2012-10-27 16:08 ` Stefan Monnier
@ 2012-10-28 19:09 ` Stefan Monnier
2012-10-30 4:10 ` Daniel Colascione
1 sibling, 1 reply; 19+ messages in thread
From: Stefan Monnier @ 2012-10-28 19:09 UTC (permalink / raw
To: Daniel Colascione; +Cc: Emacs development discussions
> Here's what I threw together to try to get this working. I took a look
> at minibuffer.el and other pieces of code seem to make the same
> assumption. Maybe the requote operation needs a a file-name-handler?
I installed a new implementation of the requote, which should handle
your case better. It still tripped up some later assertions, but
I think those assertions are too strict in this case, so I commented
them out and it seemed to work in my test.
If you still find bogus behavior, please file a bug-report.
Stefan
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: substitute-in-file-name is not distributive
2012-10-28 19:09 ` Stefan Monnier
@ 2012-10-30 4:10 ` Daniel Colascione
2012-10-30 13:15 ` Stefan Monnier
0 siblings, 1 reply; 19+ messages in thread
From: Daniel Colascione @ 2012-10-30 4:10 UTC (permalink / raw
To: Stefan Monnier; +Cc: Emacs development discussions
[-- Attachment #1: Type: text/plain, Size: 1070 bytes --]
On 10/28/2012 12:09 PM, Stefan Monnier wrote:
>> Here's what I threw together to try to get this working. I took a look
>> at minibuffer.el and other pieces of code seem to make the same
>> assumption. Maybe the requote operation needs a a file-name-handler?
>
> I installed a new implementation of the requote, which should handle
> your case better. It still tripped up some later assertions, but
> I think those assertions are too strict in this case, so I commented
> them out and it seemed to work in my test.
> If you still find bogus behavior, please file a bug-report.
>
Now c:\bin\ gets transformed into c:/usr/bin/ at the completion prompt, which is
no good: besides being the wrong completion (with respect to c:\bin\, since
there is no c:\usr at the Windows level), the lack of backslashes in the
substituted path completely disables the file-name-handler I'm trying to use.
I feel like I need a hook outside the quoting done by the function with
completion-table-with-quoting. I'll see whether I can mock something up with advice.
[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 256 bytes --]
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: substitute-in-file-name is not distributive
2012-10-30 4:10 ` Daniel Colascione
@ 2012-10-30 13:15 ` Stefan Monnier
2012-10-30 15:01 ` Daniel Colascione
0 siblings, 1 reply; 19+ messages in thread
From: Stefan Monnier @ 2012-10-30 13:15 UTC (permalink / raw
To: Daniel Colascione; +Cc: Emacs development discussions
>>> Here's what I threw together to try to get this working. I took a look
>>> at minibuffer.el and other pieces of code seem to make the same
>>> assumption. Maybe the requote operation needs a a file-name-handler?
>> I installed a new implementation of the requote, which should handle
>> your case better. It still tripped up some later assertions, but
>> I think those assertions are too strict in this case, so I commented
>> them out and it seemed to work in my test.
>> If you still find bogus behavior, please file a bug-report.
> Now c:\bin\ gets transformed into c:/usr/bin/ at the completion
> prompt, which is no good:
Hmm... that's odd. Can you give me some details:
- tell me exactly which text you typed in the minibuffer.
- also tell me how the rfn-eshadow highlights the file name at each step.
> besides being the wrong completion (with respect to c:\bin\, since
> there is no c:\usr at the Windows level), the lack of backslashes in
> the substituted path completely disables the file-name-handler I'm
> trying to use.
Right. BTW I'm not convinced this is the right pattern to use for your
file-name-handler. I think catching "\\[a-zA-Z]:" or something along
these lines might be a better choice.
BTW, does Cygwin allow backslashes in file-names or does it interpret it
as a separator, like Windows does?
Stefan
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: substitute-in-file-name is not distributive
2012-10-30 13:15 ` Stefan Monnier
@ 2012-10-30 15:01 ` Daniel Colascione
2012-10-30 18:58 ` Stefan Monnier
0 siblings, 1 reply; 19+ messages in thread
From: Daniel Colascione @ 2012-10-30 15:01 UTC (permalink / raw
To: Stefan Monnier; +Cc: Emacs development discussions
[-- Attachment #1: Type: text/plain, Size: 1171 bytes --]
On 10/30/2012 6:15 AM, Stefan Monnier wrote:
> Hmm... that's odd. Can you give me some details:
> - tell me exactly which text you typed in the minibuffer.
I typed "c:\bin\" in the minibuffer and hit tab. After hitting tab, the
minibuffer contained "c:/usr/bin", with point at the end.
> - also tell me how the rfn-eshadow highlights the file name at each step.
Now that you mention it, I do see that the leading "c:" in the minibuffer
ishighlighted. That explains why we're substituting "c:/usr/bin" and not "/usr/bin".
> Right. BTW I'm not convinced this is the right pattern to use for your
> file-name-handler. I think catching "\\[a-zA-Z]:" or something along
> these lines might be a better choice.
Not all paths I want to catch are absolute, so looking for a drive letter won't
catch everything. Even "absolute" paths can be drive-letter-relative and begin
with a simple backslash. Looking for a backslash is convenient because no
legitimate Cygwin path contains one.
> BTW, does Cygwin allow backslashes in file-names or does it interpret it
> as a separator, like Windows does?
Cygwin interprets backslashes as separators.
[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 256 bytes --]
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: substitute-in-file-name is not distributive
2012-10-30 15:01 ` Daniel Colascione
@ 2012-10-30 18:58 ` Stefan Monnier
2012-10-30 20:12 ` Daniel Colascione
0 siblings, 1 reply; 19+ messages in thread
From: Stefan Monnier @ 2012-10-30 18:58 UTC (permalink / raw
To: Daniel Colascione; +Cc: Emacs development discussions
>> Hmm... that's odd. Can you give me some details:
>> - tell me exactly which text you typed in the minibuffer.
> I typed "c:\bin\" in the minibuffer and hit tab. After hitting tab, the
> minibuffer contained "c:/usr/bin", with point at the end.
>> - also tell me how the rfn-eshadow highlights the file name at each step.
> Now that you mention it, I do see that the leading "c:" in the
> minibuffer is highlighted. That explains why we're substituting
> "c:/usr/bin" and not "/usr/bin".
Right.
The "c:" is highlighted because (s-i-f-n "c:\\bin") = (s-i-f-n "\\bin").
Now the problem is that when you replace \bin by /usr/bin suddenly that
same rule doesn't apply any more.
Hmm... I think the core of the problem here is that minibuffer
completion is actually only performed on "the current field" which is
usually the whole minibuffer content, but not with rfn-eshadow.
To fix this, we should invert the relationship between
minibuffer-complete and completion-in-region (i.e. minibuffer-complete
should call completion-in-region rather than the other way around).
This would probably be a good change, but we can't do it for 24.3.
You should be able to work around this problem by removing "field
shadow" from file-name-shadow-properties.
>> Right. BTW I'm not convinced this is the right pattern to use for your
>> file-name-handler. I think catching "\\[a-zA-Z]:" or something along
>> these lines might be a better choice.
> Not all paths I want to catch are absolute,
Why not? Which non-absolute file names [we only use "path" for lists
of directories, as in $INFOPATH] would you need/want to rewrite?
Do you just want to replace \ with / in relative file names or is there
more to it?
> Even "absolute" paths can be drive-letter-relative and begin with
> a simple backslash.
Right, that's what triggers the above problem.
>> BTW, does Cygwin allow backslashes in file-names or does it interpret it
>> as a separator, like Windows does?
> Cygwin interprets backslashes as separators.
So Cygin itself treats "\\bin" and "/bin" as equivalent, but your
rewrite rules treat "\\bin" as a Windows file name and rewrite it to
"/usr/bin"?
If you limit yourself to:
- rewrite "\\`[a-zA-Z]:" to "/cygdrive/c" (regardless if it is followed
by backslashes or forwardslashes).
- rewrite \ to / everywhere.
This should cover the main needs without tripping over the above problem.
Stefan
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: substitute-in-file-name is not distributive
2012-10-30 18:58 ` Stefan Monnier
@ 2012-10-30 20:12 ` Daniel Colascione
2012-10-30 21:24 ` Stefan Monnier
0 siblings, 1 reply; 19+ messages in thread
From: Daniel Colascione @ 2012-10-30 20:12 UTC (permalink / raw
To: Stefan Monnier; +Cc: Emacs development discussions
[-- Attachment #1: Type: text/plain, Size: 3844 bytes --]
On 10/30/2012 11:58 AM, Stefan Monnier wrote:
>>> Hmm... that's odd. Can you give me some details:
>>> - tell me exactly which text you typed in the minibuffer.
>> I typed "c:\bin\" in the minibuffer and hit tab. After hitting tab, the
>> minibuffer contained "c:/usr/bin", with point at the end.
>>> - also tell me how the rfn-eshadow highlights the file name at each step.
>> Now that you mention it, I do see that the leading "c:" in the
>> minibuffer is highlighted. That explains why we're substituting
>> "c:/usr/bin" and not "/usr/bin".
>
> Right.
> The "c:" is highlighted because (s-i-f-n "c:\\bin") = (s-i-f-n "\\bin").
> Now the problem is that when you replace \bin by /usr/bin suddenly that
> same rule doesn't apply any more.
>
> Hmm... I think the core of the problem here is that minibuffer
> completion is actually only performed on "the current field" which is
> usually the whole minibuffer content, but not with rfn-eshadow.
> To fix this, we should invert the relationship between
> minibuffer-complete and completion-in-region (i.e. minibuffer-complete
> should call completion-in-region rather than the other way around).
> This would probably be a good change, but we can't do it for 24.3.
>
> You should be able to work around this problem by removing "field
> shadow" from file-name-shadow-properties.
Doing that globally will break normal file shadowing, which we want to keep working.
>>> Right. BTW I'm not convinced this is the right pattern to use for your
>>> file-name-handler. I think catching "\\[a-zA-Z]:" or something along
>>> these lines might be a better choice.
>> Not all paths I want to catch are absolute,
>
> Why not? Which non-absolute file names [we only use "path" for lists
> of directories, as in $INFOPATH] would you need/want to rewrite?
> Do you just want to replace \ with / in relative file names or is there
> more to it?
Remember that the mapping of Cygwin names to Windows ones is *arbitrary*. Any
approach that's based on "replacing slashes" is prone to failure. To a Cygwin
Emacs, it's as if Windows file names were written in encrypted EBCDIC. Emacs
must treat Windows filenames as opaque blobs to be passed to
cygwin-convert-path-from-windows.
Relative file names come up during builds. Say I'm editing foo.c and the build
system outputs "objchk\x86\foo.o" in some message: I want to be able to append
this relative path and get back a full Cygwin path.
>> Even "absolute" paths can be drive-letter-relative and begin with
>> a simple backslash.
>
> Right, that's what triggers the above problem.
>
>>> BTW, does Cygwin allow backslashes in file-names or does it interpret it
>>> as a separator, like Windows does?
>> Cygwin interprets backslashes as separators.
>
> So Cygin itself treats "\\bin" and "/bin" as equivalent
No --- Cygwin treats "\\bin" just as Windows would: it's a drive-letter-relative
Windows path. "/bin" is a perfectly normal POSIX path.
> , but your
> rewrite rules treat "\\bin" as a Windows file name and rewrite it to
> "/usr/bin"?
Yes.
> If you limit yourself to:
> - rewrite "\\`[a-zA-Z]:" to "/cygdrive/c" (regardless if it is followed
Not all Cygwin installations use "cygdrive". Every instance of the word
"cygdrive" in Emacs is a bug.
> by backslashes or forwardslashes).
> - rewrite \ to / everywhere.
> This should cover the main needs without tripping over the above problem.
This approach doesn't work either. The resulting POSIX file names alias the same
files named with mounted Cygwin paths.
"/cygdrive/c/bin/ls.exe" and "/bin/ls.exe" refer to the same file, but because
the paths differ, Emacs will consider these as two distinct files. Also, access
semantics differ between drive-prefix-prefixed paths and native Cygwin paths.
[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 256 bytes --]
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: substitute-in-file-name is not distributive
2012-10-30 20:12 ` Daniel Colascione
@ 2012-10-30 21:24 ` Stefan Monnier
2012-10-30 21:34 ` Daniel Colascione
0 siblings, 1 reply; 19+ messages in thread
From: Stefan Monnier @ 2012-10-30 21:24 UTC (permalink / raw
To: Daniel Colascione; +Cc: Emacs development discussions
> Relative file names come up during builds. Say I'm editing foo.c and
> the build system outputs "objchk\x86\foo.o" in some message: I want to
> be able to append this relative path and get back a full Cygwin path.
What do you append it to? If the mapping is arbitrary, you first need
to convert the Cywin name to Windows, the concat, then convert
back, right?
>> So Cygin itself treats "\\bin" and "/bin" as equivalent
> No --- Cygwin treats "\\bin" just as Windows would: it's
> a drive-letter-relative Windows path. "/bin" is a perfectly normal
> POSIX path.
Now I'm lost. So you're saying that Cygwin accepts backslash delimited
file names and assumes they're Window file names? IOW Cygwin already
accepts just as happily Windows file names? In this case, I'm wondering
why you need s-i-f-n.
Is it because Cygwin needs backslashes to recognize Windows file names
whereas Emacs wants to turn all backslashes into slashes?
Side related question: this seems to be related to your cygw32, yet at
the same tine it seems to be more GUI-independent. How much of this
affects Cygwin-X11 builds? Why has it not been a problem until now?
>> If you limit yourself to:
>> - rewrite "\\`[a-zA-Z]:" to "/cygdrive/c" (regardless if it is followed
> Not all Cygwin installations use "cygdrive".
I kind of know.
> Every instance of the word "cygdrive" in Emacs is a bug.
Feel free to fix them.
> "/cygdrive/c/bin/ls.exe" and "/bin/ls.exe" refer to the same file, but
> because the paths differ, Emacs will consider these as two distinct
> files. Also, access semantics differ between drive-prefix-prefixed
> paths and native Cygwin paths.
That doesn't sound too terrible as a stop-gap until we can fix the
underlying problem.
Stefan
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: substitute-in-file-name is not distributive
2012-10-30 21:24 ` Stefan Monnier
@ 2012-10-30 21:34 ` Daniel Colascione
2012-10-31 3:41 ` Stefan Monnier
0 siblings, 1 reply; 19+ messages in thread
From: Daniel Colascione @ 2012-10-30 21:34 UTC (permalink / raw
To: Stefan Monnier; +Cc: Emacs development discussions
[-- Attachment #1: Type: text/plain, Size: 3020 bytes --]
On 10/30/2012 2:24 PM, Stefan Monnier wrote:
>> Relative file names come up during builds. Say I'm editing foo.c and
>> the build system outputs "objchk\x86\foo.o" in some message: I want to
>> be able to append this relative path and get back a full Cygwin path.
>
> What do you append it to? If the mapping is arbitrary, you first need
> to convert the Cywin name to Windows, the concat, then convert
> back, right?
Sure. In practice, concatenating short relative paths works pretty well, and I'd
like to translate /foo/bar/qux\bar/spam.txt to /foo/bar/qux/bar/spam.txt. That
work can be done inside the s-i-f-n handler.
>>> So Cygin itself treats "\\bin" and "/bin" as equivalent
>> No --- Cygwin treats "\\bin" just as Windows would: it's
>> a drive-letter-relative Windows path. "/bin" is a perfectly normal
>> POSIX path.
>
> Now I'm lost. So you're saying that Cygwin accepts backslash delimited
> file names and assumes they're Window file names? IOW Cygwin already
> accepts just as happily Windows file names? In this case, I'm wondering
> why you need s-i-f-n.
Cygwin handles them, but Emacs doesn't. In the above example, as far as Emacs is
concerned, I'm editing a monolithic file with backslashes. For example,
find-file on "/etc\\passwd" successfully opens the passwd file (because Cygwin
does the translation internally), but the Emacs buffer name is "etc\\passwd" and
default-directory is "/".
> Is it because Cygwin needs backslashes to recognize Windows file names
> whereas Emacs wants to turn all backslashes into slashes?
I see Emacs treating backslashes as just another filename constituent.
> Side related question: this seems to be related to your cygw32, yet at
> the same tine it seems to be more GUI-independent. How much of this
> affects Cygwin-X11 builds? Why has it not been a problem until now?
You're right: the problem isn't GUI-specific. I just came across the problem
while doing general improvements to Cygwin Emacs. Maybe I'm the first one to be
really bothered by the problem. I do a lot of mixed Cygwin and Windows
development work.
>>> If you limit yourself to:
>>> - rewrite "\\`[a-zA-Z]:" to "/cygdrive/c" (regardless if it is followed
>> Not all Cygwin installations use "cygdrive".
>
> I kind of know.
Sorry for being repetitive.
>> Every instance of the word "cygdrive" in Emacs is a bug.
>
> Feel free to fix them.
After feature freeze.
>> "/cygdrive/c/bin/ls.exe" and "/bin/ls.exe" refer to the same file, but
>> because the paths differ, Emacs will consider these as two distinct
>> files. Also, access semantics differ between drive-prefix-prefixed
>> paths and native Cygwin paths.
>
> That doesn't sound too terrible as a stop-gap until we can fix the
> underlying problem.
The aliasing issue breaks my workflow. If we can't fix the problem the right way
in 24.3, I'm happy leaving the situation the way it is, hacking around the
problem locally, and fixing it in 24.4.
[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 256 bytes --]
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: substitute-in-file-name is not distributive
2012-10-30 21:34 ` Daniel Colascione
@ 2012-10-31 3:41 ` Stefan Monnier
0 siblings, 0 replies; 19+ messages in thread
From: Stefan Monnier @ 2012-10-31 3:41 UTC (permalink / raw
To: Daniel Colascione; +Cc: Emacs development discussions
>> What do you append it to? If the mapping is arbitrary, you first need
>> to convert the Cywin name to Windows, the concat, then convert
>> back, right?
> Sure. In practice, concatenating short relative paths works pretty
> well, and I'd like to translate /foo/bar/qux\bar/spam.txt to
> /foo/bar/qux/bar/spam.txt. That work can be done inside the
> s-i-f-n handler.
So for relative names you'd just convert \ to / ?
>>>> So Cygin itself treats "\\bin" and "/bin" as equivalent
>>> No --- Cygwin treats "\\bin" just as Windows would: it's
>>> a drive-letter-relative Windows path. "/bin" is a perfectly normal
>>> POSIX path.
>>
>> Now I'm lost. So you're saying that Cygwin accepts backslash delimited
>> file names and assumes they're Window file names? IOW Cygwin already
>> accepts just as happily Windows file names? In this case, I'm wondering
>> why you need s-i-f-n.
> Cygwin handles them, but Emacs doesn't.
Currently, that's true, and while under w32 we just treat \ and / as
equivalent, it sounds like this is not an option for Cygwin, right?
I mean that Emacs-w32 is happy to treat \ as a separator but it will not
itself add a \, so it often silently turns \ into /. We could do the
same under Cygwin, but from you say it sounds like it might not do the
right thing.
Of course, that depends on details: is /usr\bin treated by Cygwin as
identical to /usr/bin? What about \bin compared to /bin?
>> Is it because Cygwin needs backslashes to recognize Windows file names
>> whereas Emacs wants to turn all backslashes into slashes?
> I see Emacs treating backslashes as just another filename constituent.
Right, because the Cygwin build uses the "Unix" code which presumes
POSIX-like semantics.
> You're right: the problem isn't GUI-specific. I just came across the
> problem while doing general improvements to Cygwin Emacs. Maybe I'm
> the first one to be really bothered by the problem. I do a lot of
> mixed Cygwin and Windows development work.
OK, makes sense.
>>>> If you limit yourself to:
>>>> - rewrite "\\`[a-zA-Z]:" to "/cygdrive/c" (regardless if it is followed
>>> Not all Cygwin installations use "cygdrive".
>> I kind of know.
> Sorry for being repetitive.
That's not what I meant: I meant that I have a vague knowledge that this
is the case, but I don't know what it really entails (e.g. can this
name be changed, or can it even not exist at all?).
Stefan
^ permalink raw reply [flat|nested] 19+ messages in thread
end of thread, other threads:[~2012-10-31 3:41 UTC | newest]
Thread overview: 19+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2012-10-10 5:36 substitute-in-file-name is not distributive Daniel Colascione
2012-10-10 6:39 ` Andreas Schwab
2012-10-10 15:31 ` Eli Zaretskii
2012-10-10 16:48 ` Daniel Colascione
2012-10-10 17:18 ` Eli Zaretskii
2012-10-10 17:40 ` Daniel Colascione
2012-10-11 3:25 ` Stephen Leake
2012-10-25 3:20 ` Stefan Monnier
2012-10-25 3:28 ` Daniel Colascione
2012-10-27 16:08 ` Stefan Monnier
2012-10-28 19:09 ` Stefan Monnier
2012-10-30 4:10 ` Daniel Colascione
2012-10-30 13:15 ` Stefan Monnier
2012-10-30 15:01 ` Daniel Colascione
2012-10-30 18:58 ` Stefan Monnier
2012-10-30 20:12 ` Daniel Colascione
2012-10-30 21:24 ` Stefan Monnier
2012-10-30 21:34 ` Daniel Colascione
2012-10-31 3:41 ` Stefan Monnier
Code repositories for project(s) associated with this external index
https://git.savannah.gnu.org/cgit/emacs.git
https://git.savannah.gnu.org/cgit/emacs/org-mode.git
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.