summaryrefslogtreecommitdiff
path: root/test/hxcases
diff options
context:
space:
mode:
authorGabriel Schneider <[email protected]>2026-09-06 18:11:36 -0300
committerGabriel Schneider <[email protected]>2026-09-07 13:59:12 -0300
commit60367d8fe23f6af98ec28e3cf6c2094dfe332df0 (patch)
tree310fc734173cf771881f4691c71909135fadde97 /test/hxcases
parentfa82cac885cb4738fe36d1e49b4749b5a3e31a4a (diff)
downloadpardes-60367d8fe23f6af98ec28e3cf6c2094dfe332df0.tar.gz
pardes-60367d8fe23f6af98ec28e3cf6c2094dfe332df0.zip
Refactor panes and filesystem; replace FUSE with 9P
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.
Diffstat (limited to 'test/hxcases')
-rw-r--r--test/hxcases/parity-waivers.jsonl26
-rwxr-xr-xtest/hxcases/regen.sh16
-rw-r--r--test/hxcases/waivers.jsonl12
3 files changed, 19 insertions, 35 deletions
diff --git a/test/hxcases/parity-waivers.jsonl b/test/hxcases/parity-waivers.jsonl
index 1a6fd269..39a6a7c9 100644
--- a/test/hxcases/parity-waivers.jsonl
+++ b/test/hxcases/parity-waivers.jsonl
@@ -1,13 +1,13 @@
-{"name":"ctrl-b-page","reason":"not a parity bug: Ctrl-b IS pardes's tty toggle (Options.tty_toggle = 'b'), so on a shell pane it enters raw tty mode instead of paging the view. Deliberate binding, same class as the alt-c-window-op waiver in the helix suite; Ctrl-u/Ctrl-d and PageUp cover half/full page scrolling on terminals."}
-{"name":"ctrl-f-page","reason":"viewport geometry: a file pane's view scrolls anywhere inside its line count, a terminal's is the vt's and cannot move below the live grid bottom, so a full-page move clamps and the cursor snaps into a different scrolloff band. The edit model is not involved - no text differs, only where the view landed."}
-{"name":"ctrl-f-small","reason":"viewport geometry: same as ctrl-f-page with a document shorter than the pane, where the terminal's view cannot scroll at all and the cursor snaps to the top scrolloff margin instead of the last line."}
-{"name":"pgdn-basic","reason":"viewport geometry: PageDown is the same view scroll as Ctrl-f, and clamps at the terminal's live grid bottom. Text identical, view position differs."}
-{"name":"z-pgdn-alias","reason":"viewport geometry: z-prefixed PageDown aliases the Ctrl-f view scroll, so it clamps at the terminal's live grid bottom exactly like pgdn-basic."}
-{"name":"ins-pgdn","reason":"viewport geometry: insert-mode PageDown is bound to the same view scroll as normal mode, so it clamps at the terminal's live grid bottom. Text identical, view position differs."}
-{"name":"zj-snaps-cursor","reason":"viewport geometry: zj scrolls the view one row and snaps the cursor back into the scrolloff band; on a terminal whose view is already at the vt's bottom the scroll is a no-op, so the cursor snaps from a different band."}
-{"name":"zj-noop-in-band","reason":"viewport geometry: same as zj-snaps-cursor - the terminal's view cannot scroll past the live grid bottom, so the cursor's band differs by one row."}
-{"name":"zk-bottom-snap","reason":"viewport geometry: zk scrolls the view up one row and snaps the cursor; the terminal's starting view offset differs because it could not scroll as far down in the first place."}
-{"name":"unindent-tab","reason":"the case text is not representable in a pty pane: a literal TAB fed through the terminal is expanded to the next tab stop by the emulator, so the shell rows hold spaces and never the tab the file pane unindents. Not an editing divergence - unindent-basic, unindent-partial, unindent-realign and unindent-cursor all match; only a byte a terminal cannot hold verbatim."}
-{"name": "comment-tab-indent", "reason": "the case text is not representable in a pty pane: a literal TAB fed through the terminal is expanded to the next tab stop by the emulator, so the shell rows hold spaces and the comment token goes in at a different column. Exactly the unindent-tab waiver's class - not an editing divergence; comment-indent, comment-uncomment-deep and the rest of the comment-* family match."}
-{"name": "comment-noeol", "reason": "the case text is not representable in a pty pane: it is the one case in the corpus with NO trailing newline (that is the point - it pins helix's last-line handling), and the tty harness re-adds the newline ghostty's dump trims off the cursor row. The comment itself is identical on both sides; only the missing final byte differs."}
-{"name": "comment-only-blank", "reason": "the case text is not representable in a pty pane: a literal TAB (unindent-tab's class) plus an all-whitespace last row, which the terminal dump trims off entirely. Both panes correctly change nothing - toggle_comments skips blank lines - so the only difference is what the pty could hold in the first place."}
+{"name":"ctrl-b-page","reason":"Ctrl-b enters raw terminal mode instead of paging the view.","reference":{"name":"ctrl-b-page","text":"l00\nl01\nl02\nl03\nl04\nl05\nl06\nl07\nl08\nl09\nl10\nl11\nl12\nl13\nl14\nl15\nl16\nl17\nl18\nl19\nl20\nl21\nl22\nl23\nl24\nl25\nl26\nl27\nl28\nl29\n","mode":"normal","cursor":{"row":18,"col":0},"anchor":{"row":18,"col":0}},"expected":{"name":"ctrl-b-page","text":"l00\nl01\nl02\nl03\nl04\nl05\nl06\nl07\nl08\nl09\nl10\nl11\nl12\nl13\nl14\nl15\nl16\nl17\nl18\nl19\nl20\nl21\nl22\nl23\nl24\nl25\nl26\nl27\nl28\nl29\n","mode":"tty","cursor":{"row":20,"col":0},"anchor":{"row":20,"col":0}}}
+{"name":"ctrl-f-page","reason":"Terminal viewports cannot scroll below the live grid.","reference":{"name":"ctrl-f-page","text":"l00\nl01\nl02\nl03\nl04\nl05\nl06\nl07\nl08\nl09\nl10\nl11\nl12\nl13\nl14\nl15\nl16\nl17\nl18\nl19\nl20\nl21\nl22\nl23\nl24\nl25\nl26\nl27\nl28\nl29\n","mode":"normal","cursor":{"row":25,"col":0},"anchor":{"row":25,"col":0}},"expected":{"name":"ctrl-f-page","text":"l00\nl01\nl02\nl03\nl04\nl05\nl06\nl07\nl08\nl09\nl10\nl11\nl12\nl13\nl14\nl15\nl16\nl17\nl18\nl19\nl20\nl21\nl22\nl23\nl24\nl25\nl26\nl27\nl28\nl29\n","mode":"normal","cursor":{"row":12,"col":0},"anchor":{"row":12,"col":0}}}
+{"name":"ctrl-f-small","reason":"Terminal viewports clamp short documents to the live grid.","reference":{"name":"ctrl-f-small","text":"l00\nl01\nl02\nl03\nl04\nl05\nl06\nl07\nl08\nl09\nl10\nl11\n","mode":"normal","cursor":{"row":12,"col":0},"anchor":{"row":12,"col":0}},"expected":{"name":"ctrl-f-small","text":"l00\nl01\nl02\nl03\nl04\nl05\nl06\nl07\nl08\nl09\nl10\nl11\n","mode":"normal","cursor":{"row":3,"col":0},"anchor":{"row":3,"col":0}}}
+{"name":"pgdn-basic","reason":"Terminal page scrolling clamps to the live grid.","reference":{"name":"pgdn-basic","text":"l00\nl01\nl02\nl03\nl04\nl05\nl06\nl07\nl08\nl09\nl10\nl11\nl12\nl13\nl14\nl15\nl16\nl17\nl18\nl19\nl20\nl21\nl22\nl23\nl24\nl25\nl26\nl27\nl28\nl29\n","mode":"normal","cursor":{"row":25,"col":0},"anchor":{"row":25,"col":0}},"expected":{"name":"pgdn-basic","text":"l00\nl01\nl02\nl03\nl04\nl05\nl06\nl07\nl08\nl09\nl10\nl11\nl12\nl13\nl14\nl15\nl16\nl17\nl18\nl19\nl20\nl21\nl22\nl23\nl24\nl25\nl26\nl27\nl28\nl29\n","mode":"normal","cursor":{"row":12,"col":0},"anchor":{"row":12,"col":0}}}
+{"name":"z-pgdn-alias","reason":"Terminal page scrolling clamps to the live grid.","reference":{"name":"z-pgdn-alias","text":"l00\nl01\nl02\nl03\nl04\nl05\nl06\nl07\nl08\nl09\nl10\nl11\nl12\nl13\nl14\nl15\nl16\nl17\nl18\nl19\nl20\nl21\nl22\nl23\nl24\nl25\nl26\nl27\nl28\nl29\n","mode":"normal","cursor":{"row":25,"col":0},"anchor":{"row":25,"col":0}},"expected":{"name":"z-pgdn-alias","text":"l00\nl01\nl02\nl03\nl04\nl05\nl06\nl07\nl08\nl09\nl10\nl11\nl12\nl13\nl14\nl15\nl16\nl17\nl18\nl19\nl20\nl21\nl22\nl23\nl24\nl25\nl26\nl27\nl28\nl29\n","mode":"normal","cursor":{"row":12,"col":0},"anchor":{"row":12,"col":0}}}
+{"name":"ins-pgdn","reason":"Terminal insert-mode page scrolling clamps to the live grid.","reference":{"name":"ins-pgdn","text":"l00\nl01\nl02\nl03\nl04\nl05\nl06\nl07\nl08\nl09\nl10\nl11\nl12\nl13\nl14\nl15\nl16\nl17\nl18\nl19\nl20\nl21\nl22\nl23\nl24\nl25\nl26\nl27\nl28\nl29\n","mode":"normal","cursor":{"row":25,"col":0},"anchor":{"row":25,"col":0}},"expected":{"name":"ins-pgdn","text":"l00\nl01\nl02\nl03\nl04\nl05\nl06\nl07\nl08\nl09\nl10\nl11\nl12\nl13\nl14\nl15\nl16\nl17\nl18\nl19\nl20\nl21\nl22\nl23\nl24\nl25\nl26\nl27\nl28\nl29\n","mode":"normal","cursor":{"row":12,"col":0},"anchor":{"row":12,"col":0}}}
+{"name":"zj-snaps-cursor","reason":"Terminal scroll limits change where scrolloff places the cursor.","reference":{"name":"zj-snaps-cursor","text":"l00\nl01\nl02\nl03\nl04\nl05\nl06\nl07\nl08\nl09\nl10\nl11\nl12\nl13\nl14\nl15\nl16\nl17\nl18\nl19\nl20\nl21\nl22\nl23\nl24\nl25\nl26\nl27\nl28\nl29\n","mode":"normal","cursor":{"row":4,"col":0},"anchor":{"row":4,"col":0}},"expected":{"name":"zj-snaps-cursor","text":"l00\nl01\nl02\nl03\nl04\nl05\nl06\nl07\nl08\nl09\nl10\nl11\nl12\nl13\nl14\nl15\nl16\nl17\nl18\nl19\nl20\nl21\nl22\nl23\nl24\nl25\nl26\nl27\nl28\nl29\n","mode":"normal","cursor":{"row":12,"col":0},"anchor":{"row":12,"col":0}}}
+{"name":"zj-noop-in-band","reason":"Scrolling at the terminal grid bottom is a no-op.","reference":{"name":"zj-noop-in-band","text":"l00\nl01\nl02\nl03\nl04\nl05\nl06\nl07\nl08\nl09\nl10\nl11\nl12\nl13\nl14\nl15\nl16\nl17\nl18\nl19\nl20\nl21\nl22\nl23\nl24\nl25\nl26\nl27\nl28\nl29\n","mode":"normal","cursor":{"row":10,"col":0},"anchor":{"row":10,"col":0}},"expected":{"name":"zj-noop-in-band","text":"l00\nl01\nl02\nl03\nl04\nl05\nl06\nl07\nl08\nl09\nl10\nl11\nl12\nl13\nl14\nl15\nl16\nl17\nl18\nl19\nl20\nl21\nl22\nl23\nl24\nl25\nl26\nl27\nl28\nl29\n","mode":"normal","cursor":{"row":11,"col":0},"anchor":{"row":11,"col":0}}}
+{"name":"zk-bottom-snap","reason":"Terminal view offsets start at the live grid's scroll boundary.","reference":{"name":"zk-bottom-snap","text":"l00\nl01\nl02\nl03\nl04\nl05\nl06\nl07\nl08\nl09\nl10\nl11\nl12\nl13\nl14\nl15\nl16\nl17\nl18\nl19\nl20\nl21\nl22\nl23\nl24\nl25\nl26\nl27\nl28\nl29\n","mode":"normal","cursor":{"row":19,"col":0},"anchor":{"row":19,"col":0}},"expected":{"name":"zk-bottom-snap","text":"l00\nl01\nl02\nl03\nl04\nl05\nl06\nl07\nl08\nl09\nl10\nl11\nl12\nl13\nl14\nl15\nl16\nl17\nl18\nl19\nl20\nl21\nl22\nl23\nl24\nl25\nl26\nl27\nl28\nl29\n","mode":"normal","cursor":{"row":20,"col":0},"anchor":{"row":20,"col":0}}}
+{"name":"unindent-tab","reason":"The terminal expands literal tabs to spaces before editing.","reference":{"name":"unindent-tab","text":"x\n","mode":"normal","cursor":{"row":0,"col":0},"anchor":{"row":0,"col":0}},"expected":{"name":"unindent-tab","text":" x\n","mode":"normal","cursor":{"row":0,"col":0},"anchor":{"row":0,"col":0}}}
+{"name":"comment-tab-indent","reason":"The terminal expands literal tabs to spaces before editing.","reference":{"name":"comment-tab-indent","text":"\t# alpha\n\t# beta\n","mode":"normal","cursor":{"row":1,"col":7},"anchor":{"row":0,"col":0}},"expected":{"name":"comment-tab-indent","text":" # alpha\n # beta\n","mode":"normal","cursor":{"row":1,"col":14},"anchor":{"row":0,"col":0}}}
+{"name":"comment-noeol","reason":"Terminal capture restores a trailing newline that the source omits.","reference":{"name":"comment-noeol","text":"# alpha","mode":"normal","cursor":{"row":0,"col":2},"anchor":{"row":0,"col":2}},"expected":{"name":"comment-noeol","text":"# alpha\n","mode":"normal","cursor":{"row":0,"col":2},"anchor":{"row":0,"col":2}}}
+{"name":"comment-only-blank","reason":"Terminal capture expands tabs and trims trailing blank rows.","reference":{"name":"comment-only-blank","text":" \n\t\n","mode":"normal","cursor":{"row":1,"col":1},"anchor":{"row":0,"col":0}},"expected":{"name":"comment-only-blank","text":" \n","mode":"normal","cursor":{"row":0,"col":3},"anchor":{"row":0,"col":0}}}
diff --git a/test/hxcases/regen.sh b/test/hxcases/regen.sh
deleted file mode 100755
index 308cc9d2..00000000
--- a/test/hxcases/regen.sh
+++ /dev/null
@@ -1,16 +0,0 @@
-#!/bin/sh
-# Regenerate test/hxcases/goldens.jsonl by running the helix reference harness
-# over cases.jsonl. The harness is hx-harness on the pardes-harness branch of
-# the genizah helix checkout (see docs/helix-keys.md, "Differential testing"):
-# cd ~/05-genizah/helix && git switch pardes-harness && \
-# cargo build --release -p helix-term --features helix-term/integration --bin hx-harness
-# Override the binary with $HX_HARNESS. helix ignores pane:"tty" — a tty
-# twin's golden is helix on the same text, which IS the oracle for tty
-# navigation parity.
-set -eu
-cd "$(dirname "$0")"
-HX_HARNESS="${HX_HARNESS:-$HOME/05-genizah/helix/target/release/hx-harness}"
-[ -x "$HX_HARNESS" ] || { echo "regen.sh: no hx-harness at $HX_HARNESS (set \$HX_HARNESS)" >&2; exit 1; }
-"$HX_HARNESS" cases.jsonl > goldens.jsonl.tmp
-mv goldens.jsonl.tmp goldens.jsonl
-wc -l goldens.jsonl
diff --git a/test/hxcases/waivers.jsonl b/test/hxcases/waivers.jsonl
index ca1b8ec5..82da2a08 100644
--- a/test/hxcases/waivers.jsonl
+++ b/test/hxcases/waivers.jsonl
@@ -1,6 +1,6 @@
-{"name":"wiX-edit-drops-sel","reason":"helix maps the selection through every insert-mode edit; pardes drops it on the first edit instead (anchor-only divergence, text+cursor+mode match). Re-judged phase 5 and kept: mapping the anchor through all ~23 mutation sites in handleInsert (multi-line inserts, EOL joins, kill runs) is genuinely invasive, and nothing in pardes consumes an implicit selection after insert-mode typing - the acme chords need explicit selections, which never enter insert."}
-{"name":"alt-c-window-op","reason":"deliberate pardes binding: Alt-c is the move-pane-to-fresh-column window op in ANY mode (do-not-touch contract); helix Alt-c is change-noyank. Alt-d + i covers the helix behavior; the buffer is untouched on the pardes side."}
-{"name":"msel-append","reason":"multiple cursors + `a`: pardes restores the appended-over span for the PRIMARY only, because Pane.append_at (where the append session began) is a single field and the other ranges have nowhere to keep their own origin. Every cursor lands on the right cell and the text matches; only the secondaries' anchors differ, so they read as bare cursors instead of spanning what was typed. Same family as wiX-edit-drops-sel: pardes does not map selections through insert-mode edits. Fix = an origin per SelRange."}
-{"name":"msel-yank-paste","reason":"pardes has ONE yank register; helix's holds one VALUE PER RANGE and pastes value[i] back at range[i]. A multi-range `y` in pardes therefore joins the ranges' text with newlines and `p` puts the whole newline-joined blob at every cursor (which also makes it linewise). Deliberate: a per-range register is its own feature, not part of the selection model. Single-range yank/paste is unaffected and covered by the yank-* / paste-* cases."}
-{"name": "sel-regex-dot-newline", "reason": "mvzr's `.` matches ANY byte, newlines included; helix builds its pattern with the Rust regex crate, where `.` excludes \\n unless asked. So `%s.` selects one range per byte in pardes and one per non-newline byte in helix. Deliberate: closing it means rewriting `.` to `[^\\n]` inside the pattern, and doing that correctly needs a real parse (`\\.` is a literal dot, a `.` inside `[...]` is already literal) - a regex parser written to work around the regex engine. `[^\\n]` typed at the prompt LOOKS like the workaround and is not one: the live preview compiles every prefix, and the prefix `[^\\` panics mvzr (index out of bounds in parseCharSet) before the pattern can be finished. Guarding the compile is what would make it typable."}
-{"name": "sel-regex-caret", "reason": "helix compiles the `s`/`S` pattern with multi_line(true), so `^` and `$` are LINE anchors; mvzr has no such flag and asserts them against the START OF THE SLICE it is handed, which pardes advances to each match's end. `%s^a` therefore finds one match in pardes and one per line in helix. Same root cause for `$`. Fixing it means either searching line by line - which changes which ranges come out for every OTHER pattern, since a match may not span a line then - or an engine with multi-line assertions. Every other anchor-free pattern agrees, including \\b (sel-regex-boundary)."}
+{"name":"wiX-edit-drops-sel","reason":"Insert edits clear the selection instead of tracking its anchor.","reference":{"name":"wiX-edit-drops-sel","text":"Xalpha beta\n","mode":"normal","cursor":{"row":0,"col":1},"anchor":{"row":0,"col":6}},"expected":{"name":"wiX-edit-drops-sel","text":"Xalpha beta\n","mode":"normal","cursor":{"row":0,"col":1},"anchor":{"row":0,"col":1}}}
+{"name":"alt-c-window-op","reason":"Alt-c moves a pane to a new column instead of Helix's change-noyank.","reference":{"name":"alt-c-window-op","text":"bc def\n","mode":"insert","cursor":{"row":0,"col":0},"anchor":{"row":0,"col":0}},"expected":{"name":"alt-c-window-op","text":"abc def\n","mode":"normal","cursor":{"row":0,"col":0},"anchor":{"row":0,"col":0}}}
+{"name":"msel-append","reason":"Append-mode selection origins are tracked only for the primary selection.","reference":{"name":"msel-append","text":"aza\nbzb\n","mode":"normal","cursor":{"row":1,"col":1},"anchor":{"row":1,"col":0},"sels":[{"cursor":{"row":0,"col":1},"anchor":{"row":0,"col":0}},{"cursor":{"row":1,"col":1},"anchor":{"row":1,"col":0}}],"primary":1},"expected":{"name":"msel-append","text":"aza\nbzb\n","mode":"normal","cursor":{"row":1,"col":1},"anchor":{"row":1,"col":0},"sels":[{"cursor":{"row":0,"col":1},"anchor":{"row":0,"col":1}},{"cursor":{"row":1,"col":1},"anchor":{"row":1,"col":0}}],"primary":1}}
+{"name":"msel-yank-paste","reason":"Pardes has one combined yank register, not one value per selection.","reference":{"name":"msel-yank-paste","text":"aab\nccd\n","mode":"normal","cursor":{"row":1,"col":1},"anchor":{"row":1,"col":1},"sels":[{"cursor":{"row":0,"col":1},"anchor":{"row":0,"col":1}},{"cursor":{"row":1,"col":1},"anchor":{"row":1,"col":1}}],"primary":1},"expected":{"name":"msel-yank-paste","text":"aa\ncb\nca\ncd\n","mode":"normal","cursor":{"row":3,"col":0},"anchor":{"row":2,"col":1},"sels":[{"cursor":{"row":1,"col":0},"anchor":{"row":0,"col":1}},{"cursor":{"row":3,"col":0},"anchor":{"row":2,"col":1}}],"primary":1}}
+{"name":"sel-regex-dot-newline","reason":"The regex engine includes newlines in dot matches.","reference":{"name":"sel-regex-dot-newline","text":"ab\n","mode":"normal","cursor":{"row":0,"col":0},"anchor":{"row":0,"col":0},"sels":[{"cursor":{"row":0,"col":0},"anchor":{"row":0,"col":0}},{"cursor":{"row":0,"col":1},"anchor":{"row":0,"col":1}}],"primary":0},"expected":{"name":"sel-regex-dot-newline","text":"ab\n","mode":"normal","cursor":{"row":0,"col":0},"anchor":{"row":0,"col":0},"sels":[{"cursor":{"row":0,"col":0},"anchor":{"row":0,"col":0}},{"cursor":{"row":0,"col":1},"anchor":{"row":0,"col":1}},{"cursor":{"row":0,"col":2},"anchor":{"row":0,"col":2}}],"primary":0}}
+{"name":"sel-regex-caret","reason":"The regex engine lacks Helix's multiline anchors.","reference":{"name":"sel-regex-caret","text":"ab\nab\n","mode":"normal","cursor":{"row":0,"col":0},"anchor":{"row":0,"col":0},"sels":[{"cursor":{"row":0,"col":0},"anchor":{"row":0,"col":0}},{"cursor":{"row":1,"col":0},"anchor":{"row":1,"col":0}}],"primary":0},"expected":{"name":"sel-regex-caret","text":"ab\nab\n","mode":"normal","cursor":{"row":0,"col":0},"anchor":{"row":0,"col":0}}}