# Language intelligence Native hosts, including detached sessions, run language queries on workers. Zig uses the linked ZLS analyser; other languages use the protocol client in `src/lsp/lsp_client.zig`. Web and board builds have no language backend. `Lspinfo` (`SPC l i`) reports backend versions, server state, capabilities, recent timings and errors. `Lspwhy` (`SPC l w`) traces resolution at the cursor. ## Commands | Keys | Action | |---|---| | `gd`, `gD`, `gy`, `gi`, `gr` | Definition, declaration, type, implementation, references | | `SPC l k` | Hover | | `SPC l r` | Rename | | `SPC l a` | Code action | | `SPC l h` | Select references | | `SPC l s`, `SPC l S` | Document and workspace symbols | | `SPC l d`, `SPC l D` | Document and workspace diagnostics | | `]d`, `[d`, `]D`, `[D` | Next, previous, last and first diagnostic | | `=` | Format | | Ctrl-click | Definition | | Insert-mode Tab after `.` | Candidate declarations | | `SPC l c`, `SPC l C` | Incoming and outgoing calls | | `SPC l t`, `SPC l T` | Supertypes and subtypes | A single goto result jumps directly; several results open a reusable search buffer. `n`/`N` select result rows and Enter opens them. Hover opens prose. Locations use one-based `path:line:column` or `path:line:column-endcolumn`. Paths below the requesting pane's directory are relative to that directory; other paths stay absolute. Completion lists declarations and inserts nothing. An unanswered Tab indents only if the cursor has not moved since the request. Multicursor Tab indents without starting a query. Formatting and same-file rename apply as one undo transaction. A workspace rename spanning other files opens a preview; it does not partially apply the rename. The linked Zig analyser resolves current-file references and relative imports, but does not run the build runner to discover dependency modules. ## Configuration and testing `PARDES_LSP_RS`, `_C`, `_GO`, `_TS` and `_PY` override the server executable for each language. An empty value disables that server. `ZIG_LIB_DIR` overrides the stdlib path recorded at build time. `Lspinfo` shows the effective settings. The protocol client keeps one child server per configured language, negotiates position encoding, and handles both push and pull diagnostics. Startup and request waits have deadlines; failed starts back off before retrying. Worker status messages reach the host event queue. `zig build lspprobe -- gd :` queries the same backend from the command line. `zig build lspbench` measures it. Snapshot tests use a Zig mock server with deterministic answers while exercising the real client, including process startup, framing, edits and undo. `zig build fs-test` also checks language-worker delivery in TTY and detached sessions over 9P. ## Ownership `host_io.Lsp.Job` owns copies of the source, path, argument and root. Workers never read the live core. A request ID and pane serial reject obsolete replies; mutating replies also require the original file revision. Restore cancels owned work before replacing the core. Backends implement `query`, `speaks` and `supports` in `src/lsp/`. The first backend supporting the file and query answers; status queries visit all of them. Results are written to the caller's writer. Use `lsp.row` or `spanRow` for locations, `edit` for rename ranges, and `put` for replacement text. Edit records use half-open byte offsets into the request's source snapshot. The core validates the complete response before applying it.