Skip to content
Quick access to project files in Emacs
Emacs Lisp Shell
Latest commit faaab6e May 18, 2016 @redguardtoo redguardtoo typo

README.org

find-file-in-project (v4.9.1)

Find files in a project quickly, on any operating system.

This program provides a couple methods for quickly finding any file in a given project. It depends on GNU Find.

By default, it will automatically search file in directory managed by git/subversion/mercurial. But you can easily switch to other types of projects.

Features:

  • Only dependency is GNU Find
  • Works perfectly on any OS with minimum or no setup
  • Quick. Tested with 50,000+ files
  • You can tweak GNU find through flag ffip-find-options
  • Smart. For keyword “helloWorld”, “HelloWorld.html” “hello-world.css”, “HelloWorld.js” are searched

Screenshot:

https://raw.githubusercontent.com/technomancy/find-file-in-project/master/ffip-screenshot-nq8.png

Install

Place find-file-in-project.el on your load-path, and add this to your configuration:

(autoload 'find-file-in-project "find-file-in-project" nil t)
(autoload 'find-file-in-project "find-file-in-project-by-selected" nil t)
(autoload 'find-file-in-project "find-directory-in-project-by-selected" nil t)

It is also possible to use melpa; however be aware that as of the time of this writing installation using package.el is not recommended due to flaws in Emacs’s TLS implementation.

Ivy-mode is the optional dependency which is installed automatically if you use melpa. If it is not found, ido will be used instead.

Since v3.7, Emacs 24.3 is required.

Setup

Windows

Windows setup is as easy as install Cygwin or MYSYS2 at default directory of any driver. GNU Find executable will be detected automatically.

You can also manually specify the location of find executable,

(if (eq system-type 'windows-nt)
    (setq ffip-find-executable "c:\\\\cygwin64\\\\bin\\\\find")

Linux and OS X

NO setup needed.

Usage

Project root is automatically detected if Git/Mercurial/Subversion used.

You can override the default root directory by set the variable ffip-project-root,

(setq ffip-project-root "~/projs/PROJECT_DIR")

M-x find-file-in-project-by-selected

Use the selected region as keyword to search file. If no region selected, you need provide the keyword. Keyword could contain wildcard which passed to Find as value of -name option

If keyword contains line number like “hello.txt:32” or “hello.txt:32:”, we will move to that line in opened file.

If parameter is passed , file will be opened in new window.

If you (setq ffip-match-path-instead-of-filename t) before M-x find-file-in-project-by-selected, we try to match selected text any part of full path (directory+file name) before displaying candidates. It’s a little slower than the original setup but make find-file-in-project behaves exactly like Sublime Text’s Cmd+P.

M-x find-directory-in-project-by-selected

Use the selected region as keyword to find directory. If no region selected, you need provide the keyword. Keyword could contain wildcard character which passed to Find as value of -iwholename option

If parameter is passed , directory will be opened in new window.

M-x find-file-in-project

Starts search immediately

M-x ffip-create-project-file

Create .dir-locals.el which ”defines the same set of local variables to all the files in a certain directory and its subdirector”.

You can use it to setup find-file-in-project variable like “ffip-project-root”.

See Emacs manual for technical details.

M-x find-file-in-current-directory and M-x find-file-in-current-directory-by-selected

Like M-x find-file-in-project and M-x find-file-in-project-by-selected but find only in current directory.

Tips

Please note all tips are OPTIONAL. find-file-in-project works out of box in 99% cases.

You prefer ido-mode?

(ido-mode 1)
(setq ffip-prefer-ido-mode t)

APIs

  • “ffip-get-project-root-directory” return the full path of current project

Per-project setup using Emacs lisp

Here is complete setup you could insert into “~/.emacs.d/init.el”,

;; if the full path of current file is under SUBPROJECT1 or SUBPROJECT2
;; OR if I'm reading my personal issue track document,
(defun my-setup-develop-environment ()
  (interactive)
  (when (ffip-current-full-filename-match-pattern-p "\\(/|/PROJECT_DIR\\|issue-track.org\\)")
    ;; Though PROJECT_DIR is team's project, I care only its sub-directory "subproj1""
    (setq-local ffip-project-root "~/projs/PROJECT_DIR/subproj1")
    ;; well, I'm not interested in concatenated BIG js file or file in dist/
    (setq-local ffip-find-options "-not -size +64k -not -iwholename '*/dist/*'")
    ;; for this project, I'm only interested certain types of files
    (setq-local ffip-patterns '("*.html" "*.js" "*.css" "*.java" "*.xml" "*.js"))
    ;; exclude below directories and files
    (setq-local ffip-prune-patterns '("*/.git/*" "*/node_modules/*" "*/index.js")))
  ;; insert more WHEN statements below this line for other projects
  )
;; most major modes inherit from prog-mode, so below line is enough
(add-hook 'prog-mode-hook 'my-setup-develop-environment)

Per-directory setup using .dir-locals.el

All variables may be overridden on a per-directory basis in your .dir-locals.el. See (info “(Emacs) Directory Variables”) for details.

You only need place .dir-locals.el into your project root directory.

Here is a sample .dir-locals.el,

((nil . ((ffip-project-root . "~/projs/PROJECT_DIR")
         (ffip-find-options . "-not -size +64k -not -iwholename '*/dist/*'")
         (ffip-patterns . ("*.html" "*.js" "*.css" "*.java" "*.xml" "*.js"))
         (ffip-prune-patterns . ("*/.git/*" "*/node_modules/*" "*/index.js"))
         )))

Please use either per-directory setup or per-project setup, NOT both.

Specify root directory on Windows

(if (eq system-type 'windows-nt)
    ;; Native Windows
    (setq ffip-project-root "C:/Users/myname/projs/myproj1")
  ;; Cygwin
  (setq ffip-project-root "~/projs/myprojs1"))

Search multiple file name patterns

The variable ffip-filename-rules create some extra file names for search when calling find-file-in-project-by-selected. For example, When file basename helloWorld provided, HelloWorld, hello-world are added as the file name search patterns.

C-h v ffip-filename-rules to see its default value.

As other variables, it could be customized per project,

(setq-local ffip-filename-rules
            '(;; first, search by the original file name
              ffip-filename-identity
              ;; second, apply either below rule
              (ffip-filename-dashes-to-camelcase ffip-filename-camelcase-to-dashes)))

That’s especially useful when you are doing web front end development.

More keybinding tips

=C-h i g (ivy) Enter’ for more key-binding tips.

Development

Please note only =ivy-read= from ivy-mode is used. DO NOT use other APIs from ivy-mode. The less APIs used, the more stable this package will be.

Bug Report

Check https://github.com/technomancy/find-file-in-project.

Something went wrong with that request. Please try again.