summaryrefslogtreecommitdiff
path: root/README.md
Commit message (Collapse)AuthorAge
*-. Merge: 9P rounds 7-8 + layout files + loose ends + G3 cursorGabriel Schneider44 hours
|\ \
| * | config-test goes: config.zig is the core now, and core-test runs its testsGabriel Schneider44 hours
| |/ | | | | | | | | | | | | | | | | | | config.zig imports pardes.zig and builtins.zig, so it cannot be compiled "without the editor" any more; the step failed with 40 missing-module errors (zls, uucode, cloud9, mupdf, ...). Its two tests (Space-k unbound, wheel drift guard) already run in core-test, checked with -Dtest-filter. Wiring every core import into it would only rebuild core-test for two tests. Co-Authored-By: Claude Opus 5.5 <[email protected]>
* | Columns are named by stable serials over 9P, as panes areGabriel Schneider44 hours
| | | | | | | | | | | | | | | | | | | | | | /col/<n> named a column by its index, which shifts when a column left of it closes: exactly what scripts trip on. A column is now /col/<serial>, its serial kept while it lives and never reused; /layout lines give serial and index (`<serial> <index> ...`), active names the serial, /index's last field is the column's serial, and the log says newcol and delcol with serials. Docs, the skill and the tree's README say so. Co-Authored-By: Claude Opus 5.5 <[email protected]>
* | The tree serves the layout: /layout, /tag and /col/<n>/tagGabriel Schneider44 hours
|/ | | | | | | | | | | | | A script could not see where the panes sit or edit the tags a person clicks in. /layout lists each column, its index, x and width in cells, current or not, empty or full, and its panes' serials, then the active column; /tag is the workspace tag and /col/<n>/tag a column's, read and written as a pane tag is (one line: a newline written in is a space, and a truncating write drops the one ending it); /index's lines end with the pane's column; the log says newcol <n> and delcol <n>. acme serves no column files, and the docs say so. Co-Authored-By: Claude Opus 5.5 <[email protected]>
* zig build monkey: random snapshot scripts hunting panicsGabriel Schneider44 hours
| | | | | | | | | | | | | | | | | | | | test/monkey.zig (Zig, as the project's tooling is): one random .snap per seed, over bad-UTF-8, wide-glyph and long files: keys, leader bursts, typing (an alphabet with no path characters), workspace words run by a middle click (Newcol for narrow panes, Find and Grep for prompts, long prompt text), presses, drags, wheel, hover, and resizes down to a cell. pardes-snap runs it with --update; a panic is a record in the app's crash file (in the script's fake home: seen even when the crash cut the script short) or a `.zig:N:N: 0x` frame of the app's (not the harness's) in its report or captured grid, and a hit keeps the script, captures and log under --out (default /tmp/pardes-monkey). A seed always makes the same script (tested), so --from=N replays one. Not a gate. README documents it next to snap. No Shader line: the tty has no post chain; the core fuzz in src/draw.zig covers the compile-error notice at a gui's metrics. 80 seeds x 70 steps: no panic.
* docs/selections.md says how normal mode holds its selectionsGabriel Schneider44 hours
| | | | | | | | | The primary and the others, cells against helix's gaps, how setRanges normalizes, which commands replay per range and which make one edit, and what undo, the register and repeat do with several ranges, with the places helix differs listed at the end. Co-Authored-By: Claude Opus 5.5 <[email protected]>
* Every helix-golf example is a differential case, one per step of its walkthroughGabriel Schneider44 hours
| | | | | | | | | | | The ten examples on helix-golf are imported as 118 cases: each numbered step of an example's walkthrough is the case whose keys are the command up to and including that step, so the first mismatch names the step where pardes and helix part. Six more restart at a step that begins with %, from helix's own text there, so a later step is tested even when an earlier one misses. zig build hxgolf compares all 124 with goldens from hx-harness. Co-Authored-By: Claude Opus 5.5 <[email protected]>
* Point docs and comments at the files code moved toGabriel Schneider44 hours
| | | | | | | | | | | | | Documentation only, no code change: README's reading order and layout, docs/design.typ's paragraph on where pane kinds and editor parts live, docs/helix-keys.md's code map (normalInput and the executors now in normal.zig and edit.zig, insertTab in edit.zig), docs/open-questions.md (execute and ttyForDir in exec.zig), and the comments that named pardes.zig for fold, Cell, takesCommandLine and runBuiltin (tools/gen_themes.zig, themes/helix.zig, detached/wire.zig, host_io.zig, lsp_zls.zig). docs/design.pdf is a retained fixture and is not regenerated. Co-Authored-By: Claude Opus 5.5 <[email protected]>
* Add Linux Tty9p mounted terminals and forward raw TTY keysGabriel Schneider2026-09-15
|
* trunk: resume before the Reload experimentGabriel Schneider2026-09-15
| | | | Empty marker on the last pre-Reload change. Keep the Reload experiment on reload (3801914), its first change on reload-start (200a1fc), and the unfinished performance investigation on reload-perf-wip.
* Refactor panes and filesystem; replace FUSE with 9PGabriel Schneider2026-09-07
| | | | | | Consolidate pane, layout, memory and host code. Serve 9P by default over Unix sockets, with runtime mounts and optional TCP/QUIC transports. Remove FUSE and obsolete proof-of-concept examples. Fix highlighting and terminal-history performance, expand differential and stress-test infrastructure, sort navigation results while preserving the next occurrence, add syntax-colored Braille minimaps, remove SPC-k, and document 9P interaction as a repository skill.
* An edited row keeps its colours, four copies of forkShell become one, and ↵Gabriel Schneider2026-08-27
Esc stops recentring ## A terminal row's ANSI colours survive being edited The loudest colour bug this editor had: one keystroke anywhere in a coloured shell row turned EVERY column of it grey. `EditAnchors` anchored a buffer line only when it was BYTE-IDENTICAL to the shell row it stood over, so a single differing byte dropped the whole row's colour projection. Worst shape is invisible: append past the pane's right edge, where the text is clipped, and the row looks the same and only its colour goes. Anchoring is byte-level now. An edit leaves the row's own bytes at both ends, and being the same bytes they keep the same colours; only what was typed has no cell under it, so only that takes none. Live, on real `fastfetch`: a 32-column blue run split into 6 + 26 around one typed character. Three defects underneath it, all found by machinery rather than by reading: * A JOIN removes a buffer line while the buffer's covered span grows, so `lines == covered` and both aligned guesses — Nth line over the Nth covered row, and the same counted from the bottom — resolved to the SAME wrong row. Every untouched row below a join went plain. Anchoring is now a streaming monotone matching: one shell-row cursor that only ever moves forward, advanced once per buffer line, linear in the buffer where the version before it was quadratic. * An EMPTY line is not evidence. Splitting a row makes one, it equals every blank row in the span, and left free to look ahead it claimed the blank row below the last output and took every coloured row in between out of reach of the lines that owned them. * Reflow under a scrolled viewport. `PageList.getTopLeft(.viewport)` returns the viewport pin verbatim, x and all, while `PageList.pin` forces x to 0 — so after a reflow remapped a tracked pin into the middle of a row, the text pass dumped row 0 from that column while the colour pass paired the fragment with the row's FIRST cells. Row 0 wore its left half's colours until the pane snapped back to live output. `bodyText` dumps from column zero now, which is also what ghostty's own renderer draws. Also here: DECSCNM (reverse video) was silently dropped whenever `tty_filter` was off, because the raw path resolved a `.none` colour by role and never consulted the mode. The test that found the first two is the one worth keeping: random editing against an ABSOLUTE oracle — every row's own text names the colour it must have — because the differential oracle it replaced was blind by construction. It skipped the edited row, which is the row the user is complaining about. ## Esc returns to a pane without moving its view Esc in body normal mode runs `Last`, "the pane you were in before this one", and that went through `focusPaneLine`, which recentred a file on the target line unconditionally. So returning to a buffer repainted the whole screen to show a line that was already on it. `focusPaneLine` takes a landing now: `.center` for the three callers going somewhere you have not been (a look target, a path a pane already holds, `@pN:LINE:COL`), `.keep` for Esc. `.keep` leaves the view alone and lets `ensureCursorVisible` — which already existed and already scrolls by the minimum into the `scroll_off` band — be the only thing that may move anything. Not `line = 0`, which `focusPaneLine` already understands as "focus and touch nothing": a background pane's view can move while you are away, because the wheel scrolls the pane under the POINTER and a resize reveals no cursor, so the recorded cursor plus a minimal nudge is what actually gets you back. Ctrl-o and Ctrl-i keep centring, and the asymmetry is structural rather than arbitrary: `Last` only ever CROSSES panes, so the pane it lands on already holds the view you left it with, while `jumpBy` can land in the SAME pane, where a long in-file jump would arrive on the very top or bottom row with `scroll_off` lines of context on one side. Helix splits the same pair the same way — its jumplist centres, its buffer switch does not. One deliberate consequence: under `.keep` a PDF's page is not restored AT ALL, because a page reveal IS that pane's view and a reveal of the page you are already on still snaps `document_scroll_y` to that page's start, discarding where you had read to. When something moved the pane while you were away — the wheel again — Esc leaves it where the wheel left it, and Ctrl-o is how you reach the recorded page. ## host_io.zig: the machine-local half of a host, once `host.zig` is the seam. The part of the answer that is identical on every host with an operating system under it — fork a pane's shell, put bytes on a disk — was written FOUR times: in tty.zig, gui.zig, macos.zig and detached/server.zig. What those copies had in common says what they were for: all four were missing FD_CLOEXEC on the pty master, so in every shell pardes has shipped, a program in one pane could read another pane's terminal. One copy now, and the wire got smaller for it: `ServerMsg.spawn` is gone. A frontend never asked the server to fork anything — the server has an operating system under it and forks through `host_io` like every other host — and `decodeClient` lost the scratch buffer that message needed.