1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
|
# 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 <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` 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 ([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=<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`, ...).
| 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
```
|