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?
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.
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.
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:
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With