eclipse-che / che

Kubernetes based Cloud Development Environments for Enterprise Teams
http://eclipse.org/che
Eclipse Public License 2.0
6.99k stars 1.19k forks source link

LSP client wrapper for Theia #11468

Closed l0rd closed 5 years ago

l0rd commented 6 years ago

Description

This issue is about implementing a wrapper (in the form of a npm library) that allows using VSCode language client to support both Theia and VSCode language servers.

The Theia library will be published on npmjs registry

How it works:

For a LS in the form of a VScode extension --> call vscode-language-client --> call vscode API --> mapping to Theia API

For a LS in the form of a Theia plugin --> call to theia-to-vscode-wrapper --> call vscode-language-client --> call vscode API --> mapping to Theia API

tsmaeder commented 6 years ago

I don't really understand what the deliverable is here. Can you explain? Also a LS in the form of a VSCode plugin should be able to run as a VSCode plugin unchanged, no? Nothing to do.

l0rd commented 6 years ago

My understanding is that there wouldn't be anything to do if we supported LS in the form of VSCode plugins only (we could use VS Code language client). But we want to support LS in the form of Theia plugin too. So we need a library that handles that second case transparently.

@benoitf am I right? Do you want to add something to that issue description?

tsmaeder commented 6 years ago

@l0rd @benoitf I think there is nothing preventing us from using vscode-language-client in a Theia plugin. After all it's just binding code for hooking up a remote process to the vscode language support plugin api (like "registerReferencesProvider".

benoitf commented 6 years ago

@l0rd you're correct. The idea is to map what is required for LSP on top of Theia API. It could reuse some part of vscode langage client but it shouldn't use any of vscode namespace. This namespace is not owned by US and may change at any time.

besides the vscode namespace is only provided to VSCode extensions, in a theia plugin you never see any "vscode namespace" so I think description for theia plug-in should be adjusted to

For a LS in the form of a Theia plugin
--> call @theia/language-client
--> call Theia API

Also some stuff might be supported only in a Theia context and not in VS code.

tsmaeder commented 6 years ago

Well, if I understand correctly, we're passing the theia API as the vscode api to VSCode plugins, so if they are not compatibly, we would crash? My approach currently is to create our own 'vscode.ts' module that contains enough vscode API to make the vscode language server lib work.

tsmaeder commented 6 years ago

But I think, the whole thing is much more simple, actually. In Theia, language server back end and front end contributions are already separate, so Theia know how to hook up the messages from a language server to the UI (code completion, etc.). So all we need is a plugin API for running a language server and hooking up the appropriate streams. I guess we'd have to set up some tunneling over the plugin API?

benoitf commented 6 years ago

if library is not complex, then yes it can be added to the plugin's API and it will be much more easier then to write LSP for theia.(no external dependency)

BTW I think we really need a LSP example for theia like https://github.com/Microsoft/vscode-extension-samples/tree/master/lsp-sample

tsmaeder commented 6 years ago

To me, the simplest thing to do here is to make the back-end extension point usable as a plugin:

export interface LanguageServerContribution extends LanguageContribution {
    start(clientConnection: IConnection): void;
}

For that, we'd have to provide:

registerLanguageServerContribution(LanguageServerContribution)

However, one problem I see is that we have to tunnel the "IConnection" we get from the start method through the plugin API connection. Otherwise, we'd have to be able to open a second connection between the "back end" and the container running the plugin.

benoitf commented 6 years ago

Hello, few questions:

tsmaeder commented 6 years ago

@benoitf my suggestion is a conceptual one, not literal. Changes are left as an exercise to the reader.

tsmaeder commented 6 years ago

I think this task consists of the following tasks:

  1. Create a way to dynamically add LanguageClientContribution instances (based on BaseLanguageClientContribution) in addition to doing it via dependency injection. We'd have to change the mechanism of dependency injection to only be one method of adding a languag client contribution
  2. Create a plugin API: languageServers.registerLanguageServerContribution(contribution). This should not be in the same namespace as the languages API, since it is basically a second way to achieve the same thing.
  3. When someone calls "registerLanguageServerContribution" on the plugin API, we need to register a LanguageClientContribution that will establish a IConnection to the plugin and call start(IConnection) on the "languageServerContribution" in the plugin process when it is activated.
  4. Let's assume we have the method "start(IConnection)" on the LanguageServerContribution plugin API. When Theia wants to call this API, it needs to create a IConnection instance that tunnels through the plugin API.
svor commented 5 years ago

Related PR https://github.com/theia-ide/theia/pull/3805