ctags in sublime text - c++

I've just download sublime text 2 beta 2182 under ubuntu 10.10 with Exuberant Ctags 5.8
I want to use it for c++ coding and I need some auto completition and code navigation. (I was used to eclipse with cdt)
I googled and I found ctags a cool tool that can do it, and there is a plugin support for sublime text here.
The problem is that I want create tag file from:
c++ standard lib (std::vector std::map etc)
all classes of the framework i'm using.
Point 1 is (i think) the same of point 2, I just only have to create a tag list of std lib in my /usr/include/c++/4.4.5/
so I've downloaded the plugin and installed it, I made a taglist in this way:
$ cd /absolute_path_of_my_cpp_framework/
$ ctags -R *
I modified /home/me/.config/sublime-text-2/Packages/CTagss/CTags.sublime-settings with this line:
"extra_tag_files" : [".gemtags", "/absolute_path_of_my_cpp_framework/tags"]
Now I open a cpp file, point the cursor on a class name of my framework and used the key binding ctrl+t ctrl+t and nothing happened. Only this message in the bar in the bottom:
can't find "class_name"
Can someone help me?

I don't personally use Sublime Text, but assuming it uses tag files in a similar manner to vim, you need to generate additional info for C++ completion.
Use ctags with the following options:
ctags -R --c++-kinds=+p --fields=+iaS --extra=+q --language-force=C++
Info was taken from this article, which also supplies copies of the standard library headers that you can use to generate tags.

Shell Commands:
$ cd /absolute_path_of_my_cpp_framework/ (1)
$ ctags -R --languages=c++ --langmap=c++:+.inl --fields=+iaS --extra=+q --totals=yes --verbose=yes (2)
$ ctags -a -R --languages=c++ /usr/include/c++/4.4.5/ --fields=+iaS --extra=+q --totals=yes --verbose=yes (3)
$ subl . (4)
Description:
(1) Go to the root folder of your project to ensure that the tags file will be created there.
(2) Generate a new tags file for all C++ files in your project, adding support for .inl files, inheritance, access modifiers, class-qualified scoping etc.
(3) Append tags for the C++ standard lib headers to your generated tags file.
(4) Open the folder in Sublime Text.
References:
http://ctags.sourceforge.net/ctags.html
https://www.chromium.org/developers/sublime-text
http://www.tarosys.com/2014/07/adding-another-file-type-for-ctags.html
Exuberant ctags exclude directories
Vim and Ctags: Ignoring certain files while generating tags
https://www.topbug.net/blog/2012/03/17/generate-ctags-files-for-c-slash-c-plus-plus-source-files-and-all-of-their-included-header-files/

Related

Cannot generate c++ STL tag files for vim use

I'm a heavy vim user and often jump to function's implementation via ctrl-]. I wanna do the same thing for standard library. Here is how to generate tags file.
I have two versions of gcc/g++, one is system default 4.4.4 with source at usr/include/c++/4.4.4, and 4.9.1 with source at /opt/gcc/include/c++/4.9.1.
Command to generate tags file for 4.4.4 -
ctags -R --c++-kinds=+px --fields=+iaS --extra=+q
/usr/include/c++/4.4.4
This works well. After adding the generated tags file to vim, I can use ctrl-] without problem.
However I cannot get correct tags file for 4.9.1 with same command -
ctags -R --c++-kinds=+px --fields=+iaS --extra=+q /opt/gcc/include/c++/4.9.1
The generated file size is much smaller than above version. I checked the tags file and functions' tag is not there.
Surprisingly, I can step into the STL source code (4.9.1) when debugging my program with gdb. I have same problem under CentOS 6 and 7.
What am I missing? Can anyone share idea?
Looks few devs use tags file for STL. Still no clear answer and Closed.
This is what I use to get completion in vim for C++ STL using just ctags, and testing out stepping into STL source code it does work with gcc version 10
$ 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
Source: https://stackoverflow.com/a/24553063/6645454

