Skip to content

Latest commit

 

History

History
281 lines (199 loc) · 11 KB

File metadata and controls

281 lines (199 loc) · 11 KB

Developer Guide

This guide walks through integrating lsp4intellij into your custom JetBrains plugin in detail. For the minimum viable integration, see the Quick Start in the README.

Table of Contents


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. Copy the example from resources/plugin.xml.example, place it under src/resources/META-INF, and adjust it as needed.

3. Configure a startup activity

Add a startup activity to initialize and configure LSP support. On IntelliJ 2024.3+, PreloadingActivity is no longer run, so implement ProjectActivity and register it through the postStartupActivity extension point:

public class BallerinaStartupActivity implements ProjectActivity {
    @Nullable
    @Override
    public Object execute(@NotNull Project project, @NotNull Continuation<? super Unit> continuation) {
        IntellijLanguageClient.addServerDefinition(new RawCommandServerDefinition("bal", new String[]{"path/to/launcher-script.sh"}));
        return Unit.INSTANCE;
    }
}

addServerDefinition registers the server application-wide and reconnects any editors that are already open, so running it once per project open is sufficient.

Update your plugin.xml to include the startup activity:

<extensions defaultExtensionNs="com.intellij">
    <postStartupActivity implementation="io.ballerina.plugins.idea.preloading.BallerinaStartupActivity" />
</extensions>

Tip: For other options instead of a startup activity, see IntelliJ Plugin initialization on startup.

4. Confirm the 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.

Green status icon appearing in the IDE's bottom-right corner after the language server connects

Tip: A green icon in the IDE's bottom-right corner indicates a successful connection to the language server. Clicking on the icon will display connection details and timeouts.

Clicking the status icon to open the connection details and timeouts panel


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.

Note: All implementations use stdin/stdout for server communication.

RawCommandServerDefinition

The first argument is a file extension or a comma-separated list of file extensions (e.g., "ts,js"). Matching is based on file extensions only; filename patterns or regex-style values such as "application*.properties" are not supported by this API.

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);

ProcessBuilderServerDefinition

This definition is an extended form of RawCommandServerDefinition that accepts java.lang.ProcessBuilder instances, giving you more control over the language server process.

You can specify one or more file extensions for a server definition. To associate multiple extensions with the same server, separate them with a comma (e.g., "ts,js").

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, extend ProcessBuilderServerDefinition or RawCommandServerDefinition and override the customizeInitializeParams method:

public class MyServerDefinition extends ProcessBuilderServerDefinition {
    public MyServerDefinition(String ext, ProcessBuilder process) {
        super(ext, process);
    }

    @Override
    public void customizeInitializeParams(InitializeParams params) {
        params.setClientInfo(new ClientInfo("MyName", "MyVersion"));
    }
}

Then assign your class as a server definition:

ProcessBuilder process = new ProcessBuilder("path/to/launcher-script.sh");
IntellijLanguageClient.addServerDefinition(new MyServerDefinition("xxx", process));

See #311 for more details.


Configuration

Timeouts

The LSP4IntelliJ language client applies the following default timeouts to LSP requests:

Type Default timeout (ms)
Code Actions 2000
Completion 1000
Goto Definition 2000
Execute Command 2000
Formatting 2000
Hover Support 2000
Initialization 10000
References 2000
Shutdown 5000
WillSave 2000

The client exposes the following methods for inspecting and overriding these values at runtime:

  • getTimeouts() — returns the current timeout values (in milliseconds).

    Map<Timeouts, Integer> timeouts = IntellijLanguageClient.getTimeouts();
  • getTimeout(Timeouts timeoutType) — returns the current timeout value for a given type (in milliseconds).

    int timeout = IntellijLanguageClient.getTimeout(Timeouts.INIT);
  • setTimeouts(Map<Timeouts, Integer> newTimeouts) — overrides the defaults with a given set of timeout values.

    Map<Timeouts, Integer> newTimeouts = new HashMap<>();
    newTimeouts.put(Timeouts.INIT, 15000);
    newTimeouts.put(Timeouts.COMPLETION, 1000);
    IntellijLanguageClient.setTimeouts(newTimeouts);
  • setTimeout(Timeouts timeout, int value) — overrides a single timeout value.

    IntellijLanguageClient.setTimeout(Timeouts.INIT, 15000);

Appendix: Legacy components-based setup

Deprecated: This setup style is no longer recommended. New plugins should use the modern extension-based setup above. This appendix is preserved for older plugins that still use application components.

  1. Add IntellijLanguageClient as an application component:

    <application-components>
        <component>
            <implementation-class>org.wso2.lsp4intellij.IntellijLanguageClient</implementation-class>
        </component>
    </application-components>
  2. Add the following extensions to enable individual features:

    • Code completion (replace the language attribute if you have your own custom language implementation):

      <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 (replace the language attribute if you have your own custom language implementation):

      <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>

Note: No additional configuration is required for the other features.