ensure clangd is started for each project on it's own
ClosedPublic

Authored by cullmann on Jul 24 2019, 7:44 AM.

Details

Summary

If you work on different projects, at the moment clangd is shared.
That doesn't work, as it needs a compilation database "per project".
Therefore: move the heuristic "what is the root" to the generic code
and use the root for the compilation database

Test Plan

now, I get proper handling if I open different projects at once
before, the first project did win and all others did have
wrong compilation databases used

Diff Detail

Repository
R40 Kate
Lint
Automatic diff as part of commit; lint not applicable.
Unit
Automatic diff as part of commit; unit tests not applicable.
cullmann created this revision.Jul 24 2019, 7:44 AM
Restricted Application added a project: Kate. · View Herald TranscriptJul 24 2019, 7:44 AM
Restricted Application added a subscriber: kwrite-devel. · View Herald Transcript
cullmann requested review of this revision.Jul 24 2019, 7:44 AM

Perhaps you have some better idea how to solve this.
In any case, I don't think one can re-use the clangd instances as one does atm.
One could start with using the workspace stuff, but actually, not all language servers support it and I am not sure if one really saves that much, given as soon as at least one define is different, there is no common pre-parsed stuff anymore between two projects.

There are 2 stages of consideration here. One of (desired) functionality, and then how to implement it.

Regarding functionality, my configuration uses symlinks (to compile_commands.json) as recommended by upstream clangd and uses $HOME for the server root and no "compilationDatabasePath" whatsoever. In particular, I need only 1 clangd instance, and it can handle multiple projects fine by using the symlinks to find what it needs (e.g. the compilation database). By forcing it with custom code that adds a "compilationDatabasePath" it then indeed starts to go wrong as it would try to use that db also when it should not. So then it becomes necessary to start several instances to be able to force them independently. All in all, IMO it is easier and (very) advisable not to hand-hold either clangd or users/developers (with custom "compilationDatabasePath"). Of course, this would come at the expense of users/developers then having to deal with symlinks themselves, which is after all the upstream recommendation. I am also still (silently but fiercely) hoping that 1 (shared) clangd instance will be able to find a definition (asked in one project's file) which is present in another project. When using separate instances, there seems no chance of such happening. However, it could be argued we might nevertheless want to provide a custom "service" that makes it not necessary to add the symlink ...

... in which case we are passing into the implementation part of that "service". Such is necessarily pretty custom and server specific. In this case these changes are as good as that could get, as that is a slippery/tricky slope that hopefully does not grow to involve other servers ...

However, there is a minor problem in the the default configuration changes. The changes there will now always force a separate server per project, which as mentioned above is not really required for clangd (depends on how you configure it), but it is not needed for python's pyls (and probably not for others either). clangd custom's override is rather the exception. So makeServerConfig should rather accept a "const QJsonValue & root", and be called with a string for clangd then, but an empty (null) for pyls as it was before (note null != QString()).

Actually, I think the root issue is then that we started to mess with the compilationDatabasePath at all. (I guess I wanted that :)

I did read the clangd docs (and tooling docs in general) again, too, and yes, you are right, I guess the symlink way is the one advertised and if I didn't want to use the build stuff from the project plugin, it would just work with one instance.

cullmann updated this revision to Diff 62503.Jul 24 2019, 9:09 PM

Updating D22710: ensure clangd is started for each project on it's own

;=) Let's then try the different direction: Avoid the messing with the compilationDatabasePath at all.
I guess the symlink approach that is advertised is better.
If we want to have more convenience for the CMake generated projects one could think about generating the symlink if none is there.

mnauwelaerts accepted this revision.Jul 25 2019, 6:52 AM

We could indeed optionally (configuration based?) create the symlink later on ...

This revision is now accepted and ready to land.Jul 25 2019, 6:52 AM
This revision was automatically updated to reflect the committed changes.