[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: file-relative-name and remote files
From: |
Stefan Monnier |
Subject: |
Re: file-relative-name and remote files |
Date: |
Sun, 23 Feb 2003 13:30:43 -0500 |
> > IMHO, the following might work: file-relative-name finds a filename
> > handler for the filename and one for the directory. If they are
> > different, then the two must come from different handlers, so do like
> > the different-drives case. If they are equal, invoke the handler. This
> > requires a new file operation, file-relative-name. It seems to work
> > for Ange-FTP and Tramp. However... Imagine that there was a filename
> > handler which could look inside of tar files, so that the filename
> > /tmp/foo.tar/x/y would extract the file x/y from the tarball
> > /tmp/foo.tar. So should (file-relative-name "/tmp/foo.tar/x/y" "/tmp")
> > eval to "foo.tar/x/y" or not?
>
>
> What about changing it to:
> file-relative-name finds a filename handler for the filename and one for
> the directory. If they are non-nil and different, then the two must come
> from different handlers, so do like the different-drives case. If they
> are non-nil and equal, or one is non-nil and the other nil, invoke the
> handler. If both are nil, execute the build in code.
How about something like:
(defun f-r-n (filename &optional directory)
(let* ((dir (if directory (expand-file-name directory) default-directory))
(file (expand-file-name (file-name-directory filename)))
(hf (find-file-name-handler file 'file-relative-name))
(hd (find-file-name-handler dir 'file-relative-name)))
(cond
((not (eq hf hd))
;; `filename' and `directory' are on different drives:
;; there is hence no relative name from `directory' to `filename'.
(expand-file-name filename))
((null hf)
;; Both are plain local: use the builtin code.
(file-relative-name filename directory))
((let ((re (car (rassq hf file-name-handler-alist))))
(equal (and (string-match re file) (substring file 0 (match-end 0)))
(and (string-match re dir) (substring dir 0 (match-end 0)))))
;; Both are non-local, use the same handler and same drive name.
(file-relative-name filename directory))
(t
;; Both are non-local and on different drives.
(expand-file-name filename)))))
Note how I check the handler for (file-name-directory filename) rather
than for `filename' so as to avoid uselessly catching jka-compr-style
handlers.
Stefan