Using vim as C/C++ IDE

I’m a developer of embedded operating system and I do all my development tasks solely in the terminal.

The main tool, which helps me to accomplish this, is vim. Today, I will describe how to turn vim into a powerful IDE for C/C++ projects. I will not recommend you any plugin for project management, since vanilla vim already has all the power to cope with this task.

Despite fact that I use vim as a C IDE, the part of the following recommendations are pretty general and may be used to any kind of project.

First step

First of all, you want to enable exrc option. This option forces vim to source .vimrc file if it present in working directory, thus providing a place to store project-specific configuration.

Since vim will source .vimrc from any directory you run vim from, this is a potential security hole; so, you should consider to set secure option. This option will restrict usage of some commands in non-default .vimrc files; commands that wrote to file or execute shell commands are not allowed and map commands are displayed.

So, you should add these two lines to your main .vimrc file.

Project-specific options

After you managed to store vim settings on per-directory basis, you should place all your project-specific settings in .vimrc file at top directory of your project.

First of all, you want to set indentation rules for your project (I suppose, your project has kind of style guide).

I also try to keep my lines 110 chars at most. But I don’t trust vim such an important task as line breaking, because it depends on context too much. So, the thing I want is to see exactly how much space is left, so I highlight column number 110 with color.

File-type detection

By default, vim assumes all .h files to be C++ files. However, I work with pure C and want filetype to be c. Since project also comes with doxygen documentation, I want to set subtype to doxygen to enable very nice doxygen highlighting.

Add lines like these to your local .vimrc file:

Setting path variable

Vim has a gf command (and related, to open in new tab) which open file whose name is under or after the cursor. This feature is extremely useful for browsing header files.

By default, vim searches file in working directory. However, most projects have separated directory for include files. Thus, you should set vim’s path option to contain comma-separated list of directories to look for the file.


Java users should pay attention to includeexpr option. It contains expression which will be used to transform string to a file name. The following line changes all “.” to “/” for gf command (and related):


The best (Outdated. Now I use YouCompleteMe. See my post for details) Good autocomplete plugin for C/C++ language I found is a clang_complete (refer to plugin page for installation instructions).

It uses clang to generate list of suggestions and works fine for both C and C++.

In order to let clang know about your include directories custom defines, you should place your -I and -D compiler flags into .clang_complete file at the root of your project. After that, clang_complete will be automatically called when you press ‘.’ or ‘->’ and will show a list of autocompletion.


If you already populated path option with include directories, you may use following command to insert list of compiler options:

"='-I'.substitute(&path, ',', '\n-I', 'g')<CR>p

(After that, you should review generated list for inconsistency, because it’s okay to put several commas in row or end line with one in path option)

Other clang-based plugins

Clang is not just a compiler, but a set of libraries for code analyzing and manipulations. Thus, it provides a good base for plugins and tools. So, in near future more clang-based tools will come.

I suggest you to check out some of already existent clang-based vim plugins.

  • vim-clang uses clang to parse and complete C and C++ code.
  • clang-format uses clang to format source code.

Project drawer

To display a project tree, you can use either custom plugins (NERD Tree), or built-in netrw plugin.

I don’t use any of them as project drawer, because I’m pretty comfortable with selecting files directly from command mode.

One interesting article about project drawer and vim.

Configure build system

After you’re done with file editing and navigation, you want to configure vim to easily build your project. Vim has a make command which, by default, executes make in current directory and parse output for errors.

The actual command to execute is stored in makeprg option. If you build your project out of source, with a custom make arguments or even a different build command, just change makeprg to reflect this.

After that, you can build your project as easily as typing

. You may want to go further and bind this command to one of keys. For example:

(“!” mark prevents vim from jumping to location of first error found)

Configure launch system

After you build your project, it’s expected to run it. You can execute any shell command from vim’s command mode if you prepend it with “!”. So, to run your great program you just type :!./my_great_program.

Of course, you want to bind it to something simpler:

Version control support

Since vim provides access to the shell, I don’t actually use any special plugin for this task and manage git tree completely from the shell.

But I should mention that there are powerful vim plugins for version control systems. For example, fugitive. If you work with git, you absolutely must look at fugitive vimcasts.


After a couple of simple operations, we added and uncovered a lot of vim features and built a completely Integrated Development Environment.


    1. My project is an OS, so the most effective debug techniques are printing and thinking. They don’t need any support in IDE.

      However, I know there are a couple of plugins, which bring gdb integration into vim. For example, see clewn, gdbvim or google for “vim gdb”; I’m sure, you will find some more.

Leave a Reply

Your email address will not be published.

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code class="" title="" data-url=""> <del datetime=""> <em> <i> <q cite=""> <strike> <strong> <pre class="" title="" data-url=""> <span class="" title="" data-url="">