Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

Toss find-file-in-git-project in favor of find-file-in-project

  • Loading branch information...
commit e80c7c928358fda2536e296f8cb782099060510d 1 parent 121842e
Craig Andera authored

Showing 2 changed files with 177 additions and 2 deletions. Show diff stats Hide diff stats

  1. +165 0 find-file-in-project.el
  2. +12 2 init.el
165 find-file-in-project.el
... ... @@ -0,0 +1,165 @@
  1 +
  2 +;;; find-file-in-project.el --- Find files in a project quickly.
  3 +
  4 +;; Copyright (C) 2006-2009, 2011
  5 +;; Phil Hagelberg, Doug Alcorn, and Will Farrington
  6 +
  7 +;; Author: Phil Hagelberg, Doug Alcorn, and Will Farrington
  8 +;; URL: http://www.emacswiki.org/cgi-bin/wiki/FindFileInProject
  9 +;; Git: git://github.com/technomancy/find-file-in-project.git
  10 +;; Version: 3.0
  11 +;; Created: 2008-03-18
  12 +;; Keywords: project, convenience
  13 +;; EmacsWiki: FindFileInProject
  14 +
  15 +;; This file is NOT part of GNU Emacs.
  16 +
  17 +;;; License:
  18 +
  19 +;; This program is free software; you can redistribute it and/or modify
  20 +;; it under the terms of the GNU General Public License as published by
  21 +;; the Free Software Foundation; either version 3, or (at your option)
  22 +;; any later version.
  23 +;;
  24 +;; This program is distributed in the hope that it will be useful,
  25 +;; but WITHOUT ANY WARRANTY; without even the implied warranty of
  26 +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  27 +;; GNU General Public License for more details.
  28 +;;
  29 +;; You should have received a copy of the GNU General Public License
  30 +;; along with GNU Emacs; see the file COPYING. If not, write to the
  31 +;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
  32 +;; Boston, MA 02110-1301, USA.
  33 +
  34 +;;; Commentary:
  35 +
  36 +;; This library provides a couple methods for quickly finding any file
  37 +;; in a given project. It depends on GNU find.
  38 +
  39 +;; A project is found by searching up the directory tree until a file
  40 +;; is found that matches `ffip-project-file'. (".git" by default.)
  41 +;; You can set `ffip-project-root-function' to provide an alternate
  42 +;; function to search for the project root. By default, it looks only
  43 +;; for files whose names match `ffip-patterns',
  44 +
  45 +;; If you have so many files that it becomes unwieldy, you can set
  46 +;; `ffip-find-options' to a string which will be passed to the `find'
  47 +;; invocation in order to exclude irrelevant subdirectories. For
  48 +;; instance, in a Ruby on Rails project, you may be interested in all
  49 +;; .rb files that don't exist in the "vendor" directory. In that case
  50 +;; you could set `ffip-find-options' to "-not -regex \".*vendor.*\"".
  51 +
  52 +;; All these variables may be overridden on a per-directory basis in
  53 +;; your .dir-locals.el. See (info "(Emacs) Directory Variables") for
  54 +;; details.
  55 +
  56 +;; Recommended binding: (global-set-key (kbd "C-x f") 'find-file-in-project)
  57 +
  58 +;;; TODO:
  59 +
  60 +;; Add compatibility with BSD find (PDI; I can't virtualize OS X)
  61 +
  62 +;;; Code:
  63 +
  64 +(defvar ffip-project-file ".git"
  65 + "The file that should be used to define a project root.
  66 +
  67 +May be set using .dir-locals.el.")
  68 +
  69 +(defvar ffip-patterns
  70 + '("*.html" "*.org" "*.txt" "*.md" "*.el" "*.clj" "*.py" "*.rb" "*.js" "*.pl"
  71 + "*.sh" "*.erl" "*.hs" "*.ml")
  72 + "List of patterns to look for with `find-file-in-project'.")
  73 +
  74 +(defvar ffip-find-options ""
  75 + "Extra options to pass to `find' when using `find-file-in-project'.
  76 +
  77 +Use this to exclude portions of your project: \"-not -regex \\\".*svn.*\\\"\".")
  78 +
  79 +(defvar ffip-project-root nil
  80 + "If non-nil, overrides the project root directory location.")
  81 +
  82 +(defvar ffip-project-root-function nil
  83 + "If non-nil, this function is called to determine the project root.
  84 +
  85 +This overrides variable `ffip-project-root' when set.")
  86 +
  87 +(defvar ffip-limit 512
  88 + "Limit results to this many files.")
  89 +
  90 +(defun ffip-project-root ()
  91 + "Return the root of the project."
  92 + (let ((project-root (or ffip-project-root
  93 + (if (functionp ffip-project-root-function)
  94 + (funcall ffip-project-root-function)
  95 + (locate-dominating-file default-directory
  96 + ffip-project-file)))))
  97 + (or project-root
  98 + (progn (message "No project was defined for the current file.")
  99 + nil))))
  100 +
  101 +(defun ffip-uniqueify (file-cons)
  102 + "Set the car of FILE-CONS to include the directory name plus the file name."
  103 + ;; TODO: see if we can use uniquify.el
  104 + (setcar file-cons
  105 + (concat (cadr (reverse (split-string (cdr file-cons) "/"))) "/"
  106 + (car file-cons))))
  107 +
  108 +(defun ffip-join-patterns ()
  109 + "Turn `ffip-paterns' into a string that `find' can use."
  110 + (mapconcat (lambda (pat) (format "-name \"%s\"" pat))
  111 + ffip-patterns " -or "))
  112 +
  113 +(defun ffip-project-files ()
  114 + "Return an alist of all filenames in the project and their path.
  115 +
  116 +Files with duplicate filenames are suffixed with the name of the
  117 +directory they are found in so that they are unique."
  118 + (let ((file-alist nil))
  119 + (mapcar (lambda (file)
  120 + (let ((file-cons (cons (file-name-nondirectory file)
  121 + (expand-file-name file))))
  122 + (when (assoc (car file-cons) file-alist)
  123 + (ffip-uniqueify (assoc (car file-cons) file-alist))
  124 + (ffip-uniqueify file-cons))
  125 + (add-to-list 'file-alist file-cons)
  126 + file-cons))
  127 + (split-string (shell-command-to-string
  128 + (format "find %s -type f \\( %s \\) %s | head -n %s"
  129 + (or ffip-project-root
  130 + (ffip-project-root)
  131 + (error "No project root found"))
  132 + (ffip-join-patterns)
  133 + ffip-find-options
  134 + ffip-limit))))))
  135 +
  136 +;;;###autoload
  137 +(defun find-file-in-project ()
  138 + "Prompt with a completing list of all files in the project to find one.
  139 +
  140 +The project's scope is defined as the first directory containing
  141 +an `.emacs-project' file. You can override this by locally
  142 +setting the variable `ffip-project-root'."
  143 + (interactive)
  144 + (let* ((project-files (ffip-project-files))
  145 + (files (mapcar 'car project-files))
  146 + (file (if (and (boundp 'ido-mode) ido-mode)
  147 + (ido-completing-read "Find file in project: " files)
  148 + (completing-read "Find file in project: " files))))
  149 + (find-file (cdr (assoc file project-files)))))
  150 +
  151 +;;;###autoload
  152 +(defalias 'ffip 'find-file-in-project)
  153 +
  154 +;; safe locals
  155 +;;;###autoload
  156 +(progn
  157 + (put 'ffip-patterns 'safe-local-variable 'listp)
  158 + (put 'ffip-find-options 'safe-local-variable 'stringp)
  159 + (put 'ffip-project-file 'safe-local-variable 'stringp)
  160 + (put 'ffip-project-root 'safe-local-variable 'stringp)
  161 + (put 'ffip-project-root-function 'safe-local-variable 'functionp)
  162 + (put 'ffip-limit 'safe-local-variable 'integerp))
  163 +
  164 +(provide 'find-file-in-project)
  165 +;;; find-file-in-project.el ends here
14 init.el
@@ -908,8 +908,18 @@ if the major mode is one of 'delete-trailing-whitespace-modes'"
908 908 ;;
909 909 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
910 910
911   -(require 'find-file-in-git-repo)
912   -(global-set-key (kbd "C-x M-f") 'find-file-in-git-repo)
  911 +;; Deprecating in favor of find-file-in-project
  912 +;; (require 'find-file-in-git-repo)
  913 +;; (global-set-key (kbd "C-x M-f") 'find-file-in-git-repo)
  914 +
  915 +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  916 +;;
  917 +;; find-file-in-project
  918 +;;
  919 +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  920 +
  921 +(require 'find-file-in-project)
  922 +(global-set-key (kbd "C-x M-f") 'find-file-in-project)
913 923
914 924 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
915 925 ;;

0 comments on commit e80c7c9

Please sign in to comment.
Something went wrong with that request. Please try again.