# pardes
A text environment in the acme tradition: columns of panes, each pane a tag line
plus a body, where the body is a live terminal, a file, an image, or a PDF. The
mouse carries meaning — left selects, middle executes, right looks — and
everything on screen is text that is equally alive, whether a shell printed it or
you typed it.
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.
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)).
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
Zig **0.16.0** (`build.zig.zon` pins `minimum_zig_version`). Dependencies are
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.
## Build
```
zig build
```
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
` installs elsewhere, except
`--prefix zig-out`, which counts as no prefix. With `-Dplatform=` the
default prefix is `zig-out`. Test, benchmark and run steps build what they
need without installing.
`pardes --version` prints `pardes `, 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=` | 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; its fixed GPIO
namespace is in `src/esp32p4_gpio.zig`.
## Detached sessions
```
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
```
The detached core owns panes, shells and files; frontends come and go. See
[docs/detached.md](docs/detached.md).
## Tests
```
zig build unit-test module and shell unit tests
zig build test-build compile the unit-test programs without running them
zig build unit-profile test request time and process memory as JSONL
zig build unit-profile-test profiler timing, failure and timeout checks
zig build core-test core tests without native shell tests
zig build pane-test pane and namespace integration tests
zig build syntax-test tree-sitter tests without building the editor
zig build syntax deterministic per-byte highlighting snapshots
zig build syntax-bench highlighting latency and allocation counts
zig build perf-test benchmark validation without compiling the editor
zig build lspbench-check require every configured language probe to be correct
zig build lspbench-test language benchmark omission and expectation gates
zig build history-test historical measurement and comparison tests
zig build fs-test real sessions and mounts over 9P
zig build agent-session-test interactive session driver checks over 9P
zig build fs-bench-test filesystem benchmark option checks without the editor
zig build 9p-test freestanding protocol tests
zig build quic-test -Dquic=true optional QUIC transport tests
zig build snap scripted input traces against frozen golden grids
zig build snap-driver-test retry evidence, strict failures and fixture isolation
zig build monkey random snapshot scripts hunting panics (not a gate)
zig build monkey-test the monkey's generator and panic detector
zig build hxdiff differential suite against helix's own behaviour
zig build hxdiff-test comparator, allocation and CLI regression checks
zig build hxdiff-live compare against a freshly run hx-harness
zig build hxdiff-update update reference results only after comparison passes
zig build hxparity file-pane vs pty-pane editing parity
zig build hxgolf every helix-golf example, step by step, against helix
zig build mupdf-check compile, link, render and search docs/design.pdf
zig build web-snap browser highlighting and touch interactions
zig build web-driver-test browser driver timeouts and cleanup
zig build web-e2e Chrome-driven DOM end-to-end suite
```
- `-Dtest-filter=` 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 -- [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=`,
`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 --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`, ...).
| file | subject |
|---|---|
| `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; `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
build/ build-time helpers (the snapshot suite)
docs/ see above
```