summaryrefslogtreecommitdiff
path: root/test/snapshots
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/snapshots
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/snapshots')
-rw-r--r--test/snapshots/acmefs-event.golden15
-rw-r--r--test/snapshots/acmefs-event.snap39
-rw-r--r--test/snapshots/acmefs.golden30
-rw-r--r--test/snapshots/acmefs.snap40
-rw-r--r--test/snapshots/builtins.golden129
-rw-r--r--test/snapshots/builtins.snap75
-rw-r--r--test/snapshots/dump.golden1
-rw-r--r--test/snapshots/dump.snap4
-rw-r--r--test/snapshots/leader.golden79
-rw-r--r--test/snapshots/leader.snap92
-rw-r--r--test/snapshots/load.golden2
-rw-r--r--test/snapshots/load.snap4
-rw-r--r--test/snapshots/lsp-client.golden15
-rw-r--r--test/snapshots/lsp-client.snap9
-rw-r--r--test/snapshots/lspdebug.golden30
-rw-r--r--test/snapshots/lspdebug.snap64
-rw-r--r--test/snapshots/mini.golden183
-rw-r--r--test/snapshots/mini.snap23
-rw-r--r--test/snapshots/nested-optout.snap28
-rw-r--r--test/snapshots/nested.snap21
-rw-r--r--test/snapshots/ninep.golden195
-rw-r--r--test/snapshots/ninep.snap28
-rw-r--r--test/snapshots/shellset.snap2
23 files changed, 534 insertions, 574 deletions
diff --git a/test/snapshots/acmefs-event.golden b/test/snapshots/acmefs-event.golden
deleted file mode 100644
index 58488f1e..00000000
--- a/test/snapshots/acmefs-event.golden
+++ /dev/null
@@ -1,15 +0,0 @@
-== snap after-suppressed-click grid=100x30 cursor=7,5
-|New Newcol Joincol Find Grep Help Changelog Tutor Dump NextColor Debug Kill
-|$ /tmp/pardes-snap/acmefs-event/cwd Save New Newtty Del Filter
-| $
-| /tmp/pardes-snap/acmefs-event/cwd/+New * Save New Newtty Del
-| 1 Newcol
-| 2
-== file events
-MX0 6 1 6 Newcol|
-
-== end file
-== snap after-unsuppressed-click grid=100x30 cursor=57,2
-|1: $ /tmp/pardes-snap/acmefs-event/cwd Save New Newtt /tmp/pardes-snap/acmefs-event/cwd/+New Save New
-|2: $ 1
-|3: /tmp/pardes-snap/acmefs-event/cwd/+New * Save Ne
diff --git a/test/snapshots/acmefs-event.snap b/test/snapshots/acmefs-event.snap
deleted file mode 100644
index 33f8b01c..00000000
--- a/test/snapshots/acmefs-event.snap
+++ /dev/null
@@ -1,39 +0,0 @@
-# The acme INVERSION, end to end: while a script holds a pane's `event` file
-# open, a middle click in that pane is REPORTED to the script instead of being
-# executed by the editor. That is how an acme client defines its own commands —
-# `Step`, `Run`, `Clear` in examples/acmefs/life.py — and it is the one piece of
-# this filesystem that changes what a click MEANS.
-#
-# The clicked word is `Newcol`, a real pardes builtin, so the two halves of the
-# test cannot be confused with each other: with a reader attached the screen
-# must not change and the record must arrive; with the reader gone the same
-# click must open a column. It sits on the +New pane's first body line — row 5,
-# and the line-number gutter is 7 cells wide, so the word starts at column 8.
-run sh -c 'fusermount3 -u -z /tmp/pardes-acmefs-ev 2>/dev/null; rm -rf /tmp/pardes-acmefs-ev; exit 0'
-start 30 100 --fs=/tmp/pardes-acmefs-ev
-wait 8000 New Newcol
-stable 700 20000
-run sh -c 'M=/tmp/pardes-acmefs-ev; id=$(cut -c1-11 < $M/new/ctl | tr -d " "); echo $id > id.txt; printf "Newcol\n" >> $M/$id/body'
-wait 8000 New Newcol
-stable 700 15000
-# a reader arrives: from here on, buttons 2 and 3 in this pane are its business
-run sh -c 'M=/tmp/pardes-acmefs-ev; id=$(cat id.txt); (cat $M/$id/event > events.txt & echo $! > cat.pid); sleep 1'
-press middle 9 5
-release middle 9 5
-stable 700 15000
-# The screen must be UNCHANGED: no column opened, because the click belonged to
-# the reader. An editor that had performed it would have split the layout.
-snap after-suppressed-click
-# The reader's death is asynchronous: the kernel sends RELEASE when the process
-# closes, and pardes drains filesystem requests in its frame poll, AFTER input.
-# A click delivered in the same wakeup as that RELEASE is therefore still the
-# reader's. One second of sleep is more than the frame this takes.
-run sh -c 'sleep 1; kill $(cat cat.pid) 2>/dev/null; sleep 1; sed -e "s/$/|/" events.txt > ev.txt; exit 0'
-snapfile events ev.txt
-# ...and with the reader gone, the same click is an ordinary Exec again: this
-# one opens the column.
-press middle 9 5
-release middle 9 5
-stable 700 15000
-snap after-unsuppressed-click
-run sh -c 'fusermount3 -u -z /tmp/pardes-acmefs-ev 2>/dev/null; rm -rf /tmp/pardes-acmefs-ev; exit 0'
diff --git a/test/snapshots/acmefs.golden b/test/snapshots/acmefs.golden
deleted file mode 100644
index 8e2e37f4..00000000
--- a/test/snapshots/acmefs.golden
+++ /dev/null
@@ -1,30 +0,0 @@
-== file tree
-1
-cons
-index
-new
-
-== end file
-== snap fs-body-written grid=100x30 cursor=7,5
-|New Newcol Joincol Find Grep Help Changelog Tutor Dump NextColor Debug Kill
-|$ /tmp/pardes-snap/acmefs/cwd Save New Newtty Del Filter
-| $
-| /tmp/pardes-snap/acmefs/cwd/+New * Save New Newtty Del
-| 1 hello from outside
-| 2
-== file body
-hello from outside
-
-== end file
-== file ctlid
-2
-
-== end file
-== file firstid
-1
-
-== end file
-== snap fs-event-exec grid=100x30 cursor=57,2
-|1: $ /tmp/pardes-snap/acmefs/cwd Save New Newtty Del /tmp/pardes-snap/acmefs/cwd/+New Save New Newtty
-|2: $ 1
-|3: /tmp/pardes-snap/acmefs/cwd/+New *
diff --git a/test/snapshots/acmefs.snap b/test/snapshots/acmefs.snap
deleted file mode 100644
index e338245b..00000000
--- a/test/snapshots/acmefs.snap
+++ /dev/null
@@ -1,40 +0,0 @@
-# acme's control filesystem, end to end: a process OUTSIDE pardes opens a pane,
-# fills its body, reads it back through the same tree, and finally drives a
-# builtin by writing an event record — the acme remote-control door.
-#
-# Everything here runs through a real FUSE mount served by the real binary, so
-# a failure means the mount, the protocol, the transaction or the semantics —
-# there is nothing else in the path.
-#
-# The mount lives OUTSIDE this script's own directory, and the script unmounts
-# it at both ends. Two reasons, both about how this harness works: it kills the
-# app with SIGKILL, so pardes never gets to unmount (that is what
-# fuse.sweepStale exists for, but a `--fs=<dir>` this explicit is not ours to
-# sweep), and a stale ENOTCONN mount inside the per-script directory would make
-# the next run's `rm -rf` — and therefore its mkdir — fail.
-run sh -c 'fusermount3 -u -z /tmp/pardes-acmefs-snap 2>/dev/null; rm -rf /tmp/pardes-acmefs-snap; exit 0'
-start 30 100 --fs=/tmp/pardes-acmefs-snap
-wait 8000 New Newcol
-stable 700 20000
-# the tree acme(4) describes, served by pardes
-run sh -c 'ls /tmp/pardes-acmefs-snap > tree.txt 2>&1'
-snapfile tree tree.txt
-# `new` creates a pane on ACCESS, and its ctl reads back the pane's own id
-# (field 1 of acme's five). Writing body appends, so the pane holds the bytes.
-run sh -c 'M=/tmp/pardes-acmefs-snap; id=$(cut -c1-11 < $M/new/ctl | tr -d " "); echo $id > id.txt; printf "hello from outside\n" >> $M/$id/body'
-wait 8000 hello from outside
-stable 700 15000
-snap fs-body-written
-# ...and reading it back is the same filesystem answering about live state
-run sh -c 'M=/tmp/pardes-acmefs-snap; id=$(cat id.txt); cat $M/$id/body > body.txt; cut -c1-11 < $M/$id/ctl | tr -d " " > ctlid.txt; sed -n 1p $M/index | cut -c1-11 | tr -d " " > firstid.txt'
-snapfile body body.txt
-snapfile ctlid ctlid.txt
-snapfile firstid firstid.txt
-# THE DOOR: put a builtin in the pane's tag, then write an event record naming
-# its byte range. pardes executes it exactly as a middle click would — which is
-# how an acme client has always run editor commands, and is code execution by
-# design (see examples/README.md).
-run sh -c 'M=/tmp/pardes-acmefs-snap; id=$(cat id.txt); q0=$(wc -c < $M/$id/tag); printf " Newcol" >> $M/$id/tag; q1=$(wc -c < $M/$id/tag); printf "Mx%d %d\n" $((q0 + 1)) $q1 > $M/$id/event'
-stable 700 15000
-snap fs-event-exec
-run sh -c 'fusermount3 -u -z /tmp/pardes-acmefs-snap 2>/dev/null; rm -rf /tmp/pardes-acmefs-snap; exit 0'
diff --git a/test/snapshots/builtins.golden b/test/snapshots/builtins.golden
index a9a34616..5c9ab060 100644
--- a/test/snapshots/builtins.golden
+++ b/test/snapshots/builtins.golden
@@ -8,73 +8,8 @@
| 5 line 5
| 6 line 6
| 7
-== snap index grid=120x66 cursor=7,35
+== snap window-group grid=120x66 cursor=7,35
|34: /tmp/pardes-snap/builtins/cwd/+Help Save New Newtty Del
-|35: 1 pardes builtins, and how to run each:
-|36: 2 SPC and its keys, a chord, a button, the
-|37: 3 topbar - or the name, executed anywhere.
-|38: 4
-|39: 5 SPC ? Help topbar
-|40: 6 SPC P ClipPasteBefore
-|41: 7 SPC R ClipReplace
-|42: 8 SPC Y ClipYankMain
-|43: 9 SPC a a PanelAscii
-|44: 10 SPC a c PanelCurtain
-|45: 11 SPC a d PanelDissolve
-|46: 12 SPC a e PanelEdges
-|47: 13 SPC a f PanelFall
-|48: 14 SPC a r PanelScramble
-|49: 15 SPC a s PanelSlide
-|50: 16 SPC a t PanelType
-|51: 17 SPC a v PanelVertical
-|52: 18 SPC a w PanelWave
-|53: 19 SPC a z PanelZoom
-|54: 20 SPC c d Delcol
-|55: 21 SPC c j Joincol topbar
-|56: 22 SPC c n Newcol topbar
-|57: 23 SPC d Del
-|58: 24 SPC f c Config
-|59: 25 SPC f f Find topbar
-|60: 26 SPC f g Grep topbar
-|61: 27 SPC f n New topbar
-|62: 28 SPC f s Save
-|63: 29 SPC h c Changelog topbar
-|64: 30 SPC h m Messages
-|65: 31 SPC h t Tutor topbar
-== snap index-tail grid=120x66 cursor=7,64
-|35: 67 SPC t w Wrap
-|36: 68 SPC t z PdfFit
-|37: 69 SPC w h Left C-w h, C-w left
-|38: 70 SPC w j Down C-w j, C-w down
-|39: 71 SPC w k Up C-w k, C-w up
-|40: 72 SPC w l Right C-w l, C-w right
-|41: 73 SPC y ClipYank
-|42: 74 Look enter, right-click
-|43: 75 Exec tab, middle-click
-|44: 76 Msg
-|45: 77 ThemeFile
-|46: 78 DumpThemes
-|47: 79 Filter
-|48: 80 EffectCode
-|49: 81 9p
-|50: 82 Theme
-|51: 83 Shell
-|52: 84
-|53: 85 language keys (motions, not words):
-|54: 86 gd gD gy gi gr goto: definition,
-|55: 87 declaration, type-def,
-|56: 88 implementation, refs
-|57: 89 ]d [d ]D [D diagnostics: next,
-|58: 90 prev, last, first
-|59: 91 = format (applies, one
-|60: 92 undo step)
-|61: 93 Tab after a . completion, in insert
-|62: 94 C-left-click definition, by mouse
-|63: 95 SPC l ... hover, rename, symbols,
-|64: 96 calls, types: above
-|65: 97
-== snap not-a-picker grid=120x66 cursor=19,61
-== snap window-group grid=120x66 cursor=19,35
|35: 1 pardes builtins under SPC w
|36: 2
|37: 3 SPC w h Left C-w h, C-w left
@@ -82,30 +17,13 @@
|39: 5 SPC w k Up C-w k, C-w up
|40: 6 SPC w l Right C-w l, C-w right
|41: 7
-|42:
-|43:
-|44:
-|45:
-|46:
-|47:
-|48:
-|49:
-|50:
-|51:
-|52:
-|53:
-|54:
-|55:
-|56:
-|57:
-|58:
-|59:
-|60:
-|61:
-|62:
-|63:
-|64:
-|65:
+== snap docs-group grid=120x66 cursor=7,35
+|35: 1 pardes builtins under SPC h
+|37: 3 SPC h c Changelog topbar
+|38: 4 SPC h m Messages
+|39: 5 SPC h t Tutor topbar
+|40: 6
+|41:
== snap tutor-from-index grid=120x66 cursor=7,19
|18: /Tutor Save New Newtty Del
|19: 1
@@ -123,34 +41,3 @@
|31: 13
|32: 14 A pane is just text on screen. There is no separate "buffer" type —
|33: 15 what you see is what you edit. Some panes happen to be live terminals;
-|35: 1 pardes builtins, and how to run each:
-|36: 2 SPC and its keys, a chord, a button, the
-|37: 3 topbar - or the name, executed anywhere.
-|38: 4
-|39: 5 SPC ? Help topbar
-|40: 6 SPC P ClipPasteBefore
-|41: 7 SPC R ClipReplace
-|42: 8 SPC Y ClipYankMain
-|43: 9 SPC a a PanelAscii
-|44: 10 SPC a c PanelCurtain
-|45: 11 SPC a d PanelDissolve
-|46: 12 SPC a e PanelEdges
-|47: 13 SPC a f PanelFall
-|48: 14 SPC a r PanelScramble
-|49: 15 SPC a s PanelSlide
-|50: 16 SPC a t PanelType
-|51: 17 SPC a v PanelVertical
-|52: 18 SPC a w PanelWave
-|53: 19 SPC a z PanelZoom
-|54: 20 SPC c d Delcol
-|55: 21 SPC c j Joincol topbar
-|56: 22 SPC c n Newcol topbar
-|57: 23 SPC d Del
-|58: 24 SPC f c Config
-|59: 25 SPC f f Find topbar
-|60: 26 SPC f g Grep topbar
-|61: 27 SPC f n New topbar
-|62: 28 SPC f s Save
-|63: 29 SPC h c Changelog topbar
-|64: 30 SPC h m Messages
-|65: 31 SPC h t Tutor topbar
diff --git a/test/snapshots/builtins.snap b/test/snapshots/builtins.snap
index 95db3fd9..aebb2a18 100644
--- a/test/snapshots/builtins.snap
+++ b/test/snapshots/builtins.snap
@@ -1,72 +1,35 @@
-# RULE: Help is THE INDEX of the builtins — every one of them, and every way
-# to run it — not a listing of leader paths. Three columns, all derived at
-# comptime from config.zig's own tables: the SPC path (leader_path), the name,
-# and every other shortcut bound to that name (window_keys and jump_keys' `cmd`
-# columns, look_cmd/exec_cmd with their keys and mouse buttons, a word in
-# topbar_str). A builtin added tomorrow is a row here with nothing to edit.
-#
-# The cases this exists for are the ones a leader listing could not show:
-# Look and Exec have NO SPC path — their shortcuts are Enter/Tab and the two
-# mouse buttons — Theme has no shortcut at all, because a key path can never
-# carry the name of a theme, and Filter is reached from terminal tags rather
-# than the leader. All are rows, and their blank columns are the information.
-#
-# `SPC ?` mid-chord is the SAME array read with a non-empty prefix, which is
-# why there is one builtin here and not two: the group filter drops the
-# path-less rows by itself, and the reference page is the filter's empty case.
lines notes.txt 6
start 66 120 notes.txt
wait 8000 notes.txt
stable 700 20000
snap boot
-# SPC ? at the ROOT. Focus follows the listing — you asked to read it.
+
+# The full index includes commands without leader paths.
key space ?
-wait 10000 SPC c n
-stable 700 15000
-snap index
-# The tail of the same listing: the window group carries BOTH spellings of
-# each Ctrl-w chord (the table carries both), and past the last path come the
-# builtins SPC cannot reach. `ge` walks the buffer's own body to the end.
+wait 10000 pardes builtins, and how to run each:
+wait 10000 ClipPasteBefore
key g e
+wait 10000 Look enter, right-click
+wait 10000 Exec tab, middle-click
+wait 10000 Filter
+wait 10000 Theme
stable 700 15000
-snap index-tail
-# n/N here run NOTHING, and no longer could: they are a MOTION, and the only
-# thing they do is move the selection onto look-able text. A row here is a key
-# path and a NAME — this list holds Kill, Del and Delcol — and a name is not a
-# path, so the ring finds nothing to stop on in this buffer or in the file
-# above it. Three presses, and the panes and the listing are all where they
-# were. Picking a command is executing its row, two snaps down.
-key n
-key n
-key n
-stable 700 15000
-snap not-a-picker
-# and the mid-chord filter is untouched: `SPC w ?` still answers "what can w
-# still reach", rewriting the same +Help buffer with just that group — the four
-# directional moves, each now also showing the Ctrl-w chord that is the other
-# way in, and none of the path-less builtins, which `w` cannot reach.
+
+# n moves through look-able text; it must not execute command names.
+key n n n
+wait 10000 Look enter, right-click
+wait 10000 Exec tab, middle-click
key space w ?
wait 10000 Right
stable 700 15000
snap window-group
-# back to the whole index, and a NAME in it is live text like anywhere else:
-# middle-click `Tutor` and the tutor opens. That is how a list of commands is
-# picked from — you run the row you want and the ones you passed stay unrun,
-# which is the whole reason n/N were never allowed to be the picker.
-#
-# The one place in this suite a builtin cannot be added for free: the click is
-# a SCREEN COORDINATE. The rows above `SPC h t` in the listing move Tutor and
-# this number with them — the five clipboard builtins put three there. And
-# since the language-keys footer made the page longer than the pane, the
-# re-opened view RETAINS the scroll the `ge` above left behind, which is why
-# `gg` now pins the top before the click: an exec aimed one row into the
-# footer would run "declaration," in a shell instead of opening the tutor.
-key space ?
-wait 10000 SPC c n
-key g g
+
+key space h ?
+wait 10000 Tutor
stable 700 15000
-press middle 20 66
-release middle 20 66
+snap docs-group
+press middle @Tutor 40
+release middle @Tutor 40
wait 10000 PARDES TUTOR
stable 700 15000
snap tutor-from-index
diff --git a/test/snapshots/dump.golden b/test/snapshots/dump.golden
index 74ac0c57..fbbfd92b 100644
--- a/test/snapshots/dump.golden
+++ b/test/snapshots/dump.golden
@@ -63,5 +63,6 @@
.image = null,
},
},
+ .mounts = .{},
}
== end file
diff --git a/test/snapshots/dump.snap b/test/snapshots/dump.snap
index 02803525..ddac01a2 100644
--- a/test/snapshots/dump.snap
+++ b/test/snapshots/dump.snap
@@ -1,6 +1,4 @@
-# the Dump builtin serializes the session to $DUMP (this script's own dump
-# file under /tmp/pardes-snap/dump/); the ZON must
-# be byte-identical between old and new (golden generated from the OLD binary)
+# Dump serializes the session to this fixture's $DUMP path.
file d.txt x
start 30 100 -n 3
wait 8000 d.txt
diff --git a/test/snapshots/leader.golden b/test/snapshots/leader.golden
index d2068e8d..fd4fbf98 100644
--- a/test/snapshots/leader.golden
+++ b/test/snapshots/leader.golden
@@ -44,45 +44,14 @@
== snap abandoned grid=100x40 cursor=7,2
|39:
== snap unmapped grid=100x40 cursor=7,2
-== snap help-word grid=100x40 cursor=7,22
-|21: /tmp/pardes-snap/leader/cwd/+Help Save New Newtty Del
-|22: 1 pardes builtins, and how to run each:
-|23: 2 SPC and its keys, a chord, a button, the
-|24: 3 topbar - or the name, executed anywhere.
-|25: 4
-|26: 5 SPC ? Help topbar
-|27: 6 SPC P ClipPasteBefore
-|28: 7 SPC R ClipReplace
-|29: 8 SPC Y ClipYankMain
-|30: 9 SPC a a PanelAscii
-|31: 10 SPC a c PanelCurtain
-|32: 11 SPC a d PanelDissolve
-|33: 12 SPC a e PanelEdges
-|34: 13 SPC a f PanelFall
-|35: 14 SPC a r PanelScramble
-|36: 15 SPC a s PanelSlide
-|37: 16 SPC a t PanelType
-|38: 17 SPC a v PanelVertical
-|39: 18 SPC a w PanelWave
== snap help-group grid=100x40 cursor=7,22
+|21: /tmp/pardes-snap/leader/cwd/+Help Save New Newtty Del
|22: 1 pardes builtins under SPC h
|23: 2
|24: 3 SPC h c Changelog topbar
|25: 4 SPC h m Messages
|26: 5 SPC h t Tutor topbar
|27: 6
-|28:
-|29:
-|30:
-|31:
-|32:
-|33:
-|34:
-|35:
-|36:
-|37:
-|38:
-|39:
== snap tutor grid=100x40 cursor=7,12
|11: /Tutor Save New Newtty Del
|12: 1
@@ -105,44 +74,6 @@
|18:
|19:
|20:
-== snap help-all grid=100x40 cursor=7,22
-|22: 1 pardes builtins, and how to run each:
-|23: 2 SPC and its keys, a chord, a button, the
-|24: 3 topbar - or the name, executed anywhere.
-|25: 4
-|26: 5 SPC ? Help topbar
-|27: 6 SPC P ClipPasteBefore
-|28: 7 SPC R ClipReplace
-|29: 8 SPC Y ClipYankMain
-|30: 9 SPC a a PanelAscii
-|31: 10 SPC a c PanelCurtain
-|32: 11 SPC a d PanelDissolve
-|33: 12 SPC a e PanelEdges
-|34: 13 SPC a f PanelFall
-|35: 14 SPC a r PanelScramble
-|36: 15 SPC a s PanelSlide
-|37: 16 SPC a t PanelType
-|38: 17 SPC a v PanelVertical
-|39: 18 SPC a w PanelWave
-== snap help-toggles grid=100x40 cursor=7,22
-|22: 1 pardes builtins under SPC t
-|23: 2
-|24: 3 SPC t a Ascii
-|25: 4 SPC t b Tagbottom
-|26: 5 SPC t c Colors
-|27: 6 SPC t d Debug topbar
-|28: 7 SPC t i PdfTint
-|29: 8 SPC t l Palette
-|30: 9 SPC t n NextColor topbar
-|31: 10 SPC t p Petscii
-|32: 11 SPC t s PdfSections
-|33: 12 SPC t t ThemeSel
-|34: 13 SPC t w Wrap
-|35: 14 SPC t z PdfFit
-|36: 15
-|37:
-|38:
-|39:
== snap help-window grid=100x40 cursor=7,22
|22: 1 pardes builtins under SPC w
|24: 3 SPC w h Left C-w h, C-w left
@@ -150,14 +81,6 @@
|26: 5 SPC w k Up C-w k, C-w up
|27: 6 SPC w l Right C-w l, C-w right
|28: 7
-|29:
-|30:
-|31:
-|32:
-|33:
-|34:
-|35:
-|36:
== snap help-language grid=100x40 cursor=7,22
|22: 1 pardes builtins under SPC l
|24: 3 SPC l C Callees
diff --git a/test/snapshots/leader.snap b/test/snapshots/leader.snap
index f6eae3ea..eb253b37 100644
--- a/test/snapshots/leader.snap
+++ b/test/snapshots/leader.snap
@@ -1,106 +1,60 @@
-# The SPC leader: every builtin also has a KEY PATH, and SPC walks it. While a
-# path is pending the active pane's tag shows it at its RIGHT edge (the `/`
-# input's rule — state you can see — right-aligned so it never collides with
-# the tail's builtins). `?` at any depth opens the Help builtin, listing what
-# the prefix typed so far can still reach, into a +Help OUTPUT BUFFER (a file
-# pane with no file behind it, like +Search). The paths, the Help lines and
-# the execute dispatch are all folded out of ONE enum at comptime — so
-# executing the WORD `Help` runs the same builtin the leader does.
file cmds.txt Help
start 40 100 cmds.txt
wait 8000 New Newcol
wait 8000 cmds.txt
stable 700 20000
-# SPC arms the leader: the indicator appears on the active pane's tag
+
key space
stable 400 5000
snap spc
-# ... and grows as the path is typed (`h` = the docs group)
key h
stable 400 5000
snap spc-h
-# Esc abandons the sequence: indicator gone, nothing ran, cursor untouched
key esc
settle 100
stable 400 5000
snap abandoned
-# an UNMAPPED key abandons too, rather than waiting: a typo must not leave the
-# next keystroke armed at a builtin that closes panes
-key space
-key q
+key space q
stable 400 5000
snap unmapped
-# executing the WORD `Help` (middle-click) runs the builtin — the enum IS the
-# lookup, so a name works anywhere text lives. Every builtin, with its keys.
-press middle 9 3
-release middle 9 3
-# New builtins can push most of the index below this short pane, so this waits
-# on a row ABOVE the growth: the clipboard builtins sort first (uppercase paths)
-# and only the whole-index listing shows them, which is exactly the fact under
-# test — the word `Help` opened the full registry, not a group.
+
+# Executing Help as text opens the full index, not a filtered group.
+press middle @Help 3
+release middle @Help 3
+wait 10000 pardes builtins, and how to run each:
wait 10000 ClipPasteBefore
-stable 700 15000
-snap help-word
-# `SPC h ?`: only the `h` group, rewritten into the SAME +Help buffer
-key space
-key h
-key ?
+key space h ?
wait 10000 under SPC h
stable 700 15000
snap help-group
-# `SPC h t`: the Tutor builtin, zero arguments. It runs from the +Help pane,
-# but that is an output pane and not a document — so the tutor lands under
-# cmds.txt, the real doc, with the listing left at the foot of the column.
-key space
-key h
-key t
+
+key space h t
wait 10000 PARDES TUTOR
stable 700 15000
snap tutor
-# `SPC d`: Del is pane-scoped — it closes the tutor, focus falls back
-key space
-key d
+key space d
stable 700 15000
snap deleted
-# `SPC ?` at the root lists everything again. Waits on an EARLY row: the full
-# listing outgrew this pane when the language group landed, and the panel
-# effects pushed `SPC c n` off the bottom too. The clipboard paths sort first
-# and appear only in the whole-index listing, so they stay a valid witness.
-key space
-key ?
+
+key space ?
+wait 10000 pardes builtins, and how to run each:
wait 10000 ClipPasteBefore
-stable 700 15000
-snap help-all
-# `SPC t ?`: the TTY toggle group, including the image-renderer and PDF
-# switches that became builtins instead of tag words. Native scene shaders are
-# capability-gated out of this build, so Crt/Ripple/Glitch are absent here.
-key space
-key t
-key ?
+
+# PDF commands depend on the build; these toggles do not.
+key space t ?
+wait 10000 under SPC t
+wait 10000 Ascii
+wait 10000 Palette
wait 10000 Petscii
-stable 700 15000
-snap help-toggles
-# `SPC w ?`: the window group, whose five builtins are the tail of the full
-# listing above and fall off the bottom of this pane there
-key space
-key w
-key ?
+wait 10000 Wrap
+key space w ?
wait 10000 Right
stable 700 15000
snap help-window
-# `SPC l ?`: the LANGUAGE group — every LSP command lives here rather than on
-# the bare `<space>` letters helix uses, so `d` stays Del and `k` stays Kill.
-# Each one keeps helix's own letter INSIDE the group (hover k, rename r, code
-# action a, symbols s/S, diagnostics d/D, select-refs h), plus the two
-# introspection builtins that are ours: i and w.
-key space
-key l
-key ?
+key space l ?
wait 10000 WsDiagnostics
stable 700 15000
snap help-language
-# Output buffers close through the same explicit Del builtin as every other
-# pane. Body-normal Esc is now Last and deliberately keeps +Help alive.
key space d
settle 100
stable 700 15000
diff --git a/test/snapshots/load.golden b/test/snapshots/load.golden
index 16a07805..bc5d5ddd 100644
--- a/test/snapshots/load.golden
+++ b/test/snapshots/load.golden
@@ -1,7 +1,7 @@
== snap loaded grid=100x30 cursor=4,15
|New Newcol Joincol Find Grep Help Changelog Tutor Dump NextColor Debug Kill
| /tmp/pardes-snap/load/cwd Save New Newtty Del Fi /tmp/pardes-snap/load/cwd Save New Newtty Del Fi
-| echo LOAD''MARK; seq 1 40 ls
+| echo LOAD''MARK; seq 1 40; echo E''ND ls
| LOADMARK d.txt
| 1
| 2
diff --git a/test/snapshots/load.snap b/test/snapshots/load.snap
index c224e2fb..8ae63b28 100644
--- a/test/snapshots/load.snap
+++ b/test/snapshots/load.snap
@@ -8,9 +8,9 @@ wait 8000 d.txt
stable 700 20000
key c-b
stable 600 8000
-text echo LOAD''MARK; seq 1 40
+text echo LOAD''MARK; seq 1 40; echo E''ND
key enter
-wait 8000 LOADMARK
+wait 8000 END
stable 700 10000
key c-b
stable 600 8000
diff --git a/test/snapshots/lsp-client.golden b/test/snapshots/lsp-client.golden
index a203cc7c..d937889c 100644
--- a/test/snapshots/lsp-client.golden
+++ b/test/snapshots/lsp-client.golden
@@ -18,10 +18,17 @@
| 3 a + b
| 4 }
| 5
-== snap gr-list grid=100x24 cursor=16,15
+== snap gr-list grid=100x24 cursor=21,5
|12:
|20: /tmp/pardes-snap/lsp-client/cwd/+Search Save New Newtty Del
-|21: 1 main.rs:4:13-15 let x = add(1, 2);
-|22: 2 main.rs:5:13-15 let y = add(3, 4);
-|23: 3 lib.rs:2:8-10 pub fn add(a: i32, b: i32) -> i32 {
+|21: 1 lib.rs:2:8-10 pub fn add(a: i32, b: i32) -> i32 {
+|22: 2 main.rs:4:13-15 let x = add(1, 2);
+|23: 3 main.rs:5:13-15 let y = add(3, 4);
== snap gr-opened grid=100x24 cursor=21,6
+|21: 2 main.rs:4:13-15 let x = add(1, 2);
+|22: 3 main.rs:5:13-15 let y = add(3, 4);
+|23: 4
+== snap gr-back grid=100x24 cursor=21,5
+|21: 1 lib.rs:2:8-10 pub fn add(a: i32, b: i32) -> i32 {
+|22: 2 main.rs:4:13-15 let x = add(1, 2);
+|23: 3 main.rs:5:13-15 let y = add(3, 4);
diff --git a/test/snapshots/lsp-client.snap b/test/snapshots/lsp-client.snap
index bc5267cc..91c65975 100644
--- a/test/snapshots/lsp-client.snap
+++ b/test/snapshots/lsp-client.snap
@@ -6,7 +6,7 @@
# gd on a cross-file Location -> a look: lib.rs opens with `add` selected,
# and the message row still carries the server's settled state
# ("lsp lspmock: ready") because nothing has cleared it yet.
-# gr -> three rows with column SPANS, n arms the walk, Enter opens one.
+# gr -> sorted rows, selecting the next occurrence; n/N continue there.
file main.rs mod lib;\n\nfn main() {\n let x = add(1, 2);\n let y = add(3, 4);\n let _ = x + y;\n}\n
file lib.rs // mock fixture\npub fn add(a: i32, b: i32) -> i32 {\n a + b\n}\n
start 24 100 main.rs
@@ -26,9 +26,12 @@ key r
wait 10000 add(3, 4)
stable 700 15000
snap gr-list
-# step the list and open the second hit: main.rs with the span selected
-key n
+# step from the selected middle row to the last hit, then return
key n
key enter
stable 700 15000
snap gr-opened
+key N
+key enter
+stable 700 15000
+snap gr-back
diff --git a/test/snapshots/lspdebug.golden b/test/snapshots/lspdebug.golden
index cd9ac0c7..4dd7748e 100644
--- a/test/snapshots/lspdebug.golden
+++ b/test/snapshots/lspdebug.golden
@@ -14,31 +14,5 @@
| 11
== snap ctrlclick grid=120x44 cursor=15,4
== snap plainclick grid=120x44 cursor=21,9
-== snap why grid=120x44 cursor=7,4
-|34: /tmp/pardes-snap/lspdebug/cwd/+Lsp Save New Newtty Del
-|35: 1 lsp explain — the definition query at byte 29 of z.zig
-|36: 2
-|37: 3 zig lib dir: /usr/lib/zig (open) — `std` imports resolve
-|38: 4 parsed 122 bytes, 0 syntax error(s)
-|39: 5 position context: .empty
-|40: 6 STOP: nothing to resolve in a .empty context — `gd` only answers on
-|41: 7 an identifier, a field access, a label, an enum literal or an @import string.
-|42: 8
-|43: 9 0 row(s)
-== snap info grid=120x44 cursor=7,4
-|18: /tmp/pardes-snap/lspdebug/cwd/+Lsp Save New Newtty Del
-|19: 1 backend: zls-inproc+lsp-client
-|20: 2 zls: 0.16.1-dev+3e0d0820 (compiled in — no server process, no JSON-RPC)
-|21: 3 zig lib dir: /usr/lib/zig [OK]
-|22: 4 offsets: utf-8 walk caps: 512 files, 2000 rows
-|23: 5
-|24: 6 dependency imports gd can follow (8):
-|25: 7 zls /home/goblin/00-projects/0x4200.cafe/02-pardes-code/zig-pkg/zls-0.16.1-dev-rmm5ftfOJgAzIdWUGVB0↩
-|26: 8ycFbud2O3viKnGF1HZgfKZJ/src/zls.zig
-|27: 8 tree-sitter /home/goblin/00-projects/0x4200.cafe/02-pardes-code/zig-pkg/tree_sitter-0.26.0-8heIf3CaAQB4SSum↩
-|28: oGzq3gLSz2rkvXxcKFyskRWqDGBz/src/root.zig
-|29: 9 zstbi /home/goblin/00-projects/0x4200.cafe/02-pardes-code/zig-pkg/zstbi-0.11.0-dev-L0Ea_3GWBwAh7m54XX↩
-|30: 055vwLKPTPij5hyqyeq92MXPE2/src/zstbi.zig
-|31: 10 mvzr /home/goblin/00-projects/0x4200.cafe/02-pardes-code/zig-pkg/mvzr-0.3.9-ZSOky6t2AQCA7efmm5EYbPb5↩
-|32: sOdbXa4EFsUgYbQ6hZv9/src/mvzr.zig
-|33: 11 mupdf /home/goblin/00-projects/0x4200.cafe/02-pardes-code/src/pdf.zig
+== snap why-closed grid=120x44 cursor=7,4
+== snap report-closed grid=120x44 cursor=7,4
diff --git a/test/snapshots/lspdebug.snap b/test/snapshots/lspdebug.snap
index a2160408..514b24da 100644
--- a/test/snapshots/lspdebug.snap
+++ b/test/snapshots/lspdebug.snap
@@ -1,52 +1,46 @@
-# The mouse chord and the two introspection builtins.
-#
-# Ctrl-left-click IS `gd`. It rides the ordinary left-click drag rather than
-# firing on the press, because a click does not place the modal cursor until
-# RELEASE — asking at press time would answer about wherever the cursor
-# happened to be sitting, which is the bug this test would not have caught.
-#
-# `SPC l w` and `SPC l i` exist because this backend never fails loudly: a
-# thrown analyser must not take the editor with it, but that makes a broken
-# backend and a correct one that found nothing look identical. These two tell
-# them apart, so they are worth a test that proves they say something TRUE.
file z.zig const std = @import("std");\n\nfn helper() u32 {\n return 3;\n}\n\npub fn main() void {\n const v = helper();\n _ = v;\n}\n
start 44 120 z.zig
wait 8000 fn helper
stable 700 20000
snap opened
-# Ctrl-click on the `helper` of the CALL (row 10 = file line 8, col 22 = the
-# `h`). One definition, so it jumps rather than listing: the cursor lands on
-# line 3, the `helper` of `fn helper()`, in this same pane.
+
+# Ctrl-click jumps to the definition; plain click only moves the cursor.
press ctrl-left 22 10
release ctrl-left 22 10
stable 700 15000
snap ctrlclick
-# A PLAIN left click in the same place must NOT jump — the modifier is the
-# whole difference, and without this the test above would pass on a bug that
-# made every click a goto.
press left 22 10
release left 22 10
stable 700 15000
snap plainclick
-# `SPC l w` on a keyword: `gd` finds nothing there, and the point of Lspwhy is
-# that it says WHY rather than leaving you with a no-op key. It narrates the
-# real resolution path — the position context is the analyser's own answer,
-# not a guess reconstructed beside it.
+
text 3gg1g|
stable 400 10000
-key space
-key l
-key w
-wait 10000 position context
+key space l w
+wait 10000 parsed 122 bytes, 0 syntax error(s)
+wait 10000 position context: .empty
+wait 10000 STOP: nothing to resolve
+wait 10000 0 row(s)
+key space w j
+key space d
stable 700 15000
-snap why
-# `SPC l i`: which ZLS, which stdlib, what it answers, and the query log —
-# which by now holds the two gotos and the explain above, with their timings.
-# It answers from any pane, including one with no file, because it is about
-# the BACKEND.
-key space
-key l
-key i
-wait 10000 zls-inproc
+snap why-closed
+
+# Check the report's answers, not installed compiler paths or dependency counts.
+key space l i
+wait 10000 backend: zls-inproc+lsp-client
+wait 10000 compiled in
+wait 10000 [OK]
+wait 10000 offsets: utf-8
+key space w j
+key /
+text last queries
+key enter
+wait 10000 last queries
+wait 10000 definition z.zig
+wait 10000 explain z.zig
+key space d
+key space w j
+key space d
stable 700 15000
-snap info
+snap report-closed
diff --git a/test/snapshots/mini.golden b/test/snapshots/mini.golden
new file mode 100644
index 00000000..16e170f6
--- /dev/null
+++ b/test/snapshots/mini.golden
@@ -0,0 +1,183 @@
+== snap opened grid=90x22 cursor=7,13
+|New Newcol Joincol Find Grep Help Changelog Tutor Dump NextColor Debug Kill
+| /tmp/pardes-snap/mini/cwd/commands.txt Save New Newtty Del
+| 1 @`Mini demo.zig`
+|
+|
+|
+|
+|
+|
+|
+|
+|
+| /tmp/pardes-snap/mini/cwd/Mini demo.zig Save New Newtty Del
+| 1 ⠭⠍⣥⢩⣭⡭⣭⣬⣌⢭⣭⠌⠬⠅⠍⠁
+| 2 ⣂⢀⣉⣉⢉⣈⢁⣀⣀⢀⣀⣀⣀⢀⣀⣀⣀⣀⣀
+| 3 ⠉⠉⠁⠉⠉⠉⠈⠈⠉⠉⠉⠉⠉⠉
+| 4
+== style opened grid=90x22
+|0: 0-74 #949494,#121212, 75-89 d,#121212,
+|1: 0-1 #ffffff,#262626, 2-69 #949494,#121212, 70-89 d,#121212,
+|2: 0-0 d,#444444, 1-1 d,#080808, 2-6 #626262,#080808, 7-22 #bdbdbd,#080808, 23-89 d,#080808,
+|3: 0-0 d,#444444, 1-1 d,#080808, 2-6 #626262,#080808, 7-89 d,#080808,
+|4: 0-0 d,#444444, 1-1 d,#080808, 2-6 #626262,#080808, 7-89 d,#080808,
+|5: 0-0 d,#444444, 1-1 d,#080808, 2-6 #626262,#080808, 7-89 d,#080808,
+|6: 0-0 d,#444444, 1-1 d,#080808, 2-6 #626262,#080808, 7-89 d,#080808,
+|7: 0-0 d,#444444, 1-1 d,#080808, 2-6 #626262,#080808, 7-89 d,#080808,
+|8: 0-0 d,#444444, 1-1 d,#080808, 2-6 #626262,#080808, 7-89 d,#080808,
+|9: 0-0 d,#444444, 1-1 d,#080808, 2-6 #626262,#080808, 7-89 d,#080808,
+|10: 0-0 d,#444444, 1-1 d,#080808, 2-6 #626262,#080808, 7-89 d,#080808,
+|11: 0-0 d,#444444, 1-1 d,#080808, 2-6 #626262,#080808, 7-89 d,#080808,
+|12: 0-1 #ffffff,#626262, 2-69 #949494,#121212, 70-89 d,#121212,
+|13: 0-0 d,#444444, 1-1 d,#080808, 2-6 #949494,#121212, 7-8 #bdbdbd,#080808, 9-9 #cf87e8,#080808,b 10-12 #bdbdbd,#080808, 13-15 #cf87e8,#080808,b 16-21 #e3c78a,#080808, 22-22 #bdbdbd,#080808, 23-89 d,#080808,
+|14: 0-0 d,#444444, 1-1 d,#080808, 2-6 #626262,#080808, 7-8 #ffffff,#080808,b 9-11 #cf87e8,#080808,b 12-25 #ffffff,#080808,b 26-89 d,#080808,
+|15: 0-0 d,#444444, 1-1 d,#080808, 2-6 #626262,#080808, 7-17 #bdbdbd,#080808, 18-19 #e3c78a,#080808, 20-20 #bdbdbd,#080808, 21-89 d,#080808,
+|16: 0-0 d,#444444, 1-1 d,#080808, 2-6 #626262,#080808, 7-89 d,#080808,
+|17: 0-0 d,#444444, 1-1 d,#080808, 2-6 #626262,#080808, 7-89 d,#080808,
+|18: 0-0 d,#444444, 1-1 d,#080808, 2-6 #626262,#080808, 7-89 d,#080808,
+|19: 0-0 d,#444444, 1-1 d,#080808, 2-6 #626262,#080808, 7-89 d,#080808,
+|20: 0-0 d,#444444, 1-1 d,#080808, 2-6 #626262,#080808, 7-89 d,#080808,
+|21: 0-0 d,#444444, 1-1 d,#080808, 2-6 #626262,#080808, 7-89 d,#080808,
+== 9p opened grid=90x22 cursor=7,13,block
+|0: New Newcol Joincol Find Grep Help Changelog Tutor Dump NextColor Debug Kill
+@0: 0-74 #949494,#121212,,tagline 75-89 d,#121212,,tagline
+|1: /tmp/pardes-snap/mini/cwd/commands.txt Save New Newtty Del
+@1: 0-1 #ffffff,#262626,,tagline 2-69 #949494,#121212,,tagline 70-89 d,#121212,,tagline
+|2: 1 @`Mini demo.zig`
+@2: 0-0 d,#444444,,body 1-1 d,#080808,,body 2-6 #626262,#080808,,body 7-22 #bdbdbd,#080808,,body 23-89 d,#080808,,body
+|3:
+@3: 0-0 d,#444444,,body 1-1 d,#080808,,body 2-6 #626262,#080808,,body 7-89 d,#080808,,body
+|4:
+@4: 0-0 d,#444444,,body 1-1 d,#080808,,body 2-6 #626262,#080808,,body 7-89 d,#080808,,body
+|5:
+@5: 0-0 d,#444444,,body 1-1 d,#080808,,body 2-6 #626262,#080808,,body 7-89 d,#080808,,body
+|6:
+@6: 0-0 d,#444444,,body 1-1 d,#080808,,body 2-6 #626262,#080808,,body 7-89 d,#080808,,body
+|7:
+@7: 0-0 d,#444444,,body 1-1 d,#080808,,body 2-6 #626262,#080808,,body 7-89 d,#080808,,body
+|8:
+@8: 0-0 d,#444444,,body 1-1 d,#080808,,body 2-6 #626262,#080808,,body 7-89 d,#080808,,body
+|9:
+@9: 0-0 d,#444444,,body 1-1 d,#080808,,body 2-6 #626262,#080808,,body 7-89 d,#080808,,body
+|10:
+@10: 0-0 d,#444444,,body 1-1 d,#080808,,body 2-6 #626262,#080808,,body 7-89 d,#080808,,body
+|11:
+@11: 0-0 d,#444444,,body 1-1 d,#080808,,body 2-6 #626262,#080808,,body 7-89 d,#080808,,body
+|12: /tmp/pardes-snap/mini/cwd/Mini demo.zig Save New Newtty Del
+@12: 0-1 #ffffff,#626262,,tagline 2-69 #949494,#121212,,tagline 70-89 d,#121212,,tagline
+|13: 1 ⠭⠍⣥⢩⣭⡭⣭⣬⣌⢭⣭⠌⠬⠅⠍⠁
++13: 7="⠭" 8="⠍" 9="⣥" 10="⢩" 11="⣭" 12="⡭" 13="⣭" 14="⣬" 15="⣌" 16="⢭" 17="⣭" 18="⠌" 19="⠬" 20="⠅" 21="⠍" 22="⠁"
+@13: 0-0 d,#444444,,body 1-1 d,#080808,,body 2-6 #949494,#121212,,body 7-8 #bdbdbd,#080808,,body 9-9 #cf87e8,#080808,b,body 10-12 #bdbdbd,#080808,,body 13-15 #cf87e8,#080808,b,body 16-21 #e3c78a,#080808,,body 22-22 #bdbdbd,#080808,,body 23-89 d,#080808,,body
+|14: 2 ⣂⢀⣉⣉⢉⣈⢁⣀⣀⢀⣀⣀⣀⢀⣀⣀⣀⣀⣀
++14: 7="⣂" 8="⢀" 9="⣉" 10="⣉" 11="⢉" 12="⣈" 13="⢁" 14="⣀" 15="⣀" 16="⢀" 17="⣀" 18="⣀" 19="⣀" 20="⢀" 21="⣀" 22="⣀" 23="⣀" 24="⣀" 25="⣀"
+@14: 0-0 d,#444444,,body 1-1 d,#080808,,body 2-6 #626262,#080808,,body 7-8 #ffffff,#080808,b,body 9-11 #cf87e8,#080808,b,body 12-25 #ffffff,#080808,b,body 26-89 d,#080808,,body
+|15: 3 ⠉⠉⠁⠉⠉⠉⠈⠈⠉⠉⠉⠉⠉⠉
++15: 7="⠉" 8="⠉" 9="⠁" 10="⠉" 11="⠉" 12="⠉" 13="⠈" 14="⠈" 15="⠉" 16="⠉" 17="⠉" 18="⠉" 19="⠉" 20="⠉"
+@15: 0-0 d,#444444,,body 1-1 d,#080808,,body 2-6 #626262,#080808,,body 7-17 #bdbdbd,#080808,,body 18-19 #e3c78a,#080808,,body 20-20 #bdbdbd,#080808,,body 21-89 d,#080808,,body
+|16: 4
+@16: 0-0 d,#444444,,body 1-1 d,#080808,,body 2-6 #626262,#080808,,body 7-89 d,#080808,,body
+|17:
+@17: 0-0 d,#444444,,body 1-1 d,#080808,,body 2-6 #626262,#080808,,body 7-89 d,#080808,,body
+|18:
+@18: 0-0 d,#444444,,body 1-1 d,#080808,,body 2-6 #626262,#080808,,body 7-89 d,#080808,,body
+|19:
+@19: 0-0 d,#444444,,body 1-1 d,#080808,,body 2-6 #626262,#080808,,body 7-89 d,#080808,,body
+|20:
+@20: 0-0 d,#444444,,body 1-1 d,#080808,,body 2-6 #626262,#080808,,body 7-89 d,#080808,,body
+|21:
+@21: 0-0 d,#444444,,body 1-1 d,#080808,,body 2-6 #626262,#080808,,body 7-89 d,#080808,,body
+== style colors-off grid=90x22
+|13: 0-0 d,#444444, 1-1 d,#080808, 2-6 #949494,#121212, 7-22 #bdbdbd,#080808, 23-89 d,#080808,
+|14: 0-0 d,#444444, 1-1 d,#080808, 2-6 #626262,#080808, 7-25 #bdbdbd,#080808, 26-89 d,#080808,
+|15: 0-0 d,#444444, 1-1 d,#080808, 2-6 #626262,#080808, 7-20 #bdbdbd,#080808, 21-89 d,#080808,
+== 9p colors-off grid=90x22 cursor=7,13,block
+|13: 1 ⠭⠍⣥⢩⣭⡭⣭⣬⣌⢭⣭⠌⠬⠅⠍⠁
++13: 7="⠭" 8="⠍" 9="⣥" 10="⢩" 11="⣭" 12="⡭" 13="⣭" 14="⣬" 15="⣌" 16="⢭" 17="⣭" 18="⠌" 19="⠬" 20="⠅" 21="⠍" 22="⠁"
+@13: 0-0 d,#444444,,body 1-1 d,#080808,,body 2-6 #949494,#121212,,body 7-22 #bdbdbd,#080808,,body 23-89 d,#080808,,body
+|14: 2 ⣂⢀⣉⣉⢉⣈⢁⣀⣀⢀⣀⣀⣀⢀⣀⣀⣀⣀⣀
++14: 7="⣂" 8="⢀" 9="⣉" 10="⣉" 11="⢉" 12="⣈" 13="⢁" 14="⣀" 15="⣀" 16="⢀" 17="⣀" 18="⣀" 19="⣀" 20="⢀" 21="⣀" 22="⣀" 23="⣀" 24="⣀" 25="⣀"
+@14: 0-0 d,#444444,,body 1-1 d,#080808,,body 2-6 #626262,#080808,,body 7-25 #bdbdbd,#080808,,body 26-89 d,#080808,,body
+|15: 3 ⠉⠉⠁⠉⠉⠉⠈⠈⠉⠉⠉⠉⠉⠉
++15: 7="⠉" 8="⠉" 9="⠁" 10="⠉" 11="⠉" 12="⠉" 13="⠈" 14="⠈" 15="⠉" 16="⠉" 17="⠉" 18="⠉" 19="⠉" 20="⠉"
+@15: 0-0 d,#444444,,body 1-1 d,#080808,,body 2-6 #626262,#080808,,body 7-20 #bdbdbd,#080808,,body 21-89 d,#080808,,body
+== style colors-on grid=90x22
+|13: 0-0 d,#444444, 1-1 d,#080808, 2-6 #949494,#121212, 7-8 #bdbdbd,#080808, 9-9 #cf87e8,#080808,b 10-12 #bdbdbd,#080808, 13-15 #cf87e8,#080808,b 16-21 #e3c78a,#080808, 22-22 #bdbdbd,#080808, 23-89 d,#080808,
+|14: 0-0 d,#444444, 1-1 d,#080808, 2-6 #626262,#080808, 7-8 #ffffff,#080808,b 9-11 #cf87e8,#080808,b 12-25 #ffffff,#080808,b 26-89 d,#080808,
+|15: 0-0 d,#444444, 1-1 d,#080808, 2-6 #626262,#080808, 7-17 #bdbdbd,#080808, 18-19 #e3c78a,#080808, 20-20 #bdbdbd,#080808, 21-89 d,#080808,
+== snap resized grid=105x26 cursor=7,15
+|New Newcol Joincol Find Grep Help Changelog Tutor Dump NextColor Debug Kill
+| /tmp/pardes-snap/mini/cwd/commands.txt Save New Newtty Del
+| 1 @`Mini demo.zig`
+|
+|
+|
+|
+|
+|
+|
+|
+|
+|
+|
+| /tmp/pardes-snap/mini/cwd/Mini demo.zig Save New Newtty Del
+| 1 ⠭⠍⣥⢩⣭⡭⣭⣬⣌⢭⣭⠌⠬⠅⠍⠁
+| 2 ⣂⢀⣉⣉⢉⣈⢁⣀⣀⢀⣀⣀⣀⢀⣀⣀⣀⣀⣀
+| 3 ⠉⠉⠁⠉⠉⠉⠈⠈⠉⠉⠉⠉⠉⠉
+| 4
+== 9p resized grid=105x26 cursor=7,15,block
+|0: New Newcol Joincol Find Grep Help Changelog Tutor Dump NextColor Debug Kill
+@0: 0-74 #949494,#121212,,tagline 75-104 d,#121212,,tagline
+|1: /tmp/pardes-snap/mini/cwd/commands.txt Save New Newtty Del
+@1: 0-1 #ffffff,#262626,,tagline 2-84 #949494,#121212,,tagline 85-104 d,#121212,,tagline
+|2: 1 @`Mini demo.zig`
+@2: 0-0 d,#444444,,body 1-1 d,#080808,,body 2-6 #626262,#080808,,body 7-22 #bdbdbd,#080808,,body 23-104 d,#080808,,body
+|3:
+@3: 0-0 d,#444444,,body 1-1 d,#080808,,body 2-6 #626262,#080808,,body 7-104 d,#080808,,body
+|4:
+@4: 0-0 d,#444444,,body 1-1 d,#080808,,body 2-6 #626262,#080808,,body 7-104 d,#080808,,body
+|5:
+@5: 0-0 d,#444444,,body 1-1 d,#080808,,body 2-6 #626262,#080808,,body 7-104 d,#080808,,body
+|6:
+@6: 0-0 d,#444444,,body 1-1 d,#080808,,body 2-6 #626262,#080808,,body 7-104 d,#080808,,body
+|7:
+@7: 0-0 d,#444444,,body 1-1 d,#080808,,body 2-6 #626262,#080808,,body 7-104 d,#080808,,body
+|8:
+@8: 0-0 d,#444444,,body 1-1 d,#080808,,body 2-6 #626262,#080808,,body 7-104 d,#080808,,body
+|9:
+@9: 0-0 d,#444444,,body 1-1 d,#080808,,body 2-6 #626262,#080808,,body 7-104 d,#080808,,body
+|10:
+@10: 0-0 d,#444444,,body 1-1 d,#080808,,body 2-6 #626262,#080808,,body 7-104 d,#080808,,body
+|11:
+@11: 0-0 d,#444444,,body 1-1 d,#080808,,body 2-6 #626262,#080808,,body 7-104 d,#080808,,body
+|12:
+@12: 0-0 d,#444444,,body 1-1 d,#080808,,body 2-6 #626262,#080808,,body 7-104 d,#080808,,body
+|13:
+@13: 0-0 d,#444444,,body 1-1 d,#080808,,body 2-6 #626262,#080808,,body 7-104 d,#080808,,body
+|14: /tmp/pardes-snap/mini/cwd/Mini demo.zig Save New Newtty Del
+@14: 0-1 #ffffff,#626262,,tagline 2-84 #949494,#121212,,tagline 85-104 d,#121212,,tagline
+|15: 1 ⠭⠍⣥⢩⣭⡭⣭⣬⣌⢭⣭⠌⠬⠅⠍⠁
++15: 7="⠭" 8="⠍" 9="⣥" 10="⢩" 11="⣭" 12="⡭" 13="⣭" 14="⣬" 15="⣌" 16="⢭" 17="⣭" 18="⠌" 19="⠬" 20="⠅" 21="⠍" 22="⠁"
+@15: 0-0 d,#444444,,body 1-1 d,#080808,,body 2-6 #949494,#121212,,body 7-8 #bdbdbd,#080808,,body 9-9 #cf87e8,#080808,b,body 10-12 #bdbdbd,#080808,,body 13-15 #cf87e8,#080808,b,body 16-21 #e3c78a,#080808,,body 22-22 #bdbdbd,#080808,,body 23-104 d,#080808,,body
+|16: 2 ⣂⢀⣉⣉⢉⣈⢁⣀⣀⢀⣀⣀⣀⢀⣀⣀⣀⣀⣀
++16: 7="⣂" 8="⢀" 9="⣉" 10="⣉" 11="⢉" 12="⣈" 13="⢁" 14="⣀" 15="⣀" 16="⢀" 17="⣀" 18="⣀" 19="⣀" 20="⢀" 21="⣀" 22="⣀" 23="⣀" 24="⣀" 25="⣀"
+@16: 0-0 d,#444444,,body 1-1 d,#080808,,body 2-6 #626262,#080808,,body 7-8 #ffffff,#080808,b,body 9-11 #cf87e8,#080808,b,body 12-25 #ffffff,#080808,b,body 26-104 d,#080808,,body
+|17: 3 ⠉⠉⠁⠉⠉⠉⠈⠈⠉⠉⠉⠉⠉⠉
++17: 7="⠉" 8="⠉" 9="⠁" 10="⠉" 11="⠉" 12="⠉" 13="⠈" 14="⠈" 15="⠉" 16="⠉" 17="⠉" 18="⠉" 19="⠉" 20="⠉"
+@17: 0-0 d,#444444,,body 1-1 d,#080808,,body 2-6 #626262,#080808,,body 7-17 #bdbdbd,#080808,,body 18-19 #e3c78a,#080808,,body 20-20 #bdbdbd,#080808,,body 21-104 d,#080808,,body
+|18: 4
+@18: 0-0 d,#444444,,body 1-1 d,#080808,,body 2-6 #626262,#080808,,body 7-104 d,#080808,,body
+|19:
+@19: 0-0 d,#444444,,body 1-1 d,#080808,,body 2-6 #626262,#080808,,body 7-104 d,#080808,,body
+|20:
+@20: 0-0 d,#444444,,body 1-1 d,#080808,,body 2-6 #626262,#080808,,body 7-104 d,#080808,,body
+|21:
+@21: 0-0 d,#444444,,body 1-1 d,#080808,,body 2-6 #626262,#080808,,body 7-104 d,#080808,,body
+|22:
+@22: 0-0 d,#444444,,body 1-1 d,#080808,,body 2-6 #626262,#080808,,body 7-104 d,#080808,,body
+|23:
+@23: 0-0 d,#444444,,body 1-1 d,#080808,,body 2-6 #626262,#080808,,body 7-104 d,#080808,,body
+|24:
+@24: 0-0 d,#444444,,body 1-1 d,#080808,,body 2-6 #626262,#080808,,body 7-104 d,#080808,,body
+|25:
+@25: 0-0 d,#444444,,body 1-1 d,#080808,,body 2-6 #626262,#080808,,body 7-104 d,#080808,,body
diff --git a/test/snapshots/mini.snap b/test/snapshots/mini.snap
new file mode 100644
index 00000000..eacd86b9
--- /dev/null
+++ b/test/snapshots/mini.snap
@@ -0,0 +1,23 @@
+file commands.txt @`Mini demo.zig`
+file demo.zig const greeting = "café λ 界 é";\n\npub fn choose(ok: bool) u32 {\n if (ok) return 42;\n return 7;\n}\n\n// space and color survive compression\nconst answer = choose(true);\n
+start 22 90 commands.txt
+wait 8000 Mini demo.zig
+stable 400 10000
+press middle @Mini 3
+release middle @Mini 3
+wait 8000 /Mini demo.zig
+stable 500 10000
+snap opened
+snapstyle opened
+snap9p opened
+key space t c
+stable 300 8000
+snapstyle colors-off
+snap9p colors-off
+key space t c
+stable 300 8000
+snapstyle colors-on
+resize 26 105
+stable 400 10000
+snap resized
+snap9p resized
diff --git a/test/snapshots/nested-optout.snap b/test/snapshots/nested-optout.snap
index 27e1ba3d..973b8817 100644
--- a/test/snapshots/nested-optout.snap
+++ b/test/snapshots/nested-optout.snap
@@ -1,22 +1,6 @@
-# `--nested` is the documented escape hatch out of the hand-the-file-outward
-# mechanism, and nested.snap covers only the mechanism. The flag says two
-# things at once and both are asserted here: an instance carrying it keeps its
-# own argument instead of forwarding it, AND it is not an outer instance for
-# anything launched inside IT (tty.zig binds no socket when opts.nested).
-#
-# The same trick nested.snap uses to get a genuine descendant: a pane shell's
-# parent IS the app under test, so `$(readlink /proc/$PPID/exe)` in a pane is
-# this exact binary. What discriminates is the GRID — a second topbar drawn
-# INSIDE the pane, with the outer instance still one shell wide.
-#
-# Long waits on purpose: each arm forks and execs whole further pardes.
file nested.txt optout-marker\nsecond-optout-line\n
dirmk innerdir
file innerdir/deeper.txt deepest-marker\n
-# --- a file argument, WITH the flag: the inner keeps it ---
-# Without --nested this is nested.snap's first arm and the outer grows a
-# file pane beside the shell. Here the outer's layout never changes: one
-# shell, and a whole second pardes drawn inside it holding nested.txt.
start 30 100
wait 8000 $
stable 700 20000
@@ -25,12 +9,6 @@ key enter
wait 20000 optout-marker
stable 700 20000
snap optout-file
-# --- ...and it is not an outer instance either ---
-# The subshell is what makes the wait unambiguous: the inner boots in
-# `innerdir` while the outer pane's own shell stays in cwd, so `cwd/innerdir`
-# on the grid can only be the inner instance's tagline. --nested with no
-# argument is still a bare launch, so the inner comes up in tty mode and
-# keystrokes travel through both layers to its shell.
start 30 100
wait 8000 $
stable 700 20000
@@ -39,12 +17,6 @@ key enter
wait 20000 cwd/innerdir
stable 700 20000
snap inner-shell
-# A third pardes, launched from inside the inner one. Its nearest pardes
-# ancestor is the INNER instance, which bound no socket, so the send fails and
-# it opens its own session where it stands — three topbars. The assertion is
-# the row it did NOT appear on: the outer instance is still one shell pane, and
-# a walk that had skipped past the opted-out instance would have put
-# deeper.txt up there beside it.
text $(readlink /proc/$PPID/exe) deeper.txt
key enter
wait 20000 deepest-marker
diff --git a/test/snapshots/nested.snap b/test/snapshots/nested.snap
index 0beeabf8..790b9b0c 100644
--- a/test/snapshots/nested.snap
+++ b/test/snapshots/nested.snap
@@ -1,34 +1,14 @@
-# a pardes launched INSIDE a pardes hands its argument to the outer one.
-#
-# No harness support is needed to get a genuinely nested launch: a pane
-# shell's parent IS the app under test, so `$(readlink /proc/$PPID/exe)` in a
-# pane is this exact binary, and running it from there makes a real
-# descendant — the same process tree a person typing `pardes foo.txt` in a
-# pane produces. Each arm gets its own `start` so the Look never has to be
-# aimed at a pane a previous arm moved.
-#
-# What discriminates is the GOLDEN GRID, not the `wait` below it: a nested
-# pardes that opened its own UI in the pane would show the same file, so the
-# content wait passes either way. The layout is what differs — an outer file
-# pane beside the shell versus a whole second topbar inside it — and the
-# `cursor=` on the first arm's header moves the moment that changes.
-#
-# Long waits on purpose: this forks and execs a whole second pardes.
dirmk nestdir
file nestdir/inside-nested.txt marker
file nested.txt hello-from-nested\nsecond-nested-line\n
-# --- a FILE argument: a file pane appears in the OUTER instance ---
start 30 100
wait 8000 $
stable 700 20000
text $(readlink /proc/$PPID/exe) nested.txt
key enter
-# the CONTENT, not the border: the shell only ever echoed the file's NAME
-# (see above for why the grid, not this line, is the real assertion)
wait 15000 hello-from-nested
stable 700 20000
snap file-arg
-# --- no argument: the spicy message, in the pane, and no second UI ---
start 30 100
wait 8000 $
stable 700 20000
@@ -37,7 +17,6 @@ key enter
wait 15000 already inside pardes
stable 700 20000
snap no-arg
-# --- a DIRECTORY argument: a shell there, greeted with ls ---
start 30 100
wait 8000 $
stable 700 20000
diff --git a/test/snapshots/ninep.golden b/test/snapshots/ninep.golden
new file mode 100644
index 00000000..c0e90e3f
--- /dev/null
+++ b/test/snapshots/ninep.golden
@@ -0,0 +1,195 @@
+== snap opened grid=90x14 cursor=7,2
+|New Newcol Joincol Find Grep Help Changelog Tutor Dump NextColor Debug Kill
+| /tmp/pardes-snap/ninep/cwd/demo.zig Save New Newtty Del
+| 1 const greeting = "café λ 界 é";
+| 2
+| 3 pub fn choose(ok: bool) u32 {
+| 4 if (ok) return 42;
+| 5 return 7;
+| 6 }
+| 7
+== style opened grid=90x14
+|0: 0-74 #949494,#121212, 75-89 d,#121212,
+|1: 0-1 #ffffff,#626262, 2-69 #949494,#121212, 70-89 d,#121212,
+|2: 0-0 d,#444444, 1-1 d,#080808, 2-6 #949494,#121212, 7-23 #bdbdbd,#080808, 24-32 #e3c78a,#080808, 33-33 d,d, 34-36 #e3c78a,#080808, 37-37 #bdbdbd,#080808, 38-89 d,#080808,
+|3: 0-0 d,#444444, 1-1 d,#080808, 2-6 #626262,#080808, 7-89 d,#080808,
+|4: 0-0 d,#444444, 1-1 d,#080808, 2-6 #626262,#080808, 7-10 #bdbdbd,#080808, 11-12 #cf87e8,#080808,b 13-35 #bdbdbd,#080808, 36-89 d,#080808,
+|5: 0-0 d,#444444, 1-1 d,#080808, 2-6 #626262,#080808, 7-10 #bdbdbd,#080808, 11-12 #cf87e8,#080808,b 13-18 #bdbdbd,#080808, 19-24 #cf87e8,#080808,b 25-25 #bdbdbd,#080808, 26-27 #e3c78a,#080808, 28-28 #bdbdbd,#080808, 29-89 d,#080808,
+|6: 0-0 d,#444444, 1-1 d,#080808, 2-6 #626262,#080808, 7-10 #bdbdbd,#080808, 11-16 #cf87e8,#080808,b 17-17 #bdbdbd,#080808, 18-18 #e3c78a,#080808, 19-19 #bdbdbd,#080808, 20-89 d,#080808,
+|7: 0-0 d,#444444, 1-1 d,#080808, 2-6 #626262,#080808, 7-7 #bdbdbd,#080808, 8-89 d,#080808,
+|8: 0-0 d,#444444, 1-1 d,#080808, 2-6 #626262,#080808, 7-89 d,#080808,
+|9: 0-0 d,#444444, 1-1 d,#080808, 2-6 #626262,#080808, 7-89 d,#080808,
+|10: 0-0 d,#444444, 1-1 d,#080808, 2-6 #626262,#080808, 7-89 d,#080808,
+|11: 0-0 d,#444444, 1-1 d,#080808, 2-6 #626262,#080808, 7-89 d,#080808,
+|12: 0-0 d,#444444, 1-1 d,#080808, 2-6 #626262,#080808, 7-89 d,#080808,
+|13: 0-0 d,#444444, 1-1 d,#080808, 2-6 #626262,#080808, 7-89 d,#080808,
+== 9p opened grid=90x14 cursor=7,2,block
+|0: New Newcol Joincol Find Grep Help Changelog Tutor Dump NextColor Debug Kill
+@0: 0-74 #949494,#121212,,tagline 75-89 d,#121212,,tagline
+|1: /tmp/pardes-snap/ninep/cwd/demo.zig Save New Newtty Del
+@1: 0-1 #ffffff,#626262,,tagline 2-69 #949494,#121212,,tagline 70-89 d,#121212,,tagline
+|2: 1 const greeting = "café λ 界 é";
++2: 28="é" 30="λ" 32="界" 33="" 35="é"
+@2: 0-0 d,#444444,,body 1-1 d,#080808,,body 2-6 #949494,#121212,,body 7-23 #bdbdbd,#080808,,body 24-36 #e3c78a,#080808,,body 37-37 #bdbdbd,#080808,,body 38-89 d,#080808,,body
+|3: 2
+@3: 0-0 d,#444444,,body 1-1 d,#080808,,body 2-6 #626262,#080808,,body 7-89 d,#080808,,body
+|4: 3 pub fn choose(ok: bool) u32 {
+@4: 0-0 d,#444444,,body 1-1 d,#080808,,body 2-6 #626262,#080808,,body 7-10 #bdbdbd,#080808,,body 11-12 #cf87e8,#080808,b,body 13-35 #bdbdbd,#080808,,body 36-89 d,#080808,,body
+|5: 4 if (ok) return 42;
+@5: 0-0 d,#444444,,body 1-1 d,#080808,,body 2-6 #626262,#080808,,body 7-10 #bdbdbd,#080808,,body 11-12 #cf87e8,#080808,b,body 13-18 #bdbdbd,#080808,,body 19-24 #cf87e8,#080808,b,body 25-25 #bdbdbd,#080808,,body 26-27 #e3c78a,#080808,,body 28-28 #bdbdbd,#080808,,body 29-89 d,#080808,,body
+|6: 5 return 7;
+@6: 0-0 d,#444444,,body 1-1 d,#080808,,body 2-6 #626262,#080808,,body 7-10 #bdbdbd,#080808,,body 11-16 #cf87e8,#080808,b,body 17-17 #bdbdbd,#080808,,body 18-18 #e3c78a,#080808,,body 19-19 #bdbdbd,#080808,,body 20-89 d,#080808,,body
+|7: 6 }
+@7: 0-0 d,#444444,,body 1-1 d,#080808,,body 2-6 #626262,#080808,,body 7-7 #bdbdbd,#080808,,body 8-89 d,#080808,,body
+|8: 7
+@8: 0-0 d,#444444,,body 1-1 d,#080808,,body 2-6 #626262,#080808,,body 7-89 d,#080808,,body
+|9:
+@9: 0-0 d,#444444,,body 1-1 d,#080808,,body 2-6 #626262,#080808,,body 7-89 d,#080808,,body
+|10:
+@10: 0-0 d,#444444,,body 1-1 d,#080808,,body 2-6 #626262,#080808,,body 7-89 d,#080808,,body
+|11:
+@11: 0-0 d,#444444,,body 1-1 d,#080808,,body 2-6 #626262,#080808,,body 7-89 d,#080808,,body
+|12:
+@12: 0-0 d,#444444,,body 1-1 d,#080808,,body 2-6 #626262,#080808,,body 7-89 d,#080808,,body
+|13:
+@13: 0-0 d,#444444,,body 1-1 d,#080808,,body 2-6 #626262,#080808,,body 7-89 d,#080808,,body
+== style colors-off grid=90x14
+|2: 0-0 d,#444444, 1-1 d,#080808, 2-6 #949494,#121212, 7-32 #bdbdbd,#080808, 33-33 d,d, 34-37 #bdbdbd,#080808, 38-89 d,#080808,
+|4: 0-0 d,#444444, 1-1 d,#080808, 2-6 #626262,#080808, 7-35 #bdbdbd,#080808, 36-89 d,#080808,
+|5: 0-0 d,#444444, 1-1 d,#080808, 2-6 #626262,#080808, 7-28 #bdbdbd,#080808, 29-89 d,#080808,
+|6: 0-0 d,#444444, 1-1 d,#080808, 2-6 #626262,#080808, 7-19 #bdbdbd,#080808, 20-89 d,#080808,
+== 9p colors-off grid=90x14 cursor=7,2,block
+|2: 1 const greeting = "café λ 界 é";
++2: 28="é" 30="λ" 32="界" 33="" 35="é"
+@2: 0-0 d,#444444,,body 1-1 d,#080808,,body 2-6 #949494,#121212,,body 7-37 #bdbdbd,#080808,,body 38-89 d,#080808,,body
+|4: 3 pub fn choose(ok: bool) u32 {
+@4: 0-0 d,#444444,,body 1-1 d,#080808,,body 2-6 #626262,#080808,,body 7-35 #bdbdbd,#080808,,body 36-89 d,#080808,,body
+|5: 4 if (ok) return 42;
+@5: 0-0 d,#444444,,body 1-1 d,#080808,,body 2-6 #626262,#080808,,body 7-28 #bdbdbd,#080808,,body 29-89 d,#080808,,body
+|6: 5 return 7;
+@6: 0-0 d,#444444,,body 1-1 d,#080808,,body 2-6 #626262,#080808,,body 7-19 #bdbdbd,#080808,,body 20-89 d,#080808,,body
+== snap edited-with-colors-off grid=90x14 cursor=7,3
+|1: /tmp/pardes-snap/ninep/cwd/demo.zig * Save New Newtty Del
+|2: 1 // café λ 界
+|3: 2 const greeting = "café λ 界 é";
+|4: 3
+|5: 4 pub fn choose(ok: bool) u32 {
+|6: 5 if (ok) return 42;
+|7: 6 return 7;
+|8: 7 }
+|9: 8
+== 9p edited-with-colors-off grid=90x14 cursor=7,3,block
+|1: /tmp/pardes-snap/ninep/cwd/demo.zig * Save New Newtty Del
+@1: 0-1 #ffffff,#626262,,tagline 2-69 #949494,#121212,,tagline 70-89 d,#121212,,tagline
+|2: 1 // café λ 界
++2: 13="é" 15="λ" 17="界" 18=""
+@2: 0-0 d,#444444,,body 1-1 d,#080808,,body 2-6 #626262,#080808,,body 7-18 #bdbdbd,#080808,,body 19-89 d,#080808,,body
+|3: 2 const greeting = "café λ 界 é";
++3: 28="é" 30="λ" 32="界" 33="" 35="é"
+@3: 0-0 d,#444444,,body 1-1 d,#080808,,body 2-6 #949494,#121212,,body 7-37 #bdbdbd,#080808,,body 38-89 d,#080808,,body
+|4: 3
+@4: 0-0 d,#444444,,body 1-1 d,#080808,,body 2-6 #626262,#080808,,body 7-89 d,#080808,,body
+|5: 4 pub fn choose(ok: bool) u32 {
+@5: 0-0 d,#444444,,body 1-1 d,#080808,,body 2-6 #626262,#080808,,body 7-35 #bdbdbd,#080808,,body 36-89 d,#080808,,body
+|6: 5 if (ok) return 42;
+@6: 0-0 d,#444444,,body 1-1 d,#080808,,body 2-6 #626262,#080808,,body 7-28 #bdbdbd,#080808,,body 29-89 d,#080808,,body
+|7: 6 return 7;
+@7: 0-0 d,#444444,,body 1-1 d,#080808,,body 2-6 #626262,#080808,,body 7-19 #bdbdbd,#080808,,body 20-89 d,#080808,,body
+|8: 7 }
+@8: 0-0 d,#444444,,body 1-1 d,#080808,,body 2-6 #626262,#080808,,body 7-7 #bdbdbd,#080808,,body 8-89 d,#080808,,body
+|9: 8
+@9: 0-0 d,#444444,,body 1-1 d,#080808,,body 2-6 #626262,#080808,,body 7-89 d,#080808,,body
+== style colors-on grid=90x14
+|2: 0-0 d,#444444, 1-1 d,#080808, 2-6 #626262,#080808, 7-17 #ffffff,#080808,b 18-18 d,d, 19-89 d,#080808,
+|3: 0-0 d,#444444, 1-1 d,#080808, 2-6 #949494,#121212, 7-23 #bdbdbd,#080808, 24-32 #e3c78a,#080808, 33-33 d,d, 34-36 #e3c78a,#080808, 37-37 #bdbdbd,#080808, 38-89 d,#080808,
+|4: 0-0 d,#444444, 1-1 d,#080808, 2-6 #626262,#080808, 7-89 d,#080808,
+|5: 0-0 d,#444444, 1-1 d,#080808, 2-6 #626262,#080808, 7-10 #bdbdbd,#080808, 11-12 #cf87e8,#080808,b 13-35 #bdbdbd,#080808, 36-89 d,#080808,
+|6: 0-0 d,#444444, 1-1 d,#080808, 2-6 #626262,#080808, 7-10 #bdbdbd,#080808, 11-12 #cf87e8,#080808,b 13-18 #bdbdbd,#080808, 19-24 #cf87e8,#080808,b 25-25 #bdbdbd,#080808, 26-27 #e3c78a,#080808, 28-28 #bdbdbd,#080808, 29-89 d,#080808,
+|7: 0-0 d,#444444, 1-1 d,#080808, 2-6 #626262,#080808, 7-10 #bdbdbd,#080808, 11-16 #cf87e8,#080808,b 17-17 #bdbdbd,#080808, 18-18 #e3c78a,#080808, 19-19 #bdbdbd,#080808, 20-89 d,#080808,
+|8: 0-0 d,#444444, 1-1 d,#080808, 2-6 #626262,#080808, 7-7 #bdbdbd,#080808, 8-89 d,#080808,
+== 9p colors-on grid=90x14 cursor=7,3,block
+|2: 1 // café λ 界
++2: 13="é" 15="λ" 17="界" 18=""
+@2: 0-0 d,#444444,,body 1-1 d,#080808,,body 2-6 #626262,#080808,,body 7-18 #ffffff,#080808,b,body 19-89 d,#080808,,body
+|3: 2 const greeting = "café λ 界 é";
++3: 28="é" 30="λ" 32="界" 33="" 35="é"
+@3: 0-0 d,#444444,,body 1-1 d,#080808,,body 2-6 #949494,#121212,,body 7-23 #bdbdbd,#080808,,body 24-36 #e3c78a,#080808,,body 37-37 #bdbdbd,#080808,,body 38-89 d,#080808,,body
+|5: 4 pub fn choose(ok: bool) u32 {
+@5: 0-0 d,#444444,,body 1-1 d,#080808,,body 2-6 #626262,#080808,,body 7-10 #bdbdbd,#080808,,body 11-12 #cf87e8,#080808,b,body 13-35 #bdbdbd,#080808,,body 36-89 d,#080808,,body
+|6: 5 if (ok) return 42;
+@6: 0-0 d,#444444,,body 1-1 d,#080808,,body 2-6 #626262,#080808,,body 7-10 #bdbdbd,#080808,,body 11-12 #cf87e8,#080808,b,body 13-18 #bdbdbd,#080808,,body 19-24 #cf87e8,#080808,b,body 25-25 #bdbdbd,#080808,,body 26-27 #e3c78a,#080808,,body 28-28 #bdbdbd,#080808,,body 29-89 d,#080808,,body
+|7: 6 return 7;
+@7: 0-0 d,#444444,,body 1-1 d,#080808,,body 2-6 #626262,#080808,,body 7-10 #bdbdbd,#080808,,body 11-16 #cf87e8,#080808,b,body 17-17 #bdbdbd,#080808,,body 18-18 #e3c78a,#080808,,body 19-19 #bdbdbd,#080808,,body 20-89 d,#080808,,body
+== style resized grid=105x19
+|0: 0-74 #949494,#121212, 75-104 d,#121212,
+|1: 0-1 #ffffff,#626262, 2-84 #949494,#121212, 85-104 d,#121212,
+|2: 0-0 d,#444444, 1-1 d,#080808, 2-6 #626262,#080808, 7-17 #ffffff,#080808,b 18-18 d,d, 19-104 d,#080808,
+|3: 0-0 d,#444444, 1-1 d,#080808, 2-6 #949494,#121212, 7-23 #bdbdbd,#080808, 24-32 #e3c78a,#080808, 33-33 d,d, 34-36 #e3c78a,#080808, 37-37 #bdbdbd,#080808, 38-104 d,#080808,
+|4: 0-0 d,#444444, 1-1 d,#080808, 2-6 #626262,#080808, 7-104 d,#080808,
+|5: 0-0 d,#444444, 1-1 d,#080808, 2-6 #626262,#080808, 7-10 #bdbdbd,#080808, 11-12 #cf87e8,#080808,b 13-35 #bdbdbd,#080808, 36-104 d,#080808,
+|6: 0-0 d,#444444, 1-1 d,#080808, 2-6 #626262,#080808, 7-10 #bdbdbd,#080808, 11-12 #cf87e8,#080808,b 13-18 #bdbdbd,#080808, 19-24 #cf87e8,#080808,b 25-25 #bdbdbd,#080808, 26-27 #e3c78a,#080808, 28-28 #bdbdbd,#080808, 29-104 d,#080808,
+|7: 0-0 d,#444444, 1-1 d,#080808, 2-6 #626262,#080808, 7-10 #bdbdbd,#080808, 11-16 #cf87e8,#080808,b 17-17 #bdbdbd,#080808, 18-18 #e3c78a,#080808, 19-19 #bdbdbd,#080808, 20-104 d,#080808,
+|8: 0-0 d,#444444, 1-1 d,#080808, 2-6 #626262,#080808, 7-7 #bdbdbd,#080808, 8-104 d,#080808,
+|9: 0-0 d,#444444, 1-1 d,#080808, 2-6 #626262,#080808, 7-104 d,#080808,
+|10: 0-0 d,#444444, 1-1 d,#080808, 2-6 #626262,#080808, 7-104 d,#080808,
+|11: 0-0 d,#444444, 1-1 d,#080808, 2-6 #626262,#080808, 7-104 d,#080808,
+|12: 0-0 d,#444444, 1-1 d,#080808, 2-6 #626262,#080808, 7-104 d,#080808,
+|13: 0-0 d,#444444, 1-1 d,#080808, 2-6 #626262,#080808, 7-104 d,#080808,
+|14: 0-0 d,#444444, 1-1 d,#080808, 2-6 #626262,#080808, 7-104 d,#080808,
+|15: 0-0 d,#444444, 1-1 d,#080808, 2-6 #626262,#080808, 7-104 d,#080808,
+|16: 0-0 d,#444444, 1-1 d,#080808, 2-6 #626262,#080808, 7-104 d,#080808,
+|17: 0-0 d,#444444, 1-1 d,#080808, 2-6 #626262,#080808, 7-104 d,#080808,
+|18: 0-0 d,#444444, 1-1 d,#080808, 2-6 #626262,#080808, 7-104 d,#080808,
+== 9p resized grid=105x19 cursor=7,3,block
+|0: New Newcol Joincol Find Grep Help Changelog Tutor Dump NextColor Debug Kill
+@0: 0-74 #949494,#121212,,tagline 75-104 d,#121212,,tagline
+|1: /tmp/pardes-snap/ninep/cwd/demo.zig * Save New Newtty Del
+@1: 0-1 #ffffff,#626262,,tagline 2-84 #949494,#121212,,tagline 85-104 d,#121212,,tagline
+|2: 1 // café λ 界
++2: 13="é" 15="λ" 17="界" 18=""
+@2: 0-0 d,#444444,,body 1-1 d,#080808,,body 2-6 #626262,#080808,,body 7-18 #ffffff,#080808,b,body 19-104 d,#080808,,body
+|3: 2 const greeting = "café λ 界 é";
++3: 28="é" 30="λ" 32="界" 33="" 35="é"
+@3: 0-0 d,#444444,,body 1-1 d,#080808,,body 2-6 #949494,#121212,,body 7-23 #bdbdbd,#080808,,body 24-36 #e3c78a,#080808,,body 37-37 #bdbdbd,#080808,,body 38-104 d,#080808,,body
+|4: 3
+@4: 0-0 d,#444444,,body 1-1 d,#080808,,body 2-6 #626262,#080808,,body 7-104 d,#080808,,body
+|5: 4 pub fn choose(ok: bool) u32 {
+@5: 0-0 d,#444444,,body 1-1 d,#080808,,body 2-6 #626262,#080808,,body 7-10 #bdbdbd,#080808,,body 11-12 #cf87e8,#080808,b,body 13-35 #bdbdbd,#080808,,body 36-104 d,#080808,,body
+|6: 5 if (ok) return 42;
+@6: 0-0 d,#444444,,body 1-1 d,#080808,,body 2-6 #626262,#080808,,body 7-10 #bdbdbd,#080808,,body 11-12 #cf87e8,#080808,b,body 13-18 #bdbdbd,#080808,,body 19-24 #cf87e8,#080808,b,body 25-25 #bdbdbd,#080808,,body 26-27 #e3c78a,#080808,,body 28-28 #bdbdbd,#080808,,body 29-104 d,#080808,,body
+|7: 6 return 7;
+@7: 0-0 d,#444444,,body 1-1 d,#080808,,body 2-6 #626262,#080808,,body 7-10 #bdbdbd,#080808,,body 11-16 #cf87e8,#080808,b,body 17-17 #bdbdbd,#080808,,body 18-18 #e3c78a,#080808,,body 19-19 #bdbdbd,#080808,,body 20-104 d,#080808,,body
+|8: 7 }
+@8: 0-0 d,#444444,,body 1-1 d,#080808,,body 2-6 #626262,#080808,,body 7-7 #bdbdbd,#080808,,body 8-104 d,#080808,,body
+|9: 8
+@9: 0-0 d,#444444,,body 1-1 d,#080808,,body 2-6 #626262,#080808,,body 7-104 d,#080808,,body
+|10:
+@10: 0-0 d,#444444,,body 1-1 d,#080808,,body 2-6 #626262,#080808,,body 7-104 d,#080808,,body
+|11:
+@11: 0-0 d,#444444,,body 1-1 d,#080808,,body 2-6 #626262,#080808,,body 7-104 d,#080808,,body
+|12:
+@12: 0-0 d,#444444,,body 1-1 d,#080808,,body 2-6 #626262,#080808,,body 7-104 d,#080808,,body
+|13:
+@13: 0-0 d,#444444,,body 1-1 d,#080808,,body 2-6 #626262,#080808,,body 7-104 d,#080808,,body
+|14:
+@14: 0-0 d,#444444,,body 1-1 d,#080808,,body 2-6 #626262,#080808,,body 7-104 d,#080808,,body
+|15:
+@15: 0-0 d,#444444,,body 1-1 d,#080808,,body 2-6 #626262,#080808,,body 7-104 d,#080808,,body
+|16:
+@16: 0-0 d,#444444,,body 1-1 d,#080808,,body 2-6 #626262,#080808,,body 7-104 d,#080808,,body
+|17:
+@17: 0-0 d,#444444,,body 1-1 d,#080808,,body 2-6 #626262,#080808,,body 7-104 d,#080808,,body
+|18:
+@18: 0-0 d,#444444,,body 1-1 d,#080808,,body 2-6 #626262,#080808,,body 7-104 d,#080808,,body
+== snap resized grid=105x19 cursor=7,3
+|New Newcol Joincol Find Grep Help Changelog Tutor Dump NextColor Debug Kill
+| /tmp/pardes-snap/ninep/cwd/demo.zig * Save New Newtty Del
+| 1 // café λ 界
+| 2 const greeting = "café λ 界 é";
+| 3
+| 4 pub fn choose(ok: bool) u32 {
+| 5 if (ok) return 42;
+| 6 return 7;
+| 7 }
+| 8
+== 9p unchanged grid=105x19 cursor=7,3,block
diff --git a/test/snapshots/ninep.snap b/test/snapshots/ninep.snap
new file mode 100644
index 00000000..5c9da02a
--- /dev/null
+++ b/test/snapshots/ninep.snap
@@ -0,0 +1,28 @@
+file demo.zig const greeting = "café λ 界 é";\n\npub fn choose(ok: bool) u32 {\n if (ok) return 42;\n return 7;\n}\n
+start 14 90 demo.zig
+wait 8000 choose
+stable 400 10000
+snap opened
+snapstyle opened
+snap9p opened
+key space t c
+stable 300 8000
+snapstyle colors-off
+snap9p colors-off
+key g g i
+send // café λ 界\n
+key esc
+settle 100
+stable 300 8000
+snap edited-with-colors-off
+snap9p edited-with-colors-off
+key space t c
+stable 300 8000
+snapstyle colors-on
+snap9p colors-on
+resize 19 105
+stable 400 10000
+snapstyle resized
+snap9p resized
+snap resized
+snap9p unchanged
diff --git a/test/snapshots/shellset.snap b/test/snapshots/shellset.snap
index 45c94dee..e50d29bc 100644
--- a/test/snapshots/shellset.snap
+++ b/test/snapshots/shellset.snap
@@ -10,7 +10,7 @@
#
# The rest of the feature is unit-tested rather than pinned here, on purpose.
# Which family a binary belongs to, what argv each one gets and where the
-# lookup searches are in shell_bin.zig's own tests; the fish end of it cannot
+# lookup searches are in host_io.Shell's own tests; the fish end of it cannot
# be a golden at all, because fish's prompt carries a hostname and its greeting
# a version number. (Every script in this suite runs bash, pinned through an
# ordinary config file the harness writes — see snapshot.zig.)