diff --git a/textmate.el b/textmate.el index 3f26974..ba56388 100644 --- a/textmate.el +++ b/textmate.el @@ -468,3 +468,90 @@ A place is considered `tab-width' character columns." (provide 'textmate) ;;; textmate.el ends here + +;;; find-file-in-project.el contributions begins here +;; Copyright (C) 2006-2009, 2011 +;; Phil Hagelberg, Doug Alcorn, and Will Farrington + +;; Author: Phil Hagelberg, Doug Alcorn, and Will Farrington +;; URL: http://www.emacswiki.org/cgi-bin/wiki/FindFileInProject +;; Git: git://github.com/technomancy/find-file-in-project.git +;; Version: 3.0 +;; Created: 2008-03-18 +;; Keywords: project, convenience +;; EmacsWiki: FindFileInProject + +;; This file is NOT part of GNU Emacs. + +;;; License: + +;; This program is free software; you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation; either version 3, or (at your option) +;; any later version. +;; +;; This program is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. +;; +;; You should have received a copy of the GNU General Public License +;; along with GNU Emacs; see the file COPYING. If not, write to the +;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, +;; Boston, MA 02110-1301, USA. + +(require 'vc) + +(defvar ffip-find-options "-path *.hg -prune -o -name *.git -prune -o -print") + +(defun ffip-uniqueify (file-cons) + "Set the car of FILE-CONS to include the directory name plus the file name." + ;; TODO: see if we can use uniquify.el + (setcar file-cons + (concat (cadr (reverse (split-string (cdr file-cons) "/"))) "/" + (car file-cons)))) + +(defun ffip-project-files () + "Return an alist of all filenames in the project and their path. + +Files with duplicate filenames are suffixed with the name of the +directory they are found in so that they are unique." + (let ((file-alist nil) + (vc-name (vc-responsible-backend (buffer-file-name))) + (project-root (or (textmate-project-root) + (error "No project root found")))) + (mapcar (lambda (file) + (let ((file-cons (cons (file-name-nondirectory file) + (expand-file-name file)))) + (when (assoc (car file-cons) file-alist) + (ffip-uniqueify (assoc (car file-cons) file-alist)) + (ffip-uniqueify file-cons)) + (add-to-list 'file-alist file-cons) + file-cons)) + ;; git ls-files in some basic tests can be faster compared to a + ;; find command that is filtering out .git or .hg directories + (if (string= vc-name "Git") + (split-string (shell-command-to-string + (format "git ls-files %s" project-root))) + (split-string (shell-command-to-string + (format "find %s %s" + project-root + ffip-find-options + ))))))) + +;;;###autoload +(defun find-file-in-project () + "Prompt with a completing list of all files in the project to find one." + (interactive) + (let* ((project-files (ffip-project-files)) + (files (mapcar 'car project-files)) + (file (if (and (boundp 'ido-mode) ido-mode) + (ido-completing-read "Find file in project: " files) + (completing-read "Find file in project: " files)))) + (find-file (cdr (assoc file project-files))))) + +;;;###autoload +(defalias 'ffip 'find-file-in-project) + +(provide 'find-file-in-project) +;;; find-file-in-project.el ends here