Thursday, October 6, 2011

Vim - Omnicompletion - ctags!

How to get intellisense like (omnicompletion) feature on Vim for standard C libraries!
If you're a Vim user and also code C sources in Vim, than you quickly find yourself switching between terminals or browser to look for the type of arguments you need for standard C functions like strcmp() or strtok() or whatever. Well, not anymore! I found a lot of examples how to use omnicompletion whitin Vim, but almost all of them assume you need omnicompletion for C++, php, python or whatever. I googled my ass off to find an example of omnicompletion for standard C libraries.
First, what I did that didn't work. I looked at the folders where those standard c include files reside and found those in /usr/include/ directory. So I was analyzing the files for C only headers like stdio.h and such. I was also looking for Linux's systemcall files, like sockets etc...
Since version Vim 7.0 Vim supports omnicompletion and to work with that feature Vim needs a ctagged file (a file that is generated by ctags). This tag files contains a list of functionnames, prototypes, defines and other C related stuff, formatted in an indexed way so it can be looked up in a fast and efficient way (I guess, I'd rather use an SQLite engine as a solution). So to put it all together, we need to make a tag file using ctags. On Linux distros like Ubuntu, it's installed by default, but if you don't have one, google for exuberant ctags, download it and install it.
To generate a ctags file, you need to do the following:
# ctags /usr/include/*.h
This will generate a ctags file named tags.
If you open a c file and try out omnicompletion on the word "prin" by hitting Ctrl+x Ctrl+o, Vim won't give you a printf in the list of possible functions. Well, that sucks :(
One of the solutions is figure out how ctags work! Well, I'm sorry, I just don't have the time to do that just because I happen to want omnicompletion for standard C libraries in Vim.
The other solution is this: Be sure you downloaded and installed apt-file. If you never used apt-file than run "apt-file update". After that do the following:
Create file "libcs-ignore" with the following content:
__attribute__
__attribute_deprecated__
__attribute_format_arg__
__attribute_format_strfmon__
__attribute_malloc__
__attribute_noinline__
__attribute_pure__
__attribute_used__
__attribute_warn_unused_result__
__wur
__THROW
__nonnull+


Than execute:
# apt-file list libc6-dev | grep -o '/usr/include/.*\.h'> ~/.vim/tags/libc6-filelist
Finally do this:
# ctags --sort=foldcase --c++-kinds=+p --fields=+iaS --extra=+q -I./libc6-ignore -f ~/.vim/tags/libc6 -L ~/.vim/tags/libc6-filelist

And voila! You're done, you're finished! Try it out, but don't forget to set the tags in Vim:
# :set tags+=path/to/tag

Somehow, when ctags process the files, it gets fooled by those attributes listed in libc6-ignore file. -I option tells ctags to ignore thow words, so functionname will be parsed with the right functionname instead of __attribute__ etc... 



.


I found this solution from the following link:
http://stackoverflow.com/questions/1632633/ctags-does-not-parse-stdio-h-properly

2 comments:

  1. Hi man, that's cool! I had that issue too, thanks for sharing this, keep up the good work!

    ReplyDelete
    Replies
    1. I know what you mean :-)
      It's a long time I haven't programmed for Linux, but I'm back now.
      There is a better alternative called CLang, I'll try this one out and hopefully it will work better than omni-completion.

      Delete

NSNotification example