6

I'm a long time Emacs user, but partially switched to MacVim 2 years ago, and have been using it for all my programming work (still using Emacs for other stuff). I decided to switch back to Emacs now, mainly because of the awesome evil-mode. I'm quite happy, but I still haven't found something as good and simple as the Vim Command-T plugin.

The main problem with the Emacs alternatives is that they are either too complicated and or slow.

The closest thing to Command-T is helm/helm-cmd-t, but it doesn't quite work like it.

Let's say you have two paths:

  • app/controllers/admin/feedback_controller.rb
  • app/controllers/fee_controller.rb

In Vim's Command-T, you can write:

app/controllers/fe

And it will match both paths.

With helm-cmd-t, if I write app/controllers/fee, it will only match fee_controller. If I want to match both, I have to use a regexp, as in app/controllers/.*, which is not that bad, but requires more keystrokes.

Any suggestions appreciated!

itsjeyd
  • 5,070
  • 2
  • 30
  • 49
FullOfCaffeine
  • 539
  • 1
  • 6
  • 22
  • 1
    Did you try using spaces instead of slashes when searching? AFAIK helm uses spaces for lazy matching by default (I remember reading somwehere the matching algorithm is pluggable, so an other implementation is also possible), so you can try using those between words. Typing the slashes is superfluous anyway if the search is about matching words in the path, so you can use spaces instead of slashes and see what happens. – Tom Mar 26 '13 at 17:31
  • Vim's command-t is close to Sublime Text 2's search feature. Emacs has nothing close natively. I'll be playing around with a regexp implementation for `helm-cmd-t` soon. – event_jr Mar 27 '13 at 00:29
  • 1
    Seems like you want to find a file with partial path. Have you tried `helm-locate`? https://github.com/emacs-helm/helm/wiki#helmlocate – Amumu Apr 05 '14 at 14:44
  • In your example, you can try this regex in `helm-locate`: app.*contr.*fe – Amumu Apr 05 '14 at 14:46
  • 1
    Presently ONLY flx + ido-mode + Projectile + ido-vertical will replicate the Cmd-T feature properly. Without using .* or / or whatever interspersed chars, and just allow you to fuzzy match (fast). Note that nothing, currently, implements the multiple selection feature of Ctrl+P – ocodo Jul 30 '14 at 02:41

8 Answers8

3

Any Emacs package that uses ido can do this, provided that ido-flex-match is non-nil. Helm-cmd-t deliberately doesn't support this kind of flexible matching.

You can get the behaviour you describe using find-file-in-repository with ido-flex-match set to 't.

Wilfred Hughes
  • 29,846
  • 15
  • 139
  • 192
  • ido is not bad, I like it. I've been trying different options, including the Textmate plugin, which provides a find-file implementation that uses Ido. However, I've grown used to the way Command-T renders the file list - stacked up vertically. I'd like something that mimics the way Command-T works. I actually find it quite amazing that Emacs doesn't have something as good, simple as fast as Command-T. – FullOfCaffeine Mar 26 '13 at 15:05
  • To be clear, I deliberately dislike ido's unsophisticated implementation of "flex". Sublime Text 2's search is wonderful. – event_jr Mar 27 '13 at 00:35
  • 1
    @FullOfCaffeine: Here's how I got vertical result list http://emacswiki.org/emacs/InteractivelyDoThings#toc20 – tungd Mar 27 '13 at 15:23
  • It has ... :) just installed it, and instead of "Ctrl+P" - now I'm using "Alt+T" :) ... https://github.com/defunkt/textmate.el – pesho hristov May 01 '15 at 19:33
3

I've recently started using flx with ido-mode and projectile it has exceptionally good, ranked fuzzy matching and has a very similar feel to CtrlP and CmdT for Vim.

It can be installed via MELPA.

M-x package-install
flx

For more info see the flx project.

Here's a screengrab to illustrate...

flx fuzzy matching

ocodo
  • 29,401
  • 18
  • 105
  • 117
2

Here it is, but required helm to be installed first: https://github.com/emacs-helm/helm-cmd-t

EDIT: See my Helm guide. Read why it is powerful. See helm with projectile in action in that section.

With fuzzy searcher like Ido + flx or the like in Vim, you have to type thing in order. With Helm, you can perform out of order matching.I called it out of order because whether I enter "main.c x86" or "x86 main.c", I get the same set of results for the either query. But it also makes sense to call it multi-steps search. Without having to enter the search strings (called "patterns", which are actually regexp) in an orderly fashion, Helm gives me greater freedom: I can enter the thing I wanted first in my mind without having to remember its complex path; if there are many candidates from the target I wanted, I narrow it down further with more details (patterns).

The above example to illustrate the two cases from the advantage above:

  • If my desire target is not unique, fine I can narrow further.
  • If my desire target is unique, I can immediately get it.

As you can see, the Linux kernel source tree contains more than 40kfiles, and I narrowed it down to a few files immediately.

Visual Studio also implements this mechanism in their project search, but it's not generic as Helm. In Helm, you can reuse the same Helm interface for many other things; for example, see helm-semantic-or-imenu. You have something like an outline tree, but you can interactively and incrementally narrow to the candidates you want with a few simple patterns.

Finally, fyi, flx author - Le Wang - is using Helm.

