summaryrefslogtreecommitdiff
path: root/src/lsp/lsp.zig
diff options
context:
space:
mode:
authorGabriel Schneider <[email protected]>2026-08-12 13:32:43 -0300
committerGabriel Schneider <[email protected]>2026-08-12 16:07:33 -0300
commitbc89f57cb576e23a58572ec35f96db068367f1b4 (patch)
tree06f1ea2b7e95f229c10b316214ae904b9d43e343 /src/lsp/lsp.zig
parentb424164922842796619cb6894ec46d729a8a6826 (diff)
downloadpardes-bc89f57cb576e23a58572ec35f96db068367f1b4.tar.gz
pardes-bc89f57cb576e23a58572ec35f96db068367f1b4.zip
docs: the tutor taught three keystrokes wrong, and the rest had drifted
The documentation had gone stale in the ordinary way -- claims that were true when they were written and that nothing since had been obliged to re-read. Some of them were load-bearing. THE TUTOR. It still said there is no multi-cursor, that NextColor cycles three themes, and that its practice blocks "are also run as unit tests (generated from this file by tutor_gen)" -- a tool that appears nowhere in the tree, and nothing anywhere parses a `# keys:` block. Left alone, that claim is what makes the next wrong block survive. Three of those blocks WERE wrong, and all three for one reason: since the helix motion model landed, w/e/f/t SELECT the range they cross, so `i` after one inserts at the SELECTION'S START. `w i Z esc` on "foo bar" gives "Zfoo bar", not the "foo Zbar" the file promised. They were written against a vim reading of the same keys. Every block in the file has now been run through `zig build hxdiff` against the real core and matches byte for byte, and the trap itself is written down in 3.3 rather than left to be rediscovered. The tutor gains a PART 4 for everything added since it was written -- PDF panes, the in-process ZLS backend, themes and fonts, the startup file -- and PART 3 gains counts (and which keys ignore one), f/F/t/T, the whole g table (bare `G` is a no-op; `ge` is the START of the last line), multiple cursors and the s/S regex pair, `m`, `]`/`[`, `|`, insert mode, and all fifty leader paths. THE REST. design.typ's line table claimed 7,626 lines against a real 38,048, and its rows did not sum to its own total; its Event/Effect boundary contract -- the part a shell author writes against -- named four variants that do not exist and omitted fourteen that do. lsp.md's probe count. config.md's theme-name rules, which as written could not reach a zed theme at all. helix-keys.md's Skipped section, holding five families that have since landed. macos.md's menu bar, undocumented, along with sixteen other claims. web.md on what the browser build can actually do. SOURCE COMMENTS that had rotted alongside them: `tag_normal` is a space, not the `•` its own comment describes; Wrap is ON by default, not off; a FontSel row is SELECTED by n and RUN by Tab, not run by n; the SPC paths in lsp.zig lost their `l` group prefix when the language group moved; and the differential suites are 481 and 561 cases, not 360 and 440. TWO THINGS FOUND BY DOCUMENTING THEM, both left standing and written down rather than papered over. Typing `[^\n]` at an s/S prompt panics: the live preview compiles every prefix, and `[^\` indexes an empty slice in mvzr's parseCharSet. Both the tutor and a waiver recommended that pattern as the workaround for `.` matching a newline; they now say what it costs and what would make it sayable. And `Exec` is a builtin, so an `Exec` line in the startup config types that command into a shell before the first frame -- the tutor said nothing in that file is ever sent to one. Nine adversarial reviews over two rounds, each with the hxdiff harness to execute what it doubted. The second round exists because the first round's fixes needed checking too, and it caught three regressions of my own -- one of them a probe count I had "corrected" away from the truth. Verified: unit-test, snap 87/87, hxdiff 481/0, hxparity 561/0, mupdf-check. docs/design.pdf regenerated. The tutor's first seventeen lines are byte- identical, which is what tutor.golden pins.
Diffstat (limited to 'src/lsp/lsp.zig')
-rw-r--r--src/lsp/lsp.zig34
1 files changed, 21 insertions, 13 deletions
diff --git a/src/lsp/lsp.zig b/src/lsp/lsp.zig
index 29e82968..255a8200 100644
--- a/src/lsp/lsp.zig
+++ b/src/lsp/lsp.zig
@@ -22,7 +22,10 @@
const std = @import("std");
/// What the caller wants to know. The helix command each one backs is named
-/// alongside, because the keymap is helix's and these are its verbs.
+/// alongside, because the keymap is helix's and these are its verbs — helix's
+/// bare `<space>X` spelled `SPC l X` here, because `d`, `k`, `s` and `h` were
+/// already pardes's own most-pressed leader keys and the rest follow them into
+/// the group rather than splitting the menu (see config.leader_path).
pub const Kind = enum {
/// gd
definition,
@@ -34,23 +37,23 @@ pub const Kind = enum {
implementation,
/// gr
references,
- /// SPC k
+ /// SPC l k
hover,
- /// SPC s
+ /// SPC l s
document_symbols,
- /// SPC S (arg = the query)
+ /// SPC l S (arg = the query)
workspace_symbols,
- /// SPC d, and the list that ]d / [d step
+ /// SPC l d, and the list that ]d / [d step
diagnostics,
- /// SPC D
+ /// SPC l D
workspace_diagnostics,
- /// SPC r (arg = the new name)
+ /// SPC l r (arg = the new name)
rename,
- /// SPC a
+ /// SPC l a
code_action,
/// =
format,
- /// SPC h
+ /// SPC l h
select_refs,
/// Tab in insert mode, with a `.` immediately before the cursor. NOT an
/// autocomplete popup — the seam returns locations, so this answers "what
@@ -196,9 +199,12 @@ pub fn query(gpa: std.mem.Allocator, arena: std.mem.Allocator, req: Req, out: *s
}
/// ZLS, linked in as a module and called directly — no subprocess, no
-/// JSON-RPC. See `lsp_zls.zig`. The web shell has no threads, never emits the
-/// effect, and cannot build ZLS anyway, so there it is the empty backend the
-/// base tree shipped with.
+/// JSON-RPC. See `lsp_zls.zig`. The web shell cannot build ZLS (no threads,
+/// freestanding wasm), so there it is the empty backend the base tree shipped
+/// with — and empty means SILENT rather than failing: `supports` below is then
+/// an empty set, `lspRequest` returns on it before emitting, and the effect
+/// never leaves the core. `web.zig`'s prong for it is waiting for a host that
+/// links a backend, not dead weight for one that never will.
const backend = if (@import("pardes_config").zls_backend) @import("lsp_zls.zig") else struct {
pub fn query(_: std.mem.Allocator, _: std.mem.Allocator, _: Req, _: *std.Io.Writer) void {}
pub fn speaks(_: []const u8) bool {
@@ -221,5 +227,7 @@ pub const supports: std.EnumSet(Kind) = backend.supports;
/// knowing, so the list of extensions stays the backend's business.
pub const speaks = backend.speaks;
-/// Name shown by the harness and in `SPC ?`. Each implementation renames it.
+/// Name shown by the harness and in `SPC ?`. This is the SEAM's, not the
+/// backend's: a backend does not declare it, so renaming a backend means
+/// editing this line.
pub const backend_name = "zls-inproc";