• Stars
    star
    428
  • Rank 101,481 (Top 2 %)
  • Language
    Emacs Lisp
  • License
    GNU General Publi...
  • Created almost 16 years ago
  • Updated over 1 year ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

Quick access to project files in Emacs

find-file-in-project

https://github.com/redguardtoo/find-file-in-project/actions/workflows/test.yml/badge.svg http://melpa.org/packages/find-file-in-project-badge.svg http://stable.melpa.org/packages/find-file-in-project-badge.svg

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 under any Version Control Software (VCS) or no VCS at all. Please check ffip-diff-* commands.

Features:

  • Works on Windows64/Linux/macOS with minimum setup. Only dependency is BSD/GNU Find
  • Fast. Tested with 50,000+ files
  • Works flawlessly with Tramp Mode
  • Uses native API completing-read and supports ido/helm/ivy/consult/selectrum out of box

Screenshot:

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

Try it

Run make runemacs in this project’s root directory. The demo works out of box.

Install

Place find-file-in-project.el under Load Path. Then add (require 'find-file-in-project) to your configuration.

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.

Since v3.7, Emacs 24.3 is required.

Since v5.7.5, Emacs 24.4 is required.

Since v6, Emacs 25.1 is required.

Users of Debian ≥10 and derivatives can install this program with the following command: sudo apt install elpa-find-file-in-project

Setup

Since v6, ffip gives you freedom to choose your favorite completion framework.

It only uses builtin api completing-read.

Ido setup,

(setq ffip-prefer-ido-mode t)

Helm setup,

(helm-mode 1)

Ivy setup,

(ivy-mode 1)

Windows

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

You can also manually specify the executable path,

(when (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 is used.

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

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

Per-project and per-directory setup is easy. Check “Tips” section for details.

find-file-in-project-at-point

Guess the file path at point and try to find file. The path could contain environment variables.

find-file-in-project-by-selected

Use the selected region as keyword to search file. If no region is active, you could provide the keyword which could contain wildcard.

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 (setq ffip-match-path-instead-of-filename t) is placed 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 could replace old command find-file-in-project (or ffip) because it’s faster. It was tested searching in 50K+ files without any performance issue.

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.

find-directory-in-project-by-selected

Use the selected region as keyword to find directory. If no region is active, you could 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.

ffip-fix-file-path-at-point

It replaces file path at point with correct relative/absolute path. File path could contain environment variables.

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 in big project..

ffip-find-files-resume

File/directory searching actions are automatically stored into ffip-find-files-history.

Use ffip-find-files-resume to replay any previous action.

The maximum number of items of the history is set in ffip-find-files-history-max-items.

ffip-lisp-find-file-in-project

By default it finds file in project. f its parameter is not nil, it find directory instead.

It’s written in pure Lisp and does not use any third party command line program. So it works in all environments.

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 subdirectory”.

You can setup variables like ffip-project-root in this file.

The original setup in .dir-locals.el is respected. This command will merge new setup with old content.

See Emacs manual for technical details.

find-file-in-current-directory

Like find-file-in-project but find file in current directory.

find-file-in-current-directory-by-selected

Like find-file-in-project-by-selected but find file in current directory.

ffip-show-diff

Execute backend from ffip-diff-backends.

The output of backend execution is in 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 in ffip-diff-find-file. Two file names are passed to it as parameters. One name is returned by the hook as the file searching keyword.

For example, you can M-x ffip-show-diff to view the git commit and open file inside patch.

, M-x 5 ffip-show-diff executes 5th backend from ffip-diff-backends.

Please press C-h v ffip-diff-backends to view available back-ends.

Other key bindings defined in *ffip-diff* buffer,

key bindingcommand
pdiff-hunk-prev
ndiff-hunk-next
Pdiff-file-prev
Ndiff-file-next

Insert below code into .emacs if you use evil-mode,

(defun ffip-diff-mode-hook-setup ()
    (evil-local-set-key 'normal "K" 'diff-hunk-prev)
    (evil-local-set-key 'normal "J" 'diff-hunk-next)
    (evil-local-set-key 'normal "P" 'diff-file-prev)
    (evil-local-set-key 'normal "N" 'diff-file-next)
    (evil-local-set-key 'normal (kbd "RET") 'ffip-diff-find-file)
    (evil-local-set-key 'normal "o" 'ffip-diff-find-file))
(add-hook 'ffip-diff-mode-hook 'ffip-diff-mode-hook-setup)

You can customize the ffip-diff-backends,

(setq ffip-diff-backends
      '(ffip-diff-backend-git-show-commit
        "cd $(git rev-parse --show-toplevel) && git diff"
        "cd $(git rev-parse --show-toplevel) && git diff --cached"
        ffip-diff-backend-hg-show-commit
        ("Diff from `kill-ring'" . (car kill-ring))
        "cd $(hg root) && hg diff"
        "svn diff"))

Please note some backends assume that the git cli program is added into environment variable PATH.

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)

ffip-diff-apply-hunk

Similar to diff-apply-hunk, it applies current hunk on the target file (please note ffip-diff-mode inherits from diff-mode).

The target file could be found by searching (ffip-project-root). You can also apply extra operation on the file in ffip-diff-apply-hunk-hook before hunk applying happens.

For example, for files under Perforce control,

(defun p4-edit-file-and-make-buffer-writable(file)
  "p4 edit FILE and make corresponding buffer writable."
  (shell-command (format "p4 edit %s" file))
  ;; make sure the buffer is readable
  (let* ((buf (get-file-buffer file)))
    (if buf
        (with-current-buffer buf
          ;; turn off read-only since we've already `p4 edit'
          (read-only-mode -1)))))
(defun ffip-diff-apply-hunk-hook-setup (file)
  (unless (featurep 'init-perforce) (require 'init-perforce))
  (if (string-match-p "/myproject/" file)
      (p4-edit-file-and-make-buffer-writable file)))
(add-hook 'ffip-diff-apply-hunk-hook 'ffip-diff-apply-hunk-hook-setup)

ffip-diff-filter-hunks-by-file-name

It can filter hunks by their file names.

For example, user input pattern “regex !exclude1 exclude1” means the hunk’s file name does match “regex”, but does not match “exclude1” or “exclude2”.

Please note in “regex”, space represents any string.

ffip-insert-file

Insert file content into current buffer.

Tips

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

Use fd (A simple, fast and user-friendly alternative to ‘find’)

Please insert (setq ffip-use-rust-fd t) into .emacs to use fd (alternative to GNU Find).

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=,

;; 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"))
    ;; ignore files whose name match certain glob pattern
    (setq-local ffip-ignore-filenames '("*.bmp" "*.jpg"))
    ;; exclude `dist/' 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)

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 . "~/projs/PROJECT_DIR")
         ;; ignore files bigger than 64k and directory "dist/" when searching
         (ffip-find-options . "-not -size +64k -not -iwholename '*/dist/*'")
         ;; only search files with following extensions
         (ffip-patterns . ("*.html" "*.js" "*.css" "*.java" "*.xml" "*.js"))
         (eval . (progn
                   (require 'find-file-in-project)
                   ;; ignore directory ".tox/" when searching
                   (setq ffip-prune-patterns `("*/.tox" ,@ffip-prune-patterns))
                   ;; Do NOT ignore directory "bin/" when searching
                   (setq ffip-prune-patterns `(delete "*/bin" ,@ffip-prune-patterns))))
         )))

As mentioned, ffip-create-project-file could create a minimum .dir-locals.el.

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
    (setq ffip-project-root "C:/Users/myname/projs/myproj1")
  ;; Cygwin
  (setq ffip-project-root "~/projs/myprojs1"))

Search and grep files under Git control

Install counsel.

Use counsel-git to find file and counsel-git-grep to grep.

Bug Report

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

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 of the License, 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.

More Repositories

1

mastering-emacs-in-one-year-guide

Be great at emacs in one year
6,370
star
2

emacs.d

Fast and robust Emacs setup.
Emacs Lisp
2,411
star
3

evil-nerd-commenter

Comment/uncomment lines efficiently. Like Nerd Commenter in Vim
Emacs Lisp
390
star
4

elpa-mirror

Create local emacs package repository. 15 seconds to install 115 packages.
Emacs Lisp
315
star
5

evil-matchit

Vim matchit ported into Emacs
Emacs Lisp
287
star
6

cpputils-cmake

Easy real time C++ syntax check and intellisense if you use CMake
Emacs Lisp
196
star
7

counsel-etags

Fast, energy-saving, and powerful code navigation solution
Emacs Lisp
174
star
8

wucuo

Fastest solution to spell check camel case code or plain text
Emacs Lisp
121
star
9

eacl

eacl - Emacs auto complete lines by grepping project
Emacs Lisp
97
star
10

vc-msg

Show commit message of current line in Emacs
Emacs Lisp
79
star
11

cliphist

Paste from clipboard manager into Emacs
Emacs Lisp
75
star
12

js-comint

js-comint will send the code from Emacs into node.js or rhino
Emacs Lisp
71
star
13

company-ctags

Fastest Emacs auto-completion using Company and Ctags
Emacs Lisp
56
star
14

pyim-tsinghua-dict

用清华大学开放中文词库数据建立的pyim 输入法]词库. 已基于词频统计信息DF值(Document Frequency)优化
Python
48
star
15

mybigword

Use Zipf frequency of each word to extract English big words
Emacs Lisp
38
star
16

org2nikola

export org into html used by static blog generator like https://github.com/getnikola/nikola
Emacs Lisp
27
star
17

myelpa

Mirror of Emacs packages I'm using
23
star
18

vscode-setup

21
star
19

gmail2bbdb

convert gmail contacts to BBDB file, easy to use, robust, no dependency
Emacs Lisp
20
star
20

vscode-matchit

Jump between matching HTML tags and brackets smartly in VS Code. It's ported from Vim matchit by Benji Fisher
TypeScript
20
star
21

find-by-pinyin-dired

Find file by first Pinyin characters of Chinese Hanzi. 输入拼音首字母定位对应的中文目录/文件
Emacs Lisp
18
star
22

imenu-extra

Add extra items into lsp-mode/js2-mode imenu items
Emacs Lisp
15
star
23

redguardtoo.github.io

my blog
HTML
14
star
24

NinjaWebCoder

Use keyboard to copy code from stackoverflow
HTML
14
star
25

test-git-mergetool

toy project to test git mergetool
14
star
26

dianyou

Search/Analyze mails in Gnus
Emacs Lisp
12
star
27

pyim2fcitx

Conver pyim dictionary to fcitx dictionary
Python
12
star
28

lazyflymake

Lightweight syntax checker for Emacs, alternative of `flymake-mode'
Emacs Lisp
11
star
29

shellcop

Analyze errors reported in Emacs builtin shell
Emacs Lisp
10
star
30

evil-mark-replace

replace string in marked region effectively
Emacs Lisp
9
star
31

counsel-bbdb

Quick search&input email from BBDB based on ivy
Emacs Lisp
9
star
32

js2hl

Highlight/rename things using `js2-mode' parser
Emacs Lisp
8
star
33

shenshou

download subtitles from opensubtitles.org
Emacs Lisp
8
star
34

spell-check-code-in-ci

Free and powerful solution to spell check code at Continuous integration server
Makefile
7
star
35

fastdef

Insert terminology faster
Emacs Lisp
6
star
36

diff-lisp

Diff files&strings in pure Emacs Lisp.
Emacs Lisp
6
star
37

root-dotfiles

my dotfiles as root at Linux host
Shell
6
star
38

jqcuo

Powerful and simple solution to spell check code in command line
Emacs Lisp
6
star
39

jest-coverage-for-files-outside-of-root

jest coverage for files outside of root
JavaScript
5
star
40

find-and-ctags

Use `find' and `ctags' for code navigation
Emacs Lisp
5
star
41

portable-percol

portable percol (https://github.com/mooz/percol)
Python
5
star
42

zhfreq

processing chinese text using word frequency data
Emacs Lisp
4
star
43

my-emacs.d-snapshot

Emacs Lisp
4
star
44

AX88772C_Source

my usb to net adapter
C
4
star
45

test-git-blame

A project to test git blame
JavaScript
3
star
46

roblox-mode

Emacs major mode to edit Roblox Studio rbxlx files
Emacs Lisp
3
star
47

org-mime

org html export for text/html MIME emails
3
star
48

perl-recordmydesktop

perl-recordmydesktop.pl is the frontend for recordMyDesktop screencast tool
Prolog
3
star
49

counsel-ctags

Fast code navigation using Universal Ctags
Emacs Lisp
3
star
50

test-git-log

JavaScript
1
star
51

asus-pce-n53-11n-n600

ASUS PCE-N53 wireless patched driver and gentoo installation mini-guide
C
1
star
52

ms-frontend-sandbox

sandbox for interviewers
JavaScript
1
star
53

helloworld

hello world
C
1
star
54

wxwidgets-help

Look up wxWidgets API in Emacs by using local html manual
Emacs Lisp
1
star