From: "Stuart D. Herring" <herring@lanl.gov>
To: "Denis Bueno" <dbueno@gmail.com>
Cc: emacs-devel@gnu.org
Subject: Re: Looking for interactive `locate-file'
Date: Tue, 6 Mar 2007 08:23:07 -0800 (PST) [thread overview]
Message-ID: <42279.128.165.123.18.1173198187.squirrel@webmail.lanl.gov> (raw)
In-Reply-To: <6dbd4d000703051753j23014087ob8beb4edf1741458@mail.gmail.com>
> 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.
next prev parent reply other threads:[~2007-03-06 16:23 UTC|newest]
Thread overview: 8+ messages / expand[flat|nested] mbox.gz Atom feed top
2007-03-06 1:53 Looking for interactive `locate-file' Denis Bueno
2007-03-06 2:37 ` Stefan Monnier
2007-03-06 3:32 ` Denis Bueno
2007-03-06 14:32 ` Stefan Monnier
2007-03-06 11:37 ` Johan Bockgård
2007-03-06 14:29 ` Drew Adams
2007-03-06 16:23 ` Stuart D. Herring [this message]
[not found] ` <mailman.522.1173191449.7795.help-gnu-emacs@gnu.org>
2007-03-06 18:38 ` weber
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=42279.128.165.123.18.1173198187.squirrel@webmail.lanl.gov \
--to=herring@lanl.gov \
--cc=dbueno@gmail.com \
--cc=emacs-devel@gnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
Code repositories for project(s) associated with this external index
https://git.savannah.gnu.org/cgit/emacs.git
https://git.savannah.gnu.org/cgit/emacs/org-mode.git
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.