Posts Tagged ‘Omni Complete’

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
  filetype on

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

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

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
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 🙂