csharp-language-server-protocol icon indicating copy to clipboard operation
csharp-language-server-protocol copied to clipboard

CodeAction capability doesn't work with VS Code LSP client

Open heeko opened this issue 4 years ago • 3 comments

I been trying to get textDocument/codeAction working with VS Code but it's impossible to get any call to that endpoint from vscode with a omnisharp LSP server using handlers. My handler is implementing ICodeActionHandler.

I dig a bit the issue and it seems to came from server capabilities that are not set correctly on the Initialize request. LanguageServer.Handle method for the Initialize request is setting server capabilities based on received client capabilities https://github.com/OmniSharp/csharp-language-server-protocol/blob/4d53a6eccad0826b54d0fe206e5383643c525978/src/Server/LanguageServer.cs#L321

The GetStaticOptions will set the capability to false if the client capability support DynamicRegistration. https://github.com/OmniSharp/csharp-language-server-protocol/blob/4d53a6eccad0826b54d0fe206e5383643c525978/src/Server/ClientCapabilityProvider.cs#L30 That will end up to send capabilities with a codeActionProvider to false to the client, which seems to be the source of the problem. Even if it supposed to dynamic registered VS Code seems to have to receive the codeActionProvider capability to true on initilialization in order to have the codeAction working. I verified my hypothesis by "hacking" the client request on the OnInitialize of my server to skip the dynamic registration thing:

var serverOptions = new LanguageServerOptions()
                .WithInput(stream)
                .WithOutput(stream)
                .WithServices(ConfigureServices)
                .WithHandler<TextDocumentHandler>()
                .OnInitialize((server, request, token) =>
                {
                    request.Capabilities.TextDocument.CodeAction.Value.DynamicRegistration = false;
                    return Task.CompletedTask;
                });

and it's indeed working, and now I receive textDocument/codeAction events from vs code. This also seems to be documented on the vscode side: https://code.visualstudio.com/api/language-extensions/programmatic-language-features#possible-actions-on-errors-or-warnings (under Possible Actions on Errors or Warnings/Language Server Protocol)

Am I missing something about Omnisharp LSP server regarding the management of capabilities or is there an issue here? I always make it worked with just implemented the right interface on my handlers, and thought it was the way to go.

I'm using version 0.17.4, but I also had the issue on 0.15.0.

heeko avatar Aug 13 '20 22:08 heeko

So one of the things the library tries to do is abstract away the need to deal with registration or dynamic registration.

So the goal is that if the client tells the server "I support dynamic registration " then we will never statically register that item. When that happens we usually get a double registration (statically and dynamically), so the easiest way is to only statically register when we see a static registration coming.

Your handler should however be registered dynamically, so my guess is that something is happening there. Do you by chance happen to have the code available anywhere?

You "hack" isn't really a hack, the initialize and initialized handlers are there for for consumers to be able to inject their own first hand knowledge into the bootstrapping process. I still think there is some subtle change that needs to happen.

david-driscoll avatar Aug 20 '20 00:08 david-driscoll

Do you have any example code anywhere that I can look at, to try and determine why this might be happening.

As I sit here thinking about it, if you don't give a DocumentSelector to the registration options... this might be the behavior. I'll see if I can add a test to verify my thought process.

david-driscoll avatar Dec 15 '20 12:12 david-driscoll

Actually can you check one other thing for me?

Based on the spec https://microsoft.github.io/language-server-protocol/specifications/specification-current/#textDocumentRegistrationOptions the document selector is allowed to be null when registering dynamically. Do you have a document selector set on the vscode side?

david-driscoll avatar Dec 15 '20 12:12 david-driscoll