helix-editor/helix
helix-dap
The Debug Adapter Protocol client. Lets Helix drive any DAP-compliant debugger (lldb-vscode, debugpy, codelldb, etc.). 1,100 lines of Rust. The 1,050 LOC) defines the protocol types.helix-dap-types companion crate (
Purpose
DAP support in Helix is structurally similar to LSP: a child process speaks JSON over stdio (or TCP), Helix sends typed requests, the debug adapter sends typed responses and events. Where LSP exposes language semantics, DAP exposes execution: stack frames, scopes, variables, breakpoints, run control.
Directory layout
helix-dap/src
├── lib.rs # Error type, Result, public re-exports
├── client.rs # Client: spawn process, request/response, threads, frames (~17.5k chars)
├── transport.rs # Async stdio/TCP framing for DAP messages (~10k chars)
└── registry.rs # Registry: per-language-config debug adapter sessionsKey abstractions
| Type | File | Purpose |
|---|---|---|
Client |
client.rs |
Per-debug-session state: child process, request counter, capabilities, thread states, stack frames. |
Registry |
registry.rs |
SlotMap<DebugAdapterId, Client>. The editor talks to clients through this registry. |
Transport |
transport.rs |
Stdio or TCP transport. Reads Content-Length-framed JSON. |
Payload (re-export) |
transport.rs |
Either a request, response, or event. |
DebugAdapterId |
registry.rs |
Slot key in the registry. |
DebugAdapterConfig |
re-exported from helix-core::syntax::config |
TOML configuration of the adapter (command, args, transport). |
DebuggerQuirks |
re-exported from helix-core::syntax::config |
Per-adapter behaviour flags (e.g. some adapters need absolute_paths). |
Re-exports from helix-dap-types |
lib.rs |
All DAP request/response types are re-exported so consumers use helix_dap as dap. |
Lifecycle
sequenceDiagram
participant Editor
participant Reg as Registry
participant Cli as Client
participant Adapter as Debug Adapter (child)
Editor->>Reg: start adapter for "rust"
Reg->>Cli: spawn process (stdio or TCP)
Cli->>Adapter: initialize
Adapter-->>Cli: capabilities
Editor->>Cli: launch / attach
Adapter-->>Cli: initialized event
Editor->>Cli: setBreakpoints (per file)
Editor->>Cli: configurationDone
Adapter-->>Cli: stopped (breakpoint, step, exception)
Cli-->>Editor: emit event → application loop dispatches
Editor->>Cli: stackTrace, scopes, variables
Editor->>Cli: continue / next / stepIn / stepOutThe Application event loop selects over the registry's combined stream, dispatching each Payload in helix-term/src/application.rs::handle_debugger_message. helix-term/src/commands/dap.rs contains the user-visible commands (set breakpoint, edit log point, evaluate, run/continue, step).
startDebugging reverse request
DAP supports a startDebugging reverse request — the debugger asks the editor to spawn a child debug session. This was added in 25.07 and lives in client.rs.
Configuration
Debug adapters are declared in languages.toml as [language.debugger]:
[language.debugger]
name = "lldb-vscode"
transport = "stdio"
command = "lldb-vscode"
[[language.debugger.templates]]
name = "binary"
request = "launch"
completion = [ { name = "binary", completion = "filename" } ]
args = { program = "{0}" }The DebugAdapterConfig in helix-core/src/syntax/config.rs parses these. Templates are surfaced in the :debug-start UI for argument prompting.
Integration points
Editor::debug_adaptersis theRegistry.Editor::breakpointsis the global breakpoint store.- DAP messages flow through
Application::handle_debugger_message. - The DAP-specific UI (variable picker, stack frame picker) is in
helix-term/src/commands/dap.rs. - The DAP gutter (red dot for breakpoints, arrow for the active frame) is in
helix-view/src/gutter.rs.
Entry points for modification
- Adding a new request: extend
Clientinclient.rsfollowing the existing pattern. - Adding a debugger quirk: extend
DebuggerQuirksinhelix-core/src/syntax/config.rsand gate the new behaviour inClient. - Updating DAP types: edit
helix-dap-types/src/lib.rs. - Adding a debugger UI command: see
helix-term/src/commands/dap.rs.
Built by Factory AutoWiki from public repository content. It is a generated preview for codebase exploration, not source-maintained documentation.