From bc89f57cb576e23a58572ec35f96db068367f1b4 Mon Sep 17 00:00:00 2001 From: Gabriel Schneider Date: Wed, 12 Aug 2026 13:32:43 -0300 Subject: docs: the tutor taught three keystrokes wrong, and the rest had drifted MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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. --- src/pardes.zig | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'src/pardes.zig') diff --git a/src/pardes.zig b/src/pardes.zig index ae6c4cbc..da6e540c 100644 --- a/src/pardes.zig +++ b/src/pardes.zig @@ -6798,7 +6798,11 @@ pub const Pardes = struct { /// ponytail: mvzr searches from each match's end, so `^` and `$` assert /// against THAT position rather than against a line the way helix's /// multi_line regex does, and `.` matches a newline like any other byte. - /// Both are waived cases; `[^\n]` is the workaround for the second. + /// Both are waived. `[^\n]` LOOKS like the workaround for the second and + /// must not be suggested as one: the live preview compiles every prefix, + /// and the prefix `[^\` panics mvzr (index out of bounds in parseCharSet, + /// mvzr.zig valueFor) before the pattern can ever be finished. Guarding + /// the compile is what would make the advice sayable. fn applySelRegex(p: *Pardes, pane: *Pane, pat: []const u8, split: bool) void { const pl = p.paneCursorLines(pane) catch return; const text = p.flatSurface(pane, pl) catch return; -- cgit v1.3