Vim Tips Wiki
(keep the "Comments" heading; spell out "silent")
m (Reverted edits by 94.251.119.22 (talk | block) to last version by JohnBot)
(38 intermediate revisions by 24 users not shown)
Line 1: Line 1:
  +
{{TipNew
{{TipProposed
 
|id=0
+
|id=1608
|previous=0
+
|previous=1607
|next=0
+
|next=1609
|created=October 12, 2008
+
|created=2008
 
|complexity=basic
 
|complexity=basic
 
|author=Knue
 
|author=Knue
Line 9: Line 9:
 
|subpage=/200810
 
|subpage=/200810
 
|category1=C++
 
|category1=C++
|category2=
+
|category2=Omnicomplete
 
}}
 
}}
In this tip I'll show you how to setup C++ code completion in Vim.
+
This tip describes how to use C++ code completion in Vim (omni completion).
   
  +
When editing a C++ file, enter the command <code>:set omnifunc?</code> to see what completion function is currently used. If the result is <code>omnifunc=ccomplete#Complete</code>, it means you are using the C completion provided with Vim (not C++). If your <code>:set omnifunc?</code> is not set as desired or maybe empty this is a good workaround for C++ files:
1. First install {{script|id=1520|text=OmniCppComplete}}.
 
   
  +
<pre>
2. Make a directory, for example <tt>~/.vim/tags</tt> that will hold your ctags.
 
  +
au BufNewFile,BufRead,BufEnter *.cpp,*.hpp set omnifunc=omni#cpp#complete#Main
  +
</pre>
  +
  +
  +
The following procedure provides C++ completion.
  +
  +
==Required setup==
  +
1. Install {{script|id=1520|text=OmniCppComplete}}. See its <code>doc/omnicppcomplete.txt</code> file for information.
  +
 
2. Make a directory, for example <code>~/.vim/tags</code> that will hold your ctags.
   
3. Create stdc++ tags: Download and unpack the {{script|id=2358|text=modified libstdc++ headers}} to <tt>~/.vim/tags/cpp_src</tt>
+
3. Create stdc++ tags: Download and unpack the {{script|id=2358|text=modified libstdc++ headers}} to <code>~/.vim/tags/cpp_src</code>
   
 
4. Run ctags:
 
4. Run ctags:
 
<pre>
 
<pre>
 
$ cd ~/.vim/tags
 
$ cd ~/.vim/tags
$ ctags -R --c++-kinds=+p --fields=+iaS --extra=+q --language-force=C++ cpp_src
+
$ ctags -R --sort=1 --c++-kinds=+p --fields=+iaS --extra=+q --language-force=C++ -f cpp cpp_src
$ mv tags cpp
 
 
</pre>
 
</pre>
   
 
5. Add additional tags (change to your system/likings):
 
5. Add additional tags (change to your system/likings):
 
<pre>
 
<pre>
$ ctags -R --c++-kinds=+p --fields=+iaS --extra=+q --language-force=C++ /usr/include/GL/ && mv tags gl # for OpenGL
+
$ ctags -R --sort=yes --c++-kinds=+p --fields=+iaS --extra=+q --language-force=C++ -f gl /usr/include/GL/ # for OpenGL
$ ctags -R --c++-kinds=+p --fields=+iaS --extra=+q --language-force=C++ /usr/include/SDL/ && mv tags sdl # for SDL
+
$ ctags -R --sort=yes --c++-kinds=+p --fields=+iaS --extra=+q --language-force=C++ -f sdl /usr/include/SDL/ # for SDL
$ ctags -R --c++-kinds=+p --fields=+iaS --extra=+q --language-force=C++ /usr/include/qt4/ && mv tags qt4 # for QT4
+
$ ctags -R --sort=yes --c++-kinds=+p --fields=+iaS --extra=+q --language-force=C++ -f qt4 /usr/include/qt4/ # for QT4
 
</pre>
 
</pre>
   
Line 40: Line 49:
 
set tags+=~/.vim/tags/sdl
 
set tags+=~/.vim/tags/sdl
 
set tags+=~/.vim/tags/qt4
 
set tags+=~/.vim/tags/qt4
" build tags of your own project with CTRL+F12
+
" build tags of your own project with Ctrl-F12
map <C-F12> :!ctags -R --c++-kinds=+p --fields=+iaS --extra=+q .<CR>
+
map <C-F12> :!ctags -R --sort=yes --c++-kinds=+p --fields=+iaS --extra=+q .<CR>
   
 
" OmniCppComplete
 
" OmniCppComplete
Line 47: Line 56:
 
let OmniCpp_GlobalScopeSearch = 1
 
