Subject: Re: bug#13961: 24.3; ffap-url-unwrap-remote fails for remote file URIs

From: Michael Albinus <[email-masked]>
Date: Thu, 14 Mar 2013 22:57:34 +0100

Jens Lechtenboerger <[email-masked]> writes:

> Hi there,

Hi Jens,

> I’d like to access remote file URIs via ffap and ssh, e.g., /bar on
> host foo via “file://foo/bar”.  However, the behavior of
> ffap-url-unwrap-remote has changed from Emacs 23 to 24.

Yes. See the NEWS file of Emacs 24.3:

--8<---------------cut here---------------start------------->8---
** The FFAP option `ffap-url-unwrap-remote' can now be a list of strings,
specifying URL types that should be converted to remote file names at
the FFAP prompt.  The default is now '("ftp").
--8<---------------cut here---------------end--------------->8---

> I’m using:
>
> src/emacs -Q
> (ffap-bindings)
> (setq ffap-ftp-default-user nil)
>
> In Emacs 23.4, with point in “file://foo/bar”, “C-x C-f” shows
> “/foo:/bar” in  
> the minibuffer, and RET retrieves the file via ssh, which is good.

In Emacs 23, ffap-url-unwrap-remote had the intention to unwrap to an
ftp file name. It uses the ange-ftp syntax "/host:/remote/path".

Tramp is bundled with Emacs 23, and it uses an extended syntax
"/method:host:/remote/path". The "method:" part is optional; in this
case the default method ("ssh" in your case) will be used.

So it did work for you due to an unintended side effect.

> In Emacs 24.3, “C-x C-f” shows “file://foo/bar”, and RET opens a
> browser, which tries to access “file:///bar”, which is incorrect as
> it misses the host.

ffap-url-unwrap-remote has been changed to handle the scheme part of the
url as Tramp method, when it is known in ffap-url-unwrap-remote. "file"
does not belong to this list by default; therefore the url is regarded
as url, and it is sent to the browser.

> The file scheme is not recognized as remote one.  Thus:
> (setq ffap-url-unwrap-remote '("ftp" "file"))
> Now, “C-x C-f” shows “/file:foo:/bar”, and RET leads to the error:
> “Host `foo' looks like a remote host, `file' can only use the local host”

In this case, you declare "file" as Tramp method. The resulting
"/file:foo:/bar" is not accepted by Tramp; it doesn't know of any method
"file".

> I’m not sure whether the previous result should be changed
> somewhere.  Why should file only use the local host?
>
> However, the problem can be avoided by the following version of
> ffap-url-unwrap-remote.  Moreover, changing ffap-ftp-default-user is
> not necessary any more.
>
> (defun ffap-url-unwrap-remote (url)
>   "Return URL as a remote file name, or nil."
>   (let* ((obj    (url-generic-parse-url url))
> 	 (scheme (url-type obj))
> 	 (valid-schemes (if (listp ffap-url-unwrap-remote)
> 			    ffap-url-unwrap-remote
> 			  '("ftp")))
> 	 (host (url-host obj))
> 	 (port (url-port-if-non-default obj))
> 	 (user (url-user obj))
> 	 (filename (car (url-path-and-query obj))))
>     (when (and (member scheme valid-schemes)
> 	       (string-match "\\`[a-zA-Z][-a-zA-Z0-9+.]*\\'" scheme)
> 	       (not (equal host "")))
>       (concat "/"
> 	      (if (not (string= scheme "file"))
> 		  (concat scheme ":"))
> 	      (if user (concat user "@"))
> 	      host
> 	      (if port (concat "#" (number-to-string port)))
> 	      ":" filename))))

This patch tries to conserve the side effect of ffap in Emacs 23. I'm
not a user of ffap, so I don't know whether it is acceptable to add such
a kludge.

> Best wishes
> Jens

Best regards, Michael.