Hacker News new | past | comments | ask | show | jobs | submit login
Ctrl-P for Vim: Pure Vimscript Command-T (github.com)
196 points by nwjsmith on Apr 30, 2012 | hide | past | favorite | 95 comments

Ctrl-P does something that I wanted Command-T to do for a long, long time: if you invoke it and select a file that is already open in an existing window somewhere, rather than open a new window for that file, it will switch to the already-opened one.

You can change how this works, too: look up ctrlp_switch_buffer in the docs.

Does Command-T ever open new windows? For me it opens the file in the current window, and if the file is already open in a buffer, that buffer gets shown in the current window.

You're right, unless you C-s or C-v it into a split (which I do pretty often).

When I was first migrating from TextMate, the default behavior seemed like a bug. Why would you routinely want to open a buffer in two different windows? Why wouldn't you want the editor to find your already-opened file in the labyrinth of splits and tabs you've opened?

Now, partially due to this behavior, I tend to see large lattices of open windows and tabs and splits as a sign that I'm getting unfocused, and try to be better about closing splits as soon as I don't need them, and avoid tabs altogether.

That splits should be transient seems more vim-like.

Awesome, I'll have to take a look at how that works. I've gotten it to work with quickfix (set switchbuf=useopen), but still have no idea how to get vim to do that for ctags.

Also, it can sort by MRU and switch mode (Ctrl-B/F) while its window is shown. And mark multiple files.

I use vim for coding just about every day, and as a rule, I try not to install plugins unless I really need/want it. Reason being is if, on occasion, I need to do a little editing inside an ec2 instance, or whatever, I don't want to type `vi` at the shell and get a different editor than the one I use every day. So I try to keep it as stock as possible, while allowing enough customization to be productive and comfortable.

Anyway, that said, Ctrl-P makes the cut. :)

I was a vim minimalist for a short while for the same reasons. They make sense in theory. In practise, all you really need to remember for regular vi(m) is :e. All the rest of the motions and commands you'll be using anyway. The amount of productivity gained from a customized vim config > the amount of productivity gained from remembering a couple of commands in case you need to edit on another box. And that's how learned to stop worrying and love the bomb.

I can indeed safely degrade myself to use pure-vim easily enough, but the only one that bites me when missing every now and then is vim-surround.

Why not put a git repo of your .vim/ somewhere publicly accessible, then just check it out wherever you need to use it? Going further, just have a simple to remember repo address with all your dotfiles... or even just an init script that bootstraps your environment for you? A good custom environment, catering to your preferences can help a lot. It is a bit of a pain to initially set up, but then it's just a command or two at first login, and you have your environment everywhere.

I've thought about it, but in the context of, "I'm reformatting this disk, and I need to back up my home directory to have after I'm done," since I would cry many tears if I hosed my ~. But in that case, I just make a copy of it somewhere instead of putting it in git, or whatever. Putting it under version control for more casual reasons, though, sounds like a good idea. Plus, you get revision history! I might just do that. :)

Either way, I don't think I'd go much further from stock than I already do because like shortlived illustrates, there's just sometimes you have to use the vanilla version of whatever you're dealing with, no matter what you do.

I like to think of it as maximizing the following equation. How fast is my main vim going to be * percent of my vim editing time vs. how fast a one off system is * performance penalty for sometimes trying the functions that you have in the main system * the percentage time spent editing in that system.

I find that the most time is spent for me in my main vim session on my computer and the ancillary servers do not need the more advanced text editing features because I am just not in them that often.

Oh, I agree fully. Optimize for the common case. This is why I make a few exceptions like Ctrl-P.

But in this situation, there's one variable missing: the urgency with which off system editing happens. If a machine is blow'd up and stuck in single-user mode, and the only way to get it back is a heroic vi session, or if somebody screwed up an apache config and your site is bouncing customers, or whatever, those are the times you don't need the added frustration of an unfamiliar editor.

That, and I didn't find stock vim to be uncomfortable once I learned it, so I don't feel like I'm sacrificing much to get the luxury of my editor working pretty much the same everywhere in the universe.