let OmniCpp_GlobalScopeSearch = 1
 
let OmniCpp_ShowAccess = 1
 
let OmniCpp_ShowAccess = 1
  +
let OmniCpp_ShowPrototypeInAbbr = 1 " show function parameters
let OmniCpp_MayCompleteDot = 1
+
let OmniCpp_MayCompleteDot = 1 " autocomplete after .
let OmniCpp_MayCompleteArrow = 1
+
let OmniCpp_MayCompleteArrow = 1 " autocomplete after ->
let OmniCpp_MayCompleteScope = 1
+
let OmniCpp_MayCompleteScope = 1 " autocomplete after ::
 
let OmniCpp_DefaultNamespaces = ["std", "_GLIBCXX_STD"]
 
let OmniCpp_DefaultNamespaces = ["std", "_GLIBCXX_STD"]
 
" automatically open and close the popup menu / preview window
 
" automatically open and close the popup menu / preview window
Line 55: Line 65:
 
set completeopt=menuone,menu,longest,preview
 
set completeopt=menuone,menu,longest,preview
 
</pre>
 
</pre>
  +
  +
  +
==Using omni completion==
  +
When everything is set up properly you can use the code completion. Make sure the <code>'filetype'</code> of your file is set to <code>cpp</code>. You can check this by doing <code>:set filetype?</code>. If your <code>'filetype'</code> isn't <code>cpp</code>, you might have to enable file type detection by adding <code>filetype on</code> to your [[vimrc]], and restart Vim.
  +
  +
Now start typing (for me this only works if std:: is indented; otherwise I get Omni-completion (^0^N^P) Pattern not found):
  +
<pre>
  +
std::
  +
</pre>
  +
A box opens with suggestions. You can use <code>&lt;C-N&gt;</code> and <code>&lt;C-P&gt;</code> to navigate. <code>&lt;C-X&gt;&lt;C-O&gt;</code> opens the omnicompletion manually. A preview window should also appear on the top which shows the signature of functions and the like. Choose <code>vector</code> and continue:
  +
<pre>
  +
std::vector<int> vi;
  +
vi.
  +
</pre>
  +
