summaryrefslogtreecommitdiff
path: root/build.zig
Commit message (Collapse)AuthorAge
* lsp backend: ZLS as an in-process libraryGabriel Schneider2026-08-01
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | The seam's `query` now calls ZLS's analyser directly, on the worker thread, in this process. There is no zls binary, no subprocess, no JSON-RPC, no `initialize` handshake and no `Server` — `gd` is a function call whose answer comes back as rows. ZLS's build.zig already publishes its guts as an importable module (`b.modules.put("zls", ...)`), so this is a path dependency on the local 0.16.x checkout plus one new file, `src/lsp_zls.zig`. Construction is ZLS's own (tests/analysis_check.zig does exactly this): InternPool.init -> DiagnosticsCollection -> DocumentStore struct literal -> Analyser.init. `zig_exe_path` is null on purpose — shelling out to the compiler is the thing this backend exists to avoid — and `zig_lib_dir` is baked in from `b.graph.zig_lib_directory`, so `gd` on `std.mem.count` opens the same mem.zig the compiler used, with ZIG_LIB_DIR overriding at runtime. Offsets are `.@"utf-8"`, not ZLS's utf-16 default: `+Search` rows are byte columns and we are not on a wire. Seventeen probes, seventeen answering, no false claims, 5.9 MiB peak RSS. The features that were already Server-free are calls (hover, document symbols, code actions); the ones welded to `*Server` are reimplemented thin on top of public primitives — goto is gotoHandler minus the protocol, diagnostics is the in-process `std.zig.AstGen` branch of getAstCheckDiagnostics, references is symbolReferences' algorithm from the outside (offer every same-named identifier token back to the analyser and keep the ones that resolve to the same decl, so a shadowed local is not a false hit). What it does not do, deliberately: - Nothing is cached between queries. Each `query` builds a DocumentStore, resolves imports and throws it away, because the arena dies on return and `req.source` is a snapshot of a buffer the user is still typing into. So cold IS warm — there is no index to warm up. It is also fast enough not to need one: 124us for a local goto, 2.8ms into the stdlib, 8ms for references over a 5000-line file. A cross-query cache is a real design (a global, a mutex, an invalidation story), not a line of code, and it is the obvious next step rather than something smuggled in here. - References, rename and select-refs are THIS FILE only. Workspace-wide means loading every project file into the store and running the analyser over each; DocumentStore's own workspace iteration has the same limit (it can only see handles already loaded). Workspace symbols and workspace diagnostics DO walk the tree, because neither needs the analyser — a parse and a tree walk each. - Rename previews, format reports, code actions list. The seam hands back rows, not edits, so there is no channel through which a backend could rewrite the buffer. These answer the question the keypress asks and change nothing. - Without a zig binary, `@import("builtin")`, `@import("<pkg>")` and `@cImport` resolve to nothing — silently, which is ZLS's behaviour, not a bug introduced here. Relative imports and `std` work. - Non-.zig files answer nothing. The core does not gate the keymap by file type, so the gate is here: `gd` in a README must find nothing rather than parse prose as Zig and confidently resolve a word out of it. A whole-file report that ran and found nothing says so ("no diagnostics", "already formatted", "no code actions") rather than returning zero rows, because in this seam zero rows already means "no backend" — `lspResponse` opens nothing for an empty answer, so silence cannot also mean "checked, clean". Location queries keep the opposite rule: unresolvable is no rows. test/snapshots/lsp.snap covers the round trip end to end — gd jumping on a single result, SPC k opening +Hover, SPC s opening the +Search list that n steps, and gd on a keyword answering nothing without opening anything. The whole backend was also fuzzed at 20k queries over real, truncated and byte-smashed sources across every kind; that found two crashes (a decl's name token indexes its own file, not the requesting one, and is not necessarily an identifier at all on a half-typed line) which are fixed. emscripten does not get the backend: the web shell has no threads and no-ops the lsp effect, so it keeps the empty one the base tree shipped. DEPENDENCY: ZLS is FETCHED by the build system (build.zig.zon .url + .hash, pinned to commit 3e0d0820 on the 0.16.x branch) rather than a path dependency on the local genizah checkout, so it lands in zig-pkg/ like every other dependency and the build is reproducible from the .zon alone. Also passes -Dversion-string: ZLS's build.zig names itself by shelling out to `git describe`, and a fetched package is an extracted tarball with no .git, so every build printed a 'Failed to run git describe' warning. We pin the commit, so we already know the answer.
* LSP seam: async execution model, helix keymap, evaluation harnessGabriel Schneider2026-08-01
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | The base every language backend plugs into. Three parts: ASYNC. The core had no request/response shape - every effect was fire-and-forget or instantaneous. A language query is the first thing that answers later, so: Effect .lsp -> shell worker -> Event .lsp_resp. tty.zig uses io.concurrent + the vaxis queue, gui.zig a detached thread + the mutex queue it already had for ptys; web no-ops it. The worker never touches the core (path/source/arg are snapshotted into an LspJob), one query in flight identified by a monotonic id so a second press makes the first answer stale, and no rows is a legal answer. KEYMAP. Helix's, verified against its default.rs rather than recalled. gd/gD/gy/gi/gr and ]d/[d had no conflicts. The SPC letters did, so pardes's own builtins moved instead of helix's: Kill k->q, Del d->wc (closing a pane is a window op, and c is helix's own close), Dump/Restore s?->f?, Tutor ht->T. A three-exception muscle-memory map is not a map. RESULTS ARE +SEARCH ROWS. path:LINE:COL text, absolute. That is what look.zig resolves and n/N step, so one row from a goto jumps and several open a buffer - helix's multi-result picker needed no picker code. Backends supply exactly one function (lsp.query) plus a supports set and a name; the base has none on purpose. zig build lspbench scores them on the same corpus: feature matrix (trusting results, not the supports flag - a claimed-but-empty kind is reported as a false claim), cold and warm latency, peak RSS. Two snapshot scripts moved. leader.snap encoded the old key paths. chordcut.snap's last two steps clicked column 5, which lands on a FILE pane, so 'key c-b' toggled nothing and the typed text was being read as normal-mode keys - the golden recorded no TTY pane and no cat -v output anywhere. Pointing them at an actual shell makes both steps assert what their comments claim, and the tty paste chord is now covered for the first time.
* build.zig runners and testing improvementsGabriel Schneider2026-08-01
|
* fixing some crashesGabriel Schneider2026-08-01
|
* adding better search to tty modeGabriel Schneider2026-08-01
|
* docs: note native web client + WASM-only text logic in ideas.typGabriel Schneider2026-08-01
|\
| * macos fixGabriel Schneider2026-08-01
| |
* | web snapshots: add switch for saving/loading exports, update web version, ↵Gabriel Schneider2026-08-01
|/ | | | web snapshot tooling
* steam deck nice versionGabriel Schneider2026-08-01
|
* build: the gui shell installs as pardes-gui (no longer clobbers ↵Gabriel Schneider2026-08-01
| | | | zig-out/bin/pardes, so the rebuild-tty-last dance is obsolete), and non linux-x86_64 targets get os-arch appended to the binary name (e.g. pardes-linux-aarch64); native linux-x86_64 tty stays pardes for the snap/e2e harnesses.
* helix diff testing and feature parityGabriel Schneider2026-08-01
|
* fix: every external-scanner grammar crashed pardes on parse ↵Gabriel Schneider2026-08-01
| | | | (rust/cpp/python/...; e.g. opening agave cpi.rs or any tracy .cpp), Debug AND ReleaseSafe. Root cause: clang -fsanitize=function (in zig's default C UBSan set) traps at the runtime's indirect call of the scanner because grammars declare external_scanner_create() with EMPTY PARENS — a K&R non-prototype whose type hash differs from the void*(*)(void) pointer type. The ud1 trap lands on a bogus inlined line (stack.c:746), which cost the diagnosis a detour through rr (its gdbserver dies replaying past the task exit — core dump + coredumpctl worked; ud1 0x6(%eax) = SanitizerHandler kind 6 = function_type_mismatch; scanner-less c/zig grammars never crashed). Fix per review direction: -fno-sanitize=function on the grammar TUs in build.zig — uninstrumented callees make the runtime's call-site checks skip; the rest of UBSan stays live. Second half: fatal signals (SIGILL/SEGV/BUS/FPE) never run defers and bypassed the panic hook, leaving the terminal raw after a crash — root.debug.handleSegfault override now runs vaxis.recover() before std.debug.defaultHandleSegfault, verified in a raw pty (kill -ILL $PPID: rmcup + mouse resets precede the trace). Verified: rust/cpp/python opens work with real highlighting (snapstyle: keywords/strings/comments colored), agave cpi.js 2.7k-line open fine, suite 30/30, ReleaseSafe build opens rust identically.
*-. merge: twelve parallel changes — bug fixes, features, posix port — plus ↵Gabriel Schneider2026-08-01
|\ \ | | | | | | | | | | | | | | | | | | | | | | | | | | | three merge-state fixes born of branch interactions. Branch work merged: tty exit cleanup (krluslzz), drag-select effect-queue crash (zopqvlll), single-pane layout rule (tutmotnl), tty input coalescing + -Dtracy (olnvomwz), / file search (syqzvmkl) + generalized n/N look motion (nmzypsto), ghostty middle-click diagnosis (sqonpmsz), NOR/INS/TTY mode indicators (opmrortk), cursor-row gutter highlight (nymrwpwq), look path:NN centering (oktvtuss), scrolloff (wlqqyvvo), posix portability (pzwluyuw). Merge-state fixes: (1) splitBelow caps keep at body-(BOX_H+3) so a content-full source still leaves the new pane a tag + a few body rows — Alt-n from a full shell was born 0 rows tall (caught by ttylook: OVER marker had no rows to render in). (2) spawn-effect pane-id reuse crash (user-reported panic at drainEffects assert): no close effect exists, so a deleted pane pty lingers in its slot until a respawn lands on it — both shells now reap the stale pty at spawn (tty: cancel reader + close; gui: SIGKILL, reader delivers the old fd through the eof event) and per-slot generations drop the dead shell late output/eof, which otherwise nuked the NEW pty on the reused id. New respawn.snap golden; fails on the pre-fix assert. (3) dedup re-look now lands the modal cursor on the target line (cur_row/cur_col/cur_pinned) — scrolloff cursor-anchored reconcile otherwise yanked the recentered view back to the stale cursor (caught auditing look-center: center-dedup stayed at 97-102 instead of 146-154); this is also the requested focus-moves-cursor behavior. look-center dedup/clamp clicks re-aimed for the merged layout geometry (typed row moved from 18 to 15). Goldens reconciled by regenerating from the merged binary and auditing every diff against its origin branch; deltas are exactly: indicator text/width shift, layout-split pane sizing, cursor-row gutter styling, centering shifts, and the pane-edge hover dash now coinciding with new pane boundaries. Suite: 28/28 (27 + respawn).
| | * posix portability: linux syscalls -> libc (std.c) in one shared path. All ↵Gabriel Schneider2026-08-01
| |/ |/| | | | | raw std.os.linux.* call sites converted with the errno-convention flip (libc returns -1 + thread-local errno, not -errno): open/close/read/write/rename in tty.zig, gui.zig, look.zig; harness too (snapshot.zig: getcwd/mkdir/chdir/fork+waitpid/getdents64->opendir-readdir, e2e_harness.zig: clock_gettime/write/close), so the parity suite itself is POSIX-portable. Per-OS branches kept only where platforms genuinely diverge: shellCwd in look.zig (linux /proc/<pid>/cwd readlink; darwin libproc proc_pidinfo PROC_PIDVNODEPATHINFO with a hand-declared extern; other POSIX degrades to null), bash path (/usr/bin/bash on linux, /bin/bash elsewhere), TIOCSWINSZ constant (absent from std.c.T on darwin). forkpty/execv/chdir externs were already libc and are portable (fork-safety preserved: absolute-path execv, no malloc between fork and exec, initial spawns before worker threads). build.zig: forward target/optimize to the ghostty dep for native/cross (web keeps its no-target fetch), disable ghostty simd for darwin cross-builds (apple_sdk needs xcrun; scalar fallback = web config), link libutil on the BSDs. Pinned ghostty needs two one-line zig-0.16 darwin fixes, applied in the zig-pkg cache and documented in build.zig. Verified: aarch64-macos + x86_64-macos + x86_64-freebsd cross-compiles green; linux native tty + gui + web green; snapshot suite 18/18 with goldens untouched. Out of scope: gui-on-macos needs Metal shaders (SDL GPU rejects our SPIR-V there).
| * tty: coalesce queued input events into one frame; tracy zones behind -DtracyGabriel Schneider2026-08-01
|/ | | | | | | | | | | | | | | | | | | The tty shell rendered (core.render + full vaxis repaint + tree-sitter re-highlight of the visible window) after EVERY event, so a wheel flick over a highlighted file was 150 re-parses and 150 terminal repaints; the gui shell drains the SDL queue before drawing and never had the issue. Now the tty loop applies every queued input event, then renders once (batch cap 64; pty output keeps a frame per chunk so progress paints and transient-state waits behave exactly as before). Measured with tracy on a 2400-line .zig scroll script: 150 highlightFileRange calls at 1.85ms mean -> 4; render pipeline total 730ms -> 64ms; 364 frames -> 39. Snap suite 18/18. Tracy: -Dtracy=<path-to-tracy-checkout> compiles TracyClient.cpp into the binary and turns src/tracy.zig zones live (default off, all no-ops). Sampling, callstacks, system tracing and the crash handler are disabled: tracy's symbol worker SIGSEGVs on this binary's debug info and its crash handler then parks every thread before the first frame. Capture: tracy-capture -o t.tracy; export: tracy-csvexport t.tracy.
* pardes v2: the rewrite, complete and organized. src/ (core + three shells), ↵Gabriel Schneider2026-08-01
| | | | test/ (snapshot parity harness + 18 frozen goldens). One sans-IO core, vaxis tty + SDL3 GPU native + wasm web shells, 18/18 parity with the purged prototype, 7.6k lines vs 12.1k. Fix: gui shell pre-sized the core at init so the greet-releasing resize never fired (blank panes until first interaction); live sessions now init at defaults and get the real grid as a resize event (the shell contract, documented on Options).
* touch debug overlay: multi-touch circles with trails, finger event handling, ↵Gabriel Schneider2026-08-01
| | | | 4x larger, fade trails, SDL GPU + WebGL overlay shaders, touch-action:none in HTML, --debug-overlay flag, pinch event dispatch for all SDL backends
* sdl: main + ui_sdl rework, build.zig updatesGabriel Schneider2026-08-01
|
* improving layoutGabriel Schneider2026-08-01
|
* performance passGabriel Schneider2026-08-01
|
* fixing mouse drag on webGabriel Schneider2026-08-01
|
* fixed scaling and fitting on web uiGabriel Schneider2026-08-01
|
* patched font to maplemonoGabriel Schneider2026-08-01
|
* separated all ts grammars vs a small set of themGabriel Schneider2026-08-01
|
* wasm replay uiGabriel Schneider2026-08-01
|
* storage and replayGabriel Schneider2026-08-01
|
* sdl ui backendGabriel Schneider2026-08-01
|
* added static linkingGabriel Schneider2026-08-01
|
* more treesitter grammarsGabriel Schneider2026-08-01
|
* stealing petsciinatorfull-prototypeGabriel Schneider2026-06-30
|
* merging the colors intoGabriel Schneider2026-06-30
|
* images? lolGabriel Schneider2026-06-30
|
* chinese vibes modal editingGabriel Schneider2026-06-30
|
* working in realtime better than expected lolGabriel Schneider2026-06-25
|
* ghostty setupGabriel Schneider2026-06-25
|
* day-00: basic mouse and showing cwd relative fsGabriel Schneider2026-06-25