In my experience, as long as I don't customize the regular keymappings, switching to a vanilla vim is annoying, but not crippling. About a minute of "dammit I can't use bufexplorer or :Ack" and I'm on my way. A large number of my vim keymaps are programming language specific, so this reduces the level of annoyance even further, as I won't be editing a lot of code on a "burning" server, mostly config files. Any code that is changed, will be a bit annoying, but the changes are usually not big enough that it requires a ton of fancy editor-fu anyway.

The biggest thing I have found with all of this tho, is that everyone has different prefs, so if you're pretty happy with the way it's working, don't change because some folks on the internet are suggesting it, but if sounds interesting, give it a try, the worst that happens is you have to revert to the old way. (different optimization problem here I guess :) )

Not many plugins make it an unfamiliar editor. Actually, reconfigurations of core vim are more likely to cause that kind of frustration (e.g. if you change vim to use Ctrl-V for paste instead of blockwise visual mode). This is so easy to fix.

Getting your dotfiles in git once didn't seem necessary to me - and indeed you can get by just fine - but god it is nice not to have to redo any configs and have my setup always ratcheting forward because I don't keep losing things or not having them.

I keep my dotfiles under source control because my needs on linux servers and personal OSX machines sometimes differs quite a bit, being able to branch my zshrc is just plain awesome.

Yeah, that's badass. You guys have me convinced. :-P

This will be one of my few exceptions to a stock system. This plugin will certainly increase productivity given that I spend the majority of my time in Vim 7.

This is a great idea if you are always running on a modern system. I learned Vi (and later vim) out of necessity because I was programming on Solaris 9 and USS (unix on z/os) and modern Vim was just not available.

Optimize for the common path (editing code) and not the exception "on occasion, need to edit with raw vim."

It might make sense for a consultant admin who is managing dozens of systems and 100's of boxes. But for a developer not crafting and utilizing the best tool chain possible is just a waste.

I have heard this argument over and over again.

As a heavy plugin user who routinely connects to machines without the plugins, it is not an issue for me at all. And I learned vim while using tons of plugins. But obviously if you are depending heavily on something like Cream (which makes its behavior more like gedit or something, insert mode all the time) you are going to have a tough time adjusting. Very few plugins change vim's behavior in that kind of fundamental way, however.

Life is short. Use the plugins you want to use.

Great plugin. I love that it tracks up to the nearest .git etc folder to decide where to search from. That's a killer feature.

I've used this plugin since I discovered it. It replaced fuzzy finder for me.

It is MUCH better.

My killer feature: it will automatically avoid opening files in special buffers. I.e. if you ru. It inside the NERDtree window, it won't load there but rather will load the file in the middle buffer.

Other than this it has loads of other things that make it much better.

I didn't write it but I thought HNers would be interested.

Send praise to https://github.com/kien!


Is also quite good.

It would cool to have a performance comparison

As a quick and dirty test I tried running both Command-T and Ctrl-P against a directory tree containing some 26,000 XML files. Command-T takes roughly 10-15 seconds to become responsive. Ctrl-P chokes and requires a Vim restart after invoking it against this directory.

That should be a fairly trivial fix in both of them.

Simply abort the scanning after a configurable threshold (either seconds or files).

Needless to say that, yes, this must be implemented.

I've choked my vim more than once by accidentally running Command-T or FuzzyFinder in the "wrong" directory. That should not happen.

Command-T definitely has the feature you're talking about (CommandTMaxFiles I think.) I'm not sure about CtrlP.

If you are on Unix, add this to your vimrc and the directory indexing speed should go through the roof:


Is that offloading the task of scanning file names to the find command?

Looks like find is piped into head, though. So it would only index the first ten?

No, it's the first g:ctrlp_max_files which is defined as 10000

Oh, true. Good call.

Is there a reason that Ctrl-P, FuzzyFinder, and Command-T choke on large directories? On windows, I've used this piece of software called Everything Search that seems to index the entire filesystem (say around 30,000 files) in under 5 seconds. That's really impressive and I love using it for that.

