From mboxrd@z Thu Jan 1 00:00:00 1970 Path: main.gmane.org!not-for-mail From: "Stefan Monnier" Newsgroups: gmane.emacs.devel Subject: Re: file-relative-name and remote files Date: Sun, 23 Feb 2003 13:30:43 -0500 Sender: emacs-devel-bounces+emacs-devel=quimby.gnus.org@gnu.org Message-ID: <200302231830.h1NIUhl24956@rum.cs.yale.edu> References: <3E58EBE3.2040909@math.ku.dk> NNTP-Posting-Host: main.gmane.org Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii X-Trace: main.gmane.org 1046025091 29430 80.91.224.249 (23 Feb 2003 18:31:31 GMT) X-Complaints-To: usenet@main.gmane.org NNTP-Posting-Date: Sun, 23 Feb 2003 18:31:31 +0000 (UTC) Cc: emacs-devel@gnu.org Return-path: Original-Received: from quimby.gnus.org ([80.91.224.244]) by main.gmane.org with esmtp (Exim 3.35 #1 (Debian)) id 18n0uQ-0007eX-00 for ; Sun, 23 Feb 2003 19:31:30 +0100 Original-Received: from monty-python.gnu.org ([199.232.76.173]) by quimby.gnus.org with esmtp (Exim 3.12 #1 (Debian)) id 18n19V-0002lB-00 for ; Sun, 23 Feb 2003 19:47:05 +0100 Original-Received: from localhost ([127.0.0.1] helo=monty-python.gnu.org) by monty-python.gnu.org with esmtp (Exim 4.10.13) id 18n0u4-0003gv-04 for emacs-devel@quimby.gnus.org; Sun, 23 Feb 2003 13:31:08 -0500 Original-Received: from list by monty-python.gnu.org with tmda-scanned (Exim 4.10.13) id 18n0tj-0003dQ-00 for emacs-devel@gnu.org; Sun, 23 Feb 2003 13:30:47 -0500 Original-Received: from mail by monty-python.gnu.org with spam-scanned (Exim 4.10.13) id 18n0ti-0003bZ-00 for emacs-devel@gnu.org; Sun, 23 Feb 2003 13:30:46 -0500 Original-Received: from rum.cs.yale.edu ([128.36.229.169]) by monty-python.gnu.org with esmtp (Exim 4.10.13) id 18n0th-0003ZQ-00 for emacs-devel@gnu.org; Sun, 23 Feb 2003 13:30:45 -0500 Original-Received: (from monnier@localhost) by rum.cs.yale.edu (8.11.6/8.11.6) id h1NIUhl24956; Sun, 23 Feb 2003 13:30:43 -0500 X-Mailer: exmh version 2.4 06/23/2000 with nmh-1.0.4 Original-To: Lars Hansen X-BeenThere: emacs-devel@gnu.org X-Mailman-Version: 2.1b5 Precedence: list List-Id: Emacs development discussions. List-Help: List-Post: List-Subscribe: , List-Archive: List-Unsubscribe: , Errors-To: emacs-devel-bounces+emacs-devel=quimby.gnus.org@gnu.org Xref: main.gmane.org gmane.emacs.devel:11883 X-Report-Spam: http://spam.gmane.org/gmane.emacs.devel:11883 > > 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