Generate CTAGS for libstdc++ (from current GCC)

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
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
After try hard to search how to create c++-specific tags file using ctags, finally I made desirable progress. Need to say, ctags indeed is a little hard to use, powerful though.
First to emphasize, DONOT ignore -I option (see here for more option info) provided by ctags. It's pretty important for you to see more symbols in the tags file. Simply speaking, ctags cannot process some irregular syntactic statements, for example, prefixed or suffixed with C/C++ macros. If many functions are prefixed or suffixed with some kind of macros, ctags may be very likely to drop it. In the end, you cannot see them when coding.
Here's a way I use to find such macros as more as possible from C++ standard header path, /usr/include/c++/4.9.3 for example, and add them to -I option.
find /usr/include/c++/ -type f -exec grep '_GLIBCXX_' {} \; | grep -v -E '^[#if|#end]' | sort -u > glibcxx.log
After the command, you'll find several macros used in C++ 4.9.3 source files, then choose some of them to be ignored by ctags.
My final command to generate c++ tags file is this:
ctags -R --languages=c++ --langmap=c++:+.tcc. --c++-kinds=+p --fields=+iaS --extra=+qf -I "_GLIBCXX_NOEXCEPT _GLIBCXX_USE_NOEXCEPT _GLIBCXX_NOTHROW _GLIBCXX_USE_CONSTEXPR _GLIBCXX_BEGIN_NAMESPACE_CONTAINER _GLIBCXX_END_NAMESPACE_CONTAINER _GLIBCXX_CONSTEXPR _GLIBCXX_NAMESPACE_LDBL _GLIBCXX_BEGIN_NAMESPACE_VERSION _GLIBCXX_END_NAMESPACE_VERSION _GLIBCXX_VISIBILITY+" -f gcc-4.9.3.tags /usr/include/c++/4.9.3/
Caveat
DONOT forget to write . sign following word tcc, it means match those files without explicit extension name such as vector,set
DONOT forget to write + sign following word VISIBILITY, it means match std _GLIBCXX_VISIBILITY(**)
DONOT forget to write + sign followed by .tcc, it means append the denoted extension to current map of the langugae, otherwise replace the map
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!

Using ctags and cscope

I did a ctags -R on my project which is in c++, in the directory /project/ntopng. Now, when I start cscope using cscope -R and search for main.cpp, it opens up. But, when I hit ctrl-] on #include "ntop-includes.h" in main.cpp, the error message is tag not found. The header file is inside a sub-directory in /project/ntopng/include. But, ctags -R is recursive so why is it that I am getting an error? I am using Ubuntu 12.04 with the latest version of ctags and cscope. Thank You.
I have given the below answer for Ubuntu 12.04
1. Open any file with vim
2. type :echo &tags ,It will show what path vim is using for tags file.
If it is not the expected tag file path type:
:set tags=path_to_your_tag_file (ex /project/ntopng/tags)
Remember it is valid for the current session only, Now if permanent changes required there are two options.
For All users (requires root privileges) --
1. cd /etc/vim
2. vim vimrc
3. Go to end and add set tags+=tags;path_to_your_tag_file
For the individual user:
1. cd ~
2. vim .vimrc (This file may not exists in that case newly created)
3. set tags+=tags;path_to_your_tag_file
Let me know if it worked for you.

Vim C++ auto complete

How do I enable auto completion in Vim?
I tried to do this one, but I'm not proficient with the vimrc file, etc., so it didn't work out. Can you give me step by step instructions on how to do this?
Edit
I tried installing OmniCppComplete. Followed the instructions, but when I try to use it I get the following error:
Error detected while processing function omni#cpp#complete#Main..24_InitComplete:
line 24:
E10: \ should be followed by /, ? or &
Vim by default will do completion based on words in the file using Ctrl-N or Ctrl-P, which is handy for recently referenced local variables etc, and works for code in any language or even ordinary text (handy for completing difficult to spell names). However it doesn't do this semantically or with reference to what actual types you're allowed in the particular context you're writing. For this you will need to install ctags, and then in /usr/include type:
ctags -f ~/.vim/stdtags -R --c++-kinds=+p --fields=+iaS --extra=+q .
And then add this to your .vimrc:
set nocp
filetype plugin on
map <C-L> :!ctags -R --c++-kinds=+p --fields=+iaS --extra=+q .<CR><CR>
set tags=~/.vim/stdtags,tags,.tags,../tags
autocmd InsertLeave * if pumvisible() == 0|pclose|endif
That will also make Ctrl-L reload tags, and thus pick up new autocomplete tags, from the current directory.
Detailed instructions Auto complete (archive.org) Type in first few characters and press Ctrl->P(for backward search) or Ctrl->N(for forward search), list down all options available or completes it.
I use vim7.2 (auto complete was introduced in vim7) and these controls work just fine.
My favorite is clang_complete here. It's very easy to install and the default configuration in the ReadMe document works good. You don't need to generate the tags,
It automatically show the complete options when available. It also can highlight the
syntax errors.

Generating a reasonable ctags database for Boost

