|Number of watchers on Github||226|
|Number of open issues||10|
|Average time to close an issue||4 months|
|Main language||Emacs Lisp|
|Average time to merge a PR||17 days|
|Open pull requests||0+|
|Closed pull requests||11+|
|Last commit||over 2 years ago|
|Repo Created||over 11 years ago|
|Repo Last Updated||over 2 years ago|
|Organization / Author||technomancy|
|Do you use find-file-in-project? Leave a review!|
|View open issues (10)|
|View find-file-in-project activity|
|View on github|
|Fresh, new opensource launches 🚀🚀🚀|
Software engineers: It's time to get promoted. Starting NOW! Subscribe to my mailing list and I will equip you with tools, tips and actionable advice to grow in your career.
Find file/directory and review Diff/Patch/Commit quickly everywhere.
User Case One: Find file/directory quickly in current project. The project root is detected automatically if Git/Subversion/Mercurial is used.
User Case Two: Diff/patch files. Target files could be understand any Version Control Software (VCS) or there is no VCS at all. Please check =ffip-diff-*= commands.
It is also possible to use [[http://stable.melpa.org/#/find-file-in-project][melpa]]; however be aware that as of the time of this writing installation using =package.el= is [[https://glyph.twistedmatrix.com/2015/11/editor-malware.html][not recommended]] due to flaws in Emacs's TLS implementation.
[[https://github.com/abo-abo/swiper][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.
Users of Debian 10 and derivatives can install find-file-in-project with the following command: =sudo apt install elpa-find-file-in-project=
You can also manually specify the file path,
(if (eq system-type 'windows-nt)
** Linux and OS X NO setup needed.
You can override the default root directory by setting =ffip-project-root=,
Per-project and per-directory setup is easy. Check
Tips section for details.
** =M-x find-file-in-project-at-point=
Guess the file name at point and try to find file.
** =M-x find-file-in-project-by-selected=
Use the selected region as keyword to search file. If no region selected, you may provide the keyword which could contain wildcard.
If keyword contains line number like
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 with any part of full path before displaying candidates. It's a little slower than the original setup.
It could replace old command =find-file-in-project= (or =ffip=) because it's more efficient. It was tested searching in 50K+ files without any performance issue. ** =M-x find-file-with-similar-name= Find file with similar name to current opened file.
The regular expression =ffip-strip-file-name-regex= is also used by =find-file-with-similar-name=. ** =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. This command is slow if there 10K+ files because it use ONLY Emacs Lisp to filter candidates. You should always use =find-file-in-project-by-selected= unless in small project.
** =M-x ffip-create-project-file=
Create =.dir-locals.el= which
[[http://www.gnu.org/software/emacs/manual/html_node/emacs/Directory-Variables.html][defines the same set of local variables to all the files in a certain directory and its subdirectory]].
You can use it to setup variables like =ffip-project-root=.
This command respects existing =.dir-locals.el=. So it will merge new setup into existing content.
See [[http://www.gnu.org/software/emacs/manual/html_node/emacs/Directory-Variables.html][Emacs manual]] for technical details. ** =M-x find-file-in-current-directory= Like =M-x find-file-in-project= but find only in current directory. ** =M-x find-file-in-current-directory-by-selected= Like =M-x find-file-in-project-by-selected= but find only in current directory. ** =M-x ffip-show-diff= Execute selected backend from =ffip-diff-backends=.
The output of backend execution is in [[http://www.gnu.org/software/diffutils/manual/html_node/Unified-Format.html][Unified Diff Format]] and is inserted into =ffip-diff= buffer where you can press =o=, =C-c C-c=, =ENTER= , =M-x ffip-diff-find-file= to open the corresponding file.
=ffip-diff-find-file-before-hook= is called before =M-x ffip-diff-find-file=.
For example, you can =M-x ffip-show-diff= to view the git commit and open corresponding file.
If you use [[https://www.mercurial-scm.org/][Mercurial]], =M-x 5 ffip-show-diff=.
Please press =C-h v ffip-diff-backends= to view the available back-ends.
Other key bindings available in =ffip-diff= buffer, | key binding | command | |-------------+----------------| | p | diff-hunk-prev | | n | diff-hunk-next | | P | diff-file-prev | | N | diff-file-next |
Insert below code into ~/.emacs if you use evil-mode,
(defun ffip-diff-mode-hook-setup ()
(evil-local-set-key 'normal (kbd
(add-hook 'ffip-diff-mode-hook 'ffip-diff-mode-hook-setup)
You can customize the =ffip-diff-backends=,
cd $(git rev-parse --show-toplevel) && git diff
cd $(git rev-parse --show-toplevel) && git diff --cached
Diff from `kill-ring' . (car kill-ring))
cd $(hg root) && hg diff
** =M-x ffip-save-ivy-last= and =M-x ffip-ivy-resume= These two commands requires [[https://github.com/abo-abo/swiper][ivy-mode]].
=ffip-save-ivy-last= saves the most recent search result.
=ffip-ivy-resume= re-use the search result saved by =ffip-save-ivy-last=.
You can always use =ivy-resume= to re-use the most recent search result. ** =M-x find-relative-path= Find file/directory and copy its relative path into `kill-ring'.
File's path is copied by default. =C-u M-x find-relative-path= copy directory's path.
You can set =ffip-find-relative-path-callback= to format the string before copying.
;; (setq ffip-find-relative-path-callback 'ffip-copy-reactjs-import) (setq ffip-find-relative-path-callback 'ffip-copy-org-file-link)
** =M-x ffip-diff-apply-hunk= Similar to =diff-apply-hunk=, it applies current hunk in =diff-mode= to the target file (please note =ffip-diff-mode= inherits from =diff-mode=).
The target file could be located by searching =(ffip-project-root)=. You can also apply extra operation on the file in =ffip-diff-apply-hunk-hook= before hunk applying actually happens.
For example, for files under [[https://www.perforce.com/][Perforce]] control,
p4 edit FILE and make corresponding buffer writable.
p4 edit %s file))
;; make sure the buffer is readable
(let* ((buf (get-file-buffer file)))
;; turn off read-only since we've already `p4 edit'
(defun ffip-diff-apply-hunk-hook-setup (file)
(unless (featurep 'init-perforce) (require 'init-perforce))
(add-hook 'ffip-diff-apply-hunk-hook 'ffip-diff-apply-hunk-hook-setup)
** =ffip-split-window-horizontally= and =ffip-split-window-vertically= Find&Open file in split window.
ffip-get-project-root-directoryreturn the full path of current project ** Per-project setup using Emacs lisp Here is complete setup you could insert into =~/.emacs.d/init.el=, #+begin_src elisp ;; 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
) ;; 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"
*.js)) ;; maybe you want to search files in
bin' directory? (setq-local ffip-prune-patterns (delete "*/bin/*" ffip-prune-patterns)) ;; excludedist/' directory (add-to-list 'ffip-prune-patterns
*/dist/*)) ;; 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) #+end_src ** 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 can place =.dir-locals.el= into your project root directory.
A sample =.dir-locals.el=,
((nil . ((ffip-project-root .
;; ingore files bigger than 64k and directory
-not -size +64k -not -iwholename '*/dist/*')
;; only search files with following extensions
(ffip-patterns . (
(eval . (progn
;; ingore directory
;; Do NOT ignore directory "bin/"
As we mentioned, =ffip-create-project-file= could create a minimum =.dir-locals.el= for you.
BTW, 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
** More keybinding tips =C-h i g (ivy) Enter= for more key-binding tips. ** Search and grep files under Git control Install [[https://github.com/abo-abo/swiper][counsel]].
Use =cousel-git= to find file and =counsel-git-grep= to grep. It's developed by the author of Ivy.
DO NOT use other APIs from =ivy-mode=. The less APIs used, the more stable this package will be.
Run =tests/test.sh= before =git commit=.
find-file-in-project 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 [[https://raw.githubusercontent.com/technomancy/find-file-in-project/master/LICENSE][GNU General Public License]] for more details.