Add support for multi-root workspaces
These changes add proper support for multi root workspaces with a clangd server per workspace folder.
On a high level, we have a single language client per folder, and have to rework things so that various global objects (views, ...) are actually global and not instantiated per client anymore.
The important use case this enables is where clangd is invoked within a container per process with all the dependencies installed in the container. To make this use case work in a multi-root setup, a clangd instance per workspace folder has to be spawned.
Fixes #38
This currently doesn't work because the second client tries to register clangd.applyFix command twice which fails. This is done by the clangd server so it's not something I can fix in this PR.
https://github.com/microsoft/vscode-languageserver-node/issues/607 and https://github.com/microsoft/vscode-languageserver-node/issues/333 discuss this issue with https://github.com/microsoft/vscode-languageserver-node/issues/333 suggesting to use random UUIDs instead of hardcoded command names but I'm not sure how this would work for clangd.
Given the impact of this change, can you change the version number to 0.2.1 (or another patch number if that's already used) such that it triggers a pre-release version?
have plan to merge this PR? it's an useful function
It does not work yet. Changes have to be made to clangd to make this possible at all.
A couple of thoughts / questions:
-
Does having a multi-root workspace need to imply using a separate clangd instance for each root? I can see use cases where this is desirable, but also other use cases where having the different roots share a single instance is desirable (e.g. to allow navigation between a library and an application that uses it).
-
Are you aware of the previous work on this referenced in https://github.com/clangd/vscode-clangd/issues/498?
Does having a multi-root workspace need to imply using a separate clangd instance for each root? I can see use cases where this is desirable, but also other use cases where having the different roots share a single instance is desirable (e.g. to allow navigation between a library and an application that uses it).
It does not, I reworked this to make the behavior configurable with a new enablePerFolderServer option.
Are you aware of the previous work on this referenced in https://github.com/clangd/vscode-clangd/issues/498?
I am not, this was developed completely separately.
I finally got time to get back to this. Reworked it quite heavily. I introduced a ClangdContextManager class and reworked every feature to handle multiroot workspaces properly. Whether or not multiple instances of clangd are spawned is now configurable per workspace.
@JVApen @HighCommander4 @sam-mccall One remaining thing I need to handle better is all the setContext calls done in the vscode client features which are currently instantiated per instance but modify what is effectively global data so they'll end up conflicting with each other.
InlayHintsFeaturemodifiesclangd.inlayHints.supportedMemoryUsageFeaturemodifiesclangd.memoryUsage.supportedTypeHierarchyFeaturemodifiesclangd.enableTypeHierarchyASTFeaturemodifiesclangd.ast.supported
All of these seem to be there for backwards compat with older clangd versions. Can we by any chance drop these and assume they're all supported?