From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.org!not-for-mail From: "Stuart D. Herring" Newsgroups: gmane.emacs.devel Subject: Re: Looking for interactive `locate-file' Date: Tue, 6 Mar 2007 08:23:07 -0800 (PST) Message-ID: <42279.128.165.123.18.1173198187.squirrel@webmail.lanl.gov> References: <6dbd4d000703051753j23014087ob8beb4edf1741458@mail.gmail.com> Reply-To: herring@lanl.gov NNTP-Posting-Host: lo.gmane.org Mime-Version: 1.0 Content-Type: text/plain;charset=iso-8859-1 Content-Transfer-Encoding: 8bit X-Trace: sea.gmane.org 1173198276 7399 80.91.229.12 (6 Mar 2007 16:24:36 GMT) X-Complaints-To: usenet@sea.gmane.org NNTP-Posting-Date: Tue, 6 Mar 2007 16:24:36 +0000 (UTC) Cc: emacs-devel@gnu.org To: "Denis Bueno" Original-X-From: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Tue Mar 06 17:24:24 2007 Return-path: Envelope-to: ged-emacs-devel@m.gmane.org Original-Received: from lists.gnu.org ([199.232.76.165]) by lo.gmane.org with esmtp (Exim 4.50) id 1HOcSS-0004GG-Nk for ged-emacs-devel@m.gmane.org; Tue, 06 Mar 2007 17:24:23 +0100 Original-Received: from localhost ([127.0.0.1] helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1HOcSH-0006Wg-JO for ged-emacs-devel@m.gmane.org; Tue, 06 Mar 2007 11:24:01 -0500 Original-Received: from mailman by lists.gnu.org with tmda-scanned (Exim 4.43) id 1HOcS6-0006WF-7c for emacs-devel@gnu.org; Tue, 06 Mar 2007 11:23:50 -0500 Original-Received: from exim by lists.gnu.org with spam-scanned (Exim 4.43) id 1HOcRw-0006VB-Gb for emacs-devel@gnu.org; Tue, 06 Mar 2007 11:23:49 -0500 Original-Received: from [199.232.76.173] (helo=monty-python.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1HOcRw-0006V8-Bg for emacs-devel@gnu.org; Tue, 06 Mar 2007 11:23:40 -0500 Original-Received: from mailwasher.lanl.gov ([192.65.95.54] helo=mailwasher-b.lanl.gov) by monty-python.gnu.org with esmtp (Exim 4.52) id 1HOcRt-00005h-U4 for emacs-devel@gnu.org; Tue, 06 Mar 2007 11:23:39 -0500 Original-Received: from mailrelay1.lanl.gov (mailrelay1.lanl.gov [128.165.4.101]) by mailwasher-b.lanl.gov (8.13.8/8.13.8/(ccn-5)) with ESMTP id l26GN7oi019171 for ; Tue, 6 Mar 2007 09:23:08 -0700 Original-Received: from webmail1.lanl.gov (webmail1.lanl.gov [128.165.4.106]) by mailrelay1.lanl.gov (8.13.8/8.13.8/(ccn-5)) with ESMTP id l26GN7EJ013802; Tue, 6 Mar 2007 09:23:07 -0700 Original-Received: from webmail1.lanl.gov (localhost.localdomain [127.0.0.1]) by webmail1.lanl.gov (8.12.11.20060308/8.12.11) with ESMTP id l26GN7W2006980; Tue, 6 Mar 2007 09:23:07 -0700 Original-Received: (from apache@localhost) by webmail1.lanl.gov (8.12.11.20060308/8.12.11/Submit) id l26GN7Kg006978; Tue, 6 Mar 2007 08:23:07 -0800 X-Authentication-Warning: webmail1.lanl.gov: apache set sender to herring@lanl.gov using -f Original-Received: from 128.165.123.18 (SquirrelMail authenticated user 196434) by webmail.lanl.gov with HTTP; Tue, 6 Mar 2007 08:23:07 -0800 (PST) In-Reply-To: <6dbd4d000703051753j23014087ob8beb4edf1741458@mail.gmail.com> User-Agent: SquirrelMail/1.4.8-2.el3.7lanl X-Priority: 3 (Normal) Importance: Normal X-PMX-Version: 4.7.1.128075 X-detected-kernel: Linux 2.4-2.6 X-BeenThere: emacs-devel@gnu.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "Emacs development discussions." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Original-Sender: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Errors-To: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Xref: news.gmane.org gmane.emacs.devel:67438 Archived-At: > Dear list- > > I would like to be able to interactive find a file inside a list of > paths, interactively, and in a way that supports some basic pattern > matching. (For reference, the reason I want this is that Eclipse has > it, and I find it quite useful.) Currently, I have a first > approximation [1], but, it sucks. All it does is ask for a (possibly > non-existent) filename, then look for that in a default list of paths. What I have written is an improvement on this approximation: it does recursive searches and automatically figures out where GCC keeps its include files. ;; Should these be organized by extension or so? (defvar common-file-locations (eval-when-compile (nconc (let ((str (shell-command-to-string "g++ -v -xc++ /dev/null"))) (and (string-match "^#include <...> search starts here:\n\\(\\(?:.*\n\\)*?\\)End of search list." str) (split-string (match-string 1 str) " *\n *\\|^ *"))) '("/etc" "~"))) "Directories in which to find common files.") (defun locate-common-file (name &optional noisy) "Return full file name ending in NAME, or nil if not found. NAME is a relative file name. Looks in `common-file-locations', then looks in all directories they contain. The current directory is considered to be the first element of the list. If called interactively (NOISY is numeric), print the name. If NOISY is otherwise non-nil, print messages during search." (interactive "sCommon file: \np") (let* ((places (cons default-directory common-file-locations)) (ret (save-match-data (catch 'file (dolist (dir places) (let ((full (expand-file-name name dir))) (if (file-regular-p full) (throw 'file full)))) (dolist (dir places) (if noisy (message "Searching %s..." dir)) (locate-common-file-0 name dir)) nil)))) (if (numberp noisy) (if ret (message "%s is %s" name ret) (message "%s not found" name))) ret)) (defun locate-common-file-0 (name dir) "Throw full name of file in DIR ending in NAME to `file'. Return normally if not found." (setq dir (file-name-as-directory dir)) (let ((full (expand-file-name name dir))) (if (file-regular-p full) (throw 'file full))) (dolist (entry (directory-files dir t)) (or (file-symlink-p entry) (string-match "\\.\\.?" (file-name-nondirectory entry)) (and (file-directory-p entry) (file-readable-p entry) (locate-common-file-0 name entry))))) Then I have this command to call it, whose utility is in its default value: (defvar common-file-characters "a-zA-Z0-9-_+./" "Characters composing common file names, for use with `find-common-file'. The default is chosen to be useful with #include directives.") (defun find-common-file (name) "Visit common file NAME. See `locate-common-file'." (interactive (list (let ((def (buffer-substring (point-after (skip-chars-backward common-file-characters)) (point-after (skip-chars-forward common-file-characters)))) val) (if (zerop (length def)) (setq def nil)) (setq val (read-string (if def (format "Common file: (default %s) " def) "Common file: ") nil def)) (if (zerop (length val)) def val)))) (find-file (or (locate-common-file name t) (error "Cannot find common file: %s" name)))) Together it makes header files (my original application) a cinch, but it works on lots of other things too. Obviously it doesn't deal with file name patterns, but I've found it useful. (If others do, too, I'll probably post it at the EmacsWiki page Drew mentioned.) Davis -- This product is sold by volume, not by mass. If it appears too dense or too sparse, it is because mass-energy conversion has occurred during shipping.