Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

emacs find file in project on a big project

Tags:

emacs

In vim, there is this amazing plugin called command-t, that lets you fuzzy-search through all the files in your project. We have a fairly large rails app with a ton of files, and it is able to handle it pretty much without any slowdown at all.

tried a few things (like ffip, textmate.el's command-t, and rinari's rinari-find-in-project). The UI is great (I <3 flex), but the problem they all have is on a large project, the performance is bad to the point of being unusable.

Currently I am making more use of rinaris navigation commands and ido-find-file. Between the two of them it is a usable setup, but it would be nice to have a crazy fast fuzzy find in project.

Does anyone know of a more performant script then what I have tried?

like image 510
Matt Briggs Avatar asked Nov 01 '11 17:11

Matt Briggs


3 Answers

A github rep for my concoction is here: https://github.com/lewang/anything-project-files

I added a few more anything sources so that anything-project-find can be a drop-in replacement for "C-x b". So the idea is when you hit "C-x b" you are completing against existing buffers, recent files through recentf (personally I hack it to use "session.el" instead, but it's a small diff), files in current dir, files in current project. I find it pretty handy.

I've used this for a while, but it's not well tested, so please report any bugs you find.

like image 158
event_jr Avatar answered Sep 28 '22 08:09

event_jr


Try https://github.com/redguardtoo/find-file-in-project which use GNU Find or BSD Find to find files. Nothing can beat the speed of C!

M-x find-file-in-project-by-selected is the only command you need use.

I tested with 50000+ files at some stone-aged netbook without any issue.

By default it uses efficient ivy-mode to filter the candidate and ido-mode as fallback. I tested ivy-mode with three million candidates. Now you get the idea that Emacs Lisp itself is quick enough.

At *nix, the kernel provides cache for find, so if you search the files with same input, the response is instant.

Besides, the ivy-mode automatically cache the last search results in Emacs lisp variable ivy-last, so you can M-x ivy-resume to get the previous candidates without bothering Find.

You can (setq my-cached-result ivy-last) to store ivy-last into another variable. Then you can M-x my-ivy-resume:

(defun my-ivy-resume ()
  (interactive)
  (let* ((ivy-last (if my-cached-result my-cached-result ivy-last))
         (default-directory (ffip-get-project-root-directory)))
    (ivy-resume)))

In this way you can store last 1000 results and re-use them ;)

UPDATE 1: Since version 6, ffip use Emacs builtin API completing-read instead of ivy-read. So ivy specific feature like ivy-resume is not usable, yet. You can downgrade to version 5. ffip is just single Emacs Lisp file using only Emacs builtin API, so it's easy to downgrade.

Or wait the ivy to fix the issue (see https://github.com/abo-abo/swiper/pull/2785 )

UPDATE 2: Since version 6.1.1, I added command ffip-find-files-resume. It's more powerful than ivy-resume. For example, it can replay any previous action. ivy-resume can only replay last action.

like image 30
chen bin Avatar answered Sep 28 '22 09:09

chen bin


Depends what you mean by fuzzy matching. Most fuzzy matching is inherently slow, but some lightweight, pseudo-fuzzy algorithms are pretty fast. Generally speaking, you're probably better off with a regexp search, not a fuzzy-match search.

Anyway, there are two parts to the question:

  • Defining a project as a given set of files and directories.
  • Searching through the project files & directories -- all or some

Icicles can help with both:

  • Project definition, management, etc.

  • Searching a project or parts of it:

    • Searching file content (and search-and-replace)

    • Locating files

like image 25
Drew Avatar answered Sep 28 '22 07:09

Drew