This tutorial describes how the define an language server integration for the Eclipse IDE
1. Developing with a language server
The Language Server Protocol (LSP) defines the protocol used between an editor or IDE and a language server. The language server provides language features like auto complete, go to definition, find all references etc. To learn about the language server protocol see https://github.com/Microsoft/language-server-protocol and https://microsoft.github.io/language-server-protocol/specification
LSP4J (Language Server Protocol for Java) is an Eclipse project which provides Java bindings for the Language Server Protocol. The LSP is based on an extended version of JSON RPC v2.0, for which LSP4J provides a Java implementation. Therefore, we are able to use it to create a language server without having to deal with the JSON specifics of the LSP and instead create endpoints for which we are given parameters from the client and return the required actions in object form based on which message our server receives.
The Eclipse LSP4E provides technologies to simplify the integration of language servers into the Eclipse IDE.
1.1. Required dependencies
For a server with Java bindings you need:
-
org.eclipse.lsp4j
-
org.eclipse.lsp4j.jsonrpc
For an Eclipse client you need:
-
org.eclipse.lsp4e
2. Exercise: Dart LanguageServer implementation
In this exercise you will implement a runnable extension that adds Language Server features like auto completion and problem highlighting for the Dart programming language.
The Dart SDK contains a fully fledged implementation of the language server protocol for the Dart language. You can install it by installing at least the Dart SDK 2.2.
2.1. Install the LSP4E project
Use the p2 repository from https://download.eclipse.org/lsp4e/releases/latest/ to install the lsp4e
package and its dependencies.
Install the package org.eclipse.lsp4j
and Language Server Protocol client for Eclipse IDE (Incubation) Source
.
This will give enough functionality to add the language server features to your plug-in.
2.2. Setting up the language server
Create a new plug-in project.
Name it com.vogella.dartlanguageserver
.
No template is required.
2.2.1. Adding the necessary dependencies
Once the project has then been created, open the MANIFEST.MF
file in the META-INF
folder of your project.
Click on the Extensions tab to add the necessary extension points.
The list of available extensions will be empty at first.
To fix this uncheck the Show only extension points from the required plugins checkbox.
This will give you the ability to choose from all available extension points.
Filter and choose the extension org.eclipse.core.contenttype.contentTypes
from the list and click Finish.
Since you don’t declare the dependency on the required plug-in there will be a pop-up shown.
Click Yes.
This will add the missing dependency to your plug-in.
Repeat this process for the extensions
-
org.eclipse.ui.editors
-
org.eclipse.lsp4e.languageServer
.
Your list of extensions should now look like this:
2.2.2. Define content-type and associate it with generic editor
Now that you added the extension points these need be configured.
First you will need to add a content type.
Right Click on org.eclipse.core.contenttype.contentTypes
, select .
Field | Value | Description |
---|---|---|
|
|
An id that identifies your contentType for later references. |
|
Dart Language Server |
Some name for the contentType. |
|
|
The base type of the contentType. |
|
|
The files this contentType should be registered to. In this case |
Next you will need an editorContentBinding
.
Right click on org.eclipse.ui.editors
and select .
Fill in the following data:
Field | Value | Description |
---|---|---|
|
|
This is the id of the contentType you created earlier. |
|
|
This is the id of the Generic Editor. |
This will associate any .dart
file with the generic editor.
2.3. Define the language server and associate with your content-type
Now define your language server implementation via the org.eclipse.lsp4e.languageServer
extension
If you get the warning "No schema found for the 'org.eclipse.lsp4e.languageserver' extension point", check if you have installed the Language Server Protocol client for Eclipse IDE (Incubation) Source package. |
Field | Value | Description |
---|---|---|
|
|
The class which will initialize the language server |
|
|
A unique id that identifies your server. Useful if you want to add multiple servers. |
|
|
The label for the server |
The class field points to a class that implements StreamConnectionProvider .
You will add that in the next step.
|
Now associate the defined server
with your contentType
via the contentTypeMapping
property.
Field | Value | Description |
---|---|---|
|
|
The contentType you created earlier |
|
|
The id of the language server from the step above |
2.3.1. Configuring the language server
Now you need to supply the class that handles the lifecycle of the language server, the StreamConnectionProvider
.
Create the class com.vogella.dartlanguageserver.DartStreamConnectionProvider
.
This is the class you referenced in the server
extension point above.
package com.vogella.dartlanguageserver;
import java.util.ArrayList;
import java.util.List;
import org.eclipse.lsp4e.server.ProcessStreamConnectionProvider;
import org.eclipse.lsp4e.server.StreamConnectionProvider;
public class DartStreamConnectionProvider extends ProcessStreamConnectionProvider implements StreamConnectionProvider{
public DartStreamConnectionProvider() {
String dartSdkLocation = "/usr/lib/dart"; (1)
List<String> commands = new ArrayList<>();
commands.add(dartSdkLocation + "/bin/dart");
commands.add(dartSdkLocation + "/bin/snapshots/analysis_server.dart.snapshot");
commands.add("--lsp"); (2)
setCommands(commands);
setWorkingDirectory(System.getProperty("user.dir"));
}
}
1 | The Dart SDK location.
This might be different on your OS and depends on the way how you installed the Dart SDK.
To find the exact location use the $ which dart command. |
2 | This tells the Dart analysis server to start in "lsp" mode |
2.4. Check the implementation
The resulting plugin.xml should look like the following:
<?xml version="1.0" encoding="UTF-8"?>
<?eclipse version="3.4"?>
<plugin>
<extension
point="org.eclipse.core.contenttype.contentTypes">
<content-type
base-type="org.eclipse.core.runtime.text"
file-extensions="dart"
id="com.vogella.dartlanguageserver"
name="Dart Language Server"
priority="normal">
</content-type>
</extension>
<extension
point="org.eclipse.ui.editors">
<editorContentTypeBinding
contentTypeId="com.vogella.dartlanguageserver"
editorId="org.eclipse.ui.genericeditor.GenericEditor">
</editorContentTypeBinding>
</extension>
<extension
point="org.eclipse.lsp4e.languageServer">
<server
class="com.vogella.dartlanguageserver.DartStreamConnectionProvider"
id="com.vogella.dartlanguageserver.server"
label="com.vogella.dartlanguageserver.server">
</server>
<contentTypeMapping
contentType="com.vogella.dartlanguageserver"
id="com.vogella.dartlanguageserver.server">
</contentTypeMapping>
</extension>
</plugin>
2.4.1. Testing the language server
If everything went well, you should now be able to get content assist and problem highlighting in your eclipse runtime for dart files.
To test this, right click on your project and select
.Ensure your run configuration also includes org.eclipse.ui.genericeditor
.
One way of ensuring this is to add it as Dependency
to your com.vogella.dartlanguageserver
plug-in.
Alternatively, you can modify the runtime configuration.
Create a new project in the newly started instance and add a file named test.dart
in the project.
Open it and write Dart code.
void main() {
print('Hello, World!');
}
If the file doesn’t open in the Generic Editor, you don’t get code completion or no problem highlighting, check the console log in the host eclipse instance for errors. |
3. Exercise: Dart Syntax Highlighting
The Eclipse project TM4E adds syntax highlighting capabilities to the Eclipse IDE. Using special "grammar" files that define the colors and words used by your language it can display code with the proper syntax highlight.
3.1. Getting Started using TM4E
The easiest way to get started is by adding the update site of the project: https://download.eclipse.org/tm4e/snapshots/. Add it to your eclipse installation center and install the following plugins:
-
TextMate Core
-
TextMate Core Developer Resources
3.2. Configuring the Extensions
Open the MANIFEST.MF
file in the META-INF
folder.
Navigate to the Extensions
tab and click on Add.
Again, uncheck Show only extension points from the required plugins.
Add the following extension points:
-
org.eclipse.tm4e.registry.grammars
-
org.eclipse.tm4e.languageconfiguration.languageConfigurations