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.
- 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
- Smart. For keyword “helloWorld”, “HelloWorld.html” “hello-world.css”, “HelloWorld.js” are searched
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)
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.
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.
Project root is automatically detected if Git/Mercurial/Subversion used.
You can override the default root directory by set the variable
(setq ffip-project-root "~/projs/PROJECT_DIR")
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
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.
(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.
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
If parameter is passed , directory will be opened in new window.
Starts search immediately
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-project and
M-x find-file-in-project-by-selected but find only in current directory.
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)
- “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
ffip-filename-rules create some extra file names for
search when calling
find-file-in-project-by-selected. For example,
When file basename
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.
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.