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, 2023 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, 2023 at 12:05
  • 1
    You can add --compile-commands-dir=… to clangd as well. Jul 4, 2023 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, 2023 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, 2023 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 documentation says that the compile_commands.json is searched next to the file and if not found searched in the parent folders until one is found (thanks to @Friedrich to pointing this to me).

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 file (compile_flags.txt) 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. (compile_flags.txt):



  • with compile_command.json the gd coc command (<Plug>(coc-definition)) goes to the implementation of the function (.cpp in general)
  • with compile_flags.txt the gd coc command (<Plug>(coc-definition)) goes to the declaration of the function (.h in general)

It seems to me that the gi coc command (<Plug>(coc-definition)) is not implemented in the coc-clangd.

  • 1
    It should be called compile_flags.txt not compiler_flags.txt
    – gagiuntoli
    Feb 12 at 8:47
  • Thanks for the feedback :-) I have adapted the solution accordingly. Feb 12 at 8:54

Your Answer

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

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