generated from redhat-developer/new-project-template
-
Notifications
You must be signed in to change notification settings - Fork 28
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Fixes #24 Signed-off-by: azerr <[email protected]>
- Loading branch information
1 parent
6b6e01d
commit 6410051
Showing
4 changed files
with
165 additions
and
3 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,157 @@ | ||
# Getting started | ||
|
||
This section explains step by step how to add your own LSP language server in your IntelliJ plugin. | ||
|
||
## Reference LSP4IJ | ||
|
||
### plugin.xml | ||
|
||
The first step is to reference LSP4IJ. LSP4IJ uses `com.redhat.devtools.lsp4ij` as plugin Id. | ||
|
||
You need [to declare dependency in your plugin.xml](https://plugins.jetbrains.com/docs/intellij/plugin-dependencies.html#3-dependency-declaration-in-pluginxml) like this: | ||
|
||
```xml | ||
<idea-plugin> | ||
... | ||
|
||
<depends>com.redhat.devtools.lsp4ij</depends> | ||
|
||
... | ||
</idea-plugin> | ||
``` | ||
|
||
### Exclude all LSP4J dependencies | ||
|
||
LSP4IJ depends on [Eclipse LSP4J](https://github.com/eclipse-lsp4j/lsp4j) (Java binding for the [Language Server Protocol](https://microsoft.github.io/language-server-protocol) and the [Debug Adapter Protocol](https://microsoft.github.io/debug-adapter-protocol).). It uses a given version of LSPJ and their classes are loaded in the LSP4IJ plugin class loader. | ||
|
||
Your IntelliJ Plugin should use `the same LSP4J classes than LSP4IJ` to avoid some `ClassCastException` errors. To do that you need to `exclude all LSP4J dependencies` from your plugin. | ||
|
||
Here a sample used in [Quarkus Tools](https://github.com/redhat-developer/intellij-quarkus) in [build.gradle.kts](https://github.com/redhat-developer/intellij-quarkus/blob/main/build.gradle.kts) to exclude LSP4J dependency from the [Qute Language Server](https://github.com/redhat-developer/quarkus-ls/tree/master/qute.ls) which have a dependency to LSP4J: | ||
|
||
``` | ||
implementation("com.redhat.microprofile:com.redhat.qute.ls:0.17.0) { | ||
exclude("org.eclipse.lsp4j") | ||
} | ||
``` | ||
|
||
## Declare server | ||
|
||
|
||
### StreamConnectionProvider Implementation | ||
|
||
You need to implement the [StreamConnectionProvider](https://github.com/redhat-developer/lsp4ij/blob/main/src/main/java/com/redhat/devtools/lsp4ij/server/StreamConnectionProvider.java) API which manages: | ||
|
||
* start of your language server | ||
* returns the input/error stream of LSP requests, responses, notifications. | ||
|
||
Generally, the language server is started with a process by using a runtime like Java, NodeJS, etc. In this case you need to extend [ProcessStreamConnectionProvider](https://github.com/redhat-developer/lsp4ij/blob/main/src/main/java/com/redhat/devtools/lsp4ij/server/ProcessStreamConnectionProvider.java) | ||
|
||
Here a basic sample which starts the `path/to/my/language/server/main.js` language server written in JavaScript with NodeJS runtime "path/to/nodejs/node.exe": | ||
|
||
```java | ||
package my.language.server; | ||
|
||
import com.redhat.devtools.lsp4ij.server.ProcessStreamConnectionProvider; | ||
|
||
import java.util.Arrays; | ||
import java.util.List; | ||
|
||
public class MyLanguageServer extends ProcessStreamConnectionProvider { | ||
|
||
public MyLanguageServer() { | ||
List<String> commands = Arrays.asList("path/to/nodejs/node.exe", "path/to/my/language/server/main.js"); | ||
super.setCommands(commands); | ||
} | ||
} | ||
``` | ||
|
||
If your language server is written in Java, to build the command, you can use [JavaProcessCommandBuilder](https://github.com/redhat-developer/lsp4ij/blob/main/src/main/java/com/redhat/devtools/lsp4ij/server/JavaProcessCommandBuilder.java): | ||
|
||
```java | ||
package my.language.server; | ||
|
||
import com.intellij.openapi.project.Project; | ||
import com.redhat.devtools.lsp4ij.server.JavaProcessCommandBuilder; | ||
import com.redhat.devtools.lsp4ij.server.ProcessStreamConnectionProvider; | ||
|
||
import java.util.Arrays; | ||
import java.util.List; | ||
|
||
public class MyLanguageServer extends ProcessStreamConnectionProvider { | ||
|
||
public MyLanguageServer(Project project) { | ||
List<String> commands = new JavaProcessCommandBuilder(project, "myLanguageServerId") | ||
.setJar("path/to/my/language/server/main.java") | ||
.create(); | ||
super.setCommands(commands); | ||
} | ||
} | ||
``` | ||
|
||
This builder takes care of filling command with Java runtime and generate the command with debug if the settings of the language server `myLanguageServerId` defines a debug port. | ||
|
||
You can see a full sample with [QuteServer](https://github.com/redhat-developer/intellij-quarkus/blob/main/src/main/java/com/redhat/devtools/intellij/qute/lsp/QuteServer.java) | ||
|
||
### LanguageClientImpl | ||
|
||
It is not required but you can override the [LanguageClientImpl](https://github.com/redhat-developer/lsp4ij/blob/main/src/main/java/com/redhat/devtools/lsp4ij/client/LanguageClientImpl.java) to for instance: | ||
|
||
* some IJ listeners when language client is created | ||
* override some LSP methods | ||
|
||
```java | ||
package my.language.server; | ||
|
||
import com.intellij.openapi.project.Project; | ||
import com.redhat.devtools.lsp4ij.client.LanguageClientImpl; | ||
|
||
public class MyLanguageClient extends LanguageClientImpl { | ||
public MyLanguageClient(Project project) { | ||
super(project); | ||
} | ||
} | ||
``` | ||
|
||
If your language server manages custom LSP requests, it is advised to extend [IndexAwareLanguageClient](https://github.com/redhat-developer/lsp4ij/blob/main/src/main/java/com/redhat/devtools/lsp4ij/client/IndexAwareLanguageClient.java) | ||
|
||
You can see a full sample with [QuteLanguageClient](https://github.com/redhat-developer/intellij-quarkus/blob/main/src/main/java/com/redhat/devtools/intellij/qute/lsp/QuteLanguageClient.java) | ||
|
||
## Declare server with extension point | ||
|
||
The last step is to declare the server in your plugin.xml to use your `my.language.server.MyLanguageServer` and `my.language.server.MyLanguageClient`: | ||
|
||
``` | ||
<idea-plugin> | ||
<extensions defaultExtensionNs="com.redhat.devtools.lsp4ij"> | ||
<server id="myLanguageServerId" | ||
label="My Language Server" | ||
class="my.language.server.MyLanguageServer" | ||
clientImpl="my.language.server.MyLanguageClient" | ||
scope="project"> | ||
<description><![CDATA[ | ||
Some description written in HTML to display it in LSP consoles and Language Servers settings. | ||
]]> | ||
</description> | ||
</server> | ||
</extensions> | ||
</idea-plugin> | ||
``` | ||
|
||
Once the declaration is done, your server should appear in the LSP console: | ||
|
||
![My LanguageServer in LSP Console](./images/MyLanguageServerInLSPConsole.png) | ||
|
||
## Declare language mapping with extension point | ||
|
||
TODO | ||
* declare mapping | ||
* DocumentMatcher | ||
|
||
## Declare IJ features | ||
|
||
* externalAnnotator, completion, etc are declared an language any with LSP4IJ => nothing to do | ||
* IJ inlayHint, hover doesn't support any language, so you need to declare them in you plugin.xml | ||
|
||
|
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters