summaryrefslogtreecommitdiff
path: root/README.md
diff options
context:
space:
mode:
authorGabriel Schneider <[email protected]>2026-09-29 19:25:00 -0300
committerGabriel Schneider <[email protected]>2026-10-01 00:12:17 -0300
commit57b30ba3e38153a4446626449b0fed5120da954c (patch)
tree7b9381327a05791181a855bd8d4ba3cfb4df5301 /README.md
parent0fd908eea63d04886b269438aa7529d3dd422256 (diff)
downloadpardes-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.md263
1 files changed, 70 insertions, 193 deletions
diff --git a/README.md b/README.md
index 14803aef..1fe1167d 100644
--- a/README.md
+++ b/README.md
@@ -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