FurqanSoftware / codemirror-languageserver

Language Server integration for CodeMirror 6
BSD 3-Clause "New" or "Revised" License
183 stars 24 forks source link

Sharing lsp clients between mutliple editors #11

Closed haeck98 closed 2 years ago

haeck98 commented 2 years ago

I'm using this library in a project which implements an online IDE. When I open a Project I also open a Language Server on the server side. Now I'm trying to connect all the open editors to this language server but of course they all open a new connection and therefor open a new language server. This wastes many resources, it would be better to just open one language server.

Is it possible to share the Extension returned by languageServer({...}) between multiple Editor Instances?

haeck98 commented 2 years ago

As I understand this is not yet supported. I had a quick look into the source code and had the following idea:

Maybe the languageServer() function could accept an optional client instance, which it uses to send further requests. This way it would be possible to create a client instance beforehand and share it between multiple Editors. By creating the client instance it sends the 'initialize'-Request and the LanguageServerPlugin then just sends the 'textDocument/didOpen'-Request via the client it receives. If you do not set a client instance for languageServer() call, it just creates a new one, like it is already doing right now.

Would You be open to integrate this feature into the library? Since I need this functionality, I'm willing to contribute to this project and implement the feature I described above.

@hjr265

hjr265 commented 2 years ago

@haeck98 Is this something the Language Server Protocol even supports?

Sorry if I am missing something obvious.

If we are going to allow a client to be passed to the plugin's constructor, we will also have to do the same for transport. Since it is used here: https://github.com/FurqanSoftware/codemirror-languageserver/blob/283b946c6914cb63e12845ce633508a6feeb5310/src/index.ts#L107

haeck98 commented 2 years ago

Hi thanks for your response @hjr265 !

"The protocol currently assumes that one server serves one tool."

As far as I understand, this only refers to the number of connections between a client and a server. One Server can only serve one client. BUT one client can get notifications and send requests for multiple open files. For example consider the following order of notifications and requests a single LSP Client can send to the server:

  1. request "initialize"
  2. notify "textDocument/didOpen" for ./src/file1.ts
  3. notify "textDocument/didOpen" for ./src/file2.ts
  4. notify "textDocument/didOpen" for ./src/file3.ts

Now the client can retrieve information for these three files, e.g. diagnostics, completions, hover, etc..

Knowing this, I propose to strictly separate the LSP client from the LanguageServerPlugin.

I actually started implementing my own library for LSP support in CodeMirror 6, since I actually needed some other features, which are also not implemented here. However, if you are interested I can explain how I managed to share one LSP Client with multiple CodeMirror Editors. But since I already implemented it in my own library, feel free to close the issue.

haeck98 commented 2 years ago

https://github.com/microsoft/language-server-protocol/issues/23

As far as I undestand, this is issue is about connecting multiple clients to a single language server instance, e.g. opening multiple web socket connections to a server which all communicate with one single language server process. This is not possible. However, what I requested was the possiblity to open a single websocket connection and share this single connections between multiple open CodeMirror Editors in a website. The current implementation will open a web socket connection for every open editor in a website and therefor, since one language server can only server one client, requires a separate language server process for every editor in a website.

hjr265 commented 2 years ago

@haeck98 I see what you mean.

Yeah, this is a current limitation of this implementation.

I will eventually have to add support for this as well once I start dealing with multiple co-existing CodeMirror instances at the same time in my project.

haeck98 commented 2 years ago

@hjr265 When my implementation is in a stable state, I will make it publicly available and also publish to npm. If you want, I can share the repository in here, when it is public.

hjr265 commented 2 years ago

@haeck98 Sure, thank you.

hjr265 commented 2 years ago

@haeck98 In the meantime I have added preliminary support for reusing the LSP client across multiple plugin instances.

panchaoco commented 2 years ago

Hello, may I ask this package has been released?

hjr265 commented 2 years ago

@panchaoco Do you mean with the support for reusing LSP clients? Yes.

https://www.npmjs.com/package/codemirror-languageserver