diff options
| author | Gabriel Schneider <[email protected]> | 2026-09-29 19:25:00 -0300 |
|---|---|---|
| committer | Gabriel Schneider <[email protected]> | 2026-10-01 00:12:17 -0300 |
| commit | 57b30ba3e38153a4446626449b0fed5120da954c (patch) | |
| tree | 7b9381327a05791181a855bd8d4ba3cfb4df5301 /README.md | |
| parent | 0fd908eea63d04886b269438aa7529d3dd422256 (diff) | |
| download | pardes-57b30ba3e38153a4446626449b0fed5120da954c.tar.gz pardes-57b30ba3e38153a4446626449b0fed5120da954c.zip | |
The docs and the 9P skill say each fact once, in the file that owns it, and say only what a live session does
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Diffstat (limited to 'README.md')
| -rw-r--r-- | README.md | 263 |
1 files changed, 70 insertions, 193 deletions
@@ -10,41 +10,16 @@ One core, five frontends. The core owns editing, layout, rendering, and the filesystem namespace. Frontends translate native input into `pardes.Event`, present `pardes.Surface`, and perform host effects such as spawning processes. -Fifteen [native Pardes themes](docs/themes.md) coordinate the editor, search, -diagnostics and embedded terminal: `orchard` (the near-black default), `dusk`, -`ink`, `paper`, `daybreak`, and the Acme-inspired `atelier`. `ink` and -`daybreak` provide high contrast dark and light choices. Six classic-inspired -adaptations add `forge`, `lagoon`, `solarium`, `spectrum`, `harvest`, and `clay`. -`forge_black` and `orchard_black` offer pure-black variations; `forge_soft` -offers a deliberately softer contrast. Execute `Themes` to choose native -themes first, followed by the existing legacy/imported collection. `FocusTint` toggles -the active pane and column tag tints (on by default), and `SyntaxBold` toggles bold -syntax keywords (off by default), in both GUI and TTY. +Every session serves its panes, columns and tags as a 9P control filesystem, +as acme does ([docs/fs.md](docs/fs.md)). `pardes FILE` run in a pane opens +FILE in that session; `EDITOR='pardes --wait'` makes it your editor +([forwarding](docs/fs.md#connecting)). `Tty9p` opens a terminal with the +tree mounted ([docs/v9fs.md](docs/v9fs.md)). -SDL also supports `Font <name>:<size>` and optional pixel companions in the -unused workspace tag: `Pet cat`, `Pet frog`, or `Pet off`. - -`Mini path` opens a braille minimap with syntax colors: two text columns by four -lines per cell. It reads through the normal filesystem namespace; run it again -to refresh. Mini snapshots survive Dump/Restore without rereading the source. - -On Linux, `Tty9p` (`SPC n 9`) opens a terminal with the session's 9P tree -mounted through kernel v9fs. It asks sudo in that pane, then starts your shell -as your normal user. Access the tree through `$PARDES_MOUNT`. -See [mounted terminals](docs/v9fs.md). Beyond acme's per-window files the tree -serves the layout: `/layout` lists the columns, their places and panes, and -`/tag` and `/col/<serial>/tag` are the workspace and column tags, editable like a -window's ([the tree](docs/fs.md#the-served-tree)). - -`pardes FILE` in a pane opens FILE in that session and returns at once. As -`$EDITOR`, use `EDITOR='pardes --wait'` (`GIT_EDITOR` follows it): `--wait` -returns when that pane is deleted, so fish's Ctrl-O, `git commit` and -`crontab -e` read the file after you edit it -([forwarding](docs/fs.md#filesystem)). - -plan9port's `9p write` always opens with OTRUNC, so `echo x | 9p write -pardes/<id>/body` replaces the whole body where acme would append. To append, -write through a mount with `>>` (`echo x >> $PARDES_MOUNT/<id>/body`). +Fifteen [native themes](docs/themes.md) lead a ring of ports and imports; +`Themes` lists them. `Recent` (`SPC f r`) lists files opened lately, closed +ones too, and reopens one at its last place. `Mini path` opens a braille +minimap. Settings and the startup file are in [docs/config.md](docs/config.md). ## Requirements @@ -53,7 +28,7 @@ fetched and pinned by the manifest; no system package is required for the terminal build. The SDL shell builds SDL3 and FreeType from source. Native PDF support builds MuPDF and is on by default (`-Dmupdf=false` to drop it). Optional 9P-over-QUIC support (`-Dquic=true`) uses system OpenSSL 3.6+ and -pkg-config. The default Unix socket and optional TCP transport do not need it. +pkg-config. ## Build @@ -61,76 +36,42 @@ pkg-config. The default Unix socket and optional TCP transport do not need it. zig build ``` -That is the whole of it, and it is an *install*: it builds both native shells and -puts them in `~/.local/bin`. - -``` -~/.local/bin/pardes the terminal shell (libvaxis) -~/.local/bin/pardes-gui the SDL3 window -``` - -Override with `--prefix <dir>`. Test, benchmark and run steps build what they -need without installing development binaries. +A bare `zig build` builds both native shells and **installs** them into +`~/.local/bin` (`pardes`, the terminal shell; `pardes-gui`, the SDL window; +`pardes-v9fs`, the Tty9p helper). `--prefix <dir>` installs elsewhere, except +`--prefix zig-out`, which counts as no prefix. With `-Dplatform=<shell>` the +default prefix is `zig-out`. Test, benchmark and run steps build what they +need without installing. -``` -pardes --version e.g. pardes 0.0.1 (e61bbb2e86bd) -pardes --help every flag -``` - -The version comes from `build.zig.zon`'s `.version`; the commit is read from -`git` at configure time and is simply absent when there is no repository to ask. - -## The five platforms +`pardes --version` prints `pardes <version>`, plus the commit for release +builds and the `~/.local` install (`-Dstamp-commit=true` forces it). +`pardes --help` lists every flag. | build | what it is | |---|---| | `zig build` | the terminal shell and the SDL window, together | | `zig build -Dplatform=tty` | the terminal shell alone | | `zig build -Dplatform=gui` | the SDL3 window alone | -| `zig build web -Dplatform=web -Dtarget=wasm32-freestanding -Ddump=<dump.zon>` | a freestanding wasm core plus vanilla JavaScript, rendered as HTML/CSS | -| `zig build -Dplatform=macos` | an AppKit and CoreText app over a static `libpardes.a` | +| `zig build web -Dplatform=web -Dtarget=wasm32-freestanding -Ddump=<dump.zon>` | a freestanding wasm core plus vanilla JavaScript ([docs/web.md](docs/web.md)) | +| `zig build -Dplatform=macos` | an AppKit and CoreText app over a static `libpardes.a` ([docs/macos.md](docs/macos.md)) | | `zig build -Dplatform=esp32p4` | a freestanding riscv32 editor object for ESP32-P4, using a 384 KiB heap | Firmware images are built in the sibling `../05-zig-p4` toolchain, which needs ESP-IDF register headers. After building the editor object here, `zig build -Dpardes` there links `src/esp32p4/app.zig`. The separate GPIO 9P image uses -`zig build -Dapp=../02-pardes-code/src/esp32p4_9p.zig` there; it does not link the -editor. Its fixed GPIO namespace is in `src/esp32p4_gpio.zig`. +`zig build -Dapp=../02-pardes-code/src/esp32p4_9p.zig` there; its fixed GPIO +namespace is in `src/esp32p4_gpio.zig`. ## Detached sessions -A shell need not be in the same process as the core. - ``` pardes --detach=work a core with no terminal of its own pardes --attach=work become a frontend of it pardes-gui --attach=work ...the SDL window can attach too ``` -Several frontends may be attached at once and all see the same screen. The -detached core performs every effect that needs a disk or a process table, so its -pane shells outlive every frontend; a frontend keeps only what needs the human's -own display. From inside the editor, `Attach` and `Detach` do the same thing as -words. See `docs/detached.md`. - -## Recent files - -A file closed by accident is found again. `Recent` (`SPC f r`) lists the -files opened lately, most recent first, closed ones too, each marked `open` -or `closed` at the place its dot was when it closed: - -``` -/home/me/src/main.zig:120:5 closed -/home/me/notes.txt open -``` - -A look at a row opens that file there. The list keeps 200 files, each once, -and lasts across sessions in `$XDG_STATE_HOME/pardes/recent` (else -`~/.local/state/pardes/recent`). The jumplist keeps a closed file's entries -too: `Back` to one opens the file again at its place, and `+Jumps` marks it -`(closed)`. Over 9P, `/recent` reads `open <path>` or `closed <path>` a line. -acme has nothing like it (its dump and Load are the nearest); pardes goes -beyond acme here. +The detached core owns panes, shells and files; frontends come and go. See +[docs/detached.md](docs/detached.md). ## Tests @@ -169,130 +110,66 @@ zig build web-driver-test browser driver timeouts and cleanup zig build web-e2e Chrome-driven DOM end-to-end suite ``` -`snap -- --record=/tmp/captures` writes independent snapshots for comparing -binaries without changing goldens. `snap -- --update` replaces goldens; -`snap -- --no-retry` makes the first failure decisive. Retried runs retain -each attempt's report and mismatching grid in a fresh printed directory. -For custom differential cases, use -`zig build hxdiff -- --strict cases.jsonl reference.jsonl [waivers.jsonl]`. -Without a reference, the driver only emits results; exit zero does not mean a -comparison passed. Custom arguments must include `--strict` to check coverage. -The benchmark steps — `perf`, `pdf-bench`, `pdf-scroll-bench`, `pdf-sections-bench`, -`lspbench`, `fs-bench` — all accept `-- --json`. - -Snapshot scripts can use `snap9p` to capture core cells and styles through the -default socket alongside the terminal emulator's independent captures. - -`zig build monkey -Dplatform=tty -- <seeds> [steps] [--from=N] [--out=DIR] [--keep]` -writes one random script per seed (keys, leader bursts, typing, clicks, drags, -wheel, tiny resizes, prompts and long prompt text over bad-UTF-8 and wide-glyph -files), runs it through pardes-snap and looks for a panic's `.zig:N:N: 0x` -frame in the report and in the captured grid. A hit keeps the script, its -captures and its log in DIR (default `/tmp/pardes-monkey`); a seed always makes -the same script, so `--from=N` with one seed replays it. A trace longer than -the grid scrolls away: replay the kept script at a larger `start` size. Each -crash found gets a fix and a regression script in `test/snapshots/`. The tty's -tagline is the body's pitch, so what a narrower tagline does is fuzzed by a -unit test instead (`a monkey over notices…` in `src/draw.zig`, longer with -`PARDES_FUZZ_SEED`/`PARDES_FUZZ_STEPS`). - -`-Dtest-filter=<text>` applies to every unit-test binary. Use -`-Doptimize=ReleaseFast` for performance measurements. To record output and -first/warm command runtimes across revisions, run: - -``` -jj status -zig build history -- run 'ancestors(@, 2)' /tmp/pardes-history -- zig build unit-test -zig build history -- compare /tmp/pardes-history/<before>.json /tmp/pardes-history/<after>.json 1.20 -``` - -The history runner uses `jj run` serially, with recordings outside its isolated -checkouts without integrating history changes. Run `jj status` before measuring -`@`: the runner deliberately does not snapshot pending edits. `history record` -measures current files directly. Add `run --allow-immutable` -to measure immutable revisions. Each command runs four times; the first run is reported separately -from the warm median. Standard output and errors are preserved for every run. -Commands must exist in the selected revisions. The optional comparison ratio -fails the command when runtime regresses beyond that limit. Add `--snapshots` -to require stable, identical stdout and stderr, or `--benchmarks` to compare -individual `syntax-bench` cases, including allocation counts; the ratio limit -also applies to each case's cold and median time, using medians across the last -three processes. First-process cold times are reported separately, not gated. -All four captures must contain the same cases and input sizes. Old revisions -need the same harness and uncached test execution for meaningful comparisons. -The recorded Zig version identifies the recorder's compiler; record the child -toolchain separately when comparing different compilers. -Recordings are exclusive: use a fresh output directory to repeat a measurement. -Existing results and partial runs are never overwritten. - -`perf -- --base old.json` requires matching build metadata, harness, viewport, -repetition count, fixtures, and `--only` selection. Reports identify the compiler, -resolved target/CPU, driver/core/dependency optimization modes, and feature flags. -Missing or different metadata is rejected; old reports must be regenerated. -JSON reports omit unmeasured cells. Gesture checks run -outside the timed interval, and each process owns and removes its fixture directory. -Hardware, machine load and runtime library versions must be matched separately. - -`zig build perf -Dplatform=tty -Doptimize=ReleaseFast -Dtree-sitter=zig -- --mini --json` -measures braille generation, full highlighting plus generation, and cached Mini -redraws separately, checking output hashes and allocation balance. - -`zig build perf -Doptimize=ReleaseFast -- --terminal-mib 64 --json` streams -colored, wrapped agent-like output past the terminal history limit. It checks -the newest text, colors and input, and measures raw redraws, modal movement, -edit-overlay redraws and memory. Linux RSS comes from the current process image's -`VmHWM`; allocator counts exclude the terminal library's private mappings. - -`python3 -B test/agent_session.py zig-out/bin/pardes --ready 'ready text' --min-rows 20000 -- command args` -runs a caller-selected interactive command in a private POSIX shell and checks -its history and an unsubmitted input probe through 9P. Use an owned copy of any -saved conversation. -Reports contain counts, hashes and 9P observation times, not conversation text -or physical keyboard latency. GUI builds need `--gui-grid`. - -`test-build -Dtest-rebuild` forces fresh Zig test compilation while retaining -cached C dependencies. Use a disposable local cache for repeated cold-build -experiments. Ordinary `unit-test` always runs its tests, even with cached builds. -`unit-profile` measures the request-to-result interval, including test-runner -communication, and reports whole-process time and memory separately. -Filtered test steps fail if no named test matches, even when import guards pass. - -The default differential suites require exact case coverage and reject stale -waivers. Each waiver pins both the reference and editor result. Live Helix -steps use `-Dhelix-harness=<path>`, `HX_HARNESS`, or `hx-harness` on PATH. +- `-Dtest-filter=<text>` applies to every unit-test binary; a filter that + matches nothing fails. `-Dtest-rebuild` forces fresh Zig test compilation. +- `snap -- --record=DIR` writes snapshots without touching goldens, + `snap -- --update` replaces goldens, `snap -- --no-retry` makes the first + failure decisive. Snapshot scripts can use `snap9p` to capture core cells + through 9P. +- `zig build monkey -Dplatform=tty -- <seeds> [steps] [--from=N] [--out=DIR] + [--keep]` writes one random script per seed, runs it through pardes-snap + and keeps any script that panics (in `/tmp/pardes-monkey` by default); a + seed always makes the same script. Each crash found gets a fix and a + regression script in `test/snapshots/`. +- `zig build hxdiff -- --strict cases.jsonl reference.jsonl [waivers.jsonl]` + runs custom differential cases; without `--strict` and a reference it only + emits results. Live helix steps take `-Dhelix-harness=<path>`, + `HX_HARNESS`, or `hx-harness` on PATH. +- Benchmarks (`perf`, `pdf-bench`, `pdf-scroll-bench`, `pdf-sections-bench`, + `lspbench`, `fs-bench`) accept `-- --json`; measure with + `-Doptimize=ReleaseFast`. `perf -- --base old.json` refuses reports whose + build metadata differs. +- `zig build history -- run 'ancestors(@, 2)' DIR -- zig build unit-test` + records a command's output and cold/warm runtimes across revisions (`jj + status` first: pending edits are not snapshotted); `history -- compare + a.json b.json 1.20` fails past that runtime ratio (`--snapshots`, + `--benchmarks` for stricter checks). Output directories are never + overwritten. +- `python3 -B test/agent_session.py <pardes> --ready 'text' --min-rows N -- + command args` drives an interactive command in a private shell and checks + it through 9P (`--gui-grid` for GUI builds). ## Documentation Start with `src/panes.zig` (and the pane kinds it names, `src/File.zig`, `src/Terminal.zig`, ...), `src/layout.zig`, and `src/fs.zig` for ownership and operations, and `src/pardes.zig` for input, with one file per thing beside it -(`edit.zig`, `normal.zig`, `look.zig`, `exec.zig`, `mouse.zig`, ...). `docs/design.typ` is the architecture -sketch; `docs/design.pdf` is a retained rendering/search fixture and may lag it. +(`edit.zig`, `normal.zig`, `look.zig`, `exec.zig`, `mouse.zig`, ...). | file | subject | |---|---| -| `docs/design.typ` | architecture: the seams, the data model, the build graph | -| `docs/detached.md` | one core, many frontends, over a unix socket | -| `docs/config.md` | build options and runtime configuration | -| `docs/tags.md` | editable workspace, column and pane tags; filename drafts | -| `docs/selections.md` | the normal-mode selection model and how it differs from helix's | -| `docs/fs.md` | default 9P service, Look resolution, and named mounts | -| `docs/lsp.md` | in-process ZLS and external language servers | -| `docs/lsp-evaluation.md` | why that backend, measured against the alternatives | -| `docs/helix-keys.md` | the helix-compatible key model and its differential suite | -| `docs/macos.md` | the native macOS shell, its bundle and its signing | -| `docs/web.md` | the browser shell | -| `docs/ghostty-macos-notes.md` | notes on the ghostty dependency | -| `docs/ideas.typ` | scratch notes; nothing compiles it, and it says so | +| `docs/fs.md` | the 9P control filesystem: every file, error and limit | +| `docs/config.md` | settings, the startup file, dumps, build options | +| `docs/tags.md` | tags, columns, and where new panes go | +| `docs/detached.md` | one core, many frontends | +| `docs/v9fs.md` | Tty9p: a terminal with the tree kernel-mounted | +| `docs/cloud9.md` | the 9P library and the posted-9P registry | +| `docs/selections.md`, `docs/helix-keys.md` | the normal-mode model and the helix key map | +| `docs/themes.md`, `docs/effects.md` | themes and visual effects | +| `docs/lsp.md` | language servers | +| `docs/web.md`, `docs/macos.md` | the browser and macOS shells | +| `docs/design.typ` | architecture sketch (`docs/design.pdf` is a test fixture and may lag it) | +| `docs/divergences.md`, `docs/open-questions.md` | bookmarks off `main`; undecided questions | +| other `docs/*.md` | design and research notes (`render-pipeline`, `lsp-evaluation`, `ui-review`, ...) | -`next-steps.txt` is a wishlist with a status header saying which items have -shipped; `transactions.txt` records one open structural gap against helix, and -says which waiver proves it is still open. +`next-steps.txt` is a wishlist with a status header; `transactions.txt` +records one open structural gap against helix and the waiver that proves it. ## Layout ``` src/ core events (pardes.zig), panes, edit, look, exec, layout, fs, syntax +src/ninep/ the 9P control tree src/detached/ the wire, the detached core, the frontend client src/lsp/ ZLS and external language-server backends test/ harnesses, snapshot goldens, helix cases |
