I am getting into C development under Linux. However I'm struggling with correctly setting up ctags to work with vim
. It correctly registers the tags
file and offers completion based on it.
I'm not sure what is the proper way to get "necessary" includes. Currently I have some "hand-picked" headers:
AM_CTAGSFLAGS = \
--recurse=yes \
--tag-relative=yes \
--extras=* \
--fields=* \
--c-kinds=* \
--language-force=C \
/usr/include/bits \
/usr/include/fcntl.h \
/usr/include/stdio.h \
/usr/include/stdlib.h \
/usr/include/string.h \
/usr/include/sys \
/usr/include/unistd.h
In a first step, I just put same headers as I have #include ...
but that missed some stuff (like /usr/include/bits/...
). So I have added those.
But I feel like after all these years someone somewhere had to come up with better solution. So, how is this commonly done?
That's an excellent question, graywolf!
I've been using this approach for years and here's how I use it:
I usually have a single tags file for the ANSI C headers (or C++ if you use that instead) appropriate for a particular standard (typically c99. c++11 if you use C++), which typically is my "everything else" tags file.
The hardest part is feeding in the ignore list to ctags. Since you are using C, I'll assume you use the C headers from the system (just the compiler-standard ones that should be available with the language). I use the following ignore list for when I generate these (on Ubuntu 14.04):
__attribute__
__attribute_deprecated__
__attribute_format_arg__+
__attribute_format_strfmon__+
__attribute_malloc__
__attribute_noinline__
__attribute_pure__
__attribute_used__
__attribute_warn_unused_result__
__attribute_alloc_size__+
__attribute_const__
__attribute_artificial__
__wur
__THROW
__THROWNL
__BEGIN_DECLS
__END_DECLS
__BEGIN_NAMESPACE_STD
__END_NAMESPACE_STD
__USING_NAMESPACE_STD+
__BEGIN_NAMESPACE_C99
__END_NAMESPACE_C99
__USING_NAMESPACE_C99+
__warndecl+
__warnattr+
__errordecl+
__flexarr=[]
__fortify_function
__REDICRECT+
__REDIRECT_NTH+
__REDIRECT_NTHNL+
__ASMNAME+
__ASMNAME2+
__nonnull+
__always_inline
__extern_inline=extern
__extern_always_inline=extern
__extension__
__restrict
__restrict_arr
This is the most important part. If you don't see much output for headers that you've run ctags on, that's probably what's going on. It drove me nuts until I figured this out. Those keep ctags from being fooled.
As far as the headers input into ctags, you have the right idea. Don't forget the compiler-specific system headers that are usually located somewhere else like /usr/include/x86_64-linux-gnu. Those will help you drill down to your system's constants if necessary.