I've used LazyVim's mason to install clangd LSP, but it doesn't seem to work properly. It can't find files in my workspace, so when I try to jump to declaration, it does nothing if the declaration is in the workspace (vs. the c++ std lib, which clangd able to find)

I managed to hack it by using export CPLUS_INCLUDE_PATH=...workspace/include/, but that means I need to do it manually - which makes no sense.

I also tried to disable the auto formatting - which can be done by "uf" - which toggles the "on save format" - but I want to get that on startup, not click it every time I open a new nvim session

  • Normally you need to create compile_commands.json with e.g. make clean; bear -- make or cmake -DCMAKE_EXPORT_COMPILE_COMMANDS=1. See the docs. The autoformatting is a bit of a different question. Jul 4 at 11:48
  • I added the cmake flag - and got a ./build/compile_commands.json file - It still doesn't seem to work. Copying the file to my workspace root directory solved the issue Jul 4 at 12:05
  • 1
    You can add --compile-commands-dir=… to clangd as well. Jul 4 at 13:14
  • 1
    Do you still have something open in your question? How can we help you further? If the answer address your need maybe could you accept it using the v button next to the arrow voting buttons. It allow the question to rest :-) Jul 5 at 14:46
  • 1
    The save on format is unanswered, but as it is off topic, I'll accept the answer and maybe open another one dedicated to that. Thx Jul 7 at 14:29

1 Answer 1


I would have a compile_commands.json in the root of my project.

I make sure it is the working directory (using vim-rooter may help for that) but I'm not sure it is a requirement.

The compile_commands.json would contains the instructions to build each of the cpp files.

For a project like:

._ project1
| |_ main.cpp
|_ project2
| |_ foo.cpp
| |
| |_ include
|   |_ foo.h
|_ compile_commands.json


    "directory": "full/path/to/project1",
    "command": "clang++.exe -x c++ main.cpp -std=c++2b -DMYFLAG1 -DMYFLAG2 -Iinclude -I../project2/include",
    "file": "main.cpp"
    "directory": "full/path/to/project2",
    "command": "clang++.exe -x c++ foo.cpp -std=c++2b -DMYFLAG1 -DMYFLAG2 -Iinclude",
    "file": "foo.cpp"

In order to debug your compile_commands.json the following command is helpful:

clangd --check=project2/foo.cpp

It allow to to verify that:

  • The compile_commands.json is correctly identified
  • The resulting compilation flag for the selected file (project2/foo.cpp in the example)

If that is too much work you could also only have a flag with common compiler flags (it provides already some information about the available includes to clangd). It allow to navigate through the includes and to the declaration but not to the definition.

e.g. (compiler_flags.txt):


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.