summaryrefslogtreecommitdiff
path: root/test/snapshots/lsp-client.snap
diff options
context:
space:
mode:
authorGabriel Schneider <[email protected]>2026-09-01 09:23:53 -0300
committerGabriel Schneider <[email protected]>2026-09-01 11:24:12 -0300
commitae9325a5cb128d0d952afb8f9feaaca68e5e37a2 (patch)
tree9ae44ac38f7b71edfe2882d0a882dbc61304ec80 /test/snapshots/lsp-client.snap
parent848ad99fa597387a85f75e752dc4c9e10f8c24f4 (diff)
downloadpardes-ae9325a5cb128d0d952afb8f9feaaca68e5e37a2.tar.gz
pardes-ae9325a5cb128d0d952afb8f9feaaca68e5e37a2.zip
lsp: a protocol client for every other language, narrated on the message row
The seam grows a second backend: src/lsp/lsp_client.zig speaks JSON-RPC to child language servers — rust-analyzer, clangd, gopls, tsserver, pyright are rows in a spec table — while the in-process ZLS analyser keeps .zig. One reader thread per server owns the socket, routes responses to a mailbox under the conn mutex (monotonic condvar), answers server-to-client requests, feeds the diagnostics store, and narrates $/progress and state changes through a status sink both native shells post to the transient message row: "rust-analyzer: cargo check 88% 955/1083" lands where a save narrates, with the same clock. Chatty progress is throttled and deduplicated; settled states always land, which is also what makes the goldens deterministic. Nothing wedges and nothing healthy dies: waits are deadline-bounded, a timeout cancels and returns no rows, three consecutive timeouts restart the server ONLY while it is idle (an indexing server is narrating its own excuse), spawn and handshake failures back off 10s to 2min, a crash shortly after ready counts as a failure, and only a missing binary disables a spec. PARDES_LSP_{RS,C,GO,TS,PY} override binaries; empty disables; the snapshot harness pins RS to test/lspmock.zig and empties the rest. Mutating answers really mutate now: the @put record beside rename @edit carries per-range text, so = applies the formatter (both backends) and a same-file WorkspaceEdit rename applies atomically, one undo step, narrated ("renamed 2 range(s)"); a multi-file rename previews as rows instead of half-applying. Malformed responses fail closed: coordinates validated not clamped, one bad TextEdit poisons the whole edit set, poison frames kill the connection instead of buffering forever, decoded control bytes reject a uri, hierarchy items too deep to reserialize are skipped. Four kinds helix does not have, on SPC l: c/C incoming/outgoing calls (rows are call sites), t/T super/subtypes. Pull diagnostics (3.17) preferred when advertised. Help gains a language-keys footer for the motions no builtin row could carry; lsp.rel and look.grep now share one path-shortening rule. zig build lspprobe drives the seam from the CLI (comma-separated kinds share one server); measured against a 1083-crate workspace warm: gd 26ms, gr 213 rows 165ms, incoming calls 212 sites 197ms, document symbols 670 rows 347ms. docs/lsp.md tells the whole story; lsp-evaluation.md gets an addendum.
Diffstat (limited to 'test/snapshots/lsp-client.snap')
-rw-r--r--test/snapshots/lsp-client.snap34
1 files changed, 34 insertions, 0 deletions
diff --git a/test/snapshots/lsp-client.snap b/test/snapshots/lsp-client.snap
new file mode 100644
index 00000000..bc5267cc
--- /dev/null
+++ b/test/snapshots/lsp-client.snap
@@ -0,0 +1,34 @@
+# The protocol client end to end, against the deterministic mock server the
+# harness pins via PARDES_LSP_RS (test/lspmock.zig). What this exercises is
+# everything BETWEEN the keymap and the analyser: spawn, handshake, the reader
+# thread, $/progress narration onto the transient message row, and the
+# location shapes coming back as +Search rows.
+# gd on a cross-file Location -> a look: lib.rs opens with `add` selected,
+# and the message row still carries the server's settled state
+# ("lsp lspmock: ready") because nothing has cleared it yet.
+# gr -> three rows with column SPANS, n arms the walk, Enter opens one.
+file main.rs mod lib;\n\nfn main() {\n let x = add(1, 2);\n let y = add(3, 4);\n let _ = x + y;\n}\n
+file lib.rs // mock fixture\npub fn add(a: i32, b: i32) -> i32 {\n a + b\n}\n
+start 24 100 main.rs
+wait 8000 add(1, 2)
+stable 700 20000
+# cursor into the first `add` call, then helix's goto-definition
+press left 13 5
+release left 13 5
+key g
+key d
+wait 10000 pub fn add
+stable 700 15000
+snap gd-jumped
+# references from the definition the look landed on (cursor sits on `add`)
+key g
+key r
+wait 10000 add(3, 4)
+stable 700 15000
+snap gr-list
+# step the list and open the second hit: main.rs with the span selected
+key n
+key n
+key enter
+stable 700 15000
+snap gr-opened