I love you; you complete me.
- Dr. Evil
I first came to Vim by recommendation. I was looking for a good Python IDE (at the time I was new to the language) and one recommendation was to use Vim with a variety of plugins added on top. That Vim could do a lot of the things I thought only an IDE could do came as a bit of a shock. I spent a summer as an intern using Emacs at a Unix terminal, but didn't have enough curiosity at the time to use it any differently from notepad.exe. I spent that summer wishing I had automatic features for completion, indentation, and all the things that made me appreciate the IDE's I used in college. How naive I was!
So how was I directed to achieve powerful programming completions in Vim? By the use of a plugin called YouCompleteMe. My experience with it was okay, at least to start with. It took a while to install and get working, but that didn't bother me at the time since I was just playing around with it at home and the stakes were low if it suddenly broke. I did notice it slowed Vim down. Like a lot. But that was mainly when it was starting up and I didn't know enough to find it frustrating. Probably the first thing that really bothered me about the plugin was that the embedded Jedi language server used more memory than Vim itself. The other recommended plugins were similarly laggy, and I eventually went in search of something better.
What I found was Vim itself.
Did you know that Vim has built-in facilities for completions? It works admirably well out of the box too, but with a little bit of additional setup it can be great. Let's take a look at what Vim has on offer regarding completion and see what it takes to fully leverage it.
Completion in Vim is powerful, but not necessarily straightforward. Read :h ins-completion and you'll see what I mean:
Completion can be done for: 1. Whole lines |i_CTRL-X_CTRL-L| 2. keywords in the current file |i_CTRL-X_CTRL-N| 3. keywords in 'dictionary' |i_CTRL-X_CTRL-K| 4. keywords in 'thesaurus', thesaurus-style |i_CTRL-X_CTRL-T| 5. keywords in the current and included files |i_CTRL-X_CTRL-I| 6. tags |i_CTRL-X_CTRL-]| 7. file names |i_CTRL-X_CTRL-F| 8. definitions or macros |i_CTRL-X_CTRL-D| 9. Vim command-line |i_CTRL-X_CTRL-V| 10. User defined completion |i_CTRL-X_CTRL-U| 11. omni completion |i_CTRL-X_CTRL-O| 12. Spelling suggestions |i_CTRL-X_s| 13. keywords in 'complete' |i_CTRL-N| |i_CTRL-P|
Vim is smart enough to pull completion data from a variety of sources, but in turn expects users to know which source will provide the best answer and to invoke the correct keymap to draw the desired completions. It's not a huge hurdle in terms of a learning curve, but it's not as simple as hitting tab either.
The first thing one should do when trying to learn Vim's completion system is to disable any completion plugins and learn these keymaps. Getting comfortable with them will also help you learn and remember where Vim can pull completion information from. You should also read :h 'completefunc' and :h 'complete' for more information on user-defined completion and the complete option.
Now that we have a cursory understanding of completion in Vim, let's take a deeper look at tags and how they figure into completion.
That brings us back to where we started, to the issue of code completion in Vim. Yes, Vim does offer native code completion (completing from tags is done with C-x, C-] in insert mode). No, it's probably not as powerful as what you could get with something like a Jedi plugin à la YouCompleteMe, but I've found it satisfies my needs more often than not, with :grep (or my own :GrepJob filling the gap nicely in a more native fashion.
There's more you can do here too. For instance, if you find yourself instinctively reaching for the tab key in order to complete a word, there is VimCompletesMe, which takes advantage of all of Vim's built-in completions through the clever use of an omni completion function. It works, but users do give up some control over selecting what data source Vim uses for a particular completion. I used this plugin for a while after I gave up on YouCompleteMe, but ultimately removed it because it effectively made the tab key ambiguous in Insert mode. Sometimes I wanted to insert an actual tab character, but got a completion instead.
With all of this in place, it's natural to ask whether a language server is even necessary with Vim. I don't intend here to suggest an answer to that question, but I will say that many of the solutions to date for language server integration in Vim have seemed like more trouble than they're worth. That said, with the advent of Vim 8 and its asynchronous capabilities, there is headroom for these solutions to improve, and I expect the best among them to become more compelling in the near future.
I do not recommend coming to Vim with a mindset of creating an IDE in your terminal. That said, Vim is a very powerful tool and if you invest the time to learn how it works it will take you very far. In other words, use Vim for all it's worth before looking for a plugin to help you out. Anyone who (like me) jumps right to installing a bunch of plugins—whether in a spree of grabbing anything that looks interesting or just to copy someone else's configuration—will likely end up with an unmaintainable mess of a tool that doesn't work consistently, may not work at all, or works about as slow as the IDE you wanted to break free of.
The Blog of Daniel Moch is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License. Permissions beyond the scope of this license may be available at https://danielmoch.com.