pascal jungblut thoughts

People’s vim setups tend to be very individual: some are rejecting most of the features over vi or even ed while others turn the dial to eleven and build their very own IDE. Both have their pros and cons – I tend to be somewhere in the middle with a tendency to the more purist experience.

As I worked a lot on C and C++ in recent years, I started to enjoy the Asynchronous Lint Engine (ALE) vim plugin. It calls clang, clang-tidy, clang-check, etc. in the background and inserts hints these linters output into the vim buffer. These work pretty well, but require some setup to work properly. To hand clang and friends the correct compiler flags, it relied on hacks like a project-local vimrc file.

If you’re using CMake for your projects, the whole experience can be very smooth. The setup includes:

The configuration in is rather simple. Install the software as described in their documentation. Then, enable the generation of the compilation database in your CMakeLists.txt if you haven’t already.


Next, tell vim to use the clangd linter for C (or C++):

" ~/.vim/ftplugin/c.vim
let b:ale_linters = ['clangd']
" parse the compile_commands.json database
let g:ale_c_parse_compile_commands = 1
" enable clangd-based go to definition with <C-X><C-O>
set omnifunc=ale#completion#OmniFunc

Because CMake usually uses out-of-source builds, link the compile_commands.json to your projects source:

$ cd $PROJECT_ROOT && ln -s $BUILD_DIR/compile_commands.json

Alternatively, if you want support for clangd when editing your header files, you can use compdb for that:

$ compdb -p $BUILD_DIR list > $PROJECT_ROOT/compile_commands.json

This has to be done manually but could be added to the build process.