summaryrefslogtreecommitdiff
path: root/docs/lsp.md
blob: 22cf1b907b6a2268b57575220842e1c20451838f (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
# Language intelligence

Native hosts, including detached sessions, run language queries on workers.
Every language, Zig included, goes through the protocol client in
`src/lsp/lsp_client.zig`, which runs its server as a child process: Zig's is
`zls`, which must be on PATH. 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.

## Configuration and testing

`PARDES_LSP_ZIG`, `_RS`, `_C`, `_GO`, `_TS` and `_PY` override the server
executable for each language. An empty value disables that server. `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 lspbench -- probe gd <file> <line>:<column>` queries the same backend from
the command line. `zig build lspbench` measures it. The Zig snapshot tests
(lsp, lspcomplete, lspdebug and the rest) run the real `zls`; the protocol
ones 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.