I'm running Ubuntu 8.04 and I ran the command:
$ ctags -R --c++-kinds=+p --fields=+iaS --extra=+q -f ~/.vim/tags/stdlibcpp /usr/include/c++/4.2.4/
to generate a ctags database for the standard C++ library and STL ( libstdc++ ) on my system for use with the OmniCppComplete vim script. This gave me a very reasonable 4MB tags file which seems to work fairly well.
However, when I ran the same command against the installed Boost headers:
$ ctags -R --c++-kinds=+p --fields=+iaS --extra=+q -f ~/.vim/tags/boost /usr/include/boost/
I ended up with a 1.4 GB tags file! I haven't tried it yet, but that seems likes it's going to be too large to be useful. Is there a way to get a slimmer, more usable tags file for my installed Boost headers?
Edit
Just as a note, libstdc++ includes TR1, which has allot of Boost libs in it. So there must be something weird going on for libstdc++ to come out with a 4 MB tags file and Boost to end up with a 1.4 GB tags file.
Just ran across this on the Boost mailing list:
Boost-users Boost and autocompletion
THE ANSWER
Thanks to Neg_EV for figuring out what the problem was, but there's a much better way of solving the problem than what he suggested:
Make sure apt-file is install, and run the following commands
( I keep my library tags in ~/.vim/tags/ ):
$ sudo apt-file update
$ apt-file list boost | grep -E -o '/usr/include/.*\.(h|hpp)' | grep -v '/usr/include/boost/typeof/' > ~/.vim/tags/boost-filelist
$ ctags --sort=foldcase --c++-kinds=+p --fields=+iaS --extra=+q -f ~/.vim/tags/boost -L ~/.vim/tags/boost-filelist
I've upgraded to Ubuntu 10.04 and Boost 1.40 and that's what I tested this solution on, but it should work with any Boost version as far as I can tell.
I know this post is a little old, but I just ran into the same problem. I looked into it a little further and it seems it is one folder in boost that is causing the problem: typeof. I am using boost 1.37 and my tags file was 1.5G, typeof was 1.4G of that. So I just created a tags file without that directory included and the resulting size was 70M. I was even able to sort it without running out of space :) I imagine in newer versions of boost they may be other projects that are too large however the general solution I found is this...
Generate a tag file for each boost folder seperately, a simple bash for loop should be able to do this.
Look at which ones are too large.
Either create a new single tags file excluding those large directories or keep the tag files separated simply deleting the ones that are too large.
This is the script I used (taken from comments):
for i in $(find -maxdepth 1 -type d | grep -v '^\.$' | sed 's/\.\///' ); do
echo $i;
ctags -f ~/tmp_tags/$i.tags -R --c++-kinds=+p --fields=+iaS --extra=+q --languages=c++ --sort=foldcase $i;
done
Hope this helps.
use the option
--sort=foldcase
With this the searching of the tags becomes faster.
Quoting from the man page of ctags :
"The foldcase value specifies case insensitive (or case-folded) sorting. Fast binary searches of tag files sorted with case-folding will require special support from tools using tag files, such as that found in the ctags readtags library, or Vim version 6.2 or higher (using "set ignorecase"). This option must appear before the first file name"
You SHOULD add this option to your ctags invocation:
-I "BOOST_SYMBOL_VISIBLE BOOST_SYMBOL_IMPORT BOOST_SYMBOL_EXPORT BOOST_FORCEINLINE BOOST_CONSTEXPR=constexpr BOOST_CONSTEXPR_OR_CONST=constexpr BOOST_STATIC_CONSTEXPR=static\ constexpr BOOST_STD_EXTENSION_NAMESPACE=std BOOST_MOVABLE_BUT_NOT_COPYABLE+ BOOST_COPYABLE_AND_MOVABLE+ BOOST_COPYABLE_AND_MOVABLE_ALT+ BOOST_NOEXCEPT=noexcept BOOST_NOEXCEPT_OR_NOTHROW=noexcept BOOST_NOEXCEPT_IF+ BOOST_NOEXCEPT_EXPR+ BOOST_STATIC_CONSTANT BOOST_DELETED_FUNCTION BOOST_DEFAULTED_FUNCTION BOOST_NESTED_TEMPLATE BOOST_UNREACHABLE_RETURN+ BOOST_DEDUCED_TYPENAME=typename BOOST_CTOR_TYPENAME=typename BOOST_LIKELY+ BOOST_UNLIKELY+ BOOST_ALIGNMENT+ BOOST_FALLTHROUGH"
This is what I use for the ENTIRE /usr/include/boost subdirectory for Boost 1.55. I get a tags file that is ~128MB. The -I seems to be the key here and helps filter out spurious tag generation.
NOTE: I'm using ctags 5.9 on Ubuntu 14.04. I have a special -I for generating ctags for C++ standard headers. This took a while for me to figure out why some header files generated almost no tags while others generated enormous amounts of tags.
beacuse the methods generatored(eg. vector50.hpp vector100.hpp ...) is too much so that ctags generator a large tags file
find /usr/include ( -name ".h" -o -name ".hpp" ) boost/typeof > boost_files.txt
edit boost_files.txt and remove vector50.hpp vector100.hpp vector150.hpp vector200.hpp
ctags --c++-kinds=+px --fields=+iaS --extra=+q -f test.tags -L boost_files.txt