But it makes me sad to use these vim extensions choking on directories of similar size. Maybe NTFS vs ext4 has something to do with it?

I was never able to get Command-T to work. CtrlP works out of the box without extra work.

The main thing that attracted me to Ctrl-p was that it is written in pure vimscript. Command-T, however, requires your vim to be compiled with Ruby support.

In the projects I have worked on, Ctrl-P seems faster than Command-T, but it's matching results are far from a replacement for Command-T. Ctrl-P often will not find files even when I type out the full file name. Command-T's match results are great. Ctrl-P will also show results from hidden/ignored directories. When Ctrl-P is smarter about its match results, I will use it more frequently.

The overall comparison ends up being: Command-T is more of a pain to get setup, but is faster. CtrlP is easier to get setup, but is slower.

I'm also interested in knowing how fast this is with huge directory trees.

I remember in early versions of Command-T, the Ruby implementation was slow for big trees. They rewrote some of it later in C.

I just overheard Wincent say that Command-T was always written in C because previous Ruby plugins that attempted to accomplish the same thing was too slow. Command-T was written to be instant.

FWIW I ran

    (wait 10~15s for it to complete)
    find . |wc -l
Fast enough for me. (MacBookPro5,5 + aftermarket Samsung 470 SSD)

Command-T is faster for sure. But it lacks critical features that Ctrl-P has (no vim -ruby dependency for one).

When you start vim again and hit ctrl+p, does it do all that over again?

If I don't quit vim, and do Ctrl+P, things got cached (which you force-refresh with F5) so it's instant.

If I quit and restart vim, the Ctrl-P cache is invalidated thus it's scanning again, but it's down to 3~5s since disk reads got cached by the OS.

Yes. But you can specify a local cache file if you want... in which case it would not start over when you restart.

Ah, I see. I added a similar feature to Command-T, because scanning one of my projects trees takes a couple seconds.

It seems fast enough to use on mozilla-central (the Firefox repo), which is huge.

I can't find some files, though. If I type :

ctrp+p, mediaelement, it should find content/html/content/src/nsHTMLMediaElement.cpp, and it does not. I tried to set the maximum depth, but it didn't work. In fact, it does not match content/html/content files.

Another thing that I find annoying, is that when I remove multiple characters, it does its matching thing again, and because I type the backspace pretty fast, it kind of locks up for a second or so.

Anyway, other the couple quirks mentionned, excellent plugin, works out of the box.

There seems to be a bug when in full path fuzzy mode. In the CtrlP window, hit ctrl-d (match file name only) and see if it works.

Nope, does not work.

In addition to max depth there is also a max files setting to adjust.

Can somebody please point out the differences with a customized FuzzyFinder?

As I have it I get fuzzy completion from the root folder, opening splits with <c-j> and <c-k>, opening tabs with the file with <c-l>, deleting buffers from the list with <c-]>, and such.

Is there any difference or improvement one should try? Genuine question, I am really curious. It would be great to see a comparative between FuzzyFinder, Command-T and Ctrl-P...

ps: fuzz config is like this in vimrc:

    " Fuzzy Finder
    nnoremap <leader>fr :FufRenewCache<CR>
    nnoremap <leader>ff :FufFile **/<CR>
    nnoremap <leader>ff :FufFile **/<CR>
    nnoremap <leader>fg ye :FufFile **/<C-r>"<CR>
    vnoremap <leader>fg y :FufFile **/<C-r>"<CR>
    nnoremap <leader>fb :FufBuffer<CR>
    nnoremap <leader>fd :FufDirWithCurrentBufferDir<CR>
    nnoremap <leader>fl :FufLine<CR>
(Ignore the maps, thats how I like it)

Edit: I would like to point out that I have skimmed several times through the docs of Fuzzy Finder and there are several options I dont even use/grasp, so more knowledge and tips on Fuzzy Finder would be appreciated also

I use Fuzzy Finder in concert with Command-T: Command-T for quickly navigating the current working directory and Fuzzy Finder for navigating from the root like you. I imagine you could use Ctrl-P similarly, though a customized Fuzzy Finder would likely obviate the need for Ctrl-P/Command-T.

