Lsp4intellij
This language client library provides language server protocol support for IntelliJ IDEA and other Jetbrains IDEs.
Install / Use
/learn @ballerina-platform/Lsp4intellijREADME
LSP4IntelliJ - Language Server Protocol Support for JetBrains Plugins
LSP4IntelliJ is a client library that enables Language Server Protocol (LSP) support for IntelliJ IDEA and other JetBrains IDEs.
Designed for plugin developers, it facilitates integration with LSP-based features and supports language-specific extensions via the JSON-RPC protocol.
Table of Contents
How to use
Follow the below steps to integrate LSP4IntelliJ into your custom language plugin.
1. Add the lsp4intellij dependency
Include lsp4intellij in your project's build file. Instructions for popular build tools are available at jitpack/lsp4intellij.
Supported build tools:
- Gradle
- Maven
- SBT
Info: Maven Central publishing is a work in progress. Support for Maven Central will be available soon.
2. Add a plugin.xml file
Define the required configurations in your plugin.xml file.
-
Add the following extensions to get the relevant features as listed below.
- Code completion (You can replace the
languageattribute if you already have your own custom language implementations)<extensions defaultExtensionNs="com.intellij"> <completion.contributor implementationClass="org.wso2.lsp4intellij.contributors.LSPCompletionContributor" id="LSPCompletionContributor" language="any"/> </extensions> - Code Formatting
<actions> <action class="org.wso2.lsp4intellij.actions.LSPReformatAction" id="ReformatCode" use-shortcut-of="ReformatCode" overrides="true" text="Reformat Code"/> <action class="org.wso2.lsp4intellij.actions.LSPShowReformatDialogAction" id="ShowReformatFileDialog" use-shortcut-of="ShowReformatFileDialog" overrides="true" text="Show Reformat File Dialog"/> </actions> - Diagnostics and code actions (You can replace the
languageattribute if you already have your own custom language implementations)<extensions defaultExtensionNs="com.intellij"> <externalAnnotator id="LSPAnnotator" language="TEXT" implementationClass="org.wso2.lsp4intellij.contributors.annotator.LSPAnnotator"/> </extensions> - Find Usages
<actions> <action class="org.wso2.lsp4intellij.actions.LSPReferencesAction" id="LSPFindUsages"> <keyboard-shortcut first-keystroke="shift alt F7" keymap="$default"/> </action> </actions> - Workspace symbols
<extensions defaultExtensionNs="com.intellij"> <gotoSymbolContributor implementation="org.wso2.lsp4intellij.contributors.symbol.LSPSymbolContributor" id="LSPSymbolContributor"/> </extensions> - Renaming Support
<extensions defaultExtensionNs="com.intellij"> <renameHandler implementation="org.wso2.lsp4intellij.contributors.rename.LSPRenameHandler" id="LSPRenameHandler" order="first"/> <renamePsiElementProcessor implementation="org.wso2.lsp4intellij.contributors.rename .LSPRenameProcessor" id="LSPRenameProcessor" order="first"/> </extensions> - Signature Help
<extensions defaultExtensionNs="com.intellij"> <typedHandler implementation="org.wso2.lsp4intellij.listeners.LSPTypedHandler" id="LSPTypedHandler"/> </extensions>
- Code completion (You can replace the
</details>Note: You do not need any additional configurations for the other features.
Copy the example plugin.xml file from resources/plugin.xml.example, place it under src/resources/META-INF, and adjust it as needed.
3. Configure preloading activity
Add a preloading activity to initialize and configure LSP support:
public class BallerinaPreloadingActivity extends PreloadingActivity {
@Override
public void preload(ProgressIndicator indicator) {
IntellijLanguageClient.addServerDefinition(new RawCommandServerDefinition("bal", new String[]{"path/to/launcher-script.sh"}));
}
}
Update your plugin.xml to include the preloading activity:
<extensions defaultExtensionNs="com.intellij">
<preloadingActivity implementation="io.ballerina.plugins.idea.preloading.BallerinaPreloadingActivity"
id="io.ballerina.plugins.idea.preloading.BallerinaPreloadingActivity" />
</extensions>
Tip: For other options you can use instead of implementing a preloading activity, go to InteliJ Plugin initialization on startup
4. Confirm language server connection
After successfully connecting to the language server, a green icon will appear in the bottom-right corner of your IDE. Clicking on the icon will display connection details and timeouts.
Alternative ways to connect to a language server
In addition to RawCommandServerDefinition, several classes implement LanguageServerDefinition, allowing you to connect to a language server in different ways. Below are the available options:
1. RawCommandServerDefinition
You can specify multiple extensions for a server by separating them with a comma (e.g., "ts,js").
If you want to bind your language server definition only with a specific set of files, you can use that specific file pattern as a regex expression instead of binding with the file extension (e.g., "application*.properties").
Example Usage:
new RawCommandServerDefinition("bal", new String[]{"path/to/launcher-script.sh"});
String[] command = new String[]{"java", "-jar", "path/to/language-server.jar"};
new RawCommandServerDefinition("bsl,os", command);
2. ProcessBuilderServerDefinition
This definition is an extended form of the RawCommandServerDefinition, which accepts
java.lang.ProcessBuilder instances so that the users will have more controllability over the language
server
process to be created.
You can specify multiple extensions for a server by separating them with a comma (e.g., "ts,js").
If you want to bind your language server definition only with a specific set of files, you can use that specific file pattern as a regex expression instead of binding with the file extension (e.g., "application*.properties").
Example Usage:
ProcessBuilder process = new ProcessBuilder("path/to/launcher-script.sh");
new ProcessBuilderServerDefinition("bal", process);
ProcessBuilder process = new ProcessBuilder("java", "-jar", "path/to/language-server.jar");
new ProcessBuilderServerDefinition("bsl,os", process);
Custom initialization parameters
If your language server requires custom initialization options, you can extend ProcessBuilderServerDefinition or RawCommandServerDefinition and override the customizeInitializeParams method to modify the initialization parameters.
public class MyServerDefinition extends ProcessBuilderServerDefinition {
public MyServerDefinition(String ext, ProcessBuilder process) {
super(ext, process);
}
@Override
public void customizeInitializeParams(InitializeParams params) {
params.clientInfo = new ClientInfo("MyName", "MyVersion");
}
}
Finally, assign your class as a ServerDefinition:
ProcessBuilder process = new ProcessBuilder("path/to/launcher-script.sh
