From mboxrd@z Thu Jan 1 00:00:00 1970 Path: main.gmane.org!not-for-mail From: Hrvoje Niksic Newsgroups: gmane.emacs.devel Subject: Re: locate-file in Emacs Date: Thu, 18 Apr 2002 15:16:04 +0200 Sender: emacs-devel-admin@gnu.org Message-ID: References: <200204170928.g3H9SVb27019@rum.cs.yale.edu> <200204171001.g3HA1hh27230@rum.cs.yale.edu> NNTP-Posting-Host: localhost.gmane.org Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii X-Trace: main.gmane.org 1019136064 16153 127.0.0.1 (18 Apr 2002 13:21:04 GMT) X-Complaints-To: usenet@main.gmane.org NNTP-Posting-Date: Thu, 18 Apr 2002 13:21:04 +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.33 #1 (Debian)) id 16yBqS-0004CQ-00 for ; Thu, 18 Apr 2002 15:21:04 +0200 Original-Received: from fencepost.gnu.org ([199.232.76.164]) by quimby.gnus.org with esmtp (Exim 3.12 #1 (Debian)) id 16yC9d-00015g-00 for ; Thu, 18 Apr 2002 15:40:54 +0200 Original-Received: from localhost ([127.0.0.1] helo=fencepost.gnu.org) by fencepost.gnu.org with esmtp (Exim 3.34 #1 (Debian)) id 16yBnc-0008F6-00; Thu, 18 Apr 2002 09:18:08 -0400 Original-Received: from dragon.arsdigita.de ([212.84.246.66] helo=florida.arsdigita.de) by fencepost.gnu.org with esmtp (Exim 3.34 #1 (Debian)) id 16yBli-00084h-00 for ; Thu, 18 Apr 2002 09:16:11 -0400 Original-Received: from hniksic by florida.arsdigita.de with local (Exim 3.35 #1 (Debian)) id 16yBlc-0006J4-00; Thu, 18 Apr 2002 15:16:04 +0200 Original-To: "Stefan Monnier" X-Attribution: Hrvoje X-Face: &{dT~)Pu6V<0y?>3p$;@vh\`C7xB~A0T-J%Og)J,@-1%q6Q+, gs<-9M#&`I8cJp2b1{vPE|~+JE+gx;a7%BG{}nY^ehK1"q#rG O,Rn1A_Cy%t]V=Brv7h ("Stefan Monnier"'s message of "Wed, 17 Apr 2002 06:01:43 -0400") Original-Lines: 75 User-Agent: Gnus/5.090006 (Oort Gnus v0.06) XEmacs/21.4 (Common Lisp, i686-pc-linux) Errors-To: emacs-devel-admin@gnu.org X-BeenThere: emacs-devel@gnu.org X-Mailman-Version: 2.0.9 Precedence: bulk List-Help: List-Post: List-Subscribe: , List-Id: Emacs development discussions. List-Unsubscribe: , List-Archive: Xref: main.gmane.org gmane.emacs.devel:2725 X-Report-Spam: http://spam.gmane.org/gmane.emacs.devel:2725 "Stefan Monnier" writes: >> PREDICATE might make sense, but I don't remember needing it in >> practice. Plus, it'd change the interface and hence undermine the >> whole point of sharing the function. > > Well, I was wondering if it was possible to get XEmacs to adopt it > as well ;-) That would break backward compatibility, which is fairly important in this case because I've already changed the interface once. (But I've kept the compatibility with the old interface.) I've fixed the function to always check for non-directoriness, which the XEmacs version does, too. Please let me know if you include the function (which Richard promised to do, but that was some time ago): (defun locate-file (filename path-list &optional suffixes mode) "Search for FILENAME through PATH-LIST. If SUFFIXES is non-nil, it should be a list of suffixes to append to file name when searching. If MODE is non-nil, it should be a symbol or a list of symbols representing requirements. Allowed symbols are `exists', `executable', `writable', and `readable'. If MODE is nil, it defaults to `readable'." (let (all-file-names all-mode-functions) ;; Create a list of strings of FILENAME+suffix for each of ;; SUFFIXES, so we don't have to do it (and cons a new string) ;; once for each directory. (setq all-file-names (if suffixes (mapcar (lambda (suffix) (concat filename suffix)) suffixes) (list filename))) ;; Convert MODE into a list of tests all of which need to return t ;; for a file to pass. (if (null mode) (setq all-mode-functions '(file-readable-p)) (when (symbolp mode) (setq mode (list mode))) (setq all-mode-functions (mapcar (lambda (m) (cond ((eq m 'exists) 'file-exists-p) ((eq m 'executable) 'file-executable-p) ((eq m 'writable) ;; file-writable-p returns t if the dir is ;; writable and the file doesn't exist. (lambda (f) (and (file-exists-p f) (file-writable-p f)))) ((eq m 'readable) 'file-readable-p) (t (error "Invalid mode: %s" m)))) mode))) (catch 'found (dolist (directory path-list) (dolist (file all-file-names) (let ((full-name (expand-file-name file directory)) (mode-functions all-mode-functions)) (when (not (file-directory-p full-name)) (while (and mode-functions (funcall (car mode-functions) full-name)) (pop mode-functions)) (when (null mode-functions) ;; All functions passed -- we found the one. (throw 'found full-name)))))) nil)))