Ever watch someone else type at a shell, spelling out every filename, even making typos and fixing them, very slowly? “Hit tab!”, you yell, helpfully.
I do that when watching someone use vim.
The Quick Rundown
key | description |
---|---|
^P | basic tab completion, pulling from a variety of sources |
^N | the same as ^P but backward |
^X ^L | whole line completion |
^X ^O | syntax-aware omnicompletion |
Play with these to get a feel for them. I use this mapping:
imap <Tab> <C-P>
The Keyboard Details
When using completion, a helpful menu pops up, showing all the potential matches. Within this menu you can press ^P or ^N to insert the next or prior word, respectively, or you can press one of those hard-to-reach arrow keys. The arrow key will select the word from the menu but will not replace your text with the selected word; at this point you can press ^L to enter the next character from the selected word.
When you’re happy with the selected word you can press ^Y; to give up entirely, press ^E. When you’re happy with the selected word but ready to keep typing other stuff, just keep typing. It’ll figure it out.
You can also insert the tokens after a completion, which is useful for when you forget that we invented abstractions 40 years ago. For example, let’s say you have this Gherkin:
Scenario: paint a wall blue
Given I have some paint
And I have a white wall
When I paint the wall blue
Then I should see "success"
And now you want to make a similar scenario, but for red:
Scenario: paint a wall red
G^X^L^X^L^X^L^Wred
T^X^L
The Configurations
You can change all of this. Here are three useful options with the settings that make me happy:
set complete=.,b,u,]
^P and ^N pull from a list of words computed by vim; the source of these completions is determined by the complete
setting. In the above example it will pull from keywords in the current file, other buffers (closed or still open), and from the current tags file. More details: :h 'complete'
set wildmode=longest,list:longest
How vim should go about replacing your text. The above setting is closest to the default for zsh, which might be what you want. Other possiblities are listed at :h 'wildmode'
.
set completeopt=menu,preview
This is the default, and it works just fine. It shows a menu and, if available, any additional tips such as the method signature or defining file. If you really want to change it, read up on the details at :h 'completeopt'
.
Be Smarter
While the above configurations are useful for simple pleasures, we can make the configuration more intelligent by writing functions in vimscript. For example, in HTML vim should know that you can’t nest a div
inside an a
or that class
is a valid attribute name but classic
is not. Enter omnifunc
.
There are five relevant omnifunc
s that ship with vim: CSS, HTML, JavaScript, Ruby, andSQL. They are autoloaded for the relevant filetype, slower than ^P, and totally brilliant. They can fill in defined method names after .
in Ruby, complete property names in CSS, automatically close the correct tag in HTML, or guess at table and column names inSQL.
Many other omnifunc
definitions exist for other languages, and you can write your own. For more details see :h complete-functions
.
But Wait, There’s More
This blog post is a tiny fraction of what’s available. Dictionaries, thesauri, tags, filenames, vim command names, and so much more are all documented under :h ins-completion
.
So next time, hit tab!
What’s next
If you found this useful, you might also enjoy: