Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Generate CTAGS for libstdc++ (from current GCC)

Tags:

c++

vim

c++11

ctags

I know YoucompleteMe on base of LLVM, but I want to use OmniCppComplete. This works nice, if I use the modified headers for C++. This modified headers are outdated and doesn't contain anything from C++11.

If noticed that I can modifiy my headers myself e.g.:

$ find . -name '*.h' | xargs sed -i 's/__STL_BEGIN_NAMESPACE/namespace std {/'
$ find . -name '*.h' | xargs sed -i 's/__STL_END_NAMESPACE/}/'

Or use this setting:

let OmniCpp_DefaultNamespaces = ["std", "_GLIBCXX_STD"]

Both doesn't work and of course most headers doesn't have and any file extensions. I've already tried to workaround this by using a list of files. How can I create working CTAGS on base of my current GCC (e.g. /usr/include/c++/...)? What is the common way?

Thank you

This is what I got, if I try to complete something from LIBSTD++:

std::fs
Omni completion (^O^N^P) Back at original
Ctrl+x, Ctrl+o
Omni completion (^O^N^P) Pattern not found
like image 529
Peter Avatar asked Jun 30 '14 12:06

Peter


People also ask

How do you navigate with ctags?

Vim's built-in code navigation functionality using ctags is fantastically useful. Properly configured, it can allow you to jump from file to file in a project with one or two keypresses. Position the cursor over an object or function name, press C-] and Vim takes you directly to its definition; C-o takes you back.


2 Answers

Finally I've written despairingly an email to the author of the modified headers for the LIBSTDC++ (GCC). He answered me promptly (thanks!):

Requirements:
Install vim and vim-omnicppcomplete and ctags (dependency of vim-omnicppcomplete).

Solution:

$ cp -R /usr/include/c++/$GCC_VERSION ~/.vim/cpp_src
# it is not necessary to rename headers without an extension
# replace the "namespace std _GLIBCXX_VISIBILITY(default)" with "namespace std"
$ find . -type f | xargs sed -i 's/namespace std _GLIBCXX_VISIBILITY(default)/namespace std/'
$ ctags -f cpp_tags -R --c++-kinds=+p --fields=+iaS --extra=+q --language-force=C++ -I _GLIBCXX_NOEXCEPT cpp_src

Edit your ~/.vimrc:

" configure tags - add additional tags here or comment out not-used ones
set tags+=~/.vim/cpp_tags
" build tags of your own project with Ctrl-F12
map <C-F12> :!ctags -R --sort=yes --c++-kinds=+p --fields=+iaS --extra=+q -I _GLIBCXX_NOEXCEPT .<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 ::
" also necessary for fixing LIBSTDC++ releated stuff
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

Autocompletion for LIBSTDC++ should now work within vim!
Manuall autocomplete with Ctrl+x -> Ctrl+o.

If you still have trouble with autocomplete, you maybe find a solution in the documentation (see FAQ 7).

Bye

like image 181
Peter Avatar answered Oct 02 '22 14:10

Peter


I actually use OmniCppComplete too, and have been happily using a C++ only tags file (amongst others. I break my tags files up into smaller pieces, like C++, boost, X11, etc.) for quite a while. Here's the solution I use for generating that tags file on Ubuntu 14.04:

ctags -f cpp_tags --c-kinds=cdefgmstuv --c++-kinds=cdefgmstuv --fields=+iaSmKz --extra=+q --langmap=c++:+.tcc. --languages=c,c++ -I "_GLIBCXX_BEGIN_NAMESPACE_VERSION _GLIBCXX_END_NAMESPACE_VERSION _GLIBCXX_VISIBILITY+" -n $INC_DIR/* /usr/include/$CPP_TARGET/c++/$CPP_VERSION/bits/* /usr/include/$CPP_TARGET/c++/$CPP_VERSION/ext/* $INC_DIR/bits/* $INC_DIR/ext $SYSTEM/* $SYSTEM2/*

Where:

CPP_VERSION=4.8
INC_DIR=/usr/include/c++/$CPP_VERSION
CPP_TARGET=x86_64-linux-gnu
SYSTEM=/usr/lib/gcc/x86_64-linux-gnu/4.8/include
SYSTEM2=/usr/lib/gcc/x86_64-linux-gnu/4.8/include-fixed

Please note that the real trick to getting most of the tags generated is the -I option! It may need to be tweaked. Of course, the --c-kinds/c++-kinds and fields options can be adjusted as well.

The final piece is adding:

tags+=cpp_tags

to your .vimrc file to allow the tags to be seen.

All of this requires NO MODIFICATIONS to the headers. If you use a different C++ library, chances are you'll need to fiddle with the -I option to get the tags to show up properly (or even at all).

Now that I think about it, I should probably post this information in the Vim Wiki also.

Your second part about let OmniCpp_DefaultNamespaces can stand some improvement. Try let OmniCpp_DefaultNamespaces = ["std", "_GLIBCXX_STD", "_GLIBCXX_STD_A", "_GLIBCXX_STD_C"]. That's what I use and should allow for more items to be found.

Finally, don't forget about using Vim's CTRL-p to complete the std::fs. It's quite powerful... and no tags file required!

like image 42
David Harrison Avatar answered Oct 02 '22 13:10

David Harrison