Another box opens with suggestions. Choose <code>push_back(</code> and continue.
  +
  +
As you can see this is a really nice feature which is especially handy when you use an external library which you don't know very well. Simply create the tags as described above and browse through the suggestions.
   
 
==Additional information==
 
==Additional information==
 
It is nice to have the headers of the used libs really on your system so the preview window has something to show. So don't delete the headers after creating the tag files.
 
It is nice to have the headers of the used libs really on your system so the preview window has something to show. So don't delete the headers after creating the tag files.
  +
  +
==References==
  +
*{{help|new-omni-completion}}
  +
*{{help|'omnifunc'}}
  +
*{{help|complete-functions}}
   
 
==Comments==
 
==Comments==
  +
If you want completion to work for local variables in your code, you have to add the '<code>+l</code>' (letter "l" from local) option to the <code>c++-kinds</code> argument, as in:
  +
<pre>
  +
map <C-F12> :!ctags -R --c++-kinds=+pl --fields=+iaS --extra=+q .<CR>
  +
</pre>
  +
  +
----
  +
Some recent edits have introduced <code>--sort=1</code> (the "1" should be "yes") and <code>--sort=yes</code>. I believe ctags defaults to <code>sort=yes</code> so these edits are not necessary. I'm wondering if the edits are useful. [[User:JohnBeckett|JohnBeckett]] 23:32, May 28, 2010 (UTC)
  +
  +
The autocompletion does *NOT* work for boost shared pointers. So for example, if there is a section of code that looks like:
  +
<pre>
  +
boost::shared_ptr<const ObjectType> someObject=boost::shared_ptr<const ObjectType>(new ObjectType());
  +
int member = someObject->getMember();
  +
</pre>
  +
The getMember method will not show up in the dropdown list, because ctags is enabled for ObjectType, not when it's wrapped inside a boost shared pointer. If anyone knows a work around for this, it would be very useful for those C++ programmers who work with Boost.
  +
----
  +
I suggest to use GCCSense at http://cx4a.org/software/gccsense, or clang_complete at {{script|id=3302}} to have good C++ autocompletion that works with modern C++ code (e.g boost).

Revision as of 07:10, 1 December 2013

Tip 1608 Printable Monobook Previous Next

created 2008 · complexity basic · author Knue · version 7.0


This tip describes how to use C++ code completion in Vim (omni completion).

When editing a C++ file, enter the command :set omnifunc? to see what completion function is currently used. If the result is omnifunc=ccomplete#Complete, it means you are using the C completion provided with Vim (not C++). If your :set omnifunc? is not set as desired or maybe empty this is a good workaround for C++ files:

au BufNewFile,BufRead,BufEnter *.cpp,*.hpp set omnifunc=omni#cpp#complete#Main


The following procedure provides C++ completion.

Required setup

1. Install OmniCppComplete. See its doc/omnicppcomplete.txt file for information.

2. Make a directory, for example ~/.vim/tags that will hold your ctags.

3. Create stdc++ tags: Download and unpack the modified libstdc++ headers to ~/.vim/tags/cpp_src

4. Run ctags:

$ cd ~/.vim/tags
$ ctags -R --sort=1 --c++-kinds=+p --fields=+iaS --extra=+q --language-force=C++ -f cpp cpp_src

5. Add additional tags (change to your system/likings):

$ ctags -R --sort=yes --c++-kinds=+p --fields=+iaS --extra=+q --language-force=C++ -f gl /usr/include/GL/   # for OpenGL
$ ctags -R --sort=yes --c++-kinds=+p --fields=+iaS --extra=+q --language-force=C++ -f sdl /usr/include/SDL/ # for SDL
$ ctags -R --sort=yes --c++-kinds=+p --fields=+iaS --extra=+q --language-force=C++ -f qt4 /usr/include/qt4/ # for QT4

6. Edit your ~/.vimrc and change to your system/likings:

" configure tags - add additional tags here or comment out not-used ones
set tags+=~/.vim/tags/cpp
set tags+=~/.vim/tags/gl
set tags+=~/.vim/tags/sdl
set tags+=~/.vim/tags/qt4
" build tags of your own project with Ctrl-F12
map <C-F12> :!ctags -R --sort=yes --c++-kinds=+p --fields=+iaS --extra=+q .<CR>

" OmniCppComplete
let OmniCpp_NamespaceSearch = 1
let OmniCpp_GlobalScopeSearch = 1
let OmniCpp_ShowAccess = 1
let OmniCpp_ShowPrototypeInAbbr = 1 " show function parameters
let OmniCpp_MayCompleteDot = 1 " autocomplete after .
let OmniCpp_MayCompleteArrow = 1 " autocomplete after ->
let OmniCpp_MayCompleteScope = 1 " autocomplete after ::
let OmniCpp_DefaultNamespaces = ["std", "_GLIBCXX_STD"]
" automatically open and close the popup menu / preview window
au CursorMovedI,InsertLeave * if pumvisible() == 0|silent! pclose|endif
set completeopt=menuone,menu,longest,preview


Using omni completion

When everything is set up properly you can use the code completion. Make sure the 'filetype' of your file is set to cpp. You can check this by doing :set filetype?. If your 'filetype' isn't cpp, you might have to enable file type detection by adding filetype on to your vimrc, and restart Vim.

Now start typing (for me this only works if std:: is indented; otherwise I get Omni-completion (^0^N^P) Pattern not found):

std::

A box opens with suggestions. You can use <C-N> and <C-P> to navigate. <C-X><C-O> opens the omnicompletion manually. A preview window should also appear on the top which shows the signature of functions and the like. Choose vector and continue:

std::vector<int> vi;
vi.

Another box opens with suggestions. Choose push_back( and continue.

As you can see this is a really nice feature which is especially handy when you use an external library which you don't know very well. Simply create the tags as described above and browse through the suggestions.

Additional information

It is nice to have the headers of the used libs really on your system so the preview window has something to show. So don't delete the headers after creating the tag files.

References

Comments

If you want completion to work for local variables in your code, you have to add the '+l' (letter "l" from local) option to the c++-kinds argument, as in:

map <C-F12> :!ctags -R --c++-kinds=+pl --fields=+iaS --extra=+q .<CR>

Some recent edits have introduced --sort=1 (the "1" should be "yes") and --sort=yes. I believe ctags defaults to sort=yes so these edits are not necessary. I'm wondering if the edits are useful. JohnBeckett 23:32, May 28, 2010 (UTC)

The autocompletion does *NOT* work for boost shared pointers. So for example, if there is a section of code that looks like:

boost::shared_ptr<const ObjectType> someObject=boost::shared_ptr<const ObjectType>(new ObjectType());
int member = someObject->getMember();

The getMember method will not show up in the dropdown list, because ctags is enabled for ObjectType, not when it's wrapped inside a boost shared pointer. If anyone knows a work around for this, it would be very useful for those C++ programmers who work with Boost.


I suggest to use GCCSense at http://cx4a.org/software/gccsense, or clang_complete at script#3302 to have good C++ autocompletion that works with modern C++ code (e.g boost).