Amumu
  • 17,924
  • 31
  • 84
  • 131
  • @EmacsFodder But you are using [Helm](http://tuhdo.github.io/helm-intro.html#sec-17), which offers a more powerful interface. True, you cannot do proper fuzzy match, but you have something more powerful: **out of order matching**, with multiple querries. Using the fuzzy searcher, you have to type things **in order**, but using Helm, for example, you can just type **part** of a filename first, then type the path later. With Ido, you can never do that. – Amumu Jul 29 '14 at 02:58
  • Just try using the solution I outlined in my answer, with ido in vertical mode too. You'll be less concerned about how Helm could be doing this in theory. You'll just simply be happy at how well it actually works. – ocodo Jul 29 '14 at 07:15
  • @EmacsFodder I switched from `Ido` + `flx` + `vertical-ido` to Helm and never looked back. Since I have to match candidate in a specific order, it's inflexible; and I also have to remember past candidates to make the fuzzy matching work. Helm even works outside of file matching, i.e. it can be used as [completion interface with big number of candidates](http://tuhdo.github.io/static/auto_complete.gif), with syntax highlighting; or [interactively grepping](http://tuhdo.github.io/static/live_grep.gif). I think you should try `Helm`. And as I told you, `flx` author is also using `Helm`. – Amumu Jul 29 '14 at 08:35
  • @EmacsFodder For example, using `helm-M-x`, I can type "li pa" or "pa li", `Helm` correctly matches `list-package`. But using `ido` + `flx`, "pa li" is not an option. – Amumu Jul 29 '14 at 08:41
  • I've been using Helm for a long time for a variety of different things, but I guess the Cmd-t plugin is new? I'll check out your links. – ocodo Jul 29 '14 at 12:10
  • @EmacsFodder Tbh I never use `helm-cmd-t` since I use `projectile` with `Helm` already. And if it a directory is not under version control, then I use `helm-locate`, which is pretty fast since it uses `locate`. – Amumu Jul 29 '14 at 13:25
  • @EmacsFodder, in addition to out-of-order matching, helm allows negation with the "!" prefix. – event_jr Aug 04 '14 at 02:16
1

Did you try LustyExplorer? It's based on the Vim plugin with the same name.

Also, it looks like you are not using Command-T to the best of its capabilities: acfe should be enough for it to match those two files. What you do is not particularly better than :e app/con*/**/fe<Tab>.

romainl
  • 186,200
  • 21
  • 280
  • 313
  • LustyExplorer (the emacs version at least) doesn't quite work like Command-T in the sense that I can't start matching deep nested files (like the example you showed, with "acfe", which works great!), I actually need to scope it to a directory first, which is very annoying. – FullOfCaffeine Mar 26 '13 at 15:01
  • Hmm, that's probably why I switched to CtrlP. Well, not being an Emacs user I can't help you further. – romainl Mar 26 '13 at 15:30
  • No worries. What is CtrlP by the way? – FullOfCaffeine Mar 26 '13 at 16:39
  • [CtrlP](https://github.com/kien/ctrlp.vim) is similar to Command-T but better (IMO). – romainl Mar 26 '13 at 16:48
1

I've once run across gpicker which advertises speed as one of its advantages over Ido and other "native" elisp packages. Never got to try it out on real-world projects though, but it might work for you.

immerrr
  • 1,251
  • 7
  • 13
  • I used gpicker in the past, it is indeed very good. I might actually use it again, but I was looking for something that renders from inside the emacs window/frame. – FullOfCaffeine Mar 26 '13 at 15:02
  • @FullOfCaffeine, I was pretty sure gpicker did have a mode that allowed it to interact solely within Emacs buffers... I think, I need to finally check it out myself. – immerrr Mar 26 '13 at 21:04
  • UPD: it does not. It's weird indeed that nothing alike exists. – immerrr Mar 26 '13 at 21:14
  • It is. I'm a bit disappointed. I prefer Emacs in every other way, but I still prefer Vim in this aspect, and only because of Command-T - it's just the fastest and most effective of searching/picking up files IMO. – FullOfCaffeine Mar 27 '13 at 23:29
  • I've skimmed through sources of gpicker, it looks simple enough, I think I might actually find the time to write something up... – immerrr Mar 29 '13 at 10:08
1

Long story short - there's nothing quite like command-T for Emacs. Best options are gpicker or Peepcode's peepopen, but they are external applications, and I find them to be distracting after using command-T for so long. I'll stick to MacVim for now, only because of command-T, but might look into implementing something that behaves just like command-T as an exercise.

Thank you all for the answers and comments!

FullOfCaffeine
  • 539
  • 1
  • 6
  • 22
0

Give textmate.el a try :) https://github.com/defunkt/textmate.el

You'll just have to use "Command+T" instead of "Ctrl+P" :)

pesho hristov
  • 1,946
  • 1
  • 25
  • 43
0

https://github.com/bling/fzf.el

This is the best solution out there in my opinion. Here's why:

  1. Uses projectile to determine project root if you're in a project.
  2. Otherwise it very quickly indexes the file in the current directory.
  3. Fuzzy matching.
  4. Can be customized (top or bottom placement, number of records, etc.)
David
  • 606
  • 6
  • 11