Open-Source Wikis

/

Helix

/

Packages

/

helix-dap

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 helix-dap-types companion crate (1,050 LOC) defines the protocol types.

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 sessions

Key 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 / stepOut

The 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_adapters is the Registry. Editor::breakpoints is 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

Built by Factory AutoWiki from public repository content. It is a generated preview for codebase exploration, not source-maintained documentation.

helix-dap – Helix wiki | Factory