Omni Completion in Vim

Posted: August 26, 2010 in C/C++, Programming, Vim
Tags: , , ,

Vim 7 onwards, we have Omni Complete feature. This feature is similar to IntelliSense in Visual Studio or other IDEs. It can show a pop up menu displaying the structure, class or scope context. Here is a screenshot of Omni Complete displaying the class scope in CCCC code base .

OmniCppComplete screen shot in CCCC code.

As you can see, it can show all methods and variables including its original context like type, prototype (in case of method), documentation (if documented), private/protected/public, file defined in etc.

For getting Vim to work like this, you will need

Install all 4 by whatever means (apt-get, yum, build from source). OmniCppComplete and SuperTab are Vim scripts, detailed installation steps are given in the respective links. GNU has a version of ctags. But what we need is exuberant ctags which is different from GNU ctags. Most popular Linux distros bundle GNU ctags, but exuberant ctags should be available from the repository.

Vim is an excellent editor, but does not understand C/C++ natively. This is where ctags comes in to the picture. Ctags will generate a “tags” file which is like an index of the project source code. This tags file is used by Vim and OmniCppComplete script to provide contextual data in a pop-up menu.

To build a ctags tags file, give the command from the top directory of the project. This can be done from any subdirectory too (for even more focused tags file).

ctags -R --languages=C,C++ --c++-kinds=+p --fields=+iaS --extra=+q ./

Run vim from the same directory. By default, Vim will search for tags file beginning from current directory to all parent directories. First tags file found will be used. For better usability of OmniCppComplete, put these in your .vimrc file.

if v:version >= 600
  filetype plugin on
  filetype indent on
else
  filetype on
endif

if v:version >= 700
  set omnifunc=syntaxcomplete#Complete " override built-in C omnicomplete with C++ OmniCppComplete plugin
  let OmniCpp_GlobalScopeSearch   = 1
  let OmniCpp_DisplayMode         = 1
  let OmniCpp_ShowScopeInAbbr     = 0 "do not show namespace in pop-up
  let OmniCpp_ShowPrototypeInAbbr = 1 "show prototype in pop-up
  let OmniCpp_ShowAccess          = 1 "show access in pop-up
  let OmniCpp_SelectFirstItem     = 1 "select first item in pop-up
  set completeopt=menuone,menu,longest
endif

The default key mapping for invoking Omni Completion is C-X C-O. SuperTab plugin can help us invoke Omni Complete when we press TAB key. Also in the default color scheme, vim pop-up menu is in pink. Let’s change that to green.

if version >= 700
  let g:SuperTabDefaultCompletionType = "<C-X><C-O>"
  highlight   clear
  highlight   Pmenu         ctermfg=0 ctermbg=2
  highlight   PmenuSel      ctermfg=0 ctermbg=7
  highlight   PmenuSbar     ctermfg=7 ctermbg=0
  highlight   PmenuThumb    ctermfg=0 ctermbg=7
endif

As we edit code, newer types get defined, but vim continues to use the same tags file. So we need to regularly update our tags file. We can add a shortcut map (say pressing F4) in our .vimrc for the same.

function! UpdateTags()
  execute ":!ctags -R --languages=C++ --c++-kinds=+p --fields=+iaS --extra=+q ./"
  echohl StatusLine | echo "C/C++ tag updated" | echohl None
endfunction
nnoremap <F4> :call UpdateTags()

Vim is all about customizing it to your tastes. You can never get the perfect .vimrc file or plugin collection and settings from anywhere. The trick is to collect cool stuff for your .vimrc and plugins. Vim tips wiki in wikia is a good place for a lot of info. Play around with them. Find what suits best for you. And never forget to share. Happy coding πŸ™‚

Advertisements
Comments
  1. Jon Brett says:

    Thanks for the guide. This proved all I needed to get started with useful auto-completion in vim.

    I modified the UpdateTags() function and mapping to avoid the “Press ENTER or type command to continue message” and to automatically redraw the screen. Less keystrokes makes my life easier πŸ˜‰

    function! UpdateTags()
    execute “:silent !ctags -R –languages=C++ –c++-kinds=+p –fields=+iaS –extra=+q ./”
    execute “:redraw!”
    echohl StatusLine | echo “C/C++ tags updated” | echohl None
    endfunction
    nnoremap :call UpdateTags()

  2. Peter K says:

    Thanks.
    note line
    let g:SuperTabDefaultCompletionType = “”
    fails for me.
    all other – perfect

    for big projects also may use ‘-L filename’ option for ctags (see man ctags) to list all external headers.

  3. Greetings! Quick question that’s completely off
    topic. Do you know how to make your site mobile friendly?
    My website looks weird when browsing from my iphone4. I’m
    trying to find a template or plugin that might be able to resolve this issue.
    If you have any suggestions, please share. Thank you!

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s