0
-;;; extracted from rinari
0
-;; by Phil Hagelberg and Doug Alcorn
0
-;; refactored to work with project-local-variables.el
0
+;;; find-file-in-project.el --- Find files in a project quickly.
0
+;; Copyright (C) 2006, 2007, 2008 Phil Hagelberg and Doug Alcorn
0
+;; Author: Phil Hagelberg and Doug Alcorn
0
+;; URL: http://www.emacswiki.org/cgi-bin/wiki/FindFileInProject
0
+;; Keywords: project, convenience
0
+;; EmacsWiki: FindFileInProject
0
+;; This file is NOT part of GNU Emacs.
0
+;; This program is free software; you can redistribute it and/or modify
0
+;; it under the terms of the GNU General Public License as published by
0
+;; the Free Software Foundation; either version 3, or (at your option)
0
+;; This program is distributed in the hope that it will be useful,
0
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
0
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
0
+;; GNU General Public License for more details.
0
+;; You should have received a copy of the GNU General Public License
0
+;; along with GNU Emacs; see the file COPYING. If not, write to the
0
+;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
0
+;; Boston, MA 02110-1301, USA.
0
+;; This file provides a method for quickly finding any file in a given
0
+;; project. Projects are defined as per the `project-local-variables'
0
+;; library, by the presence of a `.emacs-project' file in a directory.
0
+;; By default, it looks only for files whose names match
0
+;; `ffip-regexp', but it's understood that that variable will be
0
+;; overridden locally. This can be done either with a mode hook:
0
+;; (add-hook 'emacs-lisp-mode-hook (lambda (setl ffip-regexp ".*\\.el")))
0
+;; or by setting it in your .emacs-project file, in which case it will
0
+;; get set locally by the project-local-variables library.
0
+;; You can also be a bit more specific about what files you want to
0
+;; find. For instance, in a Ruby on Rails project, you may be
0
+;; interested in all .rb files that don't exist in the "vendor"
0
+;; directory. In that case you could locally set `ffip-find-options'
0
+;; to "" from within a hook or your .emacs-project file. The options
0
+;; accepted in that variable are passed directly to the Unix `find'
0
+;; command, so any valid arguments for that program are acceptable.
0
+;; If `ido-mode' is enabled, the menu will use `ido-completing-read'
0
+;; instead of `completing-read'.
0
+;; Recommended binding:
0
+;; (global-set-key (kbd "C-x C-M-f") 'find-file-in-project)
0
+;; Performance testing with large projects
0
+;; Switch to using a hash table if it's too slow
0
(require 'project-local-variables)
0
(concat ".*\\.\\(" (mapconcat (lambda (x) x) '("rb" "rhtml" "el") "\\|") "\\)")
0
- "Regexp of things to look for when using find-file-in-project.
0
-For Rails projects, a good value is \".*\\.\\(rb\\|rhtml\\)\"")
0
+ "Regexp of things to look for when using find-file-in-project.")
0
(defvar ffip-find-options
0
"Extra options to pass to `find' when using find-file-in-project.")
0
-;; TODO: deal with files with the same name but different paths like
0
-;; the version in rinari does (without being slow)
0
+(defvar ffip-project-root nil
0
+ "If non-nil, overrides the project root directory location.")
0
(defun ffip-project-files ()
0
- "Return an assoc-list of all filenames and their path."
0
- (mapcar (lambda (file) (cons
0
- (file-name-nondirectory file)
0
- (split-string (shell-command-to-string (concat "find . -type f -regex \""
0
- "\" " ffip-find-options)))))
0
+ "Return an alist of all filenames in the project and their path.
0
+Files with duplicate filenames are suffixed with the name of the
0
+directory they are found in so that they are unique."
0
+ (let ((file-alist nil))
0
+ (mapcar (lambda (file)
0
+ (let ((file-cons (cons (file-name-nondirectory file)
0
+ (expand-file-name file))))
0
+ (when (assoc (car file-cons) file-alist)
0
+ (ffip-uniqueify (assoc (car file-cons) file-alist))
0
+ (ffip-uniqueify file-cons))
0
+ (add-to-list 'file-alist file-cons)
0
+ (split-string (shell-command-to-string (concat "find " (or ffip-project-root
0
+ "\" " ffip-find-options))))))
0
+(defun ffip-uniqueify (file-cons)
0
+ "Set the car of the argument to include the directory name plus the file name."
0
+ (concat (car file-cons) ": "
0
+ (cadr (reverse (split-string (cdr file-cons) "/"))))))
0
(defun find-file-in-project ()
0
+ "Prompt with a completing list of all files in the project to find one.
0
+The project's scope is defined as the first directory containing
0
+an `.emacs-project' file. You can override this by locally
0
+setting the `ffip-project-root' variable."
0
(let* ((project-files (ffip-project-files))
0
(file (if (functionp 'ido-completing-read)
0
@@ -34,10 +118,9 @@ For Rails projects, a good value is \".*\\.\\(rb\\|rhtml\\)\"")
0
(mapcar 'car project-files)))))
0
(find-file (cdr (assoc file project-files)))))
0
-(defun project-root (&optional dir)
0
+(defun ffip-project-root (&optional dir)
0
+ "Find the root of the project defined by presence of `.emacs-project'."
0
(file-name-nondirectory (plv-find-project-file default-directory "")))
0
-(global-set-key (kbd "C-x C-M-f") 'find-file-in-project)
0
(provide 'find-file-in-project)
0
;;; find-file-in-project.el ends here
0
\ No newline at end of file
Comments
No one has commented yet.