---
title: Vim, You Complete Me
teaser:
tags: vim
author: Mike Burns
published_on: 2012-07-12
---

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                                            |
|-------------------|-------------------------------------------------------|
|<kbd>^P</kbd>      |basic tab completion, pulling from a variety of sources|
|<kbd>^N</kbd>      |the same as <kbd>^P</kbd> but backward                 |
|<kbd>^X ^L</kbd>   |whole line completion                                  |
|<kbd>^X ^O</kbd>   |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 <kbd>^P</kbd> or <kbd>^N</kbd> 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 <kbd>^L</kbd> to enter the next character from the selected word.

When you're happy with the selected word you can press <kbd>^Y</kbd>; to give up entirely, press <kbd>^E</kbd>.  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,]

<kbd>^P</kbd> and <kbd>^N</kbd> 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'`](http://vimdoc.sourceforge.net/htmldoc/options.html#)

    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'`](http://vimdoc.sourceforge.net/htmldoc/options.html#).

    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'`](http://vimdoc.sourceforge.net/htmldoc/options.html#).

## 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 <abbr title="HyperText Markup Language">HTML</abbr> 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: <abbr title="Cascading Style Sheets">CSS</abbr>, <abbr title="HyperText Markup Language">HTML</abbr>, JavaScript, Ruby, and<abbr title="Structured Query Language">SQL</abbr>. They are autoloaded for the relevant filetype, slower than <kbd>^P</kbd>, and totally brilliant. They can fill in defined method names after `.` in Ruby, complete property names in <abbr title="Cascading Style Sheets">CSS</abbr>, automatically close the correct tag in <abbr title="HyperText Markup Language">HTML</abbr>, or guess at table and column names in<abbr title="Structured Query Language">SQL</abbr>.

Many other `omnifunc` definitions exist for other languages, and you can write your own. For more details see [`:h complete-functions`](http://vimdoc.sourceforge.net/htmldoc/insert.html#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`](http://vimdoc.sourceforge.net/htmldoc/insert.html#ins-completion).

So next time, hit tab!

## What's next

If you found this useful, you might also enjoy:

* [Onramp to Vim][onramp]
* [Vim Macros and You][macros]

[onramp]: https://thoughtbot.com/upcase/onramp-to-vim
[macros]: https://thoughtbot.com/blog/vim-macros-and-you