One Fuzzy Finder tip. Make sure and map :FufHelp, if you haven't:

    nmap <c-h> :FufHelp<CR>
It allows you to fuzzy find through the help docs. Being able to see closely related help docs through fuzzy matches is a huge boon when it comes to navigating Vim's help.

I've used fuzzy finder and it's ok, CTRL-P gives me a faster experience so give it a go.

After 2 weeks of using Sublime I just did this:

rm -rf /Applications/Sublime\ Text\ 2.app/

I will never neglect you again VIM. You've been so good to all of us.

Hitting Ctrl-F or :ControlTFlush so I can open a file that Rails or Git or whatever added to the project directory is one of my biggest issues with Command-T. Sublime Text 2 gets it right, but it's Vim compatibility mode isn't quite there yet.

Will this automatically update its cache as new files are added?

You need to hit F5 to refresh the cache.

I have this installed as it comes with Janus (https://github.com/carlhuda/janus), and it's excellent. I tried to get Command-T to work in the past and failed, but this works with no problems, and is incredibly useful.

Awesome to not have to compile this with (SYSTEM!) ruby.

Protip for python hackers: "set wildignore+=*.pyc" in your .vimrc so Ctrl-P won't pick up all the .pyc files. It's pretty annoying to get every file you search for 2x, and then get a bunch of binary junk if you pick the wrong one. :-P

I regularly use Ctrl-P and Command-T regularly. Ctrl-P seems to work well for smaller projects. It is faster than Command-T, but it often fails to find files accurately on larger projects. It searches in hidden/ignored directories that Command-T automatically ignores. I like the fact that you don't have to have vim compiled with ruby support to use Ctrl-P which is great when working on remote machines. I feel like Ctrl-P is close to being a drop-in replacement for Command-T, but it is not quite there yet. When Ctrl-P's match results are the same as Command-T's, I'll stop using Command-T.

If you're on Ubuntu and do not want to build vim with Ruby support, but still want to use Command-T for some reason, install vim-nox.

That being said, ctrlp is less of a headache since it's pure vimscript like the headline says.

Similar to vim-nox, if you're on a Mac, you can install MacVim with homebrew like so:

    brew install macvim --override-system-vim
which creates a /usr/local/bin/vim symlink, spawning a real terminal vim, not a GUI MacVim. And contrary to /usr/bin/vim this one will be built with the (system-provided) python and ruby support.

Anybody have an opinion on ctrlp vs LustyExplorer? http://www.vim.org/scripts/script.php?script_id=1890

I've used LustyExplorer for one year before switching to CtrlP about 2 or 3 months ago. In my experience:

* speed is comparable * quality of results is better in LustyExplorer * interface design is better, more Vim-like and more consistent in CtrlP * CtrlP doesn't need Ruby * CtrP is more extensible and already integrates a tight pack of useful features (MRU, grep, tags)

How does this compare to FuzzyFinder? FuF has been far better than other options people espouse like Command-T but still has some warts of its own.

It was this feature which made me switch full-time to Sublime Text in the end - Command-T was just too slow in comparison so I decided the Vim emulation in Sublime was good enough for the commands I used, which are just the basics really - arguable how much of a speed difference it makes almost but it's too ingrained in muscle memory now! :wq

I love Ctrl-P! You can use Ctrl-B to search only open buffers.

Ctrl-P is the recommended find plugin from the janus vim distribution: https://github.com/carlhuda/janus I use most of the other plugins from there and will be trying out the others.

If you use Command-T it has a mode to search buffers as well. I think its mapped to <Leader>b by default.

Love this plugin, makes vimming so much nicer and is my favorite file/buffer manager. I like you you can optionally keep the cache so when you reopen there isn't that delay for checking the directory tree too. let g:ctrlp_clear_cache_on_exit=0

Thanks to kien for making it!

Very Awesome! Commmand-T (vim plugin) has been an essental part of my workflow for years now. I can't live without it. The biggest thorn for setting up a new host is having to procure VIM with Ruby support. Thank you so much for doing this!

I didn't make it, be sure to give props to https://github.com/kien!

What's the easiest way to install this? I have pathogen if that makes any difference...

Tangential, but you might like vundle (if we're looking at replacement plugins already) instead of pathogen.

Agreed, I was a pathogen devotee until I tried vundle. Never going back.

Another vote for vundle. Not having to manage git submodules is a nice change from pathogen.

git clone https://github.com/kien/ctrlp.vim.git cp -pr ctrlp.vim/{autoload,doc,plugin} ~/.vim

It's truly a great tool. I installed it yesterday as an alternative to CTRL-T as I didn't want to install ruby system wide.

It will also allow you to quickly move between buffers with CTRL-P then CTRL-B to select buffers.

Thanks for posting this!

I've been a longtime FuzzyFinder and Command-T user but both have pretty nasty warts. Crossing my fingers that this will finally be the one to do it right.

> Written in pure Vimscript

I'm so sorry :P

In all seriousness, this looks like a good contender to Command-T judging by a cursory glance through the README. I'll have to give it a shot.

What exactly is so bad about Vimscript? I've done a decent amount of scripting in it for my .vimrc, and even contributed patches to a few plugins and haven't noticed anything wrong with it. I'm a bit confused as to why people always make it seem like it's a pain to work with (I'm guessing the bad parts are the ones I've never had to deal with).

So right, I haven't tried writing anything serious in Vimscript, but the few times I tried it I was confused. At this point, it looks like someone took Lua, added a dash of Python, and then added "fixes" here and there because why the hell not. Like the fact that you can't put an array over multiple lines without adding a backslash (I guess?). The fact that you have not just == but ==? and ==#. Sure, there are reasons for this, but there shouldn't be. The fact that you can abbreviate everything, which sounds like a good idea, but sure makes code harder to read. The fact that there's no module system or anything, functions in the "standard library" are just there out in space (fortunately, they're named consistently and they have okay names). The fact that you have to scope functions because a capitalized function is Special. The fact that to call a function, you have to use call() because otherwise Vim interprets it as a command. (Unless it's scoped?) Oh, and Vim regexes don't conform to any standard you might be used to (except for \v, but I don't know that that conforms to).

So yeah I am not an expert. If I learn it, maybe it'll be better. It's a tool thing though. Vimscript isn't a very good tool compared to the other ones that exist now. I mean, doesn't Vim support other languages now? Why don't people use them at this point?

I find that Vimscript tends to be faster than the other languages in many cases, for one reason.

But probably the #1 reason to write a plugin in it is that your users don't have to run some flaky Makefile/Rakefile or install system dependencies in order to use your plugin.

This is most of the reason I jumped ship from Command-T to Ctrl-P as soon as it came out.

I will concede that Vimscript looks grody and I wouldn't write non-editor software in it, but it is really a DSL for configuring an editor on the fly, works great for that and doesn't really hold a huge number of shocks for someone who can handle things in the range of C, bash, etc.

Is there a way to get it to open a file in a new tab instead of the current one? (instead of having to :tabnew and then invoking ctrlp)

highlight the file, then C-t

Is there a way to easily open a file into a split?

ctrl-v opens it in a vertical split.

And ctrl-s for an horizontal split.

I can attest this is awesome and works awesome.

Does anyone know how to change default search behavior from full-path to filename? I read the help but don't see the option...

Ctrl-D will switch between path and file modes.

Sorry, I meant, in your vimrc file.. Having to hit ctrl-d each time is a PITA.

let g:ctrlp_by_filename = 1

I found this in the help docs.

I was using PeepOpen which is quite nice, but (of course) it doesn't work in the terminal. This looks quite spiffy.

The readme says MacVim -- anyone know if this will work in GVim?

Yep, it does. I use it daily in plain-old terminal vim on ubuntu, so I don't use it in GVim much, but trying it just now worked fine.

it takes a lot of time for the first launch to cache. Is this normal?

Thank you, kien.

Guidelines | FAQ | Support | API | Security | Lists | Bookmarklet | Legal | Apply to YC | Contact