Nix / NixOS
Main links
Videos
Not really confident, but is the LSP running from a separate child process? Is that child process inheriting all of the anticipated environment variables from the shell that launched Neovim?
The LSPs load when you open a file in nvim, so I think it would be a child process? Is there any way to check what environment variables a process has, like with gdb or something else?
You inspect the /proc file tree or ps utility command:
i have a .clangd file with
CompileFlags:
Add: [
CompilationDatabase: /src/
-Wall,
-I/nix/store/vm10zh43xgfxvgrqs8brz6v6xyrq9qin-glibc-2.40-66-dev/include,
-I/nix/store/64819v2lcdbdqqb52gyqpic3khn4hvyf-libcxx-19.1.7-dev/include,
-I/nix/store/f4x7z33ymmqn0m0pvi5ydxifsfmic1jw-raylib-5.5/include,
-I/nix/store/wakcjb523m43qbm4xblyqm7rgg9l9s32-glu-9.0.3-dev/include,
-I/nix/store/8xbbdx4ckcdj76ldb0cbym965whipq72-libglvnd-1.7.0-dev/include,
-I/nix/store/b5i8r0l5bnaj8khjz4lsmsdph8dkha3s-libX11-1.8.12-dev/include,
-I/nix/store/l1qkka1svxk8s0myynmb6kgl0ni19mjk-xorgproto-2024.1/include,
-I/nix/store/y91x77rjip3i5zdza2ikf2lj80qc0286-libxcb-1.17.0-dev/include,
-I/nix/store/95hqc5scvz3vxhs0p1crx9rr5r1sfs1i-compiler-rt-libc-19.1.7-dev/include,
-I/nix/store/64819v2lcdbdqqb52gyqpic3khn4hvyf-libcxx-19.1.7-dev/include,
-I/nix/store/f4x7z33ymmqn0m0pvi5ydxifsfmic1jw-raylib-5.5/include,
-I/nix/store/wakcjb523m43qbm4xblyqm7rgg9l9s32-glu-9.0.3-dev/include,
-I/nix/store/8xbbdx4ckcdj76ldb0cbym965whipq72-libglvnd-1.7.0-dev/include,
-I/nix/store/b5i8r0l5bnaj8khjz4lsmsdph8dkha3s-libX11-1.8.12-dev/include,
]
and a create-clangd.py
3 includes = []
4 with open("./src/compile_commands.json", 'r') as f:
5 lines = f.readlines()
6 for line in lines:
7 if "include" in line:
8 includes += [line[1:-2].strip()]
9
10 s = """
11 CompileFlags:
12 Add: [
13 CompilationDatabase: /src/
14 -Wall,
15 """
16
17 for include in includes:
18 s += "-I" + include[1:-1] + ",\n"
19
20 s += "]"
21 print(s)
22
23 with open(".clangd", 'w') as file:
24 file.write(s)
I forgot how I made the compile-commands.json file. I think I used a program called bear.
I also don't code cpp normally, I just did this for one small project, so it might be a bad solution
Hmm, clangd should support compile_commands.json directly. Not sure why your script is needed.
Because C++ doesn't have a single well-defined build system, clangd doesn't know how exactly to compile the files you are asking it to - in this case, it doesn't know what headers to include. On some other distros it might "just work" because all headers are lumped together somewhere in /usr/include or something, and something somewhere tells clangd to just look in there. This isn't the case on NixOS (in fact the headers are not installed at all with your system), and so you have to tell clangd where to look for them.
Typically, your build system will have that information somehow. The process can vary depending on the build system you are using - some (like CMake or meson) can do it natively, for others you have to resort to a very useful hack called bear. Judging by your shell.nix, I would guess it's make, which doesn't have native compile_commands.json support, so what you have to do is:
- Add
bearto yournativeBuildInputs - Enter the shell again so that you have it in
$PATH - Run
make clean(or otherwise ensure there are no build artifacts already present - maybegit clean -fxbut be careful with that) - Run
bear -- makefrom the project root.
make should then build your entire project, compiling every file in the process. bear will inspect the system calls that make is executing and determine which commands (and hence which command arguments) it used to compile each file, and create a file called compile_commands.json recording this information. clangd should then automatically find that file and use it to figure out which headers (and other arguments) it needs to compile each file.
This is the setup I personally use to hack on Nix itself BTW, and it works great. Although I'm using helix and not neovim, but that shouldn't matter.
I'm actually using CMake for this project (I just haven't moved it over from my system config yet) so I was able to set an environment variable to get that successfully. Is there a specific place I need to put the json to get clangd to recognize it?
It would probably work if I used the python script from the other project but I want to try getting it working directly first.
Hmm, I think for me it just picks it up from the project root "magically". I'm starting my editor from the project root too, maybe that matters (i.e. clangd looks for this file in $PWD)?
Actually, looking at the docs, it should just search for it upwards from the source file you're editing, so it can find it in the project root or in the subdirectory where your code lives. If you have it in some other locaiton, you can set this option in the .clangd file in your project root.
