extensions: Yet another PR for debugger touchups (#32822)
We'll now clean up DAP locators for unloaded extensions and load schemas proper I can now load a custom Ruby extensions with all bells and whistles and use it as my debugger. Release Notes: - N/A
This commit is contained in:
parent
d92d52b508
commit
0e794fa0ac
14 changed files with 262 additions and 45 deletions
|
@ -63,6 +63,7 @@
|
|||
- [Installing Extensions](./extensions/installing-extensions.md)
|
||||
- [Developing Extensions](./extensions/developing-extensions.md)
|
||||
- [Language Extensions](./extensions/languages.md)
|
||||
- [Debugger Extensions](./extensions/debugger-extensions.md)
|
||||
- [Theme Extensions](./extensions/themes.md)
|
||||
- [Icon Theme Extensions](./extensions/icon-themes.md)
|
||||
- [Slash Command Extensions](./extensions/slash-commands.md)
|
||||
|
|
|
@ -29,6 +29,8 @@ Zed supports a variety of debug adapters for different programming languages out
|
|||
|
||||
These adapters enable Zed to provide a consistent debugging experience across multiple languages while leveraging the specific features and capabilities of each debugger.
|
||||
|
||||
> Is your desired debugger not listed? You can contribute by adding support for your favorite language or debugger. Check out our [debugger extensions](extensions/debugger-extensions.md) documentation for more information.
|
||||
|
||||
## Getting Started
|
||||
|
||||
For basic debugging, you can set up a new configuration by opening the `New Session Modal` either via the `debugger: start` (default: f4) or by clicking the plus icon at the top right of the debug panel.
|
||||
|
|
|
@ -5,6 +5,7 @@ Zed lets you add new functionality using user-defined extensions.
|
|||
- [Installing Extensions](./extensions/installing-extensions.md)
|
||||
- [Developing Extensions](./extensions/developing-extensions.md)
|
||||
- [Developing Language Extensions](./extensions/languages.md)
|
||||
- [Developing Debugger Extensions](./extensions/debugger-extensions.md)
|
||||
- [Developing Themes](./extensions/themes.md)
|
||||
- [Developing Icon Themes](./extensions/icon-themes.md)
|
||||
- [Developing Slash Commands](./extensions/slash-commands.md)
|
||||
|
|
117
docs/src/extensions/debugger-extensions.md
Normal file
117
docs/src/extensions/debugger-extensions.md
Normal file
|
@ -0,0 +1,117 @@
|
|||
# Debugger Extensions
|
||||
|
||||
[Debug Adapter Protocol](https://microsoft.github.io/debug-adapter-protocol) Servers can be exposed as extensions for use in the [debugger](../debugger.md).
|
||||
|
||||
## Defining Debugger Extensions
|
||||
|
||||
A given extension may provide one or more DAP servers.
|
||||
Each DAP server must be registered in the `extension.toml`:
|
||||
|
||||
```toml
|
||||
[debug-adapters.my-debug-adapter]
|
||||
# Optional relative path to the JSON schema for the debug adapter configuration schema. Defaults to `debug_adapter_schemas/$DEBUG_ADAPTER_NAME_ID.json`.
|
||||
# Note that while this field is optional, a schema is mandatory.
|
||||
schema_path = "relative/path/to/schema.json"
|
||||
```
|
||||
|
||||
Then, in the Rust code for your extension, implement the `get_dap_binary` method on your extension:
|
||||
|
||||
```rust
|
||||
impl zed::Extension for MyExtension {
|
||||
fn get_dap_binary(
|
||||
&mut self,
|
||||
adapter_name: String,
|
||||
config: DebugTaskDefinition,
|
||||
user_provided_debug_adapter_path: Option<String>,
|
||||
worktree: &Worktree,
|
||||
) -> Result<DebugAdapterBinary, String>;
|
||||
}
|
||||
```
|
||||
|
||||
This method should return the command to start up a debug adapter protocol server, along with any arguments or environment variables necessary for it to function.
|
||||
|
||||
If you need to download the DAP server from an external source—like GitHub Releases or npm—you can also do that in this function. Make sure to check for updates only periodically, as this function is called whenever a user spawns a new debug session with your debug adapter.
|
||||
|
||||
You must also implement `dap_request_kind`. This function is used to determine whether a given debug scenario will _launch_ a new debuggee or _attach_ to an existing one.
|
||||
We also use it to determine that a given debug scenario requires running a _locator_.
|
||||
|
||||
```rust
|
||||
impl zed::Extension for MyExtension {
|
||||
fn dap_request_kind(
|
||||
&mut self,
|
||||
_adapter_name: String,
|
||||
_config: Value,
|
||||
) -> Result<StartDebuggingRequestArgumentsRequest, String>;
|
||||
}
|
||||
```
|
||||
|
||||
These two functions are sufficient to expose your debug adapter in `debug.json`-based user workflows, but you should strongly consider implementing `dap_config_to_scenario` as well.
|
||||
|
||||
```rust
|
||||
impl zed::Extension for MyExtension {
|
||||
fn dap_config_to_scenario(
|
||||
&mut self,
|
||||
_adapter_name: DebugConfig,
|
||||
) -> Result<DebugScenario, String>;
|
||||
}
|
||||
```
|
||||
|
||||
`dap_config_to_scenario` is used when the user spawns a session via new session modal UI. At a high level, it takes a generic debug configuration (that isn't specific to any
|
||||
debug adapter) and tries to turn it into a concrete debug scenario for your adapter.
|
||||
Put another way, it is supposed to answer the question: "Given a program, a list of arguments, current working directory and environment variables, what would the configuration for spawning this debug adapter look like?".
|
||||
|
||||
## Defining Debug Locators
|
||||
|
||||
Zed offers an automatic way to create debug scenarios with _debug locators_.
|
||||
A locator locates the debug target and figures out how to spawn a debug session for it. Thanks to locators, we can automatically convert existing user tasks (e.g. `cargo run`) and convert them into debug scenarios (e.g. `cargo build` followed by spawning a debugger with `target/debug/my_program` as the program to debug).
|
||||
|
||||
> Your extension can define it's own debug locators even if it does not expose a debug adapter. We strongly recommend doing so when your extension already exposes language tasks, as it allows users to spawn a debug session without having to manually configure the debug adapter.
|
||||
|
||||
Locators can (but don't have to) be agnostic to the debug adapter they are used with. They are simply responsible for locating the debug target and figuring out how to spawn a debug session for it. This allows for a more flexible and extensible debugging experience.
|
||||
|
||||
Your extension can define one or more debug locators. Each debug locator must be registered in the `extension.toml`:
|
||||
|
||||
```toml
|
||||
[debug-locators.my-debug-locator]
|
||||
```
|
||||
|
||||
Locators have two components.
|
||||
First, each locator is ran on each available task to figure out if any of the available locators can provide a debug scenario for a given task. This is done by calling `dap_locator_create_scenario`.
|
||||
|
||||
```rust
|
||||
impl zed::Extension for MyExtension {
|
||||
fn dap_locator_create_scenario(
|
||||
&mut self,
|
||||
_locator_name: String,
|
||||
_build_task: TaskTemplate,
|
||||
_resolved_label: String,
|
||||
_debug_adapter_name: String,
|
||||
) -> Option<DebugScenario>;
|
||||
}
|
||||
```
|
||||
|
||||
This function should return `Some` debug scenario when that scenario defines a debugging counterpart to a given user task.
|
||||
Note that a `DebugScenario` can include a [build task](../debugger.md#build-tasks). If there is one, we will execute `run_dap_locator` after a build task is finished successfully.
|
||||
|
||||
```rust
|
||||
impl zed::Extension for MyExtension {
|
||||
fn run_dap_locator(
|
||||
&mut self,
|
||||
_locator_name: String,
|
||||
_build_task: TaskTemplate,
|
||||
) -> Result<DebugRequest, String>;
|
||||
}
|
||||
```
|
||||
|
||||
`run_dap_locator` is useful in case you cannot determine a build target deterministically. Some build systems may produce artifacts whose names are not known up-front.
|
||||
Note however that you do _not_ need to go through a 2-phase resolution; if you can determine the full debug configuration with just `dap_locator_create_scenario`, you can omit `build` property on a returned `DebugScenario`. Please also note that your locator **will be** called with tasks it's unlikely to accept; thus you should take some effort to return `None` early before performing any expensive operations.
|
||||
|
||||
## Available Extensions
|
||||
|
||||
Check out all the DAP servers that have already been exposed as extensions [on Zed's site](https://zed.dev/extensions?filter=debug-adapters).
|
||||
|
||||
We recommend taking a look at their repositories as a way to understand how they are generally created and structured.
|
||||
|
||||
## Testing
|
||||
|
||||
To test your new Debug Adapter Protocol server extension, you can [install it as a dev extension](./developing-extensions.md#developing-an-extension-locally).
|
|
@ -5,6 +5,7 @@
|
|||
Extensions can add the following capabilities to Zed:
|
||||
|
||||
- [Languages](./languages.md)
|
||||
- [Debuggers](./debugger-extensions.md)
|
||||
- [Themes](./themes.md)
|
||||
- [Icon Themes](./icon-themes.md)
|
||||
- [Slash Commands](./slash-commands.md)
|
||||
|
|
|
@ -27,6 +27,7 @@ line_comments = ["# "]
|
|||
- `tab_size` defines the indentation/tab size used for this language (default is `4`).
|
||||
- `hard_tabs` whether to indent with tabs (`true`) or spaces (`false`, the default).
|
||||
- `first_line_pattern` is a regular expression, that in addition to `path_suffixes` (above) or `file_types` in settings can be used to match files which should use this language. For example Zed uses this to identify Shell Scripts by matching the [shebangs lines](https://github.com/zed-industries/zed/blob/main/crates/languages/src/bash/config.toml) in the first line of a script.
|
||||
- `debuggers` is an array of strings that are used to identify debuggers in the language. When launching a debugger's `New Process Modal`, Zed will order available debuggers by the order of entries in this array.
|
||||
|
||||
<!--
|
||||
TBD: Document `language_name/config.toml` keys
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue