I've implemented some partial code that makes emacs 19 and 20 let you
load ftp://username@host/filename by delegating to ange-ftp via
file-name-handler-alist. I've put it at the bottom. This code is
proof-of-concept only, it needs work, but I hope it demonstrates that
emacs is capable of dealing with // in filenames without great pain.
Sandy says:
The trick will be that any new version of expand-file-name must do
the right thing 100% of the time, not just most of the time. Bugs in
expand-file-name cannot be tolerated. This function is too critical.
I understand that it has to be bulletproof. Personally, I think saying
"emacs can never handle URLs in filenames" is a sure way to make a lot
of people unhappy. URLs are not some passing fad, it's worthwhile to
make emacs handle them.
Happily, I don't think you even need to hack expand-file-name. I went
wading through fileio.c... The actual // code is in
substitute-in-file-name. There's lots of special cases in there for
Apollo, NT, etc. One solution would be to put in another special case
for URLs.
But even better, I learned that substitute-in-file-name first checks
if there's an appropriate handler in file-name-handler-alist. If there
is a handler it calls that instead with the operation
"substitute-in-file-name". As near as I can tell this short-circuits
// substitution (although it might be invoked on the substituted
name). So you just put a handler in for ftp:// URLs and all is well.
The code below is a really simple proof-of-concept handler. Load it up
and try it! To make this work for real, some extra effort will be
necessary to make it bullet-proof and to figure out the semantics of
filenames in ftp URLs. This substitution isn't quite right: it's
loading relative to the home directory, not the server's root. I'm not
quite sure what is right here, but it'd be good if emacs behaved the
same as other URL using tools.
;; Quick hack by Nelson Minar <nelson(a)media.mit.edu> to demonstrate that
;; it is possible to use FTP URLs in emacs. All this does is use the
;; file-name-handler-alist to catch ftp:// URLs and call ange-ftp.
;; This is a prototype only; real code needs error detection etc.
;; This code works in emacs 19.34 and emacs 20.3. Not tested in XEmacs.
;;
;; Try to open the file "ftp://yourname@localhost/.emacs". If all goes well,
;; ange-ftp will open ~/.emacs via ftp. Some notes:
;; you must kill the find-file minibuffer first.
;; filenames are relative to your homedir; the ftp protocol seems to be
;; relative to /. This should be resolved.
(defun ftp-url-to-ange-ftp (url)
"Map a ftp://user@host/filename URL to /user@host:filename ange-ftp string.
This is only a hack - it needs work to make it robust, and to make it handle
relative directory semantics right."
(string-match "ftp://[a-z]+@[a-z]+/" url)
(let ((filename-start (match-end 0)))
(concat
(substring url 5 (- filename-start 1)) ; strip out ftp:/
":" ; give ange-ftp a colon
(substring url filename-start)))) ; append the rest of filename
(defun ftp-url-handler-hack (operation &rest args)
"A file name handler for emacs to pass FTP urls through to ange-ftp."
(if (eq 'substitute-in-file-name operation)
(message (car args))
(ange-ftp-hook-function operation (ftp-url-to-ange-ftp (car args)))))
(setq file-name-handler-alist
(append '(("^ftp://" . ftp-url-handler-hack))
file-name-handler-alist))
nelson(a)media.mit.edu
. . . . . . . .
http://www.media.mit.edu/~nelson/