Command line option for asking sourcekit-lsp if the pwd is a workspace root?

I am trying to learn how to use sourcekit-lsp in the context of a compile database driven project in a way that is IDE agnostic. Both in a single project context and a mono repo style collection. I'd like to make projects that are usable no matter what IDE the cloner of the repository wants to use.

I am seeing different behaviors in different IDE's with the same config.json (So far comparing VSCode and Zed primarily. BBEdit is next.)

I think that the VScode plugin is being really generous about fixing misconfigurations on my part, that other IDE's are not. It appears that just opening a compile_commands.json file in VSCode means that VSCode just adds it to its own list of compile_commands.json's to use? So if the compile_commands.json uses absolute paths, you're set. (But if you wanted to be able to share the compile db, you can't use absolute paths.) The same cannot be said for Zed. Both VScode and Zed are rock solid at finding the json files in default locations, but I haven't found the trick to get the searchPath setting to work and I can't tell when things do appear to be working - is it because I did it right or because VScode is papering over my mess.

I'd like to ask the LSP what it thinks directly. Is the pwd a workspace root? Is it even in a project? If so, what does it think the root is?

I think I'm still trying to work out exactly how rootURI gets set and by who in what contexts.

I was able to run the diagnose command, but I found the log file hard to understand (understandably redacted directory names, etc)

Other than giving up and just leaving my compile_commands.json files in the build folder with absolute paths (for now anyway) what could be my next steps?

(FWIW, I am having zero trouble compiling these projects using CMake and a build.sh, just getting IDE's to integrate code I wrote into the search paths)

(Example repos available upon request)

The entire discovery of compile_commands.json happens inside SourceKit-LSP, so it should not matter which editor you use to open the project in. SourceKit-LSP searches for compile_commands.json in the package root, and inside a build folder inside the workspace root. You can add more workspace roots by adding compilationDatabase searchPaths to your config.json, as described in sourcekit-lsp/Documentation/Configuration File.md at main · swiftlang/sourcekit-lsp · GitHub. Does that work for you?

1 Like

No, searchPaths does not work for me. Only when the compile_commands.json is in the project root or build do either VScode and Zed find it. I have tried both relative and absolute paths. It seems what I thought was working was really just VScode "fixing it" because it doesn't work when I then open the repo in Zed, but I will try again. (Relative to where I'm not confident in, btw. What is defining the "workspace"? The IDE? the pwd? Some "I see build folders" functionality?)

I had thought it shouldn't matter which IDE one was using, too. Which is why I surprised to see a difference. VScode, as I mentioned, is doing some magic where no matter where the compile_commands.json lives inside the VSCode workspace, once you open it, my code gets found again while not being a false positive from a sk-lsp crash (sometimes). What is happening in the config.json has no impact as per searchPaths. I do have "defaultWorkspaceType" : "compdb" set.

Here are the two repos I'm playing around in - they're a little messy still.

ETA:

  • New Branch:swift-cmake/.sourcekit-lsp/config.json at tests · carlynorama/swift-cmake · GitHub
    • an example of the search paths that doesn't work for me.
    • Move the compile_commands.json file in the "george" folder to the root it works in both Zed and VScode. Leave it in the "george" folder and it does not work in Zed, but sometimes works in VSCode... unsure what the difference is. It seemed like removing the optional outputs entries helped... but it may just have been that I opened the file.
    • Can I refresh sk-lsp without restarting VScode?
    • Notice that I am sharing a file with full paths (which grates). I have had no luck using relative paths (just confirmed, relative paths work in file and command because they are off of directory, using a relative for directory is what fails.)
    • Also, seeing the error messages that sk-lsp is putting out in real time? Is that a thing? As I mentioned the diagnose output can be hard to groc.

A single project repo and a monorepo where I was hoping to have various "hand compiled" examples for reference.

What would you like to see an example of?

FWIW: I'm coming from a "write your own make files and build.sh scripts and be ecstatic if you get syntax highlighting" using gcc background. I likely have great gaping gaps in my clang/llvm/CMake knowledge so I really could be missing something basic about how language servers get their info with this toolchain. Which is why I wanted to be able to query SK-LSP directly, understanding that environment variables are a thing and the VScode shell might think something different than a fresh one in Terminal.

Looking at this issue, it looks to me as if we’re not picking up the .sourcekit-lsp/config.json file, which will be fixed by Allow workspace options to affect build system search by bnbarham · Pull Request #1889 · swiftlang/sourcekit-lsp · GitHub. Could you try if modifying ~/.sourcekit-lsp/config.json (ie. the global configuration file) fixes the issue? Also

  • Could you omit the defaultWorkspaceType setting. It shouldn’t be needed and the compilation database setting recently changed from compdb to compilationDatabase, which might be causing issues
  • The searchPath property must be inside a compilationDatabase dictionary, so the file should look as follows:
{
  "compilationDatabase": {
    "searchPaths": ["george"]
  }
}
1 Like

Uhg. Of course, thank you. Walk away for a week and forget everything. I had had it that way once before, and that does seem to be working! I must of had an error in the compile_commands.json I was testing it against at some point.

Without changing the global, that now works in both VScode and Zed. I'll go bang on that setup in the monorepo, that one may work better in a global update.

I'll keep an eye on that PR.

What is still bugging me is if I can't get a relative link to work from the compile_commands.json I might as well tell the user of the repo they have to build it once first in order to not get errors and leave it in the build folder, because I can't include a starter compile_commands.json with references to my userid!

This does go back to my original question about additional command line ways to interact with sk-lsp because I'm having a hard time getting insight into what about what I'm doing causes crashes. What isn't being found? Where is it looking? What field in the json is it choking on? Which json (.config or compile_commands.json) did I screw up on? Where is the workspace root? Why isn't that relative link working? How do where I think it should be looking and where it thinks it should be looking differ?

It's so powerful and does so much and I'm so new at clang/llvm I'm 100% sure most of what's going wrong is a me problem. I'd like some tools to get it to tell me where I'm off! Without bugging you all!

I do have Console open now and can see the messages realtime, but with all the file and folder names redacted it can be hard to chase down the error.

What do you mean by relative links here? Do you have an example of such a compile_commands.json to illustrate what you mean?

You can enable extended logging, which won’t redact any information as described here: sourcekit-lsp/Documentation/Diagnose Bundle.md at main · swiftlang/sourcekit-lsp · GitHub. Does that help you?

1 Like

Note just switched branches back to main and then back to tests and now it doesn't work again (sourcekit lsp is crashed entirely) Oh dear. Why! Why did it work before but not now!

Will retry with changing the global .config

ETA: Sorry, will enable extended logging

I don't see a lot of example of this kind of setup in terms of swift projects but in terms of this one my compile_commands.json has "/Users/carlynorama/Developer/AdventOfCode/swift-cmake/WeirdoBuildFolderName" as the directory. I have tried both "WeirdoBuildFolderName" and "../WeirdoBuildFolderName" and neither seems to work. My impression is that in both cases the relative location should be relative to the compile_commands.json file so if its in the project root "WeirdoBuildFolderName" should work, and if it is in "george", "../WeirdoBuildFolderName" should work, but it doesn't for me. But I will check again.

Some examples that don't use /User are

The documentation says that relative should work? (ETA: No sorry, does not comment on relative vs absolute for directory itself)

I will try to find a better one.

THAT HELPS SO MUCH!!! Thank you! (Installing the profile on the mac worked, .config { logging } did not seem to when I tried to do it in the local .config (which it never says you can). Will do it on the global .config on my linux box)

Well, what I want to do just isn't a thing maybe? No relative paths, which of course those example aren't really doing exactly.

This is clang issue, not a Swift one.

This sort of creates a usability problem for me if I want to create a repo with examples. It means no matter what the end user is going to have to generate the compile_commands.json themselves for their IDE to stop screaming at them that things are broken. A person new to Swift will download my example repo (a fellow gcc embedded person) and their IDE will be mad at them until they run a process. I have to think about whether that's a reasonable ask.

For smaller repos it's not a big deal, perhaps, to ask them to run a build. For bigger projects/mono repos... well what a pain. I'd have to write a small utility or assume they have their own process (bear/compdb whatever) which is very much not a safe assumption.

Or I'll just have to enforce a specific IDE and write a plugin.

Hmmmmph. Okay I have to think. Thank you so much for muddling through this with me. It's really appreciated.


Also, as per the Issue already being fixed, the workspace root is in fact "george" !

Created workspace at file:///Users/carlynorama/Developer/AdventOfCode/swift-cmake/george as Optional<BuildSystem> with project root /Users/carlynorama/Developer/AdventOfCode/swift-cmake/george

Might be worth noting that even if relative paths here were supported, you'd still need to run a build if there's any more than a single module. If you have two modules A and B where eg. B imports A, then we need the module for A to have been built in order to resolve any references to symbols inside it.

For SwiftPM (and BSP assuming the server supports the extensions) in main/6.1+ this happens automatically - when navigating to a file within B, we'll build A in the background into a separate location to the build. But for compilation databases, we require a build.

This is somewhat mentioned in the Getting Started, but maybe the impact of the statement there isn't clear enough.

1 Like

That was indeed the next step to try. And I likely would have gazed over it/forgotten I read it, like I did with the logging instructions. Thank you all for your patience.

But after that will be how to include a C library that's not even in the same directory (non apple hardware SDK's), potentially. That is a very big ask. (Again, I can compile that already, just getting the IDE's to acknowledge the connections is the trick)

Swift Package Manager is amazing and makes so many things so easy. So good. An aspect of why I'm doing this is so I can understand how it works better.

What I'm noting in a meta-analysis of the Swift embedded examples is that some folks are including a Package.swift AND an alternate build tool. (One even has a .sourcekit-lsp folder, but that's just for SwiftPM stuff. ) It seems like there is a Package.swift for sk-lsp and the real build process for the actual compiling. That could work?

There're two user bases I have in mind for example code I'll write in the future. The committed and the browsing. Both coming from a C/C++ gcc background.

The committed will read the README/Docs (better than me hopefully) and be willing to run scripts, have patience and be willing to ignore the occasional red squiggly in the IDE. Code I write just for myself falls into this category.

The browsing ... well they are maybe even possibly looking to be annoyed and reject Swift and I want nothing to go wrong. That hybrid approach might be the way forward for code directed at them.

I image sorting out the logging levels will prove to have been a really really helpful tip! I think I'm going to need them!

Making compile_commands.json support working directories relative to compile_commands.json is a reasonable request. Could you file an issue for that at Sign in to GitHub · GitHub?

Done! It's early here and I'm low on coffee and have a cold so I hope it makes sense!

1 Like