Skip to content

Commit

Permalink
feat: initialize DAP support
Browse files Browse the repository at this point in the history
Signed-off-by: azerr <[email protected]>
  • Loading branch information
angelozerr committed Jan 16, 2025
1 parent 23de6e8 commit 7a07d14
Show file tree
Hide file tree
Showing 62 changed files with 4,694 additions and 38 deletions.
5 changes: 4 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,10 @@
## Description
<!-- Plugin description -->

LSP4IJ is a free and open-source [Language Server protocol (LSP)](https://microsoft.github.io/language-server-protocol/) client compatible with all flavours of IntelliJ.
LSP4IJ is a free and open-source

* [Language Server protocol (LSP)](https://microsoft.github.io/language-server-protocol/) client compatible with all flavours of IntelliJ.
* [Debug Adapter Protocol](https://microsoft.github.io/debug-adapter-protocol/) support with [Debug Adapter Protocol Run/Debug configuration](./docs/dap/DAP.md).

It allows you to integrate any `language server` that communicates with its client via `stdio`:

Expand Down
1 change: 1 addition & 0 deletions build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ dependencies {
implementation("org.zeroturnaround:zt-zip:1.14")
implementation("org.jsoup:jsoup:1.17.1")
implementation("org.eclipse.lsp4j:org.eclipse.lsp4j:$lsp4jVersion")
implementation("org.eclipse.lsp4j:org.eclipse.lsp4j.debug:$lsp4jVersion")
// Required by lsp4j as the version from IJ is incompatible
implementation("com.google.code.gson:gson:2.10.1")
implementation("com.vladsch.flexmark:flexmark:$flexmarkVersion")
Expand Down
28 changes: 28 additions & 0 deletions docs/dap/DAP.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# Debug Adapter Protocol

LSP4IJ provides [Debug Adapter Protocol](https://microsoft.github.io/debug-adapter-protocol/) support
with the `Debug Adapter Protocol` run/debug configuration type:

![DAP Configuration Type](./images/DAP_config_type.png)

After configuring the [DAP configuration type](#dap-configuration-type), you can debug your file.
Here is an example with `JavaScript debugging`, which uses the [VSCode JS Debug DAP server](./user-defined-dap/vscode-js-debug.md):

![DAP Configuration Type](./images/DAP_vscode_js_debug_overview.png)

## DAP Configuration Type:

To configure debugging with DAP, you need to fill in:

- The `Configuration` tab to specify the working directory and the file you want to run/debug:

![DAP Configuration Type/Configuration](./images/DAP_config_type_program.png)

- The `Server` tab to specify the DAP server:

![DAP Configuration Type/Server](./images/DAP_config_type_server.png)

## Templates

- [VSCode JS Debug DAP Server](./user-defined-dap/vscode-js-debug.md)
[Swift DAP Server](./user-defined-dap/swift-lldb.md)
Binary file added docs/dap/images/DAP_config_type.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/dap/images/DAP_config_type_program.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/dap/images/DAP_config_type_server.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/dap/images/DAP_vscode_js_debug_overview.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/dap/images/vscode-js-debug_console.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/dap/images/vscode-js-debug_template.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/dap/images/vscode-js-debug_threads.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Empty file.
96 changes: 96 additions & 0 deletions docs/dap/user-defined-dap/vscode-js-debug.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
# VSCode JS Debug

To debug JavaScript or TypeScript files, you can use the [VSCode JS Debug](https://github.com/microsoft/vscode-js-debug) DAP server.

Example: debugging the `test.js` file:

```js
const s = "foo";
console.log(s);
```

![Set Breakpoint](../images/vscode-js-debug_set_breakpoint.png)

## Configure DAP server

1. Download the `js-debug-dap-v*.tar.gz` asset from the [VSCode JS Debug releases](https://github.com/microsoft/vscode-js-debug/releases).
For example, download [js-debug-dap-v1.96.0.tar.gz](https://github.com/microsoft/vscode-js-debug/releases/download/v1.96.0/js-debug-dap-v1.96.0.tar.gz), which is the latest version at the time of writing.

2. Extract the archive into any folder (e.g., `/home/path/to/dap`). The extracted folder should contain the DAP server at `/js-debug/src/dapDebugServer.js`.

3. Create a DAP Run/Debug configuration:

![DAP Configuration Type](../images/DAP_config_type.png)

4. In the `Server` tab, select `VSCode JS Debug`. This will automatically populate the name, command, and DAP parameters:

![DAP Configuration Type/Program](../images/vscode-js-debug_template.png)

The command should look like this:

```
node ${BASE_DIR}/js-debug/src/dapDebugServer.js ${port}
```

Replace `${BASE_DIR}` with the directory where you extracted the DAP server. For example:

```
node /home/path/to/dap/js-debug/src/dapDebugServer.js ${port}
```

- The `${port}` argument will be replaced with a free port when the run configuration starts.
- The (wait for) trace `Debug server listening at` indicates when the DAP client can connect to the DAP server.
This trace will appear in the console as follows:

```
node /home/path/to/dap/js-debug-dap-v1.96.0/js-debug/src/dapDebugServer.js 56425
Debug server listening at 127.0.0.1:56425
```

5. enable server trace

## Configure file mappings

TODO

## Configure the JavaScript file to run/debug

1. Fill in the `Configuration` tab to specify the `working directory` (usually the project's root directory)
and the path to the `test.js` file.
2. Select `Launch` as debugging type.
2. The DAP parameters of the launch should look like this:

```json
{
"type": "pwa-node",
"request": "launch",
"program": "${file}",
"cwd": "${workspaceFolder}"
}
```

When the run configuration starts:

- `${workspaceFolder}` will be replaced with the working directory you specified.
- `${file}` will be replaced with the full path to `test.js`.

## Set Breakpoint

After applying the run configuration, you should set a breakpoint to files which matches file mappings.
Set a breakpoint in the `test.js` file:

![Set Breakpoint](../images/vscode-js-debug_set_breakpoint.png)

# Debugging

You can start the run configuration in either Run or Debug mode. Once started, you should see DAP traces in the console:

![Debugging / Console](../images/vscode-js-debug_console.png)

You will also see `Threads` and `Variables`:

![Debugging / Threads](../images/vscode-js-debug_threads.png)

## Configure the TypeScript file to run/debug

TODO : how to configure source maps?
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,8 @@ public class LSPConsoleView extends ConsoleViewImpl {

private final LanguageServerDefinition serverDefinition;

public LSPConsoleView(@NotNull LanguageServerDefinition serverDefinition, @NotNull Project project,
public LSPConsoleView(@NotNull LanguageServerDefinition serverDefinition,
@NotNull Project project,
@NotNull GlobalSearchScope searchScope,
boolean viewer,
boolean usePredefinedMessageFilter) {
Expand All @@ -47,7 +48,7 @@ public LSPConsoleView(@NotNull LanguageServerDefinition serverDefinition, @NotNu

@Override
public AnAction @NotNull [] createConsoleActions() {
// Don't call super.createConsoleActions() to avoid having some action action like previous occurrence that we don't need.
// Don't call super.createConsoleActions() to avoid having some action like previous occurrence that we don't need.
List<AnAction> consoleActions = new ArrayList<>();
consoleActions.add(new AutoFoldingAction(getEditor()));
consoleActions.add(new ScrollToTheEndToolbarAction(getEditor()));
Expand Down
42 changes: 42 additions & 0 deletions src/main/java/com/redhat/devtools/lsp4ij/dap/DAPBundle.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
/*******************************************************************************
* Copyright (c) 2025 Red Hat, Inc.
* Distributed under license by Red Hat, Inc. All rights reserved.
* This program is made available under the terms of the
* Eclipse Public License v2.0 which accompanies this distribution,
* and is available at http://www.eclipse.org/legal/epl-v20.html
*
* Contributors:
* Red Hat, Inc. - initial API and implementation
******************************************************************************/
package com.redhat.devtools.lsp4ij.dap;

import com.intellij.DynamicBundle;
import org.jetbrains.annotations.Nls;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.PropertyKey;

import java.util.function.Supplier;

/**
* Debug Adapter Protocol (DAP) messages bundle.
*/
public final class DAPBundle extends DynamicBundle {

@NonNls public static final String BUNDLE = "messages.DAPBundle";
private static final DAPBundle INSTANCE = new DAPBundle();

private DAPBundle() {
super(BUNDLE);
}

@NotNull
public static @Nls String message(@NotNull @PropertyKey(resourceBundle = BUNDLE) String key, Object @NotNull ... params) {
return INSTANCE.getMessage(key, params);
}

@NotNull
public static Supplier<@Nls String> messagePointer(@NotNull @PropertyKey(resourceBundle = BUNDLE) String key, Object @NotNull ... params) {
return INSTANCE.getLazyMessage(key, params);
}
}
Loading

0 comments on commit 7a07d14

Please sign in to comment.