multilspy icon indicating copy to clipboard operation
multilspy copied to clipboard

Support for diagnostics

Open cotttho opened this issue 1 year ago • 5 comments

What would it take to support diagnostics?

cotttho avatar Dec 06 '24 21:12 cotttho

@cotttho Could you elaborate? Am working on a few nascent PRs right now - so I might be able to include your request if it's not too much heavy lifting.

themichaelusa avatar Dec 09 '24 22:12 themichaelusa

I am interested in using multilspy to retrieve diagnostic information from different language servers, but the diagnostics LSP API is not currently supported.

cotttho avatar Dec 10 '24 01:12 cotttho

Gotcha. I'll look into it sometime this week and get back to you.

themichaelusa avatar Dec 10 '24 02:12 themichaelusa

Hi @cotttho and @themichaelusa ,

I believe it should not be difficult to add support for diagnostics. Do you have a specific usecase in mind that you can contribute as a unittest?

multilspy internally uses a LanguageServerHandler (https://github.com/microsoft/multilspy/blob/main/src/multilspy/lsp_protocol_handler/server.py#L142) class, that supports the full LSP protocol (even the APIs not supported at the multilspy level). One hacky way to get diagnostics working (and this is actually how I got the first version of all currently supported multilspy apis to work), before we integrate it as a first-class API in multilspy is as follows:

  1. Create a multilspy lsp object and start the corresponding server that support diagnostics (for example Eclipse JDTLS)
lsp = LanguageServer.create(...)
async with lsp.start_server():
    result = await ...
  1. lsp.server is an object of type LanguageServerHandler that defines the send and notify methods, the 2 methods that clients use to communicate with the language server. Internally, multilspy uses the send and notify methods to invoke the LSP APIs. For example, the request_definition method of multilspy internally uses self.server.send.definition (https://github.com/microsoft/multilspy/blob/9cb1e5283b8e9883085e2057d60add717a66e8ec/src/multilspy/language_server.py#L364). Once you have a LanguageServer object with a running server (via start_server), you can invoke ALL lsp APIs simply by doing:
    result = await lsp.server.send.<API name like definition/references/completion etc>(<args to be passed>)
    
    In your case, you will invoke lsp.server.send.text_document_diagnostic or lsp.server.send.workspace_diagnostic (https://github.com/microsoft/multilspy/blob/9cb1e5283b8e9883085e2057d60add717a66e8ec/src/multilspy/lsp_protocol_handler/lsp_requests.py#L244-L258) with appropriate arguments (https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#documentDiagnosticParams or https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#workspaceDiagnosticParams).

Once you are able to get a version of diagnostic working with the underlying API, I would be glad if you could share your script, and we could implement first-class support for it in multilspy. I would be glad if you could actually PR this.

I would be glad to help with any part of the implementation process, or detail any more steps/help debug anything.

LakshyAAAgrawal avatar Dec 12 '24 22:12 LakshyAAAgrawal

Another note: LSP supports diagnostics in 2 modes:

  1. The server notifys the client whenever there is a diagnostic.
  2. The client requests the server when it wants diagnostics

We can discuss what would be a better way and which to integrate into multilspy (both?). The second approach seems more closer to the rest of the APIs (request -> response), which is what I shared the steps above for.

LakshyAAAgrawal avatar Dec 12 '24 22:12 LakshyAAAgrawal