summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGabriel Schneider <[email protected]>2026-08-11 18:30:13 -0300
committerGabriel Schneider <[email protected]>2026-08-12 13:04:32 -0300
commitb424164922842796619cb6894ec46d729a8a6826 (patch)
treebd4653accfaeb67012f4e7257c61eaf4fb12c892
parent08f32cdde672740b71608f3dfccd629dcbac78f7 (diff)
downloadpardes-b424164922842796619cb6894ec46d729a8a6826.tar.gz
pardes-b424164922842796619cb6894ec46d729a8a6826.zip
clipboard, n/N and the tty prompt: three things that were half-wired
Three changes that all turned out to be the same shape -- a feature that worked in one direction, or for one pane kind, and quietly did not in the others. CLIPBOARD. Every register write emitted set_clipboard, so deleting one character threw away whatever the desktop was holding; multi-cursor yank took the join's early return and emitted nothing at all, so the same key reached the clipboard on one cursor and not on two. Nothing could READ the clipboard: the SDL shell had no SDL_GetClipboardText anywhere in it, and the tty shell never asked for OSC 52, so `p` from another application was dead in both. Now it is helix's split. y/d/c/p/P/R and the acme chords are the DEFAULT REGISTER and nothing else; the system clipboard is five words on helix's own letters -- SPC y, SPC Y, SPC p, SPC P, SPC R -- spelled as builtins so they land in Help and are executable like every other verb. The one exception is the tag `y` chord, which still mirrors out because a tag is always insert, so SPC cannot be pressed there, and copying the path out is the whole point of the chord. Reading is a new read_clipboard effect answered by an ordinary Event.paste, so the round trip is honest about being one: SDL and NSPasteboard answer inside the same drain, the browser answers a promise, and a terminal answers over OSC 52 or -- far more often -- refuses. A refused read is a paste that does not happen, and the request dies at the next keystroke rather than landing minutes late in whatever pane is focused by then. The tty shell also enables BRACKETED PASTE now and coalesces paste_start..paste_end into one event. Before this a paste arrived as a flood of individual key presses: plausible in insert mode, and in normal mode every pasted character ran as a command. n/N. They stepped the armed results buffer and immediately Looked each row, so you could not walk past a hit without opening it. They are a MOTION now: select the next look-able text, open nothing, and let Enter decide. What they step is the largest whitespace-delimited run look.resolve can act on (look.lookableSpan, wrapper punctuation peeled), over a RING of panes -- every pane that has performed a look, most recent first, then the output buffers that have not, newest first, and only if both are empty the pane in front of you. N is the exact inverse of n, computed rather than remembered: both directions ask the same question about the same spans and compare against the column the walk parks on, so x presses one way and x back land exactly where you started, pane boundaries and the ring's seam included. A ring rather than a list with two ends because a shell's cursor sits at the prompt, below everything it has printed, so a walk that could not come round would have nowhere to go on the very first press -- which is the case n/N were written for. One motion everywhere, no pane-kind or buffer-kind special case. The only thing a buffer may change is the GRAIN of what a step selects, and it does it with one flag rather than a branch: output_pane.Traits.commands (renamed from `executes`, which named one reader's behaviour rather than the fact) makes a row select WHOLE, because a ThemeSel line is a word to run and has no path inside it to pick out. `]d`/`[d` are not n/N -- they are helix's diagnostic motions, their job is to ARRIVE, and they still reach searchStep. THE TTY PROMPT. Leaving raw tty blanked the prompt row, and the command you had typed at that prompt shares the row, so it went too -- a shell out of tty read as output only. OSC 133 marks the row CELL by cell, so the two are separable: config.tty_blank = .prompt cuts the prompt's own columns and leaves the command, left-hugged at column 0 in line with the output under it rather than in a bay of blanks. .prompt_and_input is the old behaviour, kept. Because the row is now something you can put a cursor in, enterTty adds the hidden prompt width back before asking ghostty to walk the shell's own cursor to it -- the modal column on a cut row is short by exactly that much. Verified: unit-test 186/186 (nine new), snap 87/87 (new ttyprompt.snap), hxdiff 481 and hxparity 561 with 0 mismatches, tty and gui both build. And against the real binaries rather than the harness: in a pty, SPC y emits OSC 52 carrying exactly the selection while plain y emits nothing, SPC p issues the read and pastes the reply, and a bracketed paste of "dd..." inserts text instead of deleting two lines. In a real SDL window, SPC y then SPC p round trips through the system clipboard while the default register holds different text. Setting tty_blank back to .prompt_and_input reproduces all 86 old goldens byte for byte.
-rw-r--r--docs/design.pdf1537
-rw-r--r--docs/design.typ19
-rw-r--r--docs/helix-keys.md31
-rw-r--r--docs/lsp.md17
-rw-r--r--docs/macos.md73
-rw-r--r--src/builtins.zig70
-rw-r--r--src/config.zig42
-rw-r--r--src/gui/gui.zig39
-rw-r--r--src/look.zig76
-rw-r--r--src/macos.zig15
-rw-r--r--src/macos/Sources/AppDelegate.swift22
-rw-r--r--src/macos/pardes.h7
-rw-r--r--src/output_pane.zig36
-rw-r--r--src/pardes.zig993
-rw-r--r--src/term_pane.zig76
-rw-r--r--src/tty/tty.zig85
-rw-r--r--src/tutor.txt44
-rw-r--r--src/web.zig4
-rw-r--r--src/web/app.mjs5
-rw-r--r--test/macos_e2e.swift14
-rw-r--r--test/snapshots/argv.golden2
-rw-r--r--test/snapshots/boot.golden2
-rw-r--r--test/snapshots/builtins.golden216
-rw-r--r--test/snapshots/builtins.snap23
-rw-r--r--test/snapshots/chordcut.golden44
-rw-r--r--test/snapshots/cmdword.golden30
-rw-r--r--test/snapshots/cornerdrag.golden30
-rw-r--r--test/snapshots/cursorline.golden8
-rw-r--r--test/snapshots/doccol.golden10
-rw-r--r--test/snapshots/dump.golden12
-rw-r--r--test/snapshots/edit.golden4
-rw-r--r--test/snapshots/exec-bigdrag.golden60
-rw-r--r--test/snapshots/exec.golden14
-rw-r--r--test/snapshots/fileedit.golden12
-rw-r--r--test/snapshots/filewatch.golden16
-rw-r--r--test/snapshots/find.golden152
-rw-r--r--test/snapshots/find.snap63
-rw-r--r--test/snapshots/fsearch.golden44
-rw-r--r--test/snapshots/fsearch.snap25
-rw-r--r--test/snapshots/ghostty-mid.golden6
-rw-r--r--test/snapshots/grep.golden68
-rw-r--r--test/snapshots/grep.snap32
-rw-r--r--test/snapshots/hscroll.golden20
-rw-r--r--test/snapshots/images.golden12
-rw-r--r--test/snapshots/jumps.golden46
-rw-r--r--test/snapshots/jumps.snap50
-rw-r--r--test/snapshots/layout-close.golden32
-rw-r--r--test/snapshots/layout-open.golden30
-rw-r--r--test/snapshots/leader.golden74
-rw-r--r--test/snapshots/load.golden4
-rw-r--r--test/snapshots/look-center.golden12
-rw-r--r--test/snapshots/look-dir.golden6
-rw-r--r--test/snapshots/look-file-1col.golden2
-rw-r--r--test/snapshots/look-file.golden4
-rw-r--r--test/snapshots/lookloaded.golden16
-rw-r--r--test/snapshots/lookpanes.golden20
-rw-r--r--test/snapshots/lookrange.golden6
-rw-r--r--test/snapshots/lookrange.snap12
-rw-r--r--test/snapshots/lsp.snap5
-rw-r--r--test/snapshots/lspcomplete.snap6
-rw-r--r--test/snapshots/lsprelpath.golden24
-rw-r--r--test/snapshots/lsprelpath.snap10
-rw-r--r--test/snapshots/modal.golden116
-rw-r--r--test/snapshots/multicursor.golden16
-rw-r--r--test/snapshots/nested.golden2
-rw-r--r--test/snapshots/psearch.golden20
-rw-r--r--test/snapshots/psearch.snap29
-rw-r--r--test/snapshots/respawn.golden2
-rw-r--r--test/snapshots/restore.golden4
-rw-r--r--test/snapshots/rsearch.golden36
-rw-r--r--test/snapshots/scroll.golden20
-rw-r--r--test/snapshots/scrolloff.golden28
-rw-r--r--test/snapshots/selarg.golden12
-rw-r--r--test/snapshots/shellset.golden2
-rw-r--r--test/snapshots/shrinktag.golden18
-rw-r--r--test/snapshots/splitparent.golden18
-rw-r--r--test/snapshots/syntax.golden8
-rw-r--r--test/snapshots/tag.golden20
-rw-r--r--test/snapshots/tagalign.golden10
-rw-r--r--test/snapshots/tagalign2col.golden10
-rw-r--r--test/snapshots/tagbottomimage.golden8
-rw-r--r--test/snapshots/tagnav.golden68
-rw-r--r--test/snapshots/theme.golden24
-rw-r--r--test/snapshots/themesel.golden50
-rw-r--r--test/snapshots/themesel.snap51
-rw-r--r--test/snapshots/tinywin.golden18
-rw-r--r--test/snapshots/topbarexec.golden12
-rw-r--r--test/snapshots/tty.golden28
-rw-r--r--test/snapshots/ttyclick.golden16
-rw-r--r--test/snapshots/ttyedit.golden40
-rw-r--r--test/snapshots/ttyfollow.golden8
-rw-r--r--test/snapshots/ttyhelp.golden88
-rw-r--r--test/snapshots/ttylook.golden40
-rw-r--r--test/snapshots/ttylook.snap12
-rw-r--r--test/snapshots/ttyprompt.golden93
-rw-r--r--test/snapshots/ttyprompt.snap35
-rw-r--r--test/snapshots/tutor.golden4
-rw-r--r--test/snapshots/winch.golden8
-rw-r--r--test/snapshots/windownav.golden38
-rw-r--r--test/snapshots/windowops.golden52
100 files changed, 3530 insertions, 2003 deletions
diff --git a/docs/design.pdf b/docs/design.pdf
index 83f97dc2..ab211161 100644
--- a/docs/design.pdf
+++ b/docs/design.pdf
@@ -2,783 +2,810 @@
%����
1 0 obj
-<</Type/Pages/Count 5/Kids[253 0 R 254 0 R 255 0 R 256 0 R 257 0 R]>>
+<</Type/Pages/Count 5/Kids[262 0 R 263 0 R 264 0 R 265 0 R 266 0 R]>>
endobj
2 0 obj
-<</Parent 10 0 R/Next 3 0 R/Title(What it is)/Dest 228 0 R>>
+<</Parent 10 0 R/Next 3 0 R/Title(What it is)/Dest 237 0 R>>
endobj
3 0 obj
-<</Parent 10 0 R/Next 4 0 R/Prev 2 0 R/Title(The shape)/Dest 229 0 R>>
+<</Parent 10 0 R/Next 4 0 R/Prev 2 0 R/Title(The shape)/Dest 238 0 R>>
endobj
4 0 obj
-<</Parent 10 0 R/Next 5 0 R/Prev 3 0 R/Title(Data structures)/Dest 230 0 R>>
+<</Parent 10 0 R/Next 5 0 R/Prev 3 0 R/Title(Data structures)/Dest 239 0 R>>
endobj
5 0 obj
-<</Parent 10 0 R/Next 6 0 R/Prev 4 0 R/Title(Style)/Dest 231 0 R>>
+<</Parent 10 0 R/Next 6 0 R/Prev 4 0 R/Title(Style)/Dest 240 0 R>>
endobj
6 0 obj
-<</Parent 10 0 R/Next 7 0 R/Prev 5 0 R/Title(Testing: the old program is the oracle)/Dest 232 0 R>>
+<</Parent 10 0 R/Next 7 0 R/Prev 5 0 R/Title(Testing: the old program is the oracle)/Dest 241 0 R>>
endobj
7 0 obj
-<</Parent 10 0 R/Next 8 0 R/Prev 6 0 R/Title(Build)/Dest 233 0 R>>
+<</Parent 10 0 R/Next 8 0 R/Prev 6 0 R/Title(Build)/Dest 242 0 R>>
endobj
8 0 obj
-<</Parent 10 0 R/Next 9 0 R/Prev 7 0 R/Title(What is deliberately absent)/Dest 234 0 R>>
+<</Parent 10 0 R/Next 9 0 R/Prev 7 0 R/Title(What is deliberately absent)/Dest 243 0 R>>
endobj
9 0 obj
-<</Parent 10 0 R/Prev 8 0 R/Title(Appendix A: feature parity checklist)/Dest 235 0 R>>
+<</Parent 10 0 R/Prev 8 0 R/Title(Appendix A: feature parity checklist)/Dest 244 0 R>>
endobj
10 0 obj
<</Type/Outlines/First 2 0 R/Last 9 0 R/Count 8>>
endobj
11 0 obj
-<</Type/StructTreeRoot/RoleMap<</Datetime/Span/Terms/Part/Title/P/Strong/Span/Em/Span>>/K[225 0 R]/ParentTree<</Nums[0 12 0 R 1 13 0 R 2 14 0 R 3 15 0 R 4 16 0 R]>>/ParentTreeNextKey 5>>
+<</Type/StructTreeRoot/RoleMap<</Datetime/Span/Terms/Part/Title/P/Strong/Span/Em/Span>>/K[234 0 R]/ParentTree<</Nums[0 12 0 R 1 13 0 R 2 14 0 R 3 15 0 R 4 16 0 R]>>/ParentTreeNextKey 5>>
endobj
12 0 obj
-[17 0 R 19 0 R 20 0 R 21 0 R 21 0 R 21 0 R 21 0 R 22 0 R 22 0 R 22 0 R 22 0 R 23 0 R 25 0 R 24 0 R 25 0 R 25 0 R 25 0 R 26 0 R 30 0 R 28 0 R 30 0 R 29 0 R 30 0 R 32 0 R 34 0 R 34 0 R 34 0 R 40 0 R 37 0 R 40 0 R 40 0 R 40 0 R 38 0 R 40 0 R 40 0 R 40 0 R 39 0 R 40 0 R 41 0 R 42 0 R 50 0 R 43 0 R 50 0 R 44 0 R 50 0 R 45 0 R 50 0 R 46 0 R 50 0 R 47 0 R 50 0 R 48 0 R 50 0 R 49 0 R 50 0 R 50 0 R 50 0 R 50 0 R 51 0 R 53 0 R 53 0 R 52 0 R 53 0 R 53 0 R 53 0 R 53 0 R 53 0 R 54 0 R 64 0 R 55 0 R 64 0 R 56 0 R 64 0 R 57 0 R 64 0 R 58 0 R 64 0 R 59 0 R 64 0 R 60 0 R 64 0 R 61 0 R 64 0 R 62 0 R 64 0 R 64 0 R 63 0 R 64 0 R 64 0 R 66 0 R 65 0 R 66 0 R]
+[17 0 R 19 0 R 20 0 R 21 0 R 21 0 R 21 0 R 21 0 R 22 0 R 22 0 R 22 0 R 22 0 R 23 0 R 25 0 R 24 0 R 25 0 R 25 0 R 25 0 R 26 0 R 30 0 R 28 0 R 30 0 R 29 0 R 30 0 R 32 0 R 34 0 R 34 0 R 34 0 R 40 0 R 37 0 R 40 0 R 40 0 R 40 0 R 38 0 R 40 0 R 40 0 R 40 0 R 39 0 R 40 0 R 41 0 R 42 0 R 50 0 R 43 0 R 50 0 R 44 0 R 50 0 R 45 0 R 50 0 R 46 0 R 50 0 R 47 0 R 50 0 R 48 0 R 50 0 R 49 0 R 50 0 R 50 0 R 50 0 R 50 0 R 51 0 R 53 0 R 53 0 R 52 0 R 53 0 R 53 0 R 53 0 R 53 0 R 53 0 R 54 0 R 68 0 R 55 0 R 68 0 R 56 0 R 68 0 R 57 0 R 68 0 R 58 0 R 68 0 R 59 0 R 68 0 R 60 0 R 68 0 R 61 0 R 68 0 R 62 0 R 68 0 R 63 0 R 68 0 R 64 0 R 68 0 R 68 0 R 65 0 R 68 0 R 68 0 R 66 0 R 68 0 R 68 0 R 68 0 R 67 0 R 68 0 R]
endobj
13 0 obj
-[67 0 R 67 0 R 67 0 R 67 0 R 67 0 R 67 0 R 67 0 R 67 0 R 67 0 R 67 0 R 67 0 R 67 0 R 67 0 R 67 0 R 67 0 R 67 0 R 67 0 R 67 0 R 67 0 R 67 0 R 67 0 R 67 0 R 68 0 R 69 0 R 69 0 R 69 0 R 69 0 R 69 0 R 69 0 R 69 0 R 69 0 R 69 0 R 69 0 R 69 0 R 69 0 R 69 0 R 69 0 R 69 0 R 69 0 R 69 0 R 70 0 R 70 0 R 70 0 R 70 0 R 70 0 R 70 0 R 70 0 R 70 0 R 70 0 R 70 0 R 70 0 R 70 0 R 70 0 R 70 0 R 70 0 R 76 0 R 72 0 R 76 0 R 73 0 R 76 0 R 76 0 R 74 0 R 76 0 R 75 0 R 76 0 R 76 0 R 77 0 R 78 0 R 79 0 R 80 0 R 80 0 R 80 0 R 80 0 R 80 0 R 80 0 R 80 0 R 81 0 R 81 0 R 81 0 R 81 0 R 81 0 R 81 0 R 81 0 R 82 0 R 82 0 R 82 0 R 82 0 R 82 0 R 83 0 R 83 0 R 83 0 R 83 0 R 83 0 R 83 0 R 83 0 R 84 0 R 84 0 R 84 0 R 84 0 R 84 0 R 84 0 R 84 0 R 85 0 R 85 0 R 85 0 R 85 0 R 85 0 R 86 0 R 86 0 R 86 0 R 86 0 R 86 0 R 86 0 R 86 0 R 87 0 R 87 0 R 87 0 R 87 0 R 87 0 R 87 0 R 87 0 R 87 0 R 89 0 R 90 0 R 90 0 R 90 0 R 90 0 R 90 0 R 90 0 R 90 0 R 91 0 R 91 0 R 91 0 R 91 0 R 91 0 R 91 0 R 91 0 R 91 0 R 91 0 R 91 0 R 91 0 R 91 0 R 91 0 R 91 0 R 91 0 R 91 0 R 91 0 R 91 0 R 91 0 R 91 0 R 91 0 R 91 0 R 91 0 R 91 0 R 91 0 R 92 0 R 92 0 R 92 0 R 92 0 R 92 0 R 93 0 R 93 0 R 93 0 R 93 0 R 93 0 R 93 0 R 93 0 R 93 0 R 93 0 R 93 0 R 93 0 R 93 0 R 93 0 R 93 0 R 93 0 R 93 0 R 93 0 R 93 0 R 93 0 R 94 0 R 94 0 R 94 0 R 94 0 R 94 0 R 94 0 R 94 0 R 94 0 R 94 0 R 94 0 R 94 0 R 95 0 R 95 0 R 95 0 R 95 0 R 95 0 R 95 0 R 95 0 R 95 0 R 95 0 R 95 0 R 95 0 R 95 0 R 95 0 R 95 0 R 95 0 R 95 0 R 95 0 R 95 0 R 95 0 R 96 0 R 96 0 R 96 0 R 96 0 R 96 0 R 96 0 R 96 0 R 97 0 R 97 0 R 97 0 R 97 0 R 97 0 R 97 0 R 97 0 R 97 0 R 97 0 R 99 0 R 99 0 R 99 0 R 99 0 R 99 0 R 99 0 R 99 0 R 99 0 R 99 0 R 99 0 R 99 0 R 99 0 R 99 0 R 99 0 R 99 0 R 99 0 R 99 0 R 99 0 R 99 0 R 99 0 R 99 0 R 99 0 R 99 0 R 99 0 R 99 0 R 99 0 R 99 0 R 100 0 R 100 0 R 100 0 R 100 0 R 100 0 R 100 0 R 100 0 R 100 0 R 100 0 R 100 0 R 100 0 R 100 0 R 100 0 R 100 0 R 100 0 R 100 0 R 100 0 R 100 0 R 100 0 R 100 0 R 100 0 R 100 0 R 100 0 R 100 0 R 100 0 R 100 0 R 100 0 R 100 0 R 100 0 R 101 0 R 101 0 R 101 0 R 101 0 R 101 0 R 101 0 R 101 0 R 101 0 R 101 0 R 101 0 R 101 0 R 101 0 R 101 0 R 101 0 R 101 0 R 105 0 R 103 0 R 105 0 R 104 0 R 105 0 R 105 0 R 105 0 R 106 0 R 109 0 R 107 0 R 109 0 R 109 0 R 108 0 R 108 0 R 109 0 R 109 0 R 110 0 R 112 0 R 116 0 R 117 0 R 118 0 R 118 0 R 118 0 R 120 0 R 121 0 R 122 0 R 124 0 R 125 0 R 126 0 R 128 0 R 129 0 R 130 0 R 130 0 R]
+[70 0 R 69 0 R 70 0 R 71 0 R 71 0 R 71 0 R 71 0 R 71 0 R 71 0 R 71 0 R 71 0 R 71 0 R 71 0 R 71 0 R 71 0 R 71 0 R 71 0 R 71 0 R 71 0 R 71 0 R 71 0 R 71 0 R 71 0 R 71 0 R 71 0 R 72 0 R 73 0 R 73 0 R 73 0 R 73 0 R 73 0 R 73 0 R 73 0 R 73 0 R 73 0 R 73 0 R 73 0 R 73 0 R 73 0 R 73 0 R 73 0 R 73 0 R 73 0 R 74 0 R 74 0 R 74 0 R 74 0 R 74 0 R 74 0 R 74 0 R 74 0 R 74 0 R 74 0 R 74 0 R 74 0 R 74 0 R 74 0 R 74 0 R 80 0 R 76 0 R 80 0 R 77 0 R 80 0 R 80 0 R 78 0 R 80 0 R 79 0 R 80 0 R 80 0 R 81 0 R 82 0 R 83 0 R 84 0 R 84 0 R 84 0 R 84 0 R 84 0 R 84 0 R 84 0 R 85 0 R 85 0 R 85 0 R 85 0 R 85 0 R 85 0 R 85 0 R 86 0 R 86 0 R 86 0 R 86 0 R 86 0 R 87 0 R 87 0 R 87 0 R 87 0 R 87 0 R 87 0 R 87 0 R 88 0 R 88 0 R 88 0 R 88 0 R 88 0 R 88 0 R 88 0 R 89 0 R 89 0 R 89 0 R 89 0 R 89 0 R 90 0 R 90 0 R 90 0 R 90 0 R 90 0 R 90 0 R 90 0 R 91 0 R 91 0 R 91 0 R 91 0 R 91 0 R 91 0 R 91 0 R 91 0 R 93 0 R 94 0 R 94 0 R 94 0 R 94 0 R 94 0 R 94 0 R 94 0 R 95 0 R 95 0 R 95 0 R 95 0 R 95 0 R 95 0 R 95 0 R 95 0 R 95 0 R 95 0 R 95 0 R 95 0 R 95 0 R 95 0 R 95 0 R 95 0 R 95 0 R 95 0 R 95 0 R 95 0 R 95 0 R 95 0 R 95 0 R 95 0 R 95 0 R 96 0 R 96 0 R 96 0 R 96 0 R 96 0 R 97 0 R 97 0 R 97 0 R 97 0 R 97 0 R 97 0 R 97 0 R 97 0 R 97 0 R 97 0 R 97 0 R 97 0 R 97 0 R 97 0 R 97 0 R 97 0 R 97 0 R 97 0 R 97 0 R 98 0 R 98 0 R 98 0 R 98 0 R 98 0 R 98 0 R 98 0 R 98 0 R 98 0 R 98 0 R 98 0 R 99 0 R 99 0 R 99 0 R 99 0 R 99 0 R 99 0 R 99 0 R 99 0 R 99 0 R 99 0 R 99 0 R 99 0 R 99 0 R 99 0 R 99 0 R 99 0 R 99 0 R 99 0 R 99 0 R 100 0 R 100 0 R 100 0 R 100 0 R 100 0 R 100 0 R 100 0 R 101 0 R 101 0 R 101 0 R 101 0 R 101 0 R 101 0 R 101 0 R 101 0 R 101 0 R 103 0 R 103 0 R 103 0 R 103 0 R 103 0 R 103 0 R 103 0 R 103 0 R 103 0 R 103 0 R 103 0 R 103 0 R 103 0 R 103 0 R 103 0 R 103 0 R 103 0 R 103 0 R 103 0 R 103 0 R 103 0 R 103 0 R 103 0 R 103 0 R 103 0 R 103 0 R 103 0 R 104 0 R 104 0 R 104 0 R 104 0 R 104 0 R 104 0 R 104 0 R 104 0 R 104 0 R 104 0 R 104 0 R 104 0 R 104 0 R 104 0 R 104 0 R 104 0 R 104 0 R 104 0 R 104 0 R 104 0 R 104 0 R 104 0 R 104 0 R 104 0 R 104 0 R 104 0 R 104 0 R 104 0 R 104 0 R 105 0 R 105 0 R 105 0 R 105 0 R 105 0 R 105 0 R 105 0 R 105 0 R 105 0 R 105 0 R 105 0 R 105 0 R 105 0 R 105 0 R 105 0 R 109 0 R 107 0 R 109 0 R 108 0 R 109 0 R 109 0 R 109 0 R 110 0 R 113 0 R 111 0 R 113 0 R 113 0 R 112 0 R 112 0 R 113 0 R 113 0 R 114 0 R 116 0 R 120 0 R 121 0 R 122 0 R 122 0 R 122 0 R 124 0 R 125 0 R 126 0 R 128 0 R 129 0 R 130 0 R]
endobj
14 0 obj
-[132 0 R 134 0 R 136 0 R 136 0 R 136 0 R 138 0 R 139 0 R 140 0 R 143 0 R 152 0 R 144 0 R 152 0 R 145 0 R 152 0 R 152 0 R 146 0 R 152 0 R 152 0 R 152 0 R 147 0 R 152 0 R 152 0 R 148 0 R 152 0 R 152 0 R 152 0 R 149 0 R 152 0 R 150 0 R 152 0 R 151 0 R 152 0 R 154 0 R 153 0 R 154 0 R 154 0 R 154 0 R 154 0 R 154 0 R 155 0 R 155 0 R 156 0 R 157 0 R 164 0 R 158 0 R 164 0 R 159 0 R 164 0 R 160 0 R 164 0 R 164 0 R 164 0 R 161 0 R 161 0 R 164 0 R 162 0 R 164 0 R 163 0 R 164 0 R 164 0 R 164 0 R 165 0 R 169 0 R 166 0 R 169 0 R 169 0 R 169 0 R 169 0 R 167 0 R 169 0 R 168 0 R 169 0 R 170 0 R 172 0 R 171 0 R 171 0 R 172 0 R 172 0 R 173 0 R 178 0 R 178 0 R 178 0 R 178 0 R 178 0 R 178 0 R 174 0 R 178 0 R 178 0 R 178 0 R 175 0 R 178 0 R 176 0 R 178 0 R 178 0 R 177 0 R 178 0 R]
+[132 0 R 133 0 R 134 0 R 134 0 R 136 0 R 138 0 R 140 0 R 140 0 R 140 0 R 142 0 R 143 0 R 144 0 R 147 0 R 156 0 R 148 0 R 156 0 R 149 0 R 156 0 R 156 0 R 150 0 R 156 0 R 156 0 R 156 0 R 151 0 R 156 0 R 156 0 R 152 0 R 156 0 R 156 0 R 156 0 R 153 0 R 156 0 R 154 0 R 156 0 R 155 0 R 156 0 R 158 0 R 157 0 R 158 0 R 158 0 R 158 0 R 158 0 R 158 0 R 159 0 R 159 0 R 160 0 R 161 0 R 168 0 R 162 0 R 168 0 R 163 0 R 168 0 R 164 0 R 168 0 R 168 0 R 168 0 R 165 0 R 168 0 R 166 0 R 168 0 R 167 0 R 168 0 R 168 0 R 168 0 R 169 0 R 173 0 R 170 0 R 173 0 R 173 0 R 173 0 R 173 0 R 171 0 R 173 0 R 172 0 R 173 0 R 174 0 R 176 0 R 175 0 R 175 0 R 176 0 R 176 0 R 177 0 R 182 0 R 182 0 R 182 0 R 182 0 R 182 0 R 182 0 R 178 0 R 182 0 R 182 0 R 182 0 R 179 0 R 182 0 R 180 0 R 182 0 R 182 0 R]
endobj
15 0 obj
-[179 0 R 186 0 R 186 0 R 186 0 R 180 0 R 186 0 R 186 0 R 181 0 R 186 0 R 182 0 R 186 0 R 186 0 R 186 0 R 186 0 R 183 0 R 186 0 R 186 0 R 186 0 R 184 0 R 186 0 R 185 0 R 186 0 R 186 0 R 186 0 R 186 0 R 187 0 R 197 0 R 188 0 R 197 0 R 189 0 R 197 0 R 190 0 R 197 0 R 197 0 R 191 0 R 197 0 R 192 0 R 197 0 R 193 0 R 197 0 R 194 0 R 197 0 R 197 0 R 197 0 R 195 0 R 197 0 R 197 0 R 196 0 R 197 0 R 197 0 R 198 0 R 204 0 R 199 0 R 204 0 R 200 0 R 204 0 R 201 0 R 204 0 R 202 0 R 202 0 R 204 0 R 203 0 R 204 0 R 204 0 R 205 0 R 207 0 R 207 0 R 206 0 R 207 0 R 207 0 R 207 0 R 207 0 R 207 0 R 208 0 R 218 0 R 209 0 R 218 0 R 218 0 R 218 0 R 210 0 R 218 0 R 218 0 R 211 0 R 218 0 R 212 0 R 218 0 R 213 0 R 218 0 R 218 0 R 218 0 R 218 0 R 214 0 R 218 0 R 215 0 R 215 0 R 218 0 R 216 0 R 218 0 R 217 0 R 218 0 R 218 0 R 218 0 R 219 0 R 224 0 R 224 0 R 224 0 R 224 0 R 224 0 R 220 0 R 224 0 R 224 0 R 221 0 R 224 0 R 224 0 R 224 0 R 224 0 R 224 0 R]
+[182 0 R 182 0 R 181 0 R 182 0 R 183 0 R 190 0 R 190 0 R 190 0 R 184 0 R 190 0 R 190 0 R 185 0 R 190 0 R 186 0 R 190 0 R 190 0 R 190 0 R 190 0 R 187 0 R 190 0 R 190 0 R 190 0 R 188 0 R 190 0 R 189 0 R 190 0 R 190 0 R 190 0 R 190 0 R 191 0 R 206 0 R 192 0 R 206 0 R 193 0 R 206 0 R 194 0 R 206 0 R 206 0 R 195 0 R 206 0 R 196 0 R 206 0 R 197 0 R 206 0 R 198 0 R 206 0 R 206 0 R 206 0 R 199 0 R 206 0 R 206 0 R 200 0 R 206 0 R 206 0 R 201 0 R 206 0 R 202 0 R 202 0 R 206 0 R 203 0 R 206 0 R 204 0 R 206 0 R 206 0 R 205 0 R 206 0 R 207 0 R 213 0 R 208 0 R 208 0 R 213 0 R 209 0 R 213 0 R 210 0 R 213 0 R 213 0 R 211 0 R 213 0 R 212 0 R 213 0 R 213 0 R 214 0 R 216 0 R 216 0 R 215 0 R 216 0 R 216 0 R 216 0 R 216 0 R 216 0 R 217 0 R 227 0 R 218 0 R 227 0 R 227 0 R 227 0 R 219 0 R 227 0 R 227 0 R 220 0 R 227 0 R 221 0 R 227 0 R 222 0 R 227 0 R 227 0 R 227 0 R 227 0 R 223 0 R 227 0 R 224 0 R 224 0 R 227 0 R 225 0 R 227 0 R 226 0 R 227 0 R 227 0 R 227 0 R 227 0 R 228 0 R 233 0 R 233 0 R 233 0 R 233 0 R 233 0 R 229 0 R 233 0 R]
endobj
16 0 obj
-[224 0 R 224 0 R 224 0 R 224 0 R 222 0 R 224 0 R 224 0 R 223 0 R 224 0 R 224 0 R]
+[233 0 R 230 0 R 233 0 R 233 0 R 233 0 R 233 0 R 233 0 R 233 0 R 233 0 R 233 0 R 233 0 R 231 0 R 233 0 R 233 0 R 232 0 R 233 0 R 233 0 R]
endobj
17 0 obj
-<</Type/StructElem/S/Strong/P 18 0 R/K[0]/Pg 253 0 R>>
+<</Type/StructElem/S/Strong/P 18 0 R/K[0]/Pg 262 0 R>>
endobj
18 0 obj
-<</Type/StructElem/S/P/P 225 0 R/K[17 0 R]>>
+<</Type/StructElem/S/P/P 234 0 R/K[17 0 R]>>
endobj
19 0 obj
-<</Type/StructElem/S/P/P 225 0 R/K[1]/Pg 253 0 R>>
+<</Type/StructElem/S/P/P 234 0 R/K[1]/Pg 262 0 R>>
endobj
20 0 obj
-<</Type/StructElem/S/H1/P 225 0 R/T(What it is)/K[2]/Pg 253 0 R>>
+<</Type/StructElem/S/H1/P 234 0 R/T(What it is)/K[2]/Pg 262 0 R>>
endobj
21 0 obj
-<</Type/StructElem/S/P/P 225 0 R/K[3 4 5 6]/Pg 253 0 R>>
+<</Type/StructElem/S/P/P 234 0 R/K[3 4 5 6]/Pg 262 0 R>>
endobj
22 0 obj
-<</Type/StructElem/S/P/P 225 0 R/K[7 8 9 10]/Pg 253 0 R>>
+<</Type/StructElem/S/P/P 234 0 R/K[7 8 9 10]/Pg 262 0 R>>
endobj
23 0 obj
-<</Type/StructElem/S/H1/P 225 0 R/T(The shape)/K[11]/Pg 253 0 R>>
+<</Type/StructElem/S/H1/P 234 0 R/T(The shape)/K[11]/Pg 262 0 R>>
endobj
24 0 obj
-<</Type/StructElem/S/Strong/P 25 0 R/K[13]/Pg 253 0 R>>
+<</Type/StructElem/S/Strong/P 25 0 R/K[13]/Pg 262 0 R>>
endobj
25 0 obj
-<</Type/StructElem/S/P/P 225 0 R/K[12 24 0 R 14 15 16]/Pg 253 0 R>>
+<</Type/StructElem/S/P/P 234 0 R/K[12 24 0 R 14 15 16]/Pg 262 0 R>>
endobj
26 0 obj
-<</Type/StructElem/S/Strong/P 27 0 R/K[17]/Pg 253 0 R>>
+<</Type/StructElem/S/Strong/P 27 0 R/K[17]/Pg 262 0 R>>
endobj
27 0 obj
<</Type/StructElem/S/TD/P 31 0 R/A[<</O/Table/Headers[]>><</O/Layout/BorderStyle/Solid>>]/K[26 0 R]>>
endobj
28 0 obj
-<</Type/StructElem/S/Code/P 30 0 R/K[19]/Pg 253 0 R>>
+<</Type/StructElem/S/Code/P 30 0 R/K[19]/Pg 262 0 R>>
endobj
29 0 obj
-<</Type/StructElem/S/Code/P 30 0 R/K[21]/Pg 253 0 R>>
+<</Type/StructElem/S/Code/P 30 0 R/K[21]/Pg 262 0 R>>
endobj
30 0 obj
-<</Type/StructElem/S/TD/P 31 0 R/A[<</O/Table/Headers[]>><</O/Layout/BorderStyle/Solid>>]/K[18 28 0 R 20 29 0 R 22]/Pg 253 0 R>>
+<</Type/StructElem/S/TD/P 31 0 R/A[<</O/Table/Headers[]>><</O/Layout/BorderStyle/Solid>>]/K[18 28 0 R 20 29 0 R 22]/Pg 262 0 R>>
endobj
31 0 obj
<</Type/StructElem/S/TR/P 36 0 R/K[27 0 R 30 0 R]>>
endobj
32 0 obj
-<</Type/StructElem/S/Strong/P 33 0 R/K[23]/Pg 253 0 R>>
+<</Type/StructElem/S/Strong/P 33 0 R/K[23]/Pg 262 0 R>>
endobj
33 0 obj
<</Type/StructElem/S/TD/P 35 0 R/A[<</O/Table/Headers[]>><</O/Layout/BorderStyle/Solid>>]/K[32 0 R]>>
endobj
34 0 obj
-<</Type/StructElem/S/TD/P 35 0 R/A[<</O/Table/Headers[]>><</O/Layout/BorderStyle/Solid>>]/K[24 25 26]/Pg 253 0 R>>
+<</Type/StructElem/S/TD/P 35 0 R/A[<</O/Table/Headers[]>><</O/Layout/BorderStyle/Solid>>]/K[24 25 26]/Pg 262 0 R>>
endobj
35 0 obj
<</Type/StructElem/S/TR/P 36 0 R/K[33 0 R 34 0 R]>>
endobj
36 0 obj
-<</Type/StructElem/S/Table/P 225 0 R/A[<</O/Layout/BorderColor[0 0 0]/BorderThickness 0.4>>]/K[31 0 R 35 0 R]>>
+<</Type/StructElem/S/Table/P 234 0 R/A[<</O/Layout/BorderColor[0 0 0]/BorderThickness 0.4>>]/K[31 0 R 35 0 R]>>
endobj
37 0 obj
-<</Type/StructElem/S/Strong/P 40 0 R/K[28]/Pg 253 0 R>>
+<</Type/StructElem/S/Strong/P 40 0 R/K[28]/Pg 262 0 R>>
endobj
38 0 obj
-<</Type/StructElem/S/Code/P 40 0 R/K[32]/Pg 253 0 R>>
+<</Type/StructElem/S/Code/P 40 0 R/K[32]/Pg 262 0 R>>
endobj
39 0 obj
-<</Type/StructElem/S/Code/P 40 0 R/K[36]/Pg 253 0 R>>
+<</Type/StructElem/S/Code/P 40 0 R/K[36]/Pg 262 0 R>>
endobj
40 0 obj
-<</Type/StructElem/S/P/P 225 0 R/K[27 37 0 R 29 30 31 38 0 R 33 34 35 39 0 R 37]/Pg 253 0 R>>
+<</Type/StructElem/S/P/P 234 0 R/K[27 37 0 R 29 30 31 38 0 R 33 34 35 39 0 R 37]/Pg 262 0 R>>
endobj
41 0 obj
-<</Type/StructElem/S/P/P 225 0 R/K[38]/Pg 253 0 R>>
+<</Type/StructElem/S/P/P 234 0 R/K[38]/Pg 262 0 R>>
endobj
42 0 obj
-<</Type/StructElem/S/Strong/P 50 0 R/K[39]/Pg 253 0 R>>
+<</Type/StructElem/S/Strong/P 50 0 R/K[39]/Pg 262 0 R>>
endobj
43 0 obj
-<</Type/StructElem/S/Code/P 50 0 R/K[41]/Pg 253 0 R>>
+<</Type/StructElem/S/Code/P 50 0 R/K[41]/Pg 262 0 R>>
endobj
44 0 obj
-<</Type/StructElem/S/Code/P 50 0 R/K[43]/Pg 253 0 R>>
+<</Type/StructElem/S/Code/P 50 0 R/K[43]/Pg 262 0 R>>
endobj
45 0 obj
-<</Type/StructElem/S/Code/P 50 0 R/K[45]/Pg 253 0 R>>
+<</Type/StructElem/S/Code/P 50 0 R/K[45]/Pg 262 0 R>>
endobj
46 0 obj
-<</Type/StructElem/S/Code/P 50 0 R/K[47]/Pg 253 0 R>>
+<</Type/StructElem/S/Code/P 50 0 R/K[47]/Pg 262 0 R>>
endobj
47 0 obj
-<</Type/StructElem/S/Code/P 50 0 R/K[49]/Pg 253 0 R>>
+<</Type/StructElem/S/Code/P 50 0 R/K[49]/Pg 262 0 R>>
endobj
48 0 obj
-<</Type/StructElem/S/Code/P 50 0 R/K[51]/Pg 253 0 R>>
+<</Type/StructElem/S/Code/P 50 0 R/K[51]/Pg 262 0 R>>
endobj
49 0 obj
-<</Type/StructElem/S/Code/P 50 0 R/K[53]/Pg 253 0 R>>
+<</Type/StructElem/S/Code/P 50 0 R/K[53]/Pg 262 0 R>>
endobj
50 0 obj
-<</Type/StructElem/S/P/P 225 0 R/K[42 0 R 40 43 0 R 42 44 0 R 44 45 0 R 46 46 0 R 48 47 0 R 50 48 0 R 52 49 0 R 54 55 56 57]/Pg 253 0 R>>
+<</Type/StructElem/S/P/P 234 0 R/K[42 0 R 40 43 0 R 42 44 0 R 44 45 0 R 46 46 0 R 48 47 0 R 50 48 0 R 52 49 0 R 54 55 56 57]/Pg 262 0 R>>
endobj
51 0 obj
-<</Type/StructElem/S/Strong/P 53 0 R/K[58]/Pg 253 0 R>>
+<</Type/StructElem/S/Strong/P 53 0 R/K[58]/Pg 262 0 R>>
endobj
52 0 obj
-<</Type/StructElem/S/Strong/P 53 0 R/K[61]/Pg 253 0 R>>
+<</Type/StructElem/S/Strong/P 53 0 R/K[61]/Pg 262 0 R>>
endobj
53 0 obj
-<</Type/StructElem/S/P/P 225 0 R/K[51 0 R 59 60 52 0 R 62 63 64 65 66]/Pg 253 0 R>>
+<</Type/StructElem/S/P/P 234 0 R/K[51 0 R 59 60 52 0 R 62 63 64 65 66]/Pg 262 0 R>>
endobj
54 0 obj
-<</Type/StructElem/S/Strong/P 64 0 R/K[67]/Pg 253 0 R>>
+<</Type/StructElem/S/Strong/P 68 0 R/K[67]/Pg 262 0 R>>
endobj
55 0 obj
-<</Type/StructElem/S/Code/P 64 0 R/K[69]/Pg 253 0 R>>
+<</Type/StructElem/S/Code/P 68 0 R/K[69]/Pg 262 0 R>>
endobj
56 0 obj
-<</Type/StructElem/S/Code/P 64 0 R/K[71]/Pg 253 0 R>>
+<</Type/StructElem/S/Code/P 68 0 R/K[71]/Pg 262 0 R>>
endobj
57 0 obj
-<</Type/StructElem/S/Code/P 64 0 R/K[73]/Pg 253 0 R>>
+<</Type/StructElem/S/Code/P 68 0 R/K[73]/Pg 262 0 R>>
endobj
58 0 obj
-<</Type/StructElem/S/Code/P 64 0 R/K[75]/Pg 253 0 R>>
+<</Type/StructElem/S/Code/P 68 0 R/K[75]/Pg 262 0 R>>
endobj
59 0 obj
-<</Type/StructElem/S/Code/P 64 0 R/K[77]/Pg 253 0 R>>
+<</Type/StructElem/S/Code/P 68 0 R/K[77]/Pg 262 0 R>>
endobj
60 0 obj
-<</Type/StructElem/S/Code/P 64 0 R/K[79]/Pg 253 0 R>>
+<</Type/StructElem/S/Code/P 68 0 R/K[79]/Pg 262 0 R>>
endobj
61 0 obj
-<</Type/StructElem/S/Code/P 64 0 R/K[81]/Pg 253 0 R>>
+<</Type/StructElem/S/Code/P 68 0 R/K[81]/Pg 262 0 R>>
endobj
62 0 obj
-<</Type/StructElem/S/Code/P 64 0 R/K[83]/Pg 253 0 R>>
+<</Type/StructElem/S/Code/P 68 0 R/K[83]/Pg 262 0 R>>
endobj
63 0 obj
-<</Type/StructElem/S/Code/P 64 0 R/K[86]/Pg 253 0 R>>
+<</Type/StructElem/S/Code/P 68 0 R/K[85]/Pg 262 0 R>>
endobj
64 0 obj
-<</Type/StructElem/S/P/P 225 0 R/K[54 0 R 68 55 0 R 70 56 0 R 72 57 0 R 74 58 0 R 76 59 0 R 78 60 0 R 80 61 0 R 82 62 0 R 84 85 63 0 R 87 88]/Pg 253 0 R>>
+<</Type/StructElem/S/Code/P 68 0 R/K[87]/Pg 262 0 R>>
endobj
65 0 obj
-<</Type/StructElem/S/Code/P 66 0 R/K[90]/Pg 253 0 R>>
+<</Type/StructElem/S/Code/P 68 0 R/K[90]/Pg 262 0 R>>
endobj
66 0 obj
-<</Type/StructElem/S/P/P 225 0 R/K[89 65 0 R 91]/Pg 253 0 R>>
+<</Type/StructElem/S/Code/P 68 0 R/K[93]/Pg 262 0 R>>
endobj
67 0 obj
-<</Type/StructElem/S/P/P 71 0 R/K[0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21]/Pg 254 0 R>>
+<</Type/StructElem/S/Code/P 68 0 R/K[97]/Pg 262 0 R>>
endobj
68 0 obj
-<</Type/StructElem/S/P/P 71 0 R/K[22]/Pg 254 0 R>>
+<</Type/StructElem/S/P/P 234 0 R/K[54 0 R 68 55 0 R 70 56 0 R 72 57 0 R 74 58 0 R 76 59 0 R 78 60 0 R 80 61 0 R 82 62 0 R 84 63 0 R 86 64 0 R 88 89 65 0 R 91 92 66 0 R 94 95 96 67 0 R 98]/Pg 262 0 R>>
endobj
69 0 obj
-<</Type/StructElem/S/P/P 71 0 R/K[23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39]/Pg 254 0 R>>
+<</Type/StructElem/S/Code/P 70 0 R/K[1]/Pg 263 0 R>>
endobj
70 0 obj
-<</Type/StructElem/S/P/P 71 0 R/K[40 41 42 43 44 45 46 47 48 49 50 51 52 53 54]/Pg 254 0 R>>
+<</Type/StructElem/S/P/P 234 0 R/K[0 69 0 R 2]/Pg 263 0 R>>
endobj
71 0 obj
-<</Type/StructElem/S/Code/P 225 0 R/A[<</O/Layout/Placement/Block>>]/K[67 0 R 68 0 R 69 0 R 70 0 R]>>
+<</Type/StructElem/S/P/P 75 0 R/K[3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24]/Pg 263 0 R>>
endobj
72 0 obj
-<</Type/StructElem/S/Code/P 76 0 R/K[56]/Pg 254 0 R>>
+<</Type/StructElem/S/P/P 75 0 R/K[25]/Pg 263 0 R>>
endobj
73 0 obj
-<</Type/StructElem/S/Strong/P 76 0 R/K[58]/Pg 254 0 R>>
+<</Type/StructElem/S/P/P 75 0 R/K[26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42]/Pg 263 0 R>>
endobj
74 0 obj
-<</Type/StructElem/S/Code/P 76 0 R/K[61]/Pg 254 0 R>>
+<</Type/StructElem/S/P/P 75 0 R/K[43 44 45 46 47 48 49 50 51 52 53 54 55 56 57]/Pg 263 0 R>>
endobj
75 0 obj
-<</Type/StructElem/S/Code/P 76 0 R/K[63]/Pg 254 0 R>>
+<</Type/StructElem/S/Code/P 234 0 R/A[<</O/Layout/Placement/Block>>]/K[71 0 R 72 0 R 73 0 R 74 0 R]>>
endobj
76 0 obj
-<</Type/StructElem/S/P/P 225 0 R/K[55 72 0 R 57 73 0 R 59 60 74 0 R 62 75 0 R 64 65]/Pg 254 0 R>>
+<</Type/StructElem/S/Code/P 80 0 R/K[59]/Pg 263 0 R>>
endobj
77 0 obj
-<</Type/StructElem/S/H1/P 225 0 R/T(Data structures)/K[66]/Pg 254 0 R>>
+<</Type/StructElem/S/Strong/P 80 0 R/K[61]/Pg 263 0 R>>
endobj
78 0 obj
-<</Type/StructElem/S/P/P 225 0 R/K[67]/Pg 254 0 R>>
+<</Type/StructElem/S/Code/P 80 0 R/K[64]/Pg 263 0 R>>
endobj
79 0 obj
-<</Type/StructElem/S/P/P 102 0 R/K[68]/Pg 254 0 R>>
+<</Type/StructElem/S/Code/P 80 0 R/K[66]/Pg 263 0 R>>
endobj
80 0 obj
-<</Type/StructElem/S/P/P 102 0 R/K[69 70 71 72 73 74 75]/Pg 254 0 R>>
+<</Type/StructElem/S/P/P 234 0 R/K[58 76 0 R 60 77 0 R 62 63 78 0 R 65 79 0 R 67 68]/Pg 263 0 R>>
endobj
81 0 obj
-<</Type/StructElem/S/P/P 102 0 R/K[76 77 78 79 80 81 82]/Pg 254 0 R>>
+<</Type/StructElem/S/H1/P 234 0 R/T(Data structures)/K[69]/Pg 263 0 R>>
endobj
82 0 obj
-<</Type/StructElem/S/P/P 102 0 R/K[83 84 85 86 87]/Pg 254 0 R>>
+<</Type/StructElem/S/P/P 234 0 R/K[70]/Pg 263 0 R>>
endobj
83 0 obj
-<</Type/StructElem/S/P/P 102 0 R/K[88 89 90 91 92 93 94]/Pg 254 0 R>>
+<</Type/StructElem/S/P/P 106 0 R/K[71]/Pg 263 0 R>>
endobj
84 0 obj
-<</Type/StructElem/S/P/P 102 0 R/K[95 96 97 98 99 100 101]/Pg 254 0 R>>
+<</Type/StructElem/S/P/P 106 0 R/K[72 73 74 75 76 77 78]/Pg 263 0 R>>
endobj
85 0 obj
-<</Type/StructElem/S/P/P 102 0 R/K[102 103 104 105 106]/Pg 254 0 R>>
+<</Type/StructElem/S/P/P 106 0 R/K[79 80 81 82 83 84 85]/Pg 263 0 R>>
endobj
86 0 obj
-<</Type/StructElem/S/P/P 102 0 R/K[107 108 109 110 111 112 113]/Pg 254 0 R>>
+<</Type/StructElem/S/P/P 106 0 R/K[86 87 88 89 90]/Pg 263 0 R>>
endobj
87 0 obj
-<</Type/StructElem/S/P/P 102 0 R/K[114 115 116 117 118 119 120 121]/Pg 254 0 R>>
+<</Type/StructElem/S/P/P 106 0 R/K[91 92 93 94 95 96 97]/Pg 263 0 R>>
endobj
88 0 obj
-<</Type/StructElem/S/P/P 102 0 R/K[]>>
+<</Type/StructElem/S/P/P 106 0 R/K[98 99 100 101 102 103 104]/Pg 263 0 R>>
endobj
89 0 obj
-<</Type/StructElem/S/P/P 102 0 R/K[122]/Pg 254 0 R>>
+<</Type/StructElem/S/P/P 106 0 R/K[105 106 107 108 109]/Pg 263 0 R>>
endobj
90 0 obj
-<</Type/StructElem/S/P/P 102 0 R/K[123 124 125 126 127 128 129]/Pg 254 0 R>>
+<</Type/StructElem/S/P/P 106 0 R/K[110 111 112 113 114 115 116]/Pg 263 0 R>>
endobj
91 0 obj
-<</Type/StructElem/S/P/P 102 0 R/K[130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154]/Pg 254 0 R>>
+<</Type/StructElem/S/P/P 106 0 R/K[117 118 119 120 121 122 123 124]/Pg 263 0 R>>
endobj
92 0 obj
-<</Type/StructElem/S/P/P 102 0 R/K[155 156 157 158 159]/Pg 254 0 R>>
+<</Type/StructElem/S/P/P 106 0 R/K[]>>
endobj
93 0 obj
-<</Type/StructElem/S/P/P 102 0 R/K[160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178]/Pg 254 0 R>>
+<</Type/StructElem/S/P/P 106 0 R/K[125]/Pg 263 0 R>>
endobj
94 0 obj
-<</Type/StructElem/S/P/P 102 0 R/K[179 180 181 182 183 184 185 186 187 188 189]/Pg 254 0 R>>
+<</Type/StructElem/S/P/P 106 0 R/K[126 127 128 129 130 131 132]/Pg 263 0 R>>
endobj
95 0 obj
-<</Type/StructElem/S/P/P 102 0 R/K[190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208]/Pg 254 0 R>>
+<</Type/StructElem/S/P/P 106 0 R/K[133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157]/Pg 263 0 R>>
endobj
96 0 obj
-<</Type/StructElem/S/P/P 102 0 R/K[209 210 211 212 213 214 215]/Pg 254 0 R>>
+<</Type/StructElem/S/P/P 106 0 R/K[158 159 160 161 162]/Pg 263 0 R>>
endobj
97 0 obj
-<</Type/StructElem/S/P/P 102 0 R/K[216 217 218 219 220 221 222 223 224]/Pg 254 0 R>>
+<</Type/StructElem/S/P/P 106 0 R/K[163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181]/Pg 263 0 R>>
endobj
98 0 obj
-<</Type/StructElem/S/P/P 102 0 R/K[]>>
+<</Type/StructElem/S/P/P 106 0 R/K[182 183 184 185 186 187 188 189 190 191 192]/Pg 263 0 R>>
endobj
99 0 obj
-<</Type/StructElem/S/P/P 102 0 R/K[225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251]/Pg 254 0 R>>
+<</Type/StructElem/S/P/P 106 0 R/K[193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211]/Pg 263 0 R>>
endobj
100 0 obj
-<</Type/StructElem/S/P/P 102 0 R/K[252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280]/Pg 254 0 R>>
+<</Type/StructElem/S/P/P 106 0 R/K[212 213 214 215 216 217 218]/Pg 263 0 R>>
endobj
101 0 obj
-<</Type/StructElem/S/P/P 102 0 R/K[281 282 283 284 285 286 287 288 289 290 291 292 293 294 295]/Pg 254 0 R>>
+<</Type/StructElem/S/P/P 106 0 R/K[219 220 221 222 223 224 225 226 227]/Pg 263 0 R>>
endobj
102 0 obj
-<</Type/StructElem/S/Code/P 225 0 R/A[<</O/Layout/Placement/Block>>]/K[79 0 R 80 0 R 81 0 R 82 0 R 83 0 R 84 0 R 85 0 R 86 0 R 87 0 R 88 0 R 89 0 R 90 0 R 91 0 R 92 0 R 93 0 R 94 0 R 95 0 R 96 0 R 97 0 R 98 0 R 99 0 R 100 0 R 101 0 R]>>
+<</Type/StructElem/S/P/P 106 0 R/K[]>>
endobj
103 0 obj
-<</Type/StructElem/S/Code/P 105 0 R/K[297]/Pg 254 0 R>>
+<</Type/StructElem/S/P/P 106 0 R/K[228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254]/Pg 263 0 R>>
endobj
104 0 obj
-<</Type/StructElem/S/Code/P 105 0 R/K[299]/Pg 254 0 R>>
+<</Type/StructElem/S/P/P 106 0 R/K[255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283]/Pg 263 0 R>>
endobj
105 0 obj
-<</Type/StructElem/S/P/P 225 0 R/K[296 103 0 R 298 104 0 R 300 301 302]/Pg 254 0 R>>
+<</Type/StructElem/S/P/P 106 0 R/K[284 285 286 287 288 289 290 291 292 293 294 295 296 297 298]/Pg 263 0 R>>
endobj
106 0 obj
-<</Type/StructElem/S/H1/P 225 0 R/T(Style)/K[303]/Pg 254 0 R>>
+<</Type/StructElem/S/Code/P 234 0 R/A[<</O/Layout/Placement/Block>>]/K[83 0 R 84 0 R 85 0 R 86 0 R 87 0 R 88 0 R 89 0 R 90 0 R 91 0 R 92 0 R 93 0 R 94 0 R 95 0 R 96 0 R 97 0 R 98 0 R 99 0 R 100 0 R 101 0 R 102 0 R 103 0 R 104 0 R 105 0 R]>>
endobj
107 0 obj
-<</Type/StructElem/S/Code/P 109 0 R/K[305]/Pg 254 0 R>>
+<</Type/StructElem/S/Code/P 109 0 R/K[300]/Pg 263 0 R>>
endobj
108 0 obj
-<</Type/StructElem/S/Code/P 109 0 R/K[308 309]/Pg 254 0 R>>
+<</Type/StructElem/S/Code/P 109 0 R/K[302]/Pg 263 0 R>>
endobj
109 0 obj
-<</Type/StructElem/S/P/P 225 0 R/K[304 107 0 R 306 307 108 0 R 310 311]/Pg 254 0 R>>
+<</Type/StructElem/S/P/P 234 0 R/K[299 107 0 R 301 108 0 R 303 304 305]/Pg 263 0 R>>
endobj
110 0 obj
-<</Type/StructElem/S/Strong/P 111 0 R/K[312]/Pg 254 0 R>>
+<</Type/StructElem/S/H1/P 234 0 R/T(Style)/K[306]/Pg 263 0 R>>
endobj
111 0 obj
-<</Type/StructElem/S/TD/P 115 0 R/A[<</O/Table/Headers[]>><</O/Layout/BorderStyle/Solid>>]/K[110 0 R]>>
+<</Type/StructElem/S/Code/P 113 0 R/K[308]/Pg 263 0 R>>
endobj
112 0 obj
-<</Type/StructElem/S/Strong/P 113 0 R/K[313]/Pg 254 0 R>>
+<</Type/StructElem/S/Code/P 113 0 R/K[311 312]/Pg 263 0 R>>
endobj
113 0 obj
-<</Type/StructElem/S/TD/P 115 0 R/A[<</O/Table/Headers[]>><</O/Layout/BorderStyle/Solid>>]/K[112 0 R]>>
+<</Type/StructElem/S/P/P 234 0 R/K[307 111 0 R 309 310 112 0 R 313 314]/Pg 263 0 R>>
endobj
114 0 obj
-<</Type/StructElem/S/TD/P 115 0 R/A[<</O/Table/Headers[]>><</O/Layout/BorderStyle/Solid>>]/K[]>>
+<</Type/StructElem/S/Strong/P 115 0 R/K[315]/Pg 263 0 R>>
endobj
115 0 obj
-<</Type/StructElem/S/TR/P 142 0 R/K[111 0 R 113 0 R 114 0 R]>>
+<</Type/StructElem/S/TD/P 119 0 R/A[<</O/Table/Headers[]>><</O/Layout/BorderStyle/Solid>>]/K[114 0 R]>>
endobj
116 0 obj
-<</Type/StructElem/S/TD/P 119 0 R/A[<</O/Table/Headers[]>><</O/Layout/BorderStyle/Solid>>]/K[314]/Pg 254 0 R>>
+<</Type/StructElem/S/Strong/P 117 0 R/K[316]/Pg 263 0 R>>
endobj
117 0 obj
-<</Type/StructElem/S/TD/P 119 0 R/A[<</O/Table/Headers[]>><</O/Layout/BorderStyle/Solid>>]/K[315]/Pg 254 0 R>>
+<</Type/StructElem/S/TD/P 119 0 R/A[<</O/Table/Headers[]>><</O/Layout/BorderStyle/Solid>>]/K[116 0 R]>>
endobj
118 0 obj
-<</Type/StructElem/S/TD/P 119 0 R/A[<</O/Table/Headers[]>><</O/Layout/BorderStyle/Solid>>]/K[316 317 318]/Pg 254 0 R>>
+<</Type/StructElem/S/TD/P 119 0 R/A[<</O/Table/Headers[]>><</O/Layout/BorderStyle/Solid>>]/K[]>>
endobj
119 0 obj
-<</Type/StructElem/S/TR/P 142 0 R/K[116 0 R 117 0 R 118 0 R]>>
+<</Type/StructElem/S/TR/P 146 0 R/K[115 0 R 117 0 R 118 0 R]>>
endobj
120 0 obj
-<</Type/StructElem/S/TD/P 123 0 R/A[<</O/Table/Headers[]>><</O/Layout/BorderStyle/Solid>>]/K[319]/Pg 254 0 R>>
+<</Type/StructElem/S/TD/P 123 0 R/A[<</O/Table/Headers[]>><</O/Layout/BorderStyle/Solid>>]/K[317]/Pg 263 0 R>>
endobj
121 0 obj
-<</Type/StructElem/S/TD/P 123 0 R/A[<</O/Table/Headers[]>><</O/Layout/BorderStyle/Solid>>]/K[320]/Pg 254 0 R>>
+<</Type/StructElem/S/TD/P 123 0 R/A[<</O/Table/Headers[]>><</O/Layout/BorderStyle/Solid>>]/K[318]/Pg 263 0 R>>
endobj
122 0 obj
-<</Type/StructElem/S/TD/P 123 0 R/A[<</O/Table/Headers[]>><</O/Layout/BorderStyle/Solid>>]/K[321]/Pg 254 0 R>>
+<</Type/StructElem/S/TD/P 123 0 R/A[<</O/Table/Headers[]>><</O/Layout/BorderStyle/Solid>>]/K[319 320 321]/Pg 263 0 R>>
endobj
123 0 obj
-<</Type/StructElem/S/TR/P 142 0 R/K[120 0 R 121 0 R 122 0 R]>>
+<</Type/StructElem/S/TR/P 146 0 R/K[120 0 R 121 0 R 122 0 R]>>
endobj
124 0 obj
-<</Type/StructElem/S/TD/P 127 0 R/A[<</O/Table/Headers[]>><</O/Layout/BorderStyle/Solid>>]/K[322]/Pg 254 0 R>>
+<</Type/StructElem/S/TD/P 127 0 R/A[<</O/Table/Headers[]>><</O/Layout/BorderStyle/Solid>>]/K[322]/Pg 263 0 R>>
endobj
125 0 obj
-<</Type/StructElem/S/TD/P 127 0 R/A[<</O/Table/Headers[]>><</O/Layout/BorderStyle/Solid>>]/K[323]/Pg 254 0 R>>
+<</Type/StructElem/S/TD/P 127 0 R/A[<</O/Table/Headers[]>><</O/Layout/BorderStyle/Solid>>]/K[323]/Pg 263 0 R>>
endobj
126 0 obj
-<</Type/StructElem/S/TD/P 127 0 R/A[<</O/Table/Headers[]>><</O/Layout/BorderStyle/Solid>>]/K[324]/Pg 254 0 R>>
+<</Type/StructElem/S/TD/P 127 0 R/A[<</O/Table/Headers[]>><</O/Layout/BorderStyle/Solid>>]/K[324]/Pg 263 0 R>>
endobj
127 0 obj
-<</Type/StructElem/S/TR/P 142 0 R/K[124 0 R 125 0 R 126 0 R]>>
+<</Type/StructElem/S/TR/P 146 0 R/K[124 0 R 125 0 R 126 0 R]>>
endobj
128 0 obj
-<</Type/StructElem/S/TD/P 131 0 R/A[<</O/Table/Headers[]>><</O/Layout/BorderStyle/Solid>>]/K[325]/Pg 254 0 R>>
+<</Type/StructElem/S/TD/P 131 0 R/A[<</O/Table/Headers[]>><</O/Layout/BorderStyle/Solid>>]/K[325]/Pg 263 0 R>>
endobj
129 0 obj
-<</Type/StructElem/S/TD/P 131 0 R/A[<</O/Table/Headers[]>><</O/Layout/BorderStyle/Solid>>]/K[326]/Pg 254 0 R>>
+<</Type/StructElem/S/TD/P 131 0 R/A[<</O/Table/Headers[]>><</O/Layout/BorderStyle/Solid>>]/K[326]/Pg 263 0 R>>
endobj
130 0 obj
-<</Type/StructElem/S/TD/P 131 0 R/A[<</O/Table/Headers[]>><</O/Layout/BorderStyle/Solid>>]/K[327 328]/Pg 254 0 R>>
+<</Type/StructElem/S/TD/P 131 0 R/A[<</O/Table/Headers[]>><</O/Layout/BorderStyle/Solid>>]/K[327]/Pg 263 0 R>>
endobj
131 0 obj
-<</Type/StructElem/S/TR/P 142 0 R/K[128 0 R 129 0 R 130 0 R]>>
+<</Type/StructElem/S/TR/P 146 0 R/K[128 0 R 129 0 R 130 0 R]>>
endobj
132 0 obj
-<</Type/StructElem/S/Strong/P 133 0 R/K[0]/Pg 255 0 R>>
+<</Type/StructElem/S/TD/P 135 0 R/A[<</O/Table/Headers[]>><</O/Layout/BorderStyle/Solid>>]/K[0]/Pg 264 0 R>>
endobj
133 0 obj
-<</Type/StructElem/S/TD/P 137 0 R/A[<</O/Table/Headers[]>><</O/Layout/BorderStyle/Solid>>]/K[132 0 R]>>
+<</Type/StructElem/S/TD/P 135 0 R/A[<</O/Table/Headers[]>><</O/Layout/BorderStyle/Solid>>]/K[1]/Pg 264 0 R>>
endobj
134 0 obj
-<</Type/StructElem/S/Strong/P 135 0 R/K[1]/Pg 255 0 R>>
+<</Type/StructElem/S/TD/P 135 0 R/A[<</O/Table/Headers[]>><</O/Layout/BorderStyle/Solid>>]/K[2 3]/Pg 264 0 R>>
endobj
135 0 obj
-<</Type/StructElem/S/TD/P 137 0 R/A[<</O/Table/Headers[]>><</O/Layout/BorderStyle/Solid>>]/K[134 0 R]>>
+<</Type/StructElem/S/TR/P 146 0 R/K[132 0 R 133 0 R 134 0 R]>>
endobj
136 0 obj
-<</Type/StructElem/S/TD/P 137 0 R/A[<</O/Table/Headers[]>><</O/Layout/BorderStyle/Solid>>]/K[2 3 4]/Pg 255 0 R>>
+<</Type/StructElem/S/Strong/P 137 0 R/K[4]/Pg 264 0 R>>
endobj
137 0 obj
-<</Type/StructElem/S/TR/P 142 0 R/K[133 0 R 135 0 R 136 0 R]>>
+<</Type/StructElem/S/TD/P 141 0 R/A[<</O/Table/Headers[]>><</O/Layout/BorderStyle/Solid>>]/K[136 0 R]>>
endobj
138 0 obj
-<</Type/StructElem/S/TD/P 141 0 R/A[<</O/Table/Headers[]>><</O/Layout/BorderStyle/Solid>>]/K[5]/Pg 255 0 R>>
+<</Type/StructElem/S/Strong/P 139 0 R/K[5]/Pg 264 0 R>>
endobj
139 0 obj
-<</Type/StructElem/S/TD/P 141 0 R/A[<</O/Table/Headers[]>><</O/Layout/BorderStyle/Solid>>]/K[6]/Pg 255 0 R>>
+<</Type/StructElem/S/TD/P 141 0 R/A[<</O/Table/Headers[]>><</O/Layout/BorderStyle/Solid>>]/K[138 0 R]>>
endobj
140 0 obj
-<</Type/StructElem/S/TD/P 141 0 R/A[<</O/Table/Headers[]>><</O/Layout/BorderStyle/Solid>>]/K[7]/Pg 255 0 R>>
+<</Type/StructElem/S/TD/P 141 0 R/A[<</O/Table/Headers[]>><</O/Layout/BorderStyle/Solid>>]/K[6 7 8]/Pg 264 0 R>>
endobj
141 0 obj
-<</Type/StructElem/S/TR/P 142 0 R/K[138 0 R 139 0 R 140 0 R]>>
+<</Type/StructElem/S/TR/P 146 0 R/K[137 0 R 139 0 R 140 0 R]>>
endobj
142 0 obj
-<</Type/StructElem/S/Table/P 225 0 R/A[<</O/Layout/BorderColor[0 0 0]/BorderThickness 0.4>>]/K[115 0 R 119 0 R 123 0 R 127 0 R 131 0 R 137 0 R 141 0 R]>>
+<</Type/StructElem/S/TD/P 145 0 R/A[<</O/Table/Headers[]>><</O/Layout/BorderStyle/Solid>>]/K[9]/Pg 264 0 R>>
endobj
143 0 obj
-<</Type/StructElem/S/H1/P 225 0 R/T(Testing: the old program is the oracle)/K[8]/Pg 255 0 R>>
+<</Type/StructElem/S/TD/P 145 0 R/A[<</O/Table/Headers[]>><</O/Layout/BorderStyle/Solid>>]/K[10]/Pg 264 0 R>>
endobj
144 0 obj
-<</Type/StructElem/S/Code/P 152 0 R/K[10]/Pg 255 0 R>>
+<</Type/StructElem/S/TD/P 145 0 R/A[<</O/Table/Headers[]>><</O/Layout/BorderStyle/Solid>>]/K[11]/Pg 264 0 R>>
endobj
145 0 obj
-<</Type/StructElem/S/Code/P 152 0 R/K[12]/Pg 255 0 R>>
+<</Type/StructElem/S/TR/P 146 0 R/K[142 0 R 143 0 R 144 0 R]>>
endobj
146 0 obj
-<</Type/StructElem/S/Strong/P 152 0 R/K[15]/Pg 255 0 R>>
+<</Type/StructElem/S/Table/P 234 0 R/A[<</O/Layout/BorderColor[0 0 0]/BorderThickness 0.4>>]/K[119 0 R 123 0 R 127 0 R 131 0 R 135 0 R 141 0 R 145 0 R]>>
endobj
147 0 obj
-<</Type/StructElem/S/Code/P 152 0 R/K[19]/Pg 255 0 R>>
+<</Type/StructElem/S/H1/P 234 0 R/T(Testing: the old program is the oracle)/K[12]/Pg 264 0 R>>
endobj
148 0 obj
-<</Type/StructElem/S/Code/P 152 0 R/K[22]/Pg 255 0 R>>
+<</Type/StructElem/S/Code/P 156 0 R/K[14]/Pg 264 0 R>>
endobj
149 0 obj
-<</Type/StructElem/S/Code/P 152 0 R/K[26]/Pg 255 0 R>>
+<</Type/StructElem/S/Code/P 156 0 R/K[16]/Pg 264 0 R>>
endobj
150 0 obj
-<</Type/StructElem/S/Code/P 152 0 R/K[28]/Pg 255 0 R>>
+<</Type/StructElem/S/Strong/P 156 0 R/K[19]/Pg 264 0 R>>
endobj
151 0 obj
-<</Type/StructElem/S/Code/P 152 0 R/K[30]/Pg 255 0 R>>
+<</Type/StructElem/S/Code/P 156 0 R/K[23]/Pg 264 0 R>>
endobj
152 0 obj
-<</Type/StructElem/S/P/P 225 0 R/K[9 144 0 R 11 145 0 R 13 14 146 0 R 16 17 18 147 0 R 20 21 148 0 R 23 24 25 149 0 R 27 150 0 R 29 151 0 R 31]/Pg 255 0 R>>
+<</Type/StructElem/S/Code/P 156 0 R/K[26]/Pg 264 0 R>>
endobj
153 0 obj
-<</Type/StructElem/S/Code/P 154 0 R/K[33]/Pg 255 0 R>>
+<</Type/StructElem/S/Code/P 156 0 R/K[30]/Pg 264 0 R>>
endobj
154 0 obj
-<</Type/StructElem/S/P/P 225 0 R/K[32 153 0 R 34 35 36 37 38]/Pg 255 0 R>>
+<</Type/StructElem/S/Code/P 156 0 R/K[32]/Pg 264 0 R>>
endobj
155 0 obj
-<</Type/StructElem/S/P/P 225 0 R/K[39 40]/Pg 255 0 R>>
+<</Type/StructElem/S/Code/P 156 0 R/K[34]/Pg 264 0 R>>
endobj
156 0 obj
-<</Type/StructElem/S/H1/P 225 0 R/T(Build)/K[41]/Pg 255 0 R>>
+<</Type/StructElem/S/P/P 234 0 R/K[13 148 0 R 15 149 0 R 17 18 150 0 R 20 21 22 151 0 R 24 25 152 0 R 27 28 29 153 0 R 31 154 0 R 33 155 0 R 35]/Pg 264 0 R>>
endobj
157 0 obj
-<</Type/StructElem/S/Code/P 164 0 R/K[42]/Pg 255 0 R>>
+<</Type/StructElem/S/Code/P 158 0 R/K[37]/Pg 264 0 R>>
endobj
158 0 obj
-<</Type/StructElem/S/Code/P 164 0 R/K[44]/Pg 255 0 R>>
+<</Type/StructElem/S/P/P 234 0 R/K[36 157 0 R 38 39 40 41 42]/Pg 264 0 R>>
endobj
159 0 obj
-<</Type/StructElem/S/Code/P 164 0 R/K[46]/Pg 255 0 R>>
+<</Type/StructElem/S/P/P 234 0 R/K[43 44]/Pg 264 0 R>>
endobj
160 0 obj
-<</Type/StructElem/S/Code/P 164 0 R/K[48]/Pg 255 0 R>>
+<</Type/StructElem/S/H1/P 234 0 R/T(Build)/K[45]/Pg 264 0 R>>
endobj
161 0 obj
-<</Type/StructElem/S/Code/P 164 0 R/K[52 53]/Pg 255 0 R>>
+<</Type/StructElem/S/Code/P 168 0 R/K[46]/Pg 264 0 R>>
endobj
162 0 obj
-<</Type/StructElem/S/Code/P 164 0 R/K[55]/Pg 255 0 R>>
+<</Type/StructElem/S/Code/P 168 0 R/K[48]/Pg 264 0 R>>
endobj
163 0 obj
-<</Type/StructElem/S/Code/P 164 0 R/K[57]/Pg 255 0 R>>
+<</Type/StructElem/S/Code/P 168 0 R/K[50]/Pg 264 0 R>>
endobj
164 0 obj
-<</Type/StructElem/S/P/P 225 0 R/K[157 0 R 43 158 0 R 45 159 0 R 47 160 0 R 49 50 51 161 0 R 54 162 0 R 56 163 0 R 58 59 60]/Pg 255 0 R>>
+<</Type/StructElem/S/Code/P 168 0 R/K[52]/Pg 264 0 R>>
endobj
165 0 obj
-<</Type/StructElem/S/H1/P 225 0 R/T(What is deliberately absent)/K[61]/Pg 255 0 R>>
+<</Type/StructElem/S/Code/P 168 0 R/K[56]/Pg 264 0 R>>
endobj
166 0 obj
-<</Type/StructElem/S/Strong/P 169 0 R/K[63]/Pg 255 0 R>>
+<</Type/StructElem/S/Code/P 168 0 R/K[58]/Pg 264 0 R>>
endobj
167 0 obj
-<</Type/StructElem/S/Code/P 169 0 R/K[68]/Pg 255 0 R>>
+<</Type/StructElem/S/Code/P 168 0 R/K[60]/Pg 264 0 R>>
endobj
168 0 obj
-<</Type/StructElem/S/Code/P 169 0 R/K[70]/Pg 255 0 R>>
+<</Type/StructElem/S/P/P 234 0 R/K[161 0 R 47 162 0 R 49 163 0 R 51 164 0 R 53 54 55 165 0 R 57 166 0 R 59 167 0 R 61 62 63]/Pg 264 0 R>>
endobj
169 0 obj
-<</Type/StructElem/S/P/P 225 0 R/K[62 166 0 R 64 65 66 67 167 0 R 69 168 0 R 71]/Pg 255 0 R>>
+<</Type/StructElem/S/H1/P 234 0 R/T(What is deliberately absent)/K[64]/Pg 264 0 R>>
endobj
170 0 obj
-<</Type/StructElem/S/H1/P 225 0 R/T(Appendix A: feature parity checklist)/K[72]/Pg 255 0 R>>
+<</Type/StructElem/S/Strong/P 173 0 R/K[66]/Pg 264 0 R>>
endobj
171 0 obj
-<</Type/StructElem/S/Code/P 172 0 R/K[74 75]/Pg 255 0 R>>
+<</Type/StructElem/S/Code/P 173 0 R/K[71]/Pg 264 0 R>>
endobj
172 0 obj
-<</Type/StructElem/S/P/P 225 0 R/K[73 171 0 R 76 77]/Pg 255 0 R>>
+<</Type/StructElem/S/Code/P 173 0 R/K[73]/Pg 264 0 R>>
endobj
173 0 obj
-<</Type/StructElem/S/Strong/P 178 0 R/K[78]/Pg 255 0 R>>
+<</Type/StructElem/S/P/P 234 0 R/K[65 170 0 R 67 68 69 70 171 0 R 72 172 0 R 74]/Pg 264 0 R>>
endobj
174 0 obj
-<</Type/StructElem/S/Code/P 178 0 R/K[85]/Pg 255 0 R>>
+<</Type/StructElem/S/H1/P 234 0 R/T(Appendix A: feature parity checklist)/K[75]/Pg 264 0 R>>
endobj
175 0 obj
-<</Type/StructElem/S/Code/P 178 0 R/K[89]/Pg 255 0 R>>
+<</Type/StructElem/S/Code/P 176 0 R/K[77 78]/Pg 264 0 R>>
endobj
176 0 obj
-<</Type/StructElem/S/Code/P 178 0 R/K[91]/Pg 255 0 R>>
+<</Type/StructElem/S/P/P 234 0 R/K[76 175 0 R 79 80]/Pg 264 0 R>>
endobj
177 0 obj
-<</Type/StructElem/S/Code/P 178 0 R/K[94]/Pg 255 0 R>>
+<</Type/StructElem/S/Strong/P 182 0 R/K[81]/Pg 264 0 R>>
endobj
178 0 obj
-<</Type/StructElem/S/P/P 225 0 R/K[173 0 R 79 80 81 82 83 84 174 0 R 86 87 88 175 0 R 90 176 0 R 92 93 177 0 R 95]/Pg 255 0 R>>
+<</Type/StructElem/S/Code/P 182 0 R/K[88]/Pg 264 0 R>>
endobj
179 0 obj
-<</Type/StructElem/S/Strong/P 186 0 R/K[0]/Pg 256 0 R>>
+<</Type/StructElem/S/Code/P 182 0 R/K[92]/Pg 264 0 R>>
endobj
180 0 obj
-<</Type/StructElem/S/Code/P 186 0 R/K[4]/Pg 256 0 R>>
+<</Type/StructElem/S/Code/P 182 0 R/K[94]/Pg 264 0 R>>
endobj
181 0 obj
-<</Type/StructElem/S/Code/P 186 0 R/K[7]/Pg 256 0 R>>
+<</Type/StructElem/S/Code/P 182 0 R/K[2]/Pg 265 0 R>>
endobj
182 0 obj
-<</Type/StructElem/S/Code/P 186 0 R/K[9]/Pg 256 0 R>>
+<</Type/StructElem/S/P/P 234 0 R/K[177 0 R 82 83 84 85 86 87 178 0 R 89 90 91 179 0 R 93 180 0 R 95 96<</Type/MCR/MCID 0/Pg 265 0 R>><</Type/MCR/MCID 1/Pg 265 0 R>>181 0 R<</Type/MCR/MCID 3/Pg 265 0 R>>]/Pg 264 0 R>>
endobj
183 0 obj
-<</Type/StructElem/S/Code/P 186 0 R/K[14]/Pg 256 0 R>>
+<</Type/StructElem/S/Strong/P 190 0 R/K[4]/Pg 265 0 R>>
endobj
184 0 obj
-<</Type/StructElem/S/Code/P 186 0 R/K[18]/Pg 256 0 R>>
+<</Type/StructElem/S/Code/P 190 0 R/K[8]/Pg 265 0 R>>
endobj
185 0 obj
-<</Type/StructElem/S/Code/P 186 0 R/K[20]/Pg 256 0 R>>
+<</Type/StructElem/S/Code/P 190 0 R/K[11]/Pg 265 0 R>>
endobj
186 0 obj
-<</Type/StructElem/S/P/P 225 0 R/K[179 0 R 1 2 3 180 0 R 5 6 181 0 R 8 182 0 R 10 11 12 13 183 0 R 15 16 17 184 0 R 19 185 0 R 21 22 23 24]/Pg 256 0 R>>
+<</Type/StructElem/S/Code/P 190 0 R/K[13]/Pg 265 0 R>>
endobj
187 0 obj
-<</Type/StructElem/S/Strong/P 197 0 R/K[25]/Pg 256 0 R>>
+<</Type/StructElem/S/Code/P 190 0 R/K[18]/Pg 265 0 R>>
endobj
188 0 obj
-<</Type/StructElem/S/Code/P 197 0 R/K[27]/Pg 256 0 R>>
+<</Type/StructElem/S/Code/P 190 0 R/K[22]/Pg 265 0 R>>
endobj
189 0 obj
-<</Type/StructElem/S/Code/P 197 0 R/K[29]/Pg 256 0 R>>
+<</Type/StructElem/S/Code/P 190 0 R/K[24]/Pg 265 0 R>>
endobj
190 0 obj
-<</Type/StructElem/S/Code/P 197 0 R/K[31]/Pg 256 0 R>>
+<</Type/StructElem/S/P/P 234 0 R/K[183 0 R 5 6 7 184 0 R 9 10 185 0 R 12 186 0 R 14 15 16 17 187 0 R 19 20 21 188 0 R 23 189 0 R 25 26 27 28]/Pg 265 0 R>>
endobj
191 0 obj
-<</Type/StructElem/S/Code/P 197 0 R/K[34]/Pg 256 0 R>>
+<</Type/StructElem/S/Strong/P 206 0 R/K[29]/Pg 265 0 R>>
endobj
192 0 obj
-<</Type/StructElem/S/Code/P 197 0 R/K[36]/Pg 256 0 R>>
+<</Type/StructElem/S/Code/P 206 0 R/K[31]/Pg 265 0 R>>
endobj
193 0 obj
-<</Type/StructElem/S/Code/P 197 0 R/K[38]/Pg 256 0 R>>
+<</Type/StructElem/S/Code/P 206 0 R/K[33]/Pg 265 0 R>>
endobj
194 0 obj
-<</Type/StructElem/S/Code/P 197 0 R/K[40]/Pg 256 0 R>>
+<</Type/StructElem/S/Code/P 206 0 R/K[35]/Pg 265 0 R>>
endobj
195 0 obj
-<</Type/StructElem/S/Code/P 197 0 R/K[44]/Pg 256 0 R>>
+<</Type/StructElem/S/Code/P 206 0 R/K[38]/Pg 265 0 R>>
endobj
196 0 obj
-<</Type/StructElem/S/Code/P 197 0 R/K[47]/Pg 256 0 R>>
+<</Type/StructElem/S/Code/P 206 0 R/K[40]/Pg 265 0 R>>
endobj
197 0 obj
-<</Type/StructElem/S/P/P 225 0 R/K[187 0 R 26 188 0 R 28 189 0 R 30 190 0 R 32 33 191 0 R 35 192 0 R 37 193 0 R 39 194 0 R 41 42 43 195 0 R 45 46 196 0 R 48 49]/Pg 256 0 R>>
+<</Type/StructElem/S/Code/P 206 0 R/K[42]/Pg 265 0 R>>
endobj
198 0 obj
-<</Type/StructElem/S/Strong/P 204 0 R/K[50]/Pg 256 0 R>>
+<</Type/StructElem/S/Code/P 206 0 R/K[44]/Pg 265 0 R>>
endobj
199 0 obj
-<</Type/StructElem/S/Code/P 204 0 R/K[52]/Pg 256 0 R>>
+<</Type/StructElem/S/Code/P 206 0 R/K[48]/Pg 265 0 R>>
endobj
200 0 obj
-<</Type/StructElem/S/Code/P 204 0 R/K[54]/Pg 256 0 R>>
+<</Type/StructElem/S/Code/P 206 0 R/K[51]/Pg 265 0 R>>
endobj
201 0 obj
-<</Type/StructElem/S/Code/P 204 0 R/K[56]/Pg 256 0 R>>
+<</Type/StructElem/S/Code/P 206 0 R/K[54]/Pg 265 0 R>>
endobj
202 0 obj
-<</Type/StructElem/S/Code/P 204 0 R/K[58 59]/Pg 256 0 R>>
+<</Type/StructElem/S/Code/P 206 0 R/K[56 57]/Pg 265 0 R>>
endobj
203 0 obj
-<</Type/StructElem/S/Code/P 204 0 R/K[61]/Pg 256 0 R>>
+<</Type/StructElem/S/Code/P 206 0 R/K[59]/Pg 265 0 R>>
endobj
204 0 obj
-<</Type/StructElem/S/P/P 225 0 R/K[198 0 R 51 199 0 R 53 200 0 R 55 201 0 R 57 202 0 R 60 203 0 R 62 63]/Pg 256 0 R>>
+<</Type/StructElem/S/Code/P 206 0 R/K[61]/Pg 265 0 R>>
endobj
205 0 obj
-<</Type/StructElem/S/Strong/P 207 0 R/K[64]/Pg 256 0 R>>
+<</Type/StructElem/S/Code/P 206 0 R/K[64]/Pg 265 0 R>>
endobj
206 0 obj
-<</Type/StructElem/S/Code/P 207 0 R/K[67]/Pg 256 0 R>>
+<</Type/StructElem/S/P/P 234 0 R/K[191 0 R 30 192 0 R 32 193 0 R 34 194 0 R 36 37 195 0 R 39 196 0 R 41 197 0 R 43 198 0 R 45 46 47 199 0 R 49 50 200 0 R 52 53 201 0 R 55 202 0 R 58 203 0 R 60 204 0 R 62 63 205 0 R 65]/Pg 265 0 R>>
endobj
207 0 obj
-<</Type/StructElem/S/P/P 225 0 R/K[205 0 R 65 66 206 0 R 68 69 70 71 72]/Pg 256 0 R>>
+<</Type/StructElem/S/Strong/P 213 0 R/K[66]/Pg 265 0 R>>
endobj
208 0 obj
-<</Type/StructElem/S/Strong/P 218 0 R/K[73]/Pg 256 0 R>>
+<</Type/StructElem/S/Code/P 213 0 R/K[68 69]/Pg 265 0 R>>
endobj
209 0 obj
-<</Type/StructElem/S/Code/P 218 0 R/K[75]/Pg 256 0 R>>
+<</Type/StructElem/S/Code/P 213 0 R/K[71]/Pg 265 0 R>>
endobj
210 0 obj
-<</Type/StructElem/S/Code/P 218 0 R/K[79]/Pg 256 0 R>>
+<</Type/StructElem/S/Code/P 213 0 R/K[73]/Pg 265 0 R>>
endobj
211 0 obj
-<</Type/StructElem/S/Code/P 218 0 R/K[82]/Pg 256 0 R>>
+<</Type/StructElem/S/Code/P 213 0 R/K[76]/Pg 265 0 R>>
endobj
212 0 obj
-<</Type/StructElem/S/Code/P 218 0 R/K[84]/Pg 256 0 R>>
+<</Type/StructElem/S/Code/P 213 0 R/K[78]/Pg 265 0 R>>
endobj
213 0 obj
-<</Type/StructElem/S/Code/P 218 0 R/K[86]/Pg 256 0 R>>
+<</Type/StructElem/S/P/P 234 0 R/K[207 0 R 67 208 0 R 70 209 0 R 72 210 0 R 74 75 211 0 R 77 212 0 R 79 80]/Pg 265 0 R>>
endobj
214 0 obj
-<</Type/StructElem/S/Code/P 218 0 R/K[91]/Pg 256 0 R>>
+<</Type/StructElem/S/Strong/P 216 0 R/K[81]/Pg 265 0 R>>
endobj
215 0 obj
-<</Type/StructElem/S/Code/P 218 0 R/K[93 94]/Pg 256 0 R>>
+<</Type/StructElem/S/Code/P 216 0 R/K[84]/Pg 265 0 R>>
endobj
216 0 obj
-<</Type/StructElem/S/Code/P 218 0 R/K[96]/Pg 256 0 R>>
+<</Type/StructElem/S/P/P 234 0 R/K[214 0 R 82 83 215 0 R 85 86 87 88 89]/Pg 265 0 R>>
endobj
217 0 obj
-<</Type/StructElem/S/Code/P 218 0 R/K[98]/Pg 256 0 R>>
+<</Type/StructElem/S/Strong/P 227 0 R/K[90]/Pg 265 0 R>>
endobj
218 0 obj
-<</Type/StructElem/S/P/P 225 0 R/K[208 0 R 74 209 0 R 76 77 78 210 0 R 80 81 211 0 R 83 212 0 R 85 213 0 R 87 88 89 90 214 0 R 92 215 0 R 95 216 0 R 97 217 0 R 99 100 101]/Pg 256 0 R>>
+<</Type/StructElem/S/Code/P 227 0 R/K[92]/Pg 265 0 R>>
endobj
219 0 obj
-<</Type/StructElem/S/Strong/P 224 0 R/K[102]/Pg 256 0 R>>
+<</Type/StructElem/S/Code/P 227 0 R/K[96]/Pg 265 0 R>>
endobj
220 0 obj
-<</Type/StructElem/S/Code/P 224 0 R/K[108]/Pg 256 0 R>>
+<</Type/StructElem/S/Code/P 227 0 R/K[99]/Pg 265 0 R>>
endobj
221 0 obj
-<</Type/StructElem/S/Code/P 224 0 R/K[111]/Pg 256 0 R>>
+<</Type/StructElem/S/Code/P 227 0 R/K[101]/Pg 265 0 R>>
endobj
222 0 obj
-<</Type/StructElem/S/Code/P 224 0 R/K[4]/Pg 257 0 R>>
+<</Type/StructElem/S/Code/P 227 0 R/K[103]/Pg 265 0 R>>
endobj
223 0 obj
-<</Type/StructElem/S/Strong/P 224 0 R/K[7]/Pg 257 0 R>>
+<</Type/StructElem/S/Code/P 227 0 R/K[108]/Pg 265 0 R>>
endobj
224 0 obj
-<</Type/StructElem/S/P/P 225 0 R/K[219 0 R 103 104 105 106 107 220 0 R 109 110 221 0 R 112 113 114 115 116<</Type/MCR/MCID 0/Pg 257 0 R>><</Type/MCR/MCID 1/Pg 257 0 R>><</Type/MCR/MCID 2/Pg 257 0 R>><</Type/MCR/MCID 3/Pg 257 0 R>>222 0 R<</Type/MCR/MCID 5/Pg 257 0 R>><</Type/MCR/MCID 6/Pg 257 0 R>>223 0 R<</Type/MCR/MCID 8/Pg 257 0 R>><</Type/MCR/MCID 9/Pg 257 0 R>>]/Pg 256 0 R>>
+<</Type/StructElem/S/Code/P 227 0 R/K[110 111]/Pg 265 0 R>>
endobj
225 0 obj
-<</Type/StructElem/S/Document/P 11 0 R/K[18 0 R 19 0 R 20 0 R 21 0 R 22 0 R 23 0 R 25 0 R 36 0 R 40 0 R 41 0 R 50 0 R 53 0 R 64 0 R 66 0 R 71 0 R 76 0 R 77 0 R 78 0 R 102 0 R 105 0 R 106 0 R 109 0 R 142 0 R 143 0 R 152 0 R 154 0 R 155 0 R 156 0 R 164 0 R 165 0 R 169 0 R 170 0 R 172 0 R 178 0 R 186 0 R 197 0 R 204 0 R 207 0 R 218 0 R 224 0 R]>>
+<</Type/StructElem/S/Code/P 227 0 R/K[113]/Pg 265 0 R>>
endobj
226 0 obj
-[/ICCBased 275 0 R]
+<</Type/StructElem/S/Code/P 227 0 R/K[115]/Pg 265 0 R>>
endobj
227 0 obj
-[/ICCBased 276 0 R]
+<</Type/StructElem/S/P/P 234 0 R/K[217 0 R 91 218 0 R 93 94 95 219 0 R 97 98 220 0 R 100 221 0 R 102 222 0 R 104 105 106 107 223 0 R 109 224 0 R 112 225 0 R 114 226 0 R 116 117 118 119]/Pg 265 0 R>>
endobj
228 0 obj
-[253 0 R/XYZ 62.362206 729.37256 0]
+<</Type/StructElem/S/Strong/P 233 0 R/K[120]/Pg 265 0 R>>
endobj
229 0 obj
-[253 0 R/XYZ 62.362206 576.02637 0]
+<</Type/StructElem/S/Code/P 233 0 R/K[126]/Pg 265 0 R>>
endobj
230 0 obj
-[254 0 R/XYZ 62.362206 679.2434 0]
+<</Type/StructElem/S/Code/P 233 0 R/K[1]/Pg 266 0 R>>
endobj
231 0 obj
-[254 0 R/XYZ 62.362206 288.38 0]
+<</Type/StructElem/S/Code/P 233 0 R/K[11]/Pg 266 0 R>>
endobj
232 0 obj
-[255 0 R/XYZ 62.362206 706.6116 0]
+<</Type/StructElem/S/Strong/P 233 0 R/K[14]/Pg 266 0 R>>
endobj
233 0 obj
-[255 0 R/XYZ 62.362206 463.47986 0]
+<</Type/StructElem/S/P/P 234 0 R/K[228 0 R 121 122 123 124 125 229 0 R 127<</Type/MCR/MCID 0/Pg 266 0 R>>230 0 R<</Type/MCR/MCID 2/Pg 266 0 R>><</Type/MCR/MCID 3/Pg 266 0 R>><</Type/MCR/MCID 4/Pg 266 0 R>><</Type/MCR/MCID 5/Pg 266 0 R>><</Type/MCR/MCID 6/Pg 266 0 R>><</Type/MCR/MCID 7/Pg 266 0 R>><</Type/MCR/MCID 8/Pg 266 0 R>><</Type/MCR/MCID 9/Pg 266 0 R>><</Type/MCR/MCID 10/Pg 266 0 R>>231 0 R<</Type/MCR/MCID 12/Pg 266 0 R>><</Type/MCR/MCID 13/Pg 266 0 R>>232 0 R<</Type/MCR/MCID 15/Pg 266 0 R>><</Type/MCR/MCID 16/Pg 266 0 R>>]/Pg 265 0 R>>
endobj
234 0 obj
-[255 0 R/XYZ 62.362206 343.90167 0]
+<</Type/StructElem/S/Document/P 11 0 R/K[18 0 R 19 0 R 20 0 R 21 0 R 22 0 R 23 0 R 25 0 R 36 0 R 40 0 R 41 0 R 50 0 R 53 0 R 68 0 R 70 0 R 75 0 R 80 0 R 81 0 R 82 0 R 106 0 R 109 0 R 110 0 R 113 0 R 146 0 R 147 0 R 156 0 R 158 0 R 159 0 R 160 0 R 168 0 R 169 0 R 173 0 R 174 0 R 176 0 R 182 0 R 190 0 R 206 0 R 213 0 R 216 0 R 227 0 R 233 0 R]>>
endobj
235 0 obj
-[255 0 R/XYZ 62.362206 252.28497 0]
+[/ICCBased 284 0 R]
endobj
236 0 obj
-<</ProcSet[/PDF/Text/ImageC/ImageB]/ColorSpace<</c0 226 0 R>>/Font<</f0 241 0 R/f1 244 0 R/f2 247 0 R>>>>
+[/ICCBased 285 0 R]
endobj
237 0 obj
-<</ProcSet[/PDF/Text/ImageC/ImageB]/ColorSpace<</c0 227 0 R/c1 226 0 R>>/Font<</f0 247 0 R/f1 244 0 R/f2 241 0 R>>>>
+[262 0 R/XYZ 62.362206 729.37256 0]
endobj
238 0 obj
-<</ProcSet[/PDF/Text/ImageC/ImageB]/ColorSpace<</c0 226 0 R>>/Font<</f0 241 0 R/f1 244 0 R/f2 247 0 R/f3 250 0 R>>>>
+[262 0 R/XYZ 62.362206 576.02637 0]
endobj
239 0 obj
-<</ProcSet[/PDF/Text/ImageC/ImageB]/ColorSpace<</c0 226 0 R>>/Font<</f0 241 0 R/f1 244 0 R/f2 247 0 R>>>>
+[263 0 R/XYZ 62.362206 659.4719 0]
endobj
240 0 obj
-<</ProcSet[/PDF/Text/ImageC/ImageB]/ColorSpace<</c0 226 0 R>>/Font<</f0 244 0 R/f1 247 0 R/f2 241 0 R>>>>
+[263 0 R/XYZ 62.362206 268.60852 0]
endobj
241 0 obj
-<</Type/Font/Subtype/Type0/BaseFont/ISLOEJ+NewCM10-Bold-Identity-H/Encoding/Identity-H/DescendantFonts[242 0 R]/ToUnicode 259 0 R>>
+[264 0 R/XYZ 62.362206 675.4436 0]
endobj
242 0 obj
-<</Type/Font/Subtype/CIDFontType0/BaseFont/ISLOEJ+NewCM10-Bold/CIDSystemInfo<</Registry(Adobe)/Ordering(Identity)/Supplement 0>>/FontDescriptor 243 0 R/DW 0/W[0 0 280 1 1 786 2 2 559 3 3 474 4 4 639 5 5 527 6 6 454 7 7 319 8 8 383 9 9 869 10 10 800 11 11 607 12 12 447 13 13 756 14 14 639 15 15 607 16 16 319 17 17 575 18 18 958 19 19 1189 20 21 639 22 22 319 23 23 639 24 24 607 25 25 510.99997 26 26 831 27 28 639 29 29 351 30 30 671 31 31 607 32 32 882 33 33 575 34 34 319 35 37 575 38 38 818 39 39 692 40 40 319 41 41 1092 42 42 831 43 44 447]>>
+[264 0 R/XYZ 62.362206 432.31186 0]
endobj
243 0 obj
-<</Type/FontDescriptor/FontName/ISLOEJ+NewCM10-Bold/Flags 131076/FontBBox[21 -249 1164 750]/ItalicAngle 0/Ascent 806/Descent -194/CapHeight 686/StemV 168.6/CIDSet 258 0 R/FontFile3 260 0 R>>
+[264 0 R/XYZ 62.362206 312.73364 0]
endobj
244 0 obj
-<</Type/Font/Subtype/Type0/BaseFont/VAXLSP+NewCM10-Regular-Identity-H/Encoding/Identity-H/DescendantFonts[245 0 R]/ToUnicode 262 0 R>>
+[264 0 R/XYZ 62.362206 221.11694 0]
endobj
245 0 obj
-<</Type/Font/Subtype/CIDFontType0/BaseFont/VAXLSP+NewCM10-Regular/CIDSystemInfo<</Registry(Adobe)/Ordering(Identity)/Supplement 0>>/FontDescriptor 246 0 R/DW 0/W[0 0 500 1 1 556 2 2 444 3 3 394 4 4 278 5 5 500 6 6 556 7 7 333 8 8 306 9 9 500 10 10 392 11 11 389 12 12 556 13 13 722 14 14 1000 15 17 500 18 18 333 19 20 500 21 21 681 22 22 500 23 24 528 25 25 833 26 26 444 27 28 278 29 30 556 31 31 278 32 32 556 33 33 528 34 34 278 35 35 556 36 36 278 37 37 722 38 38 686 39 39 528 40 40 681 41 41 528 42 42 361 43 44 389 45 45 556 46 46 764 47 47 625 48 48 500 49 49 514 50 50 750 51 51 917 52 52 500 53 53 722 54 54 444 55 56 750 57 57 778 58 58 278 59 59 583 60 60 500 61 61 750 62 62 778 63 63 750 64 64 306 65 65 736 66 66 785 67 67 708 68 68 556 69 69 500 70 70 611 71 71 778 72 73 500 74 74 778 75 75 750 76 76 1000 77 77 653 78 78 1028 79 80 750]>>
+<</ProcSet[/PDF/Text/ImageC/ImageB]/ColorSpace<</c0 235 0 R>>/Font<</f0 250 0 R/f1 253 0 R/f2 256 0 R>>>>
endobj
246 0 obj
-<</Type/FontDescriptor/FontName/VAXLSP+NewCM10-Regular/Flags 131076/FontBBox[-41 -260 1009 760]/ItalicAngle 0/Ascent 806/Descent -194/CapHeight 683/StemV 95.4/CIDSet 261 0 R/FontFile3 263 0 R>>
+<</ProcSet[/PDF/Text/ImageC/ImageB]/ColorSpace<</c0 235 0 R/c1 236 0 R>>/Font<</f0 253 0 R/f1 256 0 R/f2 250 0 R>>>>
endobj
247 0 obj
-<</Type/Font/Subtype/Type0/BaseFont/RIONKM+DejaVuSansMono/Encoding/Identity-H/DescendantFonts[248 0 R]/ToUnicode 265 0 R>>
+<</ProcSet[/PDF/Text/ImageC/ImageB]/ColorSpace<</c0 235 0 R>>/Font<</f0 253 0 R/f1 250 0 R/f2 256 0 R/f3 259 0 R>>>>
endobj
248 0 obj
-<</Type/Font/Subtype/CIDFontType2/BaseFont/RIONKM+DejaVuSansMono/CIDSystemInfo<</Registry(Adobe)/Ordering(Identity)/Supplement 0>>/FontDescriptor 249 0 R/DW 0/CIDToGIDMap/Identity/W[0 79 602.0508]>>
+<</ProcSet[/PDF/Text/ImageC/ImageB]/ColorSpace<</c0 235 0 R>>/Font<</f0 253 0 R/f1 256 0 R/f2 250 0 R>>>>
endobj
249 0 obj
-<</Type/FontDescriptor/FontName/RIONKM+DejaVuSansMono/Flags 131077/FontBBox[0 -235.83984 602.0508 844.2383]/ItalicAngle 0/Ascent 759.7656/Descent -240.23438/CapHeight 759.7656/StemV 95.4/CIDSet 264 0 R/FontFile2 266 0 R>>
+<</ProcSet[/PDF/Text/ImageC/ImageB]/ColorSpace<</c0 235 0 R>>/Font<</f0 253 0 R/f1 256 0 R/f2 250 0 R>>>>
endobj
250 0 obj
-<</Type/Font/Subtype/Type0/BaseFont/HCGNIB+LibertinusSerif-Regular-Identity-H/Encoding/Identity-H/DescendantFonts[251 0 R]/ToUnicode 268 0 R>>
+<</Type/Font/Subtype/Type0/BaseFont/ISLOEJ+NewCM10-Bold-Identity-H/Encoding/Identity-H/DescendantFonts[251 0 R]/ToUnicode 268 0 R>>
endobj
251 0 obj
-<</Type/Font/Subtype/CIDFontType0/BaseFont/HCGNIB+LibertinusSerif-Regular/CIDSystemInfo<</Registry(Adobe)/Ordering(Identity)/Supplement 0>>/FontDescriptor 252 0 R/DW 0/W[0 0 500 1 1 527]>>
+<</Type/Font/Subtype/CIDFontType0/BaseFont/ISLOEJ+NewCM10-Bold/CIDSystemInfo<</Registry(Adobe)/Ordering(Identity)/Supplement 0>>/FontDescriptor 252 0 R/DW 0/W[0 0 280 1 1 786 2 2 559 3 3 474 4 4 639 5 5 527 6 6 454 7 7 319 8 8 383 9 9 869 10 10 800 11 11 607 12 12 447 13 13 756 14 14 639 15 15 607 16 16 319 17 17 575 18 18 958 19 19 1189 20 21 639 22 22 319 23 23 639 24 24 607 25 25 510.99997 26 26 831 27 28 639 29 29 351 30 30 671 31 31 607 32 32 882 33 33 575 34 34 319 35 37 575 38 38 818 39 39 692 40 40 319 41 41 1092 42 42 831 43 44 447]>>
endobj
252 0 obj
-<</Type/FontDescriptor/FontName/HCGNIB+LibertinusSerif-Regular/Flags 131078/FontBBox[0 0 500 698]/ItalicAngle 0/Ascent 894/Descent -246/CapHeight 658/StemV 95.4/CIDSet 267 0 R/FontFile3 269 0 R>>
+<</Type/FontDescriptor/FontName/ISLOEJ+NewCM10-Bold/Flags 131076/FontBBox[21 -249 1164 750]/ItalicAngle 0/Ascent 806/Descent -194/CapHeight 686/StemV 168.6/CIDSet 267 0 R/FontFile3 269 0 R>>
endobj
253 0 obj
-<</Type/Page/Resources 236 0 R/MediaBox[0 0 595.2756 841.8898]/StructParents 0/Parent 1 0 R/Contents 270 0 R>>
+<</Type/Font/Subtype/Type0/BaseFont/NSBQKY+NewCM10-Regular-Identity-H/Encoding/Identity-H/DescendantFonts[254 0 R]/ToUnicode 271 0 R>>
endobj
254 0 obj
-<</Type/Page/Resources 237 0 R/MediaBox[0 0 595.2756 841.8898]/StructParents 1/Parent 1 0 R/Contents 271 0 R>>
+<</Type/Font/Subtype/CIDFontType0/BaseFont/NSBQKY+NewCM10-Regular/CIDSystemInfo<</Registry(Adobe)/Ordering(Identity)/Supplement 0>>/FontDescriptor 255 0 R/DW 0/W[0 0 500 1 1 556 2 2 444 3 3 394 4 4 278 5 5 500 6 6 556 7 7 333 8 8 306 9 9 500 10 10 392 11 11 389 12 12 556 13 13 722 14 14 1000 15 17 500 18 18 333 19 20 500 21 21 681 22 22 500 23 24 528 25 25 833 26 26 444 27 28 278 29 30 556 31 31 278 32 32 556 33 33 528 34 34 278 35 35 556 36 36 278 37 37 722 38 38 686 39 39 528 40 40 681 41 41 528 42 42 361 43 44 389 45 45 556 46 46 764 47 47 625 48 48 500 49 49 514 50 50 750 51 51 917 52 52 500 53 53 722 54 54 444 55 56 750 57 57 778 58 58 278 59 59 583 60 60 500 61 61 750 62 62 778 63 63 750 64 64 306 65 65 736 66 66 785 67 67 708 68 68 556 69 69 500 70 70 611 71 71 778 72 73 500 74 74 778 75 75 750 76 76 653 77 77 1000 78 78 1028 79 79 750]>>
endobj
255 0 obj
-<</Type/Page/Resources 238 0 R/MediaBox[0 0 595.2756 841.8898]/StructParents 2/Parent 1 0 R/Contents 272 0 R>>
+<</Type/FontDescriptor/FontName/NSBQKY+NewCM10-Regular/Flags 131076/FontBBox[-41 -260 1009 760]/ItalicAngle 0/Ascent 806/Descent -194/CapHeight 683/StemV 95.4/CIDSet 270 0 R/FontFile3 272 0 R>>
endobj
256 0 obj
-<</Type/Page/Resources 239 0 R/MediaBox[0 0 595.2756 841.8898]/StructParents 3/Parent 1 0 R/Contents 273 0 R>>
+<</Type/Font/Subtype/Type0/BaseFont/OYWFYY+DejaVuSansMono/Encoding/Identity-H/DescendantFonts[257 0 R]/ToUnicode 274 0 R>>
endobj
257 0 obj
-<</Type/Page/Resources 240 0 R/MediaBox[0 0 595.2756 841.8898]/StructParents 4/Parent 1 0 R/Contents 274 0 R>>
+<</Type/Font/Subtype/CIDFontType2/BaseFont/OYWFYY+DejaVuSansMono/CIDSystemInfo<</Registry(Adobe)/Ordering(Identity)/Supplement 0>>/FontDescriptor 258 0 R/DW 0/CIDToGIDMap/Identity/W[0 80 602.0508]>>
endobj
258 0 obj
+<</Type/FontDescriptor/FontName/OYWFYY+DejaVuSansMono/Flags 131077/FontBBox[0 -235.83984 602.0508 844.2383]/ItalicAngle 0/Ascent 759.7656/Descent -240.23438/CapHeight 759.7656/StemV 95.4/CIDSet 273 0 R/FontFile2 275 0 R>>
+endobj
+259 0 obj
+<</Type/Font/Subtype/Type0/BaseFont/HCGNIB+LibertinusSerif-Regular-Identity-H/Encoding/Identity-H/DescendantFonts[260 0 R]/ToUnicode 277 0 R>>
+endobj
+260 0 obj
+<</Type/Font/Subtype/CIDFontType0/BaseFont/HCGNIB+LibertinusSerif-Regular/CIDSystemInfo<</Registry(Adobe)/Ordering(Identity)/Supplement 0>>/FontDescriptor 261 0 R/DW 0/W[0 0 500 1 1 527]>>
+endobj
+261 0 obj
+<</Type/FontDescriptor/FontName/HCGNIB+LibertinusSerif-Regular/Flags 131078/FontBBox[0 0 500 698]/ItalicAngle 0/Ascent 894/Descent -246/CapHeight 658/StemV 95.4/CIDSet 276 0 R/FontFile3 278 0 R>>
+endobj
+262 0 obj
+<</Type/Page/Resources 245 0 R/MediaBox[0 0 595.2756 841.8898]/StructParents 0/Parent 1 0 R/Contents 279 0 R>>
+endobj
+263 0 obj
+<</Type/Page/Resources 246 0 R/MediaBox[0 0 595.2756 841.8898]/StructParents 1/Parent 1 0 R/Contents 280 0 R>>
+endobj
+264 0 obj
+<</Type/Page/Resources 247 0 R/MediaBox[0 0 595.2756 841.8898]/StructParents 2/Parent 1 0 R/Contents 281 0 R>>
+endobj
+265 0 obj
+<</Type/Page/Resources 248 0 R/MediaBox[0 0 595.2756 841.8898]/StructParents 3/Parent 1 0 R/Contents 282 0 R>>
+endobj
+266 0 obj
+<</Type/Page/Resources 249 0 R/MediaBox[0 0 595.2756 841.8898]/StructParents 4/Parent 1 0 R/Contents 283 0 R>>
+endobj
+267 0 obj
<</Length 14/Filter/FlateDecode>>
stream
x�������?
endstream
endobj
-259 0 obj
+268 0 obj
<</Length 549/Type/CMap/Filter/FlateDecode/WMode 0>>
stream
x�m�O��@��|���sp�q4�DQ�'�d��t�HC8��7�+��fj^WU��Uw��x?N7�9�4��w�`K�f/E����)��M�ʬYߣݒZ۔��vS���Ly4�s����Ke �eC�7����U�%M�@�':h6}��(|�|�ۮj̒"���FgM=6�y�xP�n���=�+��8�i��"E�*{Q��o]��������V2����T]oo4q�=��3"oV��̅&�f��C�^yl�B��F��`�-j�@��V������e� ���軈�b�h�ڢd[� {�0 �5��<�ף�?�$A��\�)�K�ִ
@@ -786,7 +813,7 @@ x�m�O��@��|���sp�q4�DQ�'�d��t�HC8��7�+��fj^WU��Uw��x?N7�9�4��w�`K�f/E�
�1\zU`���c�Ε��ԁ1��E��Vr���c*F�)*0����r��k9���wPֲ���s�~���W�6�X�>����IF����s?�
endstream
endobj
-260 0 obj
+269 0 obj
<</Length 4357/Filter/FlateDecode/Subtype/CIDFontType0C>>
stream
x��XiX׶������F�lL�T�ApBp�I���&F��(((eZ����4�$3�A@ZQJ�c4�!1כ�I�C5&!<�v�C�}_��r�}�{��>��9{�Zk��[���3
@@ -819,142 +846,146 @@ w1����L��42�v��9峁�L�MG�`��tfj�md�y��NE�RV�M�1��}�>������\�!�E;T��m
�66<P��h�
endstream
endobj
-261 0 obj
-<</Length 12/Filter/FlateDecode>>
+270 0 obj
+<</Length 11/Filter/FlateDecode>>
stream
-x���
-w
+x���
endstream
endobj
-262 0 obj
-<</Length 705/Type/CMap/Filter/FlateDecode/WMode 0>>
+271 0 obj
+<</Length 700/Type/CMap/Filter/FlateDecode/WMode 0>>
stream
-x�m�Io�@���=K�!Co�BH,��!�B4s&ږ��~��
-�FsH��*W���鏷���5��`~J�N}3v=���m����O�"G��g�횪�A������$M���]r����c�o ��X��М�4���/��;<q&�u�z8 y���/����3��4}�nݜ�p}2�b��5Վq��븓� }�����U�]��m|yw�:m��Ynl9S!&�t���;��8ؽpt@�s���(�.�~ �ƶ��0���)y�N���Db��קL)���ǹ%.0��ܸ�P�j����n̥�r!�eY�������k���Ͼ��j!�R�v��ʠLT����M�2�*�z�*����j
-UB-�AC��x�52�6�q����k�8��1�** �Aw>��
-|z>��
-|�
-|Wa>��)�܁���r8��g�P̷�b>���,�;�425�r�j�؊�YA�/ϯ[�`�ؓfF���1�n@�3�jഘP���#����S� N�1pfpD��r?pZp�#2 8-�3��`�i�aF|� -Wc�U����0�1�\%��ܨV7_�uF��0#ǘ.f�o�w�y,3l�2#>��9fo�- N�u��q]����[p�Y���I � ���Ք'
-�z �����
+x�m�Io�@���5K�!Co�C���b�C�h�L� c ږ��~��
+�FsH��*W��
+*���óm�܃�)�����U�a��k�4]5�xr~xu�:{��O�vMջ������C��_G�.9�KY�C�o �-�~hNI�~���=�P��6����$�4�庾n��$M��.�S�O&܃&�]Sm�@��ێ;�W�HE��V�wuڵ�����i�� idٱ�L"�ɇ;��Н�.vO��y��j��˰߂۱m�. I">u�ƿ�
+�>�L��
+|����P��������.*f̯P�̹8 &T�,����.�T�G�Sq �Q�4������L N�48 :hpx���0 F�U�Xp�e ��o4� W |*,7���Wl]�Q�<��1f�����]b� �5̈O�aF���pˀSs]pf\������S�sN 2�=j8i���F*���<`�xV0f�x��քcn���Uc�9?ēO]�k�w���6mx+�ģ���[�lG�
endstream
endobj
-263 0 obj
-<</Length 11216/Filter/FlateDecode/Subtype/CIDFontType0C>>
+272 0 obj
+<</Length 10970/Filter/FlateDecode/Subtype/CIDFontType0C>>
stream
-x�}zw\���]`wF�5��%� ��5��k�k,� �JP�����]z�����b� 5j�-�Ʈ�E��z/z��`~��|�����q���ms��|��qr"
-��i�!c���ϕ�:����R{�4��
-���
-s �}ֲ#!�;��4�"�;Ӭ+qt
-�"j�0j��r�I+<}�|��z����yz�t�r��!}��差�|��|}]g�������su�����v��O��ZO��{��
-�`��k]��=]'̘�U���\��u ��t�
-�ڿHHH������֮����� � ��_���=��w�]��~�A�B=<��|�|]�����Y�����;�������+\}|]gyz4�0����u´9}� �s����:��:�^>:O� o� W�5���!>Aޮ�A��+��~^�����
-�G�,�钡U}Gmp�4&��f$�g��~͚$7s�fM��Ef��b1�X,͚]lZZcM�$[�֤f���Bf�G�� `���#!d�|�.d���䀢���� � N�8�R�W�V�UUq���oһ s�����{�y4��ܷ��φ�$-u-�[�wY�q��m�E��V�3ڿZ�l��MU�^mO�smw��oۗvp�0�cǎg���.�p��z���N�����X�%��t)��mP�v�����ٽ��^_�Z���ޞ�����gt�����2��&T<Hk:l-u�*��6l�J�hm�$N�O_��K�hR�K�m���
-As �H�9�%�v�W�}����)�w�� ��5� y��/�0x5s��Q]!u+V�ݡ�����Ӯ�?":�!0+8�}[�Q�����&�5�r��b*��ƕ5g»~���?QEa�!9Z�����H���g�uY���h`Q)\*m�{�Ny�Ԩb����R�-�����4V�8n�1!*Ҙ����)��^�B�啡��H�I�_>�FҖS!Q����k YH���E�yA<��̂����g�|6��!�=;��F���(�؋�N������ w� q��F���X����xʊđ J4S�Cj�O�8� ��~H]�����w�\����kħ�6#qI�#��#I��kp���$�[U�,�A] $��\�}-^"Q X�^�k���_��A��˴솲�� �R$�{ݬH� ��''��EuvIY�B;�v��f�9ͯ[[۹_r���nH��i%��O���*�v�
-u��"��g�6lٸ��sp�m��!i!����L� is�+���$H6�ц�h��oȎ�.H��$ q9�5��H�g�л�3������ �X��G"�2G|8 ��GH����P���0;;?s �~y( q�3 V��/�u�5j�C��vѴ�L1p�����V�+����1߉�~���#J\��E�yQ�WZL�j�~��_?.������](Ϙ_T��g�p�z�DA��Yk ��-C�vnR$s<�n��E:��쭻x�ܾ͈�*���.X�xm`m$���n��9�G-{ ��L�=����i��H���&��E5{֨�4�XA�?��H�_��[TegMh����;��bAH0D���J\�c�<�N������M`�p�uv�[aX ��T%�u�ær#o�ȍѧl�Q6�_�l���q��l�tX\v@oO�g�LꮲJ$�!�|��6$]Ot@�n��`� ��-�Iu��<LN����.Y>x@��V�߲�e/�`-��uoڄ6�{N5���7���������4{���]e� �8�m��)C�,�^�tH���H7���nײ�! ��d� !�axѦ����Ue˅��1/t&�A>?���0dW��at��,+�&�*�pyuim)��T����j���(Ļ�jg nk�h�q�ogZ�i�~[��Ӻ��9_��le�i�՜��u���yy�5��O@20jM���'=k[L�*�C\�������4KQ�SO-�EO��G�8 ^y���O�,�C�3��
-H4K���H�u}R�Hz��J��܍�� � '��?��R`�8�_e)�>.�,�i ��0�$��[b�nQ����S&6����K�:3(�<F2��@���I;� �տJ]*�W���e�v�?}��)?�E�?@�Ǻ!~Kb��}@|�:��o1bC�I�����x%⻜KH>\��Գ?�I�C�Q&�bȁ�p�Z ����#���j��Y�Y�G���U��$�\G|����n�����R(�����x�;�󈏾�Ț\B|��Z�DBnD!��0$�+��?T�u�� �Q"Q�R Qn���<�#Q��H����H�=ُ�W�
-$��/#�jb�\ �Ao@��O=ءĒc�u�2@|�pC�s�⛏������Y �L����ҵ��o�!~�~�(K.� �^+A��G�P��*����5M+R�4���E�Uj���}Ugw9��.}`Ӽ�������
-
-��
-0s�t�ҦN��b�������i�C�;�VRj�<�,zK�f�i��OӒ��1b4�_=�b�z�� �"��E$Ƨ)�hNJMɨ>qʡ<$wU�W�j�
-��>=��Q�J/ji�WHf��E���uf�K�Qdc�}��� ���PɹG�6�T�p�z�������w�)U"�����iY{�YU�i���W�i���JTG��²G{�].?��/N?u�T�Ar�۴P�P���k�G��gZ1Z��߼9/oK��B��|�*��]6T\α�qS��D�,���[���C7M9|���+��k���#C²� ��i��~���>Hz��E����
-��+ͼ$��]����/�K�l���6w�!��9Hڸ:#�o[���"��k����Y�x�f)��� ��ۄ_2S9�{0��">�����_�: >�6z�Q���e%AB��8$$����75����:Ćz����I�u��)�����(^"Q4ق�8���+������t�7ׯ q�?�|�E i�� �j��HZx�C�� $-w}�_��5W"q� �l�B$]}�o"����x#>�x�>b"8N�qep�Z �a��H�R?
-��j���i� ��_Tq�]r�X�˅*.Q� �>REk�E��y�O
->6)!)�� �o1�6�;�? ׿J@Ҳ� ��j�R��Od�LVux�����y:���ۛ[۹ ��^n�N�u�·�B2ee-���ܖ�Z�_&@��j��m{Y�j>�EҺ��"�' v�!2Gځ�o>�X��78p�R ���R�rXK �4�.�Z����۷1�G��bn*և[�j�$踀���rX,�`���Dj��@Կ�]bv�6M}@Sm����Z�[�K�.6o�X���jQ*�*�IG�B� �٬o��@!��@�MdV����j�}Ć2�3:�5BU���ҍ2A��\�ӹ���\�� �ӳ�-�Hy՟�����9�� a���R�%��d��ֹ㾝�I`�L�\��a�
-�?K� �a�E<�{ ��# �����ܝ��#��O�����1��yb�S"��AH�H���r
-�w7x�)6RT�OPA;�)��9n�ku���#i[� G���[6Fd#��X��Vj��s�q_
-���ߨ���Ei?g�H� oT��s���}#sgzQ����һ6G�:�ЮUm`��Ng���Zm�%J�܎ԴG��j�q�i&̄)f ���N�m\'6Ts��Q��@���Ro�Ji��ם*u�������n�ZqDSO�B���8x!�
-*��:��������e-�� z��/�q�~���_y�.�F|���Ӏt�sB����v@��E�onۛu��S\
-�
-WM4Y�
-����rkP��wH�ʯ������F�E�:�S�(=yn�:ֻ���cW�+��+�"�F�,Ԭ}p���Q
-�P�P'��c u�fsɶ����W�V�� *$N�k�u�B��poċ7��L��I�Б3"�m �� ��D�����>��]��x��ݱ��������O1z�"4IB�����;�zx= V� �k6":�����:��SvZi�� =��5�^2�f9�J�~��N����l>�ษ�({��>@�@S�[�Y7�|�*��˴f�4� ���nZ#}D������?��]�S���M,�F;��t��\�Y�p��c.�l����4�ZC9��pnh���(es��Ro 9v6^C���5�`����(��<�N�����)6�rs�F.�S���ݰ��l����=�-��&��VZcR�!�������{��Mw:>cAZ���0%�_*�4o��j�,$-�����X�K%�V�٠Y����Ƴ��)�#���c�c��x����}슣���RG�G�-�ξa_�ẽb�4:�mK�gArd�D���z�o#� F*��t=͢ݯQ�H�`@�f��l�7��P�Q\.��H��H~�(�W������`�Z+jl�t���,-$#qr_�Du��S��j� �VH�YSP�&;;n�2�7�&(7Y�cDH0M�>r�^ۇ�⩫Y��\z"��/� l:{ʈ��4Q]l�o�Ɍ�/w��i����v�V=��za�U0�(�����{��Ǻv9`r�]t� }�m���r�*�t��3 L6w��#6�昆:�&�m��ud��d�ʥ�[�z�Wm�QncBB� 'E�� $�~:Ć_�"q�����Tf�a�3/y��Y��2X� q���s�(�p�D7!�Ng�RbS#�f��D� �嶸��;g���Fղ��/�jZ��Tl�\�8�JZ��Qj���i:�zP6�`��x6� `̃d�x��ԍ�zB3i�>����"X&kկ��7��>Dq���V��W(���� K� ��<�}B#�!�Sb� ��22����'�<������5�z��;ߜ�+�9��@n]s��o�߷uE�[e�.��d6O����5�c�dD��D�r_ȁ��CD������KH�~�_��g۹�|��V���+�̙ |�.S��� �rK���$%?��FD<)R���R/v��4L��Ҵ̉�P�{t{�I���6������`�1�6�16׷(u�9���� >��HOя�#���M��nGt6��
-P���ުܬ�\
-s�T]���6z�;�[��@K��"�GGGG�Ʊ���`�MF����ɩ����|71z��P�-�I���[N���8��"¹�MH�����{J�HGq��m�]Z��R�c�r�v�L�^����:�7�"��3�ַQ"6luC�$��ͬZ$��nq�o8���N$��Ax��@�a޺� �|�N���8a,��17��T$M,؏$�����B����!I׬_����׉�y�Ǻ͈�w|)�Ց�w��?y��p�ʷ�e�L- VUS��*�S›�J�O�~�N�j���K��!����o&����˾�ZLE��*8L��檂R�S"�'b�_O�~4b%+D���I��z$ݺ�!ik�E�r�"$�r�H:>�D������OJj�\� �H;�2��#>�&��<�__�- ��4Y>!~k���+ 6������&;=\L�]�p�n{�̦��&�'�+�/�����<`}v^W�:��o.'�0�Ӊ�b�s9�L;�r.g�!{�h�i�A�+$@�q_���%�H0���d�X7�C�h��|8 �,'�LcR��������������O� ��cs����/��Z��&��K��_�Щ�3�3h��\lI9�y�(ݗ)���r���A�x5�l�\G��R7�����7W�k�Q?G+� {?���}�$Di���;R9���T��m��F��ڟ �s�[pmK�ϼ&<-l��,��,�"��m��l�+TLmP�2��x�y�Oܥ�ȵ�
-A�1����`ʲ��{�u��yZKn;.R-��Zd2gK$��! �`���DHښ�-�\�5JP��
-z���p�����1uIZB��
-.��k��~��{�S]���b�).aCt��ut����zȷRe��;�7��f� �E�2mVFZ�@����<e���������Dw���GF 1mT_��UlH,�O���&��i�&��\�42#��:�^��uN�<M�2��knF'l��
-҇5�r�m"�~���⁈�GF�5��dw엋x��2�}Y���AdJ�+]��-�)�����r²[��85إ��3!
-����4����2��ɱh7���������Ӧ���q��$��Z�̋)d-ǽ����D��s�/�p��|C'����4J��ȩE���C�����+�V���*�՞P)}�P\�ISJ�
-Z�-U� X:���eܺ8�! �B�"W��A��n"�X3�΢��Bz�}J�<FDz�H/X�QFzq1"�!b�D6:���D���>o�@�������Rho��� ;�r������� N�OOOO*h5�抒����ӃEVM�UEQIQQQ����{�GEE%E�j��vҺ=|ő�J� M�����Z�zn�1}�x�{wi����"�_%".9��.i�ˢ�<;��:����9J:J��������?�S$u���<�^�Mм��m�EߍaJ���5Ӯ������.�3W'N��<SS�V�sϮ�c�۝)/^�� �8���c�������UyNIq�"���P�N��!�v{C���h6[)�B��N�o��(��BTJ|j<O/��9��ʜhIN�$��\Br|b����\�O���(��u����t_�\�bMJLL�9cR|b��h6
-]�!�}�nr���NUA������I��ɼ:��';��%9�F��9ҷ�WX&�I�F�-��-G&� ����ę��@B��>r����>�ׂ̂2��AGY/໫�G���Ҏp�w&>sm,/`�<�����77�AB� G�^1 ���?�%�Vn��&lS��2�����Z$9;*n���k��ܼ��C;�H>?�x;�I��刧�r��+�S�r���A�nܸ�g��)" �Q�ዐ4�1��ؐ4�ZóA� yJSB\B D��-��yԫ����)󀏰�lpذ��1K���ɩ�Ӄ� �s�b]���?N��EB6MGl��D1�
+x�}zw\���]`wF�5��%� ��K�-1���wAЕ" �K�ݳ�Ti�aQQQl��F��%��آ�`��=�g0��}>��|^��|f��9��s��{��89�B��ϐ��������`������� R[��LD�/m#� K������ƩJٖ���ܾhږ�F��Wu���mԑ8:Q�B��o���垾A>Aa]F����<�������wp�~}� p�����:3�O��'�'����Lo�@��5�\}]�x�<�=���.�\����:vڤo���ڳ�k����wP���޽CBBz�� ��fEo����o�g`����^����V�ڏ�� ��������<�'0h�ϲ������˨�]�ݗ/�\����:�ӣ����~^�c���)o��� OO�I_�q���y�y��z��� t � �vu�t]�����߿��oP`/Bd9M� �j�j� ��9�7=�P%8;��k� ��34jhw.4[��9�bi��RÒ*k�%�j�&5j�H�2M>�ff
+��b�tk�1
+xď��"��_���; IӃ�D*rH��i+G2p����
+HR� ~z��A���S�
+$ �7F��o��^o��ߌ�u8���WT�8$m"���o�S�e��,�G5M��s�7y�D�g�{1�y�2o�V��[��f�J#���J�8�s�"��V��d
+�u�%eYFm���ڻ��5�mmn�~�ABƹ!鰷Z�� nz$���Iؕ�*�u�J�[u�lDt�xL�qA�Ժxo�g��tJ�ɴ�+�s�y�����lY1�v�n�"}���#!L+�K��vd� �s�4Z��]KC�x�}@�Ϧ��&�#`i��b?^�~ݚH���m�4���q��0�'�#_�H@���[@|������H�&�!�����y�HF��`�{P�܃��À����U� ��!'%gc�m�� {�)\9�`ۆ��6$M�[�6��j$-tD��}��&
+�0�� ����b��07& dmxĺH?�?q�����L|⁤w�\��� ���2�
+��Ws�������#/��z��H�����s��Y�B.\5f�x{7+I�&ݑ���]T�Kj��^iR��:\x�������w������CvfƂ�`
+���r��M��]e�F ����������<�0Oש��g�^� GLeF޾��O�*��lR�B�,m��H�Yک��*�ޞ� ����ݥH��!���mH:�l����v�n���[��y���ׅ�_�l*�4�.��f�߳Ƭi7�`M��mwڀ6�yI5��m�?}�����h���]�,�8V�q6�W��ӆ|Y�� �x��{�ќ�M;]�*�$�B�iCLt$���ᅛJ7VT�,]&L�9��y����_��!ݐ�� �#�f�Q6�YQP�˛�kJ��%���UkO�L�F �?\= q[ݏ��Q���~N�%��܀B՟�]O�/��f+�Hۯ�4U�������+[���$}��"є�_ѳ�Eԫ|c� U��ޗ5�b�f *~v�E�����H�|ī��b��I��p���T�#~>�vB�q��u)��hC�,$N ��f��/ Q���`AB���CB�Iיߊ4���u�١����)6�C�MQ������+������0Xs A�
+�'&��<n�>e\�y�M;��1�r�S$I$NN]��� ^��ԡ\!y�;J^m;��7l��Ӂj�ڃ�v��Q$>��R�(�!֥��4H*�Y+�W"~Ⱦ���A���={#Q��<�e���l�G�E��8�?"����*������4.L^�>�G���Mėmݑ8��L�c:`,�"8b�,�G�����d�+D��2��u7D@�kz ���bÐ(�G��X�װ�g4[�D�F�D��3�ҎD�r Q��#i��
+|��}�����!�2��������A��8�Rx��i�i��^Y�7'H�y\�_��e�g� �ֺI�Gn��'�«Y�z졠%4M;�F��?>F���9�5ǣ�e�w�
+��$�S�"qH$H�(��
+�XCeKT ���|\�m-����I�u�Z@ ��6
+�ڙi��j�?����~�������]@Ҵ� �k��R��/d�LV�y�����:��� ����۹�-U"�9�~�*9�@���dҊj$�3ݖ�X�W*@�e�>3��ֲ�U#>~T��yk�����Ed�� w�|,�*��s����\�%�e� dh�\N��i1�C�B�ucn*փ[�j�,踀���2X$�`���D���@Կ�]bv�6M}DSm�����;���.6o�X���JQ*�*�IG��Y�o�\G!��@�E�dT������}ĺR�3:�5BU��� 2A�
+]�����^�� ��s�H-kKy՟��� ٱ� a���R�%;�x���٣�n'0N�Y�s��0N
+@�|�ɴD�+�L1������ҟ�[��u�iT� I[EZx�� �FƉ��m�= �.6��{4���4�5�J'�9
+a:� �[��
+�l�(F�Xw���F�O�G�V�A<4� qG�jēWݐ,n�����;�6$?�"�����"g
+W`ۤ�i��U�;Im�ȑ��k�u*�$� ��M>F�n�nZӷ�@s��(+ C�@���x�t �൹����b��D`9�r�+��ۂ�e�sґ��V-�ۨx�5�R=��)�v�I+_R\������>=⇟ �����E+o��#^��x���ܖ�]V�&�`B9kr� �Dlk��+���7�W�!i0�Y�ʌ�f�y���"���Z�ė���
+ $^�1�m|�Ąo���9f�T��S�tݗ���ס�זEd����_Q��>�T���ljk2� ���xъ������⢂��͗^o�b�����k��������.�\?N�k�q�� �l�$X�ɐ��3sZVF._P�ܳ���m@�y����d�Y H���x��ĺ8=�q�:=�v���,�7�!��m��s�#��0NõsG/�� �r �~ʾ�Y�!��6"U�B�x�����4H�D�%���\V�%^H
+)WTQ'���cu�fqɶ����W�V�� *$N/�?t�D��Hw�K������N����!�m$� Y��
+"J^\eTj�׮�f�Vo��Ys�׭��C��b�'��� $!^�T�x䃿�X9�+ g�t�=� �d������V�e+H�|1�C ��̦GX6� *�թ*,����q8a�0�^��P;��k�m!Ϯ
+6v3���0ż������H�E�#4��������_��Դ�_e˨�N��k'ֶ��]�����1�&�l=Ǡ�P�=�k=,JY��ԻB���Q�����g~u'�*�2�f��~�e�nn���R�Y�#�ɩ���L6y��6�����6��VXcR�!���������� w9�`AZ����J$N�V iܬ;��H���=4%4���
+�Wͺ#��3߼��g�?���� ˋ͋M�M��տ����+����K�.���l*��}˖2:���Sh�7�%m� ɑ5j2�� F"A�T���:�I;_�
+�*�Q�|�ɲ Y�ok�H��H� �
+�o^M�����_�`B��c��O�p$�����&GYc �כBt\����0�c���*]��r�!q��)Ox��C�
+���{�ӆ\$3C� �#'_�5���6#�����WG"޻7F����!8&�6�I3�,XUI���A o6*!>9�=;ͫ� �^$ݴ���v�\޿wA�[�Ak1F�8��qQ��mJ�O�L�t��Q��4�G�
+V�x�+�n;�H:urC��\��i�H��葴}��0�[$���W#>��d���eV�G|�Mcy:��T[d[-h2}B����U�o.���Lvz����P�����M!��ϴWs^���?y�z
+삮\u2��\N�aė��,�rv�v�\�DC��D�.��7H� ����^i���`6O��`�n�5����& yp�[N�Ƥ(�!>r��RO�‹�G�+��G��g�_���0+�ku�{�� ����)�=��h��\dI9 ��(=�)���r��́/x5ml�XK��R'�˱��w�W�i�~S;K+�u{?���c�xDi���=\9����r�� ֝�`?�y�7������-e���݋2�OL�d�t<�Œ�C(+W1�A9�4��e�u?s�S#׈�9X
+X�X��
+!�)$M.P�S��?��)idFh%uT������y���9��܎NX��&������l�����)?�76E��O���<��\DL���uO��kn��
+��+�`��{�Fs��Ȕ�W���[*S�/9��?�e�H�sj�K;�gC��wGi`s9�e��c�n�c '/9gףE5/��2 Iz!Z���S�6Z�{;߸�D��s�o�p9Y|]6'��O�4J��ȮF���C� ռ�+�WV�������=�B�\��d�&�8J�4_[�2ֳ�`��rk� K�L$
+��\�������c�x:����9�-(Y��1�5�Gz��B��ň���Gُ��g8�th_�u�'�=(�0�z'�v� ]�K!)w9JJ�^�*����7nL*h%��
+�6n��1Xd��RU�,�J�g|TTTRT��;mU.� Q�#Wi�t^[׀8������7��c�,-�2�B$ ~��@��'?$�@|]8�g'�@G�
+�6������I! �vX��H����13�H �a�O�b>cU�$X�355j5�w��8��۞��E�y ���ci�<f �a����*�..*Z_��[�׎65d�N��`:�/�b+dTH��E{�R�5Z�J�O���=/�]�-�I�$>�KH�O����� qqų�N�����6V�X���,Θ�o5� �.Ϯ��b�Aϫk�`S�F3Ak����N�ӟ���3m��#}�|�e��>|�'Ʋ�߳�����6��QH�i�4$ı�#'r��.��,x (èt�u��jj4x�,�(�rW� 1��r6�s,���x{�^$d�PĬ��(j;�X�jŦ���6���-\Kê<�hX����Ǒ4Q��O�J�}t����C����'�'�%ŧ$��O &ed�1LԸ�e3Mum�I�.*t��P�y��Q�]������7&�'nL��R~��Qg-���[V˵]Tn�ʉ�!�x$_��A�․��2�3�8����iC��� ��7lX³9u/� ���H� {��Hu���blH_���@ ذ�\�)!.!���c
+�<j��آ�9�G�U68b8
+��z"!��"�U�A����X������T�FDV*�NX7�eWm2�2��A8k�,���-��]��v|���tG��=Z��캋�N�E�Hi����z��>�{�H�]����K�~�q��7��9���$�bA���I���j�"�|� ��f��q3���2y#� ������|@o����3O'�Ct(-Q"Qwꌤ�3ĺ7�tm�4E���xĴ
+�%SF�r�w�a��wG�+�8�-[>��߀-Q"��AJq�!�8�T�l� S��d,�(˼WT�(Y�
endstream
endobj
-264 0 obj
-<</Length 11/Filter/FlateDecode>>
+273 0 obj
+<</Length 12/Filter/FlateDecode>>
stream
-x���
+x���
+w
endstream
endobj
-265 0 obj
-<</Length 687/Type/CMap/Filter/FlateDecode/WMode 0>>
+274 0 obj
+<</Length 692/Type/CMap/Filter/FlateDecode/WMode 0>>
stream
-x�m�MO�0����C$8�Ml'�*��H=�!�v�%q��h������)��
-=�M嚱O*�����뇺mnU��CS�ڣon�f�f/}[nݨ�uS��޽o�jU��(*�.��.ޞ��7;U��j�$S)�f��PcR��KU�=��r}��Ź�o���u�7����5U�;��O��S3��*�*���v���~l��Hi�l+7t�����ࢻ$I���+��Xx�������?�>�� u�$�l�F%(TnQ��22%��*��5��uC�jI� �L�Z�4j�9��̂*t��$�^���W(�4�)|�%J�
-���Q�w��oNש�A�
-��×K �\� �ԄOK��ͥ
-|9���e����� _N����h� 55|w �������$�L��g� ��L�,�>�{������g�3�����`೼����2 |��*�e��ef>+1�c��L����|��e�3L����3 ����g��>�k�3�[�4~�����g=�΄��gq��>%S�D��䦭�IL���>q��r�V��a��n������mWN}�1�ذ����������OX���^=g�U
+x�m��N�@E�����%X0���
+�zܵQ��b<�zx���y��Um���j������.>�ҟc�r�U�0y����1��j���jR���C5�Tr��/��USߪ4�ㇺ\5ǩ�>�����tM����Wuى�z�|�T��*Q�oqܵ���������2D�c+�J)5{�������]����y�J�U�A]��������OE�$��� ߳ �iw�j&���B�ү��S�%���cS�EJ�ES�������%I�,�]���br�g�:�������Bx�PwI2w��4*A��2���刔��=�2J_����P7D>��Dޠ�4�J�֜�,(���B��Ԁ$�k|�
+��=�o�D _��9J��Q�ͩ:>hS�w�2ك/�s�'9��R'|s�_F'4|�:�����˨Z��苆ϐS�gp��i� ��/>'��9���4|Z"��j�,�E �>����3����gy>˫3�9 |��,�9���3��=᣻>'��99��e� �7�>���g��Y:o���Z� �>�������ىO;���Yܭ�O�>Q�>�i+|�'|t���M+|���ޝ���a
endstream
endobj
-266 0 obj
-<</Length 12464/Filter/FlateDecode>>
+275 0 obj
+<</Length 12534/Filter/FlateDecode>>
stream
-x�ݼ TTW�?��tסּ�nQE1C�dDQJ�Q4qF�1**�Fm�QJ�&��H|i��v��!m4�IԤ�Q�� ��i�ۄ_��D���{�A3t��}����A��u�}���y�2�
-�,��S2c�"v��
-i�Mp�4Ai"(�� �%
-�q4�P ��
->��P 7`�
-��0��� 8X�5P ܂ո��EP ��v��Z` d���
-
-@f��;���
-��'�����D���� ��hNmm�� ��w{�p�:;4'�u{v,���w���:���?}ۀ̄�ّ�y����>{���}� }�OI ^����^j�*�!*Ć���
-��A�3
-?�%����QG�6}��x�I%� S&�e6������qJ��!$OG��$�m^�=�׵=Cg��~\SO�Z��t�2��Y'�x�*T�E^5������}����ڵ��+6�W������|�j�On��ݭ/�޺E>�����>jy��]�=�_�s~%"�IB~
-V.��aS`J@��� (�jLk�����|�&��@���8w-��|]K�� �<y~N��0%6�����6���
-�M��Y����_�5�,�*��j9�Z���2�6Ŗo� ���U��33�s͏�I�=:}l�j]fŊ�؂��~��X�>j��o��g�S�$cقP�rB�429iȬ�'y���G��ѧ�4�*.;ο�5j��f:��4Y��y
-�u0�R��_�����P�/}��2��g��w�Y9#f�kC�.�Oۖ�_/���m5^{}�x�ӧg� n���Zn��>����a�Oև꿨%{� Z���
-�'56�d�0�[���o�W���q�ň �pz��
-�W�B�b���z��* ܴ_
-��" �@c�u�=��f
-!�P�$�\��;�Z{ �Z V#F�g��t �z���'N���
-����ןFI�W֎^�%w��=S��i����@`���t�&��d�q��6N��H���Dl�{1%���G�C�#4�D��"S���Vo�o�,���Ǭ�D���)��gO�G1��1���{��-p�Ϭ߸�~v�S߾{�ۧ������~w��5�+׬�(_�O�>���ڪM�ƻ�>t�¡Շ]��v��r�L�4s�c��X�F��dž�����������;22"W��!����ժ�e��uרۻG�ø��LKO������C�{�q�;�wھA��&�C,�!�U!#���7��]�s��H`�M��n<rdj�ޒg�w��{i��w��ח=���c��� Ml�;}��?:�8&��{��|���A��M��E'7ս��q��*
-�T�)��eԒL���k���\%�m���m;ϱ�z>��-C�R�Q�/�{}��Z�G#b�d�Y'�Ѽ����:M����[����������"�
-ab N�jO�1œ��Nȣ��P�'I��Zm�ⷳ)n5G g@ IB�Q��D�(S����=��C#+f�~��B��m�~�Ԗ�'���ҽ��??�mk��{Oœڮ��񵛴��2îC8d{\�!HBj��ɋ��f��*�G��,L��������_ȐjL���y��2~�7#
-��̃��N�>�����E;*��D��T$����G������ o�t������{裾��<1�Pk4��6�Z�#USpd��X"YjXOD�R\zA�Y���4kѶ u�H��3D�#��7k����W�Y��i> ������m������O*6�f.���z�p��lz�x���y����Y `0�6�
-᧙
-LS�s�bs9YF� �L1S�c�J���tu���է?=~��q�rg��~L�n'��^������ ��c����K����S�����V�^aJ@:r�t��d,y��O�˧������Gh5�b��B~k��F�k�j"�wsD�J.���pEvQ�R��Z��ҵ��ɐ���
-j��b�c|�K��n8��#{�3:�����++7o�����͛�|s���1fLF�Q#�.�.?���wQ
-�2PJ_���_�h#z �F����/�ɒ$��d(�d*ݻ�D��d�3
- �x%+W* L�HX7űR��d�|2D"?L&��@���'+�
-�y�.�sx��mG�<x��T�x[�s�͸���F ��xM`�A�Q�V?P�A��*�Y���5"K�M1�AR "�����'���&�H�?�� �33�!Y|a��%� ���n��w��L~p ?�����L4f C?=yj�9����y��s��o8����6�������oB�>b�������;�kR�
-T�p
-=-h������U8'� �P #�N�!�m�O�u
-�V(BW�y4*�
- ����
-��wL���]���}���+�B|�&�Bپc��X��wl�b�.���a1̅9P K!
-��,��(H�H�4���PQ� sa),���f� (���fAD�
-�v�Z�}� K`6,�e0
-! �0f�<�� �`� Xs�;�`�F?
-��B��EP3a̅Y�P
-%0C�v?�qAa$��B(�\(�R�����\���, � ��۟n�^�E�Y]��>酄KadA��|�/�2H�%P
-e�f�l��ŚtI�f�R܅Z�����eqM (� �a��r��0�I��O��#7�����Vc���ůX���%F� ���P:g��f�a>DA)�K^�dc4z%�N�ik�f�䚣�"P� :E�����֭I\_
-�� ����\_�f�R���k�O�Y>��i.ո���g�,��X��NAܭ�[�l�kt ��b%њ�ij�ڻ��f�\��O��YP%���|�`.,��q�;W�.�_
-�}v.V��D�Y��
-�L㳓�BM���0�4~:q��u��,X
-�J��~fI�e����Yd�/� �;WZ�IU�=�y1�C�����g��.֦�Έ���E�M��
-kX�Eˠ��b�a���n�3`,�e1��"۴?�U�:Ͽ�1B��x_��Q��K��K�S1\\-����_�W�����S�1vAG����v���{"/���~��Y0fh��z^V���������R镖��ȋEH �<m��0
-�k댆�0&�
-_��U�b�R��������#�1@��!0H�[&��&�C��ſ��Ѡ� �a<�#`*��tȃ\ô V� ��b�= ��B�7�CwȀd�tx
-9�G��5N�Ԑ���UN�����~�0'/�C��r�Fp����?p�����H='/S�> ��^���;٫�߾��~����H���=�<�I��`VWHv?ge���sV���d�?���~d��$���mI��z
-iN��D��6��ow��I���2 I��!��p��I�D;��I�p�+%��N�RBX'�j.K�g��� !)!$9�Β�H�!�%%�=X��$6b�l��z�������%p�!�=�&�8��sҝ�8Nb��;0���H7�I��?�����\�HT"�N"�\�I8'a��,��P���`�I0'A�8s�s0 t$��\�[�#�ح$
+x��| XTW����9��:E� H�AD)q�9jM�q@����Q�kԀ�� 8%o�6�mcF�b5�1Jҙ��t� 1�\5����s�A3t����{���^�_���
+gM��Z��)
+��!� ��Ŭ �/��#�e=�=�����E�1ѝ���?��r�} �4��Ν�y4�M<�: �
+��� �$'"T�i����EX�7����$�/_��l��fd�x�5�����T+���E�cc�%�� Zv�pҶ����療m���u�>�أ��oj9-+�N������t�?j���:Oew.Q�d�xJ���Ҁv�����4Dp�kN@4�1��
+�=�p�� ��oY�'꫻���x��G����1cR�����*��n� SI��RgTLLA��,v�ŬF_Vc�&V����f!b
+R��j��K՝�Vq�ͧL)9�ŹZބ�3�DeK�ofl�sO�D}��Σe��N0� �� ���:$U�WC+��E��j� �����}�j<X/_o�,��^�j�P3R���G�aA1Q�Z!-�&��<ߥc/�/�s�A~������}=}bú}V<e����2^NH@(���zj��vB��;R"�
+�ǃ+����@����
+�^oLmn��u��Ok�p�;�4'�� }z ��������2�O��7mk���� ّ�����2?����
+}��H^ �:���^l�*�!�dž�����
+�rAh~�Of�כۣ�mz)M�:z�^�@2T�@�Yd�RBV(��An��<�/�Ė�x��^������qU-�hy�Kt��g�� �*lPay�` @l��!Z����j
+j�Rz��8�!�>.�x��M�?����7��r�&�����>���w�w����JD�1���
+���I1��E�ZM2$�����Y��SwGg��N�V���NO�>hѺ�d��H�D8�t����!�f�4�B,�DZ,^��c��� ܃eHr��e������+y� ���<��9l�a�i)^��+�1,2%Cq$���,�iL� �/�˲�C��s�Vh,ëH)]EW��WC&��jZ8����;Y���u�ց��|�pNK�x��l�}����`�S�L�iP��d�$1��`�)+3��0��I��1L� �a�F�d@�4
+�{+3�\�������{o��܌?��=3{�,ru������ex�7�˾lY��\[(>�iYكZs{����w�|}������/�C���V b8@Hv0@
+p��u�6n\�n=K�6�����ߖt�0N�7}�a�cc'��HE�(s���o�>�����!޸P�+<�@l�A��
+WpE ����
+<���}q� �K6�{�}z��Q�X���Fp7�Av��*��w�M&�_�~s�U���c���3j�?���֢Ư�j�_�\�3ν���s|�?�q_�𺤮�(+�<�2���9~�:��
+��LیP�>n�;��o&~�yΩ4tߦq��
+C�����
+tG�X}�;F�|Y$[=�Y��
+�l|��V�u�,� ���KM�'&��;`c�¥Q�� 5o��8@p��&0@go�TM���?+ u�� ��$Ө���j��1WHq�CxVˎ�����m�a)r�H͗��~zJ5��1�F2ͬ��h�C��p�"K[���-��1�2AyPm�%�^
+B�{u�ej�A"F�B' 1��R����2�D��7T�IR��f[��no�[G�.� �!IH�"�V�Hme
+�a�1g?88�l�gQ�M$=���'Ol�~�j/�� Q鳓[6��O�}���r����٨���hv " �� �`V�鮼�
+u��GP����Q����EQ۩��!՘t7}�٥�2oD^1e���k��:u����?@�ˆ�@ըX$���F��s�m~�7E��{@��=
+F�Qx�q�i*LES�T�T�.؅v�]d��vI��]�.�.�.�~؏���d?���K����~�~�~�18���c�=ƎI��c�1�1�1Ӡ_bƿ�J����Ty�2� �%B�'�ɨ�V��� �G/1��.���k���^��m*/ߴ��|�7n|�����j�ѣ{�9������ ���'J�����[�m@��Uh���:I��� �� �Kg��C�Ǟlu!Oy�͑]*]��ͨ��vY��Y���$��.Q��H��EgV�3՗�l�]�� �_Km���k7���7/���q�9��Z&�ҩj�b��4� ���j�2>��7 ?-,)���
+N��?;�3��Q��=����z�(�G�%��g�GOӅS���>�YR���9����z���믙+�O ɔ�yb��� z� ��!Zm�+���6%��X7rA�^�h�J��3�* �`�n5f�Y�l��gYS�N�+�ޒ���;��C��� 2T�jGU�H5��Rm�!Z�Ҿ�Ԫ۴T[P�c�q��m��o۾���--7���|���\���_����(��|5zm@��j�Z�k<
+� 5f<� �(
+<�on�7^aM-
+��V��}C�n}
+j��� ��!  � �A��X�:Y�B�/�bs�.o�D�����NR�S�EK�U���p�i��Q�rG�nlz�P�c��A����=ӌ��;������س����f�"o'a�%Y�.rHa��J��*�[ �od�=C�����H��X'��q��K����\����!R,���\i��
+%Q��A��S�
+�|5�wffᄃtyZkb&z��G���w�<+� �"�y:$a�0�d�Y�Y�A�C�^�������z�G�Ѽ�[$�"��w�e~�?o�P?1�0��'a�BE�Ԝ�V?�(�h��2F fɫ�8?�2ڽ�n�]���U�u+}��#1}����Q{"�o �w��bhA���Y0s*�,V���%ϐ�W�R��`�Q���eqS�*%ȱJ&�%����d˓�� �<��,����fo<��}�r���C� `
+�֖g|�p�s-�6{�P����
+#�]�&�f�L1U��L5?mD�*�b6��D0�R�!4@� �cM*Qd�4W'lΌ�d��(�KD=���zhߎ
+2����@*��3���h4����g�zTzv��3ϢR����
+}C3�p(��p>A[�x
+�tM�rȃӰ�`+��r�� އ�ڛ�{�#�*ȃu �Q/��p[qdA8�A9�C` x 6��ba
+�k�
+�g��%H#U�B]t(�F����G%*����K��)C��mC���a��C����8͸¸��`��kcz�Toz�����
+ ������O�ׯ#���1>���i�c!�w�������Fa�cd�,�q@P,Z�?�@�}'�bX����l(�%]`&�C�B
+�@D� (�(ȁ9��X�`:AW��\X
+�����P3`>́��P E0]�v/��Aa�(�(�b�������, Ҡ�]Ϸ>���ݴ ���DK�� ��BȄdѯ��_
+%���J`̄Yڳ�4�`̂%0��Vi[Q�)��@P�5f�|(�e�a�I��Ϯ�#7�����Vc���ƷX������s�(
+��3B��E0��
+�%/B���"�Z� � �k��r��V( ���ꬶ�t ��$�/�b���� �v��P 3`�_��g�_��~�[i.Ѹ��Ƨ�L��"X��JAܭ�[�,�kt ��`%њ�ij�ڧ��f���O���PE��6|
+`���q�6�W�.�_��v.Vl�D�Y���D㳝�|M��90J4~�q��u��L�%�e� j>�ď������o���mܖhv��q,pi�u��.�B����ѵM�d-�Di�u�i��z��]�V�tnu;�%����%Z��Q�o��� Z�\��P����!I���b ��0 fj��{:��|�lՐ�\H0�M�!S��q���� (�"C�:Ƣv~ D�t��-���V_Y��1��sB*�ۺ�D����t4�H>�W�)(��B�H�l���.�@��o�������g&�m����—[#��]�颶3:��V)�>;Z]k���x��|��v�ij��~+�� �5i
+��u��B:���mk܋��)S���� I��_��������x�Q\��$$�娮kI���E����6�l��{��,����L�*_{>�g�bt���>!�oͺ��M���������Zy�0��&�B1���f�r g�z��BX��b��E�i}���u��c��5��ϣX���E���b��Z��u7�ѿZ�Dߥ��S�1v~[�n��V���{"/���^�♙0�k��z^V�����E��e��JKGQ�ł6���@m�Q0�i댂A0&@?�]˅��a ��� ` ���O�"�Gk�8r5�����Nc ��hO�(���TGj �\ �gB���@�Qc4�#`4 �\mM�� �a8<
+�jx
+��܎�dc�� �8�5�s�F�h���1��8� ��8����q�<B3#�U�igu�F��,�۩�>@���!�߶�XM��0\�V�;V[a �mt[mg�FA��&��/W�P�����mw����~����y!�@d��J�J�n���u�� h � ��kw���0�k��3�=�j���c����^� �^�'����f��w���B��������Y��E�s+?š�����q���W+
+�Ƅ�t�u��h��~�l�������G���;�C�պ��x
+�t�H2�ߢ�Ǯ��\�{ �ym�O2w�걽*�Xv�k;Vz��[t�}�g�������c �s���K�zO��Z}�[�:V��Z��ׂ�۪=�U&���+�֮Et�"����-���%���)-����-�4-C��!
+^F��2�X̒�a�v��W�_qOW�����U���8�Xˢ���!,��$?�Em�Y;&}�Ut��ۭOP��I*0�݁s���5��+Ě���|-Y�{́d�G��rHҪ���|OE)�K��;�I� ��_�k��0hq��~0�xx
+T� c`����A �`8L�@�!��Pm��D@_�B,X�+��Tp@8�x�=!�!�t� �7� � �bۜ@ L�nZ<�Y I �,����}����a�9>9���P9`�����@P���6 HՎ���@�Y�〃_f�<(
+�='��7oLd7+������Xvc"���c�}�����.��/N�q�m*�j'�T���fN����ޡ_&_]�g_U�+�䟜�������=�|���y�';B��<�}q�|J>�"�r� '�`s�|XE>���}��_7��_����LҴ�Ě2�EN.�kd8y�H�s�'�SٹN��`�'oV���v��3��^I���uN^����
+o��GH'�8��d� ��� ��.2��i�L�d�$�b!���Co�'�؃v2�D&r�g'8����T2���������d4'��d$'#P"���#dX247� �Ir��Xn20� �dp�O a����!d@Г��QY�_��^���rT�S��k����/���Gǽ��63��x��j��f� ,�L��כO�r�%�>�H'���LN2���Ozu c������H����#�S�X�a$-%��q���TN�%�Y�0�F��,9�$�Y���5�%�Ib=�v���k�*ح� �yX'���}�3Y<']8��$6�x�s�g �Hb8� dќ���{%�J$�ÈK�a.N"8��:qVJ�8 �$�gps"��D�Cv+s$����ىM�a6NT���b dV�Xu�-fHu�,Ff1��]����$�yQ����m��&N��`f��L+�9�P"�8avBp&#�F� gV� X �G��6���������W�o��V
endstream
endobj
-267 0 obj
+276 0 obj
<</Length 9/Filter/FlateDecode>>
stream
x�;
endstream
endobj
-268 0 obj
+277 0 obj
<</Length 343/Type/CMap/Filter/FlateDecode/WMode 0>>
stream
x�mQ=k�0��+�� R�I�B�uj���Ύtv�$$y�/�夔��w����ѧS�x�ꊋ�s
@@ -963,7 +994,7 @@ g��7 ��քҝb}��9�)kנ�b�宔�JK�n=lj��[!�yo����n���@�%G� �J?�X�
��
endstream
endobj
-269 0 obj
+278 0 obj
<</Length 380/Filter/FlateDecode/Subtype/CIDFontType0C>>
stream
x�cd`aa`dd���LJ-*��+-N-�L� JM/�I,ɹ���!��#�C��A��A��B��<��=EFB��OVY���� �\�� ���(��>񨀨W<� ̌�l|ގ)�I��)�y%�%����E��%
@@ -973,128 +1004,123 @@ x�cd`aa`dd���LJ-*��+-N-�L� JM/�I,ɹ���!��#�C��A��A��B��<��=EFB��OVY���� �
b��W}��c�3��w�������Od�����`�.��?L��}� ���w�3{V�N��#�[����zJ����J3'v���)�G�����]���
endstream
endobj
-270 0 obj
-<</Length 5285/Filter/FlateDecode>>
+279 0 obj
+<</Length 5481/Filter/FlateDecode>>
stream
-x��=˒�qw~E�;w�;�6������#˛�Ò�q��mKT;�{E�t�
-���w.�$��D"_���~:���Ç������?���������W�̤'==��$��nJ1�C���?���_&=������'=}����'���O��ӏ�?����Z�Aks���w{��.?��g����������������n�gXO�Q_.�����������y���@_`<����y��������~��&�A���(닛�+�Y���|�Iwh~�l����vE�C��e>�YIX� H^�mZRϿ�����"�G�\�V�)�l�N\�$ѭʹ�H�f,���:�;�X�r!If�
-�������"'O���X�l)e=�r�M�
-��mŏ\p�).�;� sX�u�yg��f`�M����Y%�P�0�͓;�ww��2�]��
-�0v�X�%��rQ��U�L�3��_/����Ǜ��5�k�s��v` :������ ��^��)Rgp��,TI�H��Q�
-�k{��mϯ���0���3�WC\�Џ�a&���@�'��Ƭ��N% <ف�A;��k��`߈�H V��gP�� ���L�����n�����Y8�щ���2�iy @�x�DZ`�L��R:�����w��Y�rX�5�"y�Ё@ _I�h�J8���+2`��)萙�Ъ=�-���}+�4Z���!�8���*y�zTš��0p� :�������Y����M����]a�L��̸��z](,�xb%�X6�P�fE� >UA��u��?�C��N�^_pHCtN��i�چo3t��H����<D
-m�۷X�
-V �=�޳/#�;�8�4�*�_:c���cp�e귔Wu��-gڛ����v�m'����j"�+p��;�D<@���1��B�*���u-ǖGo\s�H���!W��{�2c$������oQ�dk�\�њU8�6�?,!� /�W����b^8Hi�JYk!F F�R�2!L8m9���uw�3G4��9�p���*1{欽� �#7��4�K[�pً�Q��A��K0G��m �<� ������ �ו00��(8���}����Qb+=�?!�ض�8a��a��b���-�d)��U%۸�� ��·pV�Cp�]]�����纻`Md5���h?�3B$;�{���)�׊?E:,����$����������0@��9�j���6Rco��.�V��I�Y�M�a ��<�+��ze��<`O�ÄR�0���}�a�մ� ���|9���O����?~�����������w��KT!G3��|�q�ӏ�u��O�?���'=����a��W?^�Z�J'cux���I.��/�X�ʜ��5��I��|ҪcҤw���&��zV+\���k�}�21U��^���7�ej��MzP�H�Ѧ
-p���\�R�n�-�� ��x�ն!'�#��0L��u`����E%D!dOƻу d��S'}"��8$1?���vxd�1�;���J��,2a�5‰����仮޳��/��O�Q����)+�*��߭� x&���.51�l����'��6�Y��� ����Aկ8e]��̩���8�hͣl$;'m�*�nI{VW!P*��O?s#e� �5��AL&9mx�1o���6<v����ݺ!�'8�M�c� �:H�B͏��<!����<x���!g)��C�i�6�������#��d�~{.��  
-+�`V
-MJ�9���-� ����*�sI�a;^���$LD
-ϭ����K0\�ٿOKKg��[#`����kS����"���t6�ސ���9v])��n[^8b�����t0���TvGî �Bߣ�:I\ ������B/)m��l�Bm��s���G&����0�P��_z��
-L�Z
-m1 j:��� '\ٻR�5���<�ł�nb���u�#M�q?)^x��tR�;o�x�GCE,�|}&K��-�8VC��:ڜ
-���</��|Ė�y��*��sR�g�� m���SѤP��f��`Pd�;�r �q�T�����[�K K���ѥ��������5�z��/�H�
-��LN�w�ry� �}�Vٺ�pn|5�T? ?%����~�/ʛ3L�^���ߣ�#�Sϧv)�܂��e$�{�� |Wә���s�@��ja;aX�q�w�{0���Tt�ԑ���G���B�L�D:�U��i���� MM��n���p��Iz�Z��b���V�݉W>�T?*
-�@3�2=��C
-
-`��UΩ6���8�� �@~PǦ��¾8mإqҝ�o�I�ڝ�f��q���ۚ>�%f����P��� �?m��⻞�u�C�B����HDHR:}3 `o�!%Rl���X��!��M������D!7a7��Nm���G��ќ:ye��#�b0�}�BSg����V��
-V0#��>\��2.��c�-#k��M2v�c8y|�m+O�N���Gf>���H�;;i��<�e��N������KeN��r8���|�k;mοnL0�\��(�̑�K�{9�Lt.��6��9;'��d��O]p����X�2C�n�j�S�#�� J;��љh<i�Ү�t)^� ���`�X�'��:��U&��U�.�a3q%�R����(
+x��=]��q��-�ں=y���H�K|����\N�7��8���}0���f}��=�ȋVҒ�bU�X��~���?޿���~7��?�t����t�����~����Lfғ��d�WZ7��T�!���Ϗ����/������껏��>~y|ғI�ǧe���ǟ�����?jm�n/?�姿� ����3�~:�y\��p_���� �i5���7qY�<C�V�X3����� �����ϯ~��տ����ׄ4�~�e}qSrE�`#K>3#�o7��oZ�-pS3֮yhW�̇3+ ���MK����1��y�[D�h����8%]���I��$�����ڌ%�ZGs'`�V.�"ɌVA�<��<�=6\��)�?k�-�̢�C.��_A1���� �8�{�d+��2� ?� 쯻 tVXB8ˠ��>
+��� ʴ?��� ��9���0T�u
+a��Θ�i�\�G��-�U�o˙�&��qG�]mۉma<���
+lh��+�!B�qL-�����:�xp]˱���ל1R�g�U/�ޣ���!���C�3�Z'�|�f�� �KH>�K���*��RZ�R�Z�Q�#��LN[���c���� nnλ��q���J��ހ9k�2C�ȍ��?͸���.\���m��tЅ>��QdsA��tB��=�+wC�u% ��?1
+��6�m�58o�@����J� �OH�9��=NXps�����)a �Y��kU�6n~~�=��!�U%�m���CW$;p,B����.XYM�7;����ű<|
+��OQ�K-d�& ��6��-h3 �|f��캹�����Ʒ˫)xtV%G�w#1��j�^��!���0�T�3 ��b�w�w5mp���_�������������?=����_��}�*�h��?Lz��ÿLZ��'?}���Ur6L����V+Q�d�/�Z8ɥq�E�V�!���r4���OZ�`L����bP��[�j���y�zͱO�S&�*��+�]����LM2�IJi0�T�^Y㣘+�A�� բ�4�!�O��6��v�6"�Ip���YBt���(���x� z0��2q��d��A��$�'�9�@��L5�~���UIy�E& �F81�rp�|��{�?�E<�I7�|;e�o_%1��u�ϤP}�ݥ&F�M0q`S���f1��\�1>�>���� 1ހ95�'��y�-�$�c� Y���-i��j"JŹ@���gn��q�&��>�ɤ � �0�m2�҆���W�[7d��� {��TɁV���^Ԃ'�|�a�����6�,���tH� �����@��Sb���p�� �o�%�6ATa�J�II9g��%pa8@��^E~."�Q l�k�����`^�0� ����Aﹴxُʤp����;,Upr���2�$'[�� �I.J�8��$簰����AJ,�݈���y��w�,b�
+ !Zps�'����́t���+�eVqF2��p��A��,�þ�^�HI�.YeC�5�/�t n.O��K`�/t��\pt ��Cv\� M�I�@ ��c���Y��CG8ˋW��"� P7�2o�7L���5�>�3�>�4�ƅ�T�rd�v��O���i�[1���v���p�����t"b�:
+�����.���(�61�z� )Y�Ȗ��5�<k�]4{�?[��I�FN����F���[{�� �AK�-�AMg�`6���+{W
+�[@��'�X��M�Y]��Ny��3�'� /�4�NJ{�� /��h������d鐳��j�6RG��C!w���~��ؒ<��Sŗ{N*���
+�����)�B'-���q��
+~_e�p� c͖��\��@��+ل��02��Y�Wd�xG�h�ƫ���Qß�Yᒕ���nY.���o�*[��
+��:�T��Psq@(��i3�Hg�
+�=��R�p�� _ݭ���
+ĺj�F�=��p��WY��flO<���ނ�z����A�d�F"^�<sAI=Q=�"�m���[8���m^���Nz~���݀��j^L�*gmv~�o� o�T ���L���z �؃@�S����T)Z~�]6�J` ���Mp��
+�H��kE\���)w:W�\��?�- � M�$��Utv�i`��H��?ۀpj�\�#�B��",I���G!bT!�9X�j?� #h���>}!�X�vue_U�U0� Q��*%{s �c_]��|gC��Ҧ�����P��vh'�� �#���X�x}�F ����cO�F�{�B������:m���@㽿S+%�ZvJ�l�vۼe�'� ���EYg|�2ۑ��l�"LbLj������v����^20��F_�D:���s
+) #�x>�6��^N�%5 ��>��d.����E��W�kZȷ[5���U��b�(�M�{b�0Mt{����eI9Ƚ�9$3��_��k!�_�2�d�E�����f�:���Re�N���+���z-�Yr٥�h(#g@��5?�.CZ��Vx���Ƹ
endstream
endobj
-271 0 obj
-<</Length 6496/Filter/FlateDecode>>
+280 0 obj
+<</Length 6543/Filter/FlateDecode>>
stream
-x��]ݓ�6r�_1Vl����(��d;�+;U)�-΃��^%u����Ur�}��$H4MA�\��i�C4���Fw���?������׿��$���߼~��'u�'yz�N�v
-*
-��[��u��
-`���خ�/�
-���V�?Gf������]W�� &
-���x��a� �0)���x�.
-/CW�������H�]}���G
-i�7�x0)����:�f9 �72���9�L�v�|f����;*�PԔ������݌0�&<�`D�y?��g����©h���č���/$��x��a
- h�U�n�1��Fm��ӷ�d>!����:%T�L�Фڐ8H�;��l��C0]Te��4�I8S�|bozҤ1*Ѩ��Jϒ�uL{H����ZWn�F�R��b��y<�l�@����l�z����$�6�_T��y.�t���/��#���f +7�WL�y������(Ʈu�V�v��� )1d;KQ�l� 3FX�M3{_p�Q�rТR[}����îRF�d��)�8��bɶ� �O�V�� ))V������� kR��ё��+�6�F��#-��5�_+��5u-�v�lm�*ዴ��B͙!唞�d�_� �|c|�\�����c�Y~O;#�F���
-���EV� �o@F�\w0��E:f%u��F6
-e#��N�_գ��&76��=�$�,�����b�Z��sh�Ԗ?4������" O&��g�rnԣ��8&FH�0�Rt�D���� ��,��g���8��`�ٌI�j���b[H�&���/���B���N1A 0�w��^�&�M��P9�eF���-'F^2e:���sp��ė�@����~?A�^\��.���w��b��y�� �]?��H=X��K�!�0�
-i+z�����s���>�����hT�X��?��"�Ե���OσӺ�z���s���^X��'� ���vVd��k�C�~���8$� H��i�� �К��Տؐ8 ��y�;�Ak��QH.��V�İ��j��!��)���
-N�TU�Ǟ�� ��o���z"\�
-��)H� *'9�B^�>�b�^W�.8���@�\ '�e^V���j`����4�Y���κ9]o&a4� V�S�(��~bV;*�o8P�=�����//�� ���^����p�9���T3��/���&��7�n�� ���|%r�����G��4K:�CN #P�,�:R74OnR)�Am+ɍ��I� e�A�����n`������#�͂J��ܝ�J�8A))�����\%���G�~_k��WW=릈�.;ѸM?���2-v�I��0�V�K}!QI�ab3 �$}�9=�a*֟N|���6^Ĩ�~�W�RI�tp���������=��Q�tK�^I�4�� �U��:pj�L„R˃�Jv��M"��%sM��15��@�l�5�fV�%)�U� 3p�&��<`������?���?j�K�D^�7GO(w�� 3�" ]������⚇ %��`Q�̉�p(
-NXM�ܔ"� -`�����tj�1�+65���U ��(�-��`� �S�aV� L��"�-�Tm�bG�(`÷�\�[T��1inIm�Y�]�S��9a`ͯ��R�c�L�"ݹ�I����i�{V�L�"�/� ���5D$f��#%�E��rZ�ܬ��\&��0n�e΍�}�]8y�'�L�q<I�t�<��2�^�E/=���,U�C�'�8��|��'���y�jє�W���W� .��7��d�r}�ιќ\'��Q(�����H�*7�p�| EL���r7Ak�L̎J� ���`9���x/�����9Gb���Z(�uh��#FI�ұ慹���,�������)j��0�PS��t�았����}E@�{R>烁�fj.5�)M�i7n
- ��v#��1sR�Rw4W���W�� �vV��6{��M��k%���UFԔ�iPv�N������YPC��1�;�
-1�IK)� ��դ�JF����p���2*Vk)t�p���Y��)㼀5��؉IF�੕�w�qd����d�ZT`�
-ю=M��e��s�2q��)��b]��9_�]wМc���X����� _�@ �����=5��zu�x�C�sie�jj�,�Q����|�]����1h�ޅɦ���k�$%z�;m; E71G 0��IY�S���9�u����86p�>�) ��&kORH�#(��I
-�t�.`>m�sֶM8?�0�:�}�d�ѝ6�4�K=52��Z#�z��s�{w>g����{��6�vk�|�7]ˋ�[W }�� 8g���
-���E)LW��&v��b=i�q�-M���:��_0��c�g^�ԗlފ2�y+4����Ňc�<{��ȍk�S4�_��2'�6�r2������.���J^��*������Gy�O7ӰV��Ѵ<��&mſ��x�+k[�7[�cx�.�V��<����w�lh���vv*��^�ܣqÄI���S��/���Y�;�&��l�(�"4�^���ߝ-��#}k�ps�� B��Lg�� �Ӑ�5�V��` ����n�V�52x~QP}�3¶����q4q�9���7D����]"yԉ���or)Ӛ�Y-ȋx�@]ڱY�ɋ�"��*�Պ����^���w�h*�n?AW�:��6��g�q�=4�WNo�-� \U�FiU���͝=@4����g���f_ߓ(^]��@t��k7W�
-���eQ��t�9S!�Y�YoG�p~���n��X`��#,�5*I��G-2s�8���Z)�<�m�� l��۩Y���M�H�H��� ��(@�8d�����!{e{�BPyj:f�a_�#;ժ�{��������ɗ��I_ǡI�����]�S��8nfT�{H�e���+�S�̘�ղ��}��\tuZ}�|U���:9��ˋ�l�%�S1�},�D� K4�����H��� &��<�5�WP�̹��Q�����-�����^�o�R�K)~T_��5�rԞ����������a��Y�VZ�2,����+��KS$� �A
-P��~�� ©�,9��j�hy����j��*U� �n �[Mk�����rD���|�g�3Z��z
-]��K�Dt`�NϦ��]�A�7u}m�$r�n�2�5J��W,M���mS���W��whtc,���4�,i-%?���hr]���T�n)�8C�ul�0�N  ��.���Mz�f!g-�0��u�_[��+����I�;��o����Qc~A-�Ւu��7�@�t���[��稑��#�m�cN���[�ц�
+x��]ݓ�q�_��%Q�8��0�eJ��R�ߢ<�,�+)��ϕ��O�� f�h��KU�喼����ݍ������ի�^����|�����I���:9�Hw���N������<���I������oޜ�����<))��������͟������?I�O�ڌ�wO�J�?ߝ>�ޏW��O���������0�]���f��r\KO�tg�_'5����7�~G�u\-{���:����^�3:�������L<Zm�F�Q<��,pӿ?�������Ǟ�v�<m�=q��?���ٷo��۳ox}��
+
+嫼�Ţ��J�ެQ.S�Gd)��(WЬ��{09��U������(�V��a�I
+?|Jw �~5r m��=d<QH�:�B�� v�]$V ˜h��ٙ�����WPN +���J�V.�t�Enih �eQ%b���\O&�����Jպ�6�UK�U1�(���["0H-�3��^6�����%���Bi��m��K\0BEmlO��@X�b#۟#� �K`c�Ю#ϡ?0QO�ϡ?�FX��~ ��Y��U���E�e�rP�x#���`��/[��(@lt�>��i9��(a5,�9cM�*:������v�OӏA�f���<�I��[:zw9�� F���� 1v���'}`�+�փ0�9k}+`���u%�nd������(�\^)h!M��U<��K!%�ꮷ?y�u�^��:&��.�f��b���4\�ћe�Lq���r�PA ���F�q�M;,d�'ß�”�d��9O��-
+B��� � �[�bҘ��V�l�� ;R������.������Ƞ�w�RVSq�B�;�;�Be �[��"�bi\���P�Il�i�D ��� ��ju�ۗdN���!��͚E�|�ِ'9l�S�߿���g?���� ̰�k�O�K��x"�ݍ��r6Ϭ��
+��xFL��F+c�n��k��[L ���rM�
+|�{�ȋ$�9�Fy>�CQf�J��d3��'�� �#�X��Tj��usV^��J�s�� f�����T��H��(�7/��`��k��/��&�[b���w?�E�n����0A$��-i��r���Ę���)�>� rfE�{�U�]�_d�BJ ��RԆ!��Vy���\��B�E����)هݤ���&�S,q2�Y���^�����dM�HI���
+�~y���p�n^q�)�0�@���efr!��� ���nCNp~�P����v
+�:�9<�xR������q�����ށ�G�a���K7 {\��&#�`]�,I�D�4\���NQ}`
+�).w-2���:�#��ϑwf�_�<�C�{�Q�c��&ݣ�p�U����?=���R7�9c�{�TG��3�0���fVd��kP ���k_qD(A�R�C%��A3К��Տؐ; �iz�;�Ak�zRH.��V�İ��j��!��)���
+N�TU+Ǟ�� �bp묈&�o��$H�ܻ����f�e����b�^א.2 ��e���dJ�2�����h5��ys�����5�G��8Uo�`4� T�3ਙ�h/-+Z �4'�%���/)<x�~y����������<���� ���ŧRA&p�����8��
+*Y�|�z�T�?��0$SCm��Q���f`�7��>��a�b���(a�%C��5 �VAX�\�hP�N�Ӑ�E�[bB�]�6jR���sM��I5��Hm���;����J%D��K���
+-�¿9�B �S���r�Džd�W>L�(�
+��dNN�S��>��`80m�a��C&�Z���͏�s L��D 0=PDDE�*Z�iF��`:� fu��+b��"a�&.v��6���%�E�9��+��g�ft�F2A iu�E_*v���J�R�3b���i�<�V㋂��B�*"��1‘� j2Q�rZ�ܬ��\+�3n�ej����� '��� ϓ�H��j.!�Eu��cI�)�S�rt|���[��L~b6O;/]-S��s� 5å*�� ~��q��W�O�9'u����(�����"�K-P�����)b�� �� Z�gb�T:p��(<� =&}���_o�;����B9�C���, 1Q*Տ5/�N����yQs|Ю���ÔCEL������Wb��Z8P*v�;���@o35���2�bڍ��M�vZ�4]%D�JD!Ay�n$�vfN
+܄�F�#q�J���CO��J���!b��<0���Ü�9}e�냳�w�
+(�d&��$Z��x�H�� i.�*���
+܌�+��� �}�o7�{F�j�hl�zYq��*a��Z*f��wѮ X��.�l� �1}���\߹�h;_8��4��߲j�y���3\�~�\a�S|ᇶ-���\��%�q�,�!*�d��{���˭� #h�V1d�kS���zr�j��}�v�A��q{*`�r`J�W/|�1p�'G+p{jF��J��j�������Y�.���Ǖ��hK�*c��I�M3)R*�w�%��m3 EK1G�ej��R�����sF�8 d��qL�^{�4ڲ�L֞��RGP�œ���!\�$&r ��|m�d~�aV�L�Ŋ��k6(-H.�������M9�9�e;�3Dq��]���7���s��hT^d�z��S�K�s
+Q�w��3� r�w3�dх�� �횤B3��*�z80�SE�mܸV:�N�e
++�aj�.'�}]��rw���,�P6���3�� ﹙���w�z��T�I[��)^$���]�Z��Ʋ�;9�����+���h������'�h��`R0}��ዙ�y�⎪�/�9�"WM��ש'�w�F��H�ڄ!��`��g�銱D���4�rM�T��f�3�O��m� ϯ%
+� ���nwM��Fi�� �[<� �<��#����9L�V�9<R�vlD �Y�]e��Z�P{A�+�B�;��NMe��m&�U�����#������M��4���C��6�l����D�xz�|Nj7p&:��]���^� D#��i���p&��qH�HPm76�KJ���0N�_� I����07���
+�y�;���!y*�l�!.�  �s��/��c�jV6�X|�t��g��
+�C1��9D�7��O�S}�i��^|md+:��8��FO�%���F;�g1>PR;' �`��컲 ����:�D;��N�-`�Ѐ��^�F�he�M ��4a��>L#ɪk��D��w�����K���/q����A�X�"˞\����#�F&�q& ?���K�D��"~��n�o_�ar��u�v�7��
+؂\q�P��B��� ^7~+�;���\-Y�y�zs(PԉW
+��K~� !=��>��Ƚ�L Īᤌ��ew7:!�DLd��C����^5��� [�ˉ�H�֕ �!���A!]ƻ���w�(����=��uL%��D��&�p���qM�W���� �K|�R<�)��p5ʥ��Gq�7Ԃϫw�c8��T�y��̤�Q��a�n�yPj)���Pjb^�qQX�
+׀Ce�s��d��G������a�Z���fy|�cS-g1���������X:b�� t͢�v�̿]��.oML6�����SQ�dqcQ)���uM���Lq�QL���es�>�,�dȰ��dMXœӝ���`׭)evrV�لuc���?�u�h
endstream
endobj
-272 0 obj
-<</Length 5389/Filter/FlateDecode>>
+281 0 obj
+<</Length 5457/Filter/FlateDecode>>
stream
-x��=�r\�����!��f(��_��dcY�fc�*e���`�­M�LVa*��O��9�os�H/���K����������?�~���ݿ����o��_����_|�͛��3;�ӻ;��V�h�����J6�{���{�{��N����V~�ϝ�}����NO���������^������d.fU�K�b.�����O1WpvZ��sE��D���,����I��I;�i:畋N�O5�I��ry���ǧׯ�{��ov�������?=���Re����ӽ��N��������vz���������������O����Z��o��x�=��?hg����W{�j��6����o����x��X���;nƍ+��~\O?>�~������j�q�N��hXH� �����;���e�o����t�
-�t�{83W�uC�r<*�����n�g�������J��gZ�$>{u2��M�Yz��u�#�_r�~�Qn9���3-߲�z��=�)F�8��c|k��o[r�A-�S{�����?.u.v�A�X{)f���k�.��C�"�pij���:�vh���f�x� w3���aY�Y# 8cTH٥���1�7YY���^4sR����T�2�+�=L ?�%��C#F�; � �%��r�nU��l�ʇ`�
-�'��/�t��Y?����'�J��P�
-�� �<h�F���ΌS�6�L�hw$lxJ*@��n�����N���/{
-бh���X��f����<A�j*N&�) (�҈!v��A��s4.���g
-=�C@L
-,�����[o�Z]�0�\d��ACZ����}��`��?�
-@hI�$�t(��'� �,z����;cE��/i7L�9Y����o��C��
-�kE&�敨��|LqC.tW>�(�6�BlN�J �D~�=w���Q����KV�A��}ɫ��w�1��9��w @}��h D'�.9�80�f(;���\-��nm);���w/�P{�̻��˒���JT>�-��1�[7A�*�lk��ƍ���(}=<��;����H�9�Oa1d&"̻�:�N(j�P �1S��D-+��N&G��X\4SP�(Ay SV��K��@0��]U�O��8aA�1\���'�2 B5��(�fl�����i`3��oyp�$\�U>��Z����k��y�a�)'}v~
-<�g�@��c
-1:�U~�o5w�n_7�6Ko�t�����\O�dEs�Ȁ���A�Ao�c�]7�y7%4:�Pk1ʖ)�o�� ����
-�9��b߸w��߀I †aKP(�%S 
-)��#pL���쏧�Xz�37ΨRJ�5� �ڈ&� X�����$%X㔍Ů~�廚�Ėj�Fk�_�o[^2� ��]�%�a�Ʊ�L��Gf�/�M(h�M�l�xT,�H]cW+gHQ}�w~Ȗ�`>������9�B;=$��)9�v��Hg��$얜nAG��YL FQ�P�[�Krw�R�M6�O ��r��=U�u���}�~��k�ʙ�X��ڤ�<�kJ��鯰�60�_�J1=SlWF�,@9��(t��ֿ�؞G�
-I ֱ���2�a���.ܛ �sJ |w�d��yRV
-�qE�.����N��lrP6E��0~�'����~f*�=F�v'�|�̏�
-(?�E�}�+<@SN��M�4�����
-��MB;�#�����!�E �k1`�ߏ�TN�f�C�FF�� �������r!�p�z;\*�օ�w�. e=ėi/܀������J�Y�l\R>������Br*�����ְ���G�ԝ~:��.�Hz^�ٱ�A�+DQ�%�
+x��=�r\�q���!��M���V��j��*U��[����L9��m�)���uf�`���9#�upit7}C��o>=��᧏Oo޼���?���?��O����_}���gٙ���ݝ�E�\�V�]JE%���}���G�{��N�~|��;���o;�{����N�SE���>���<{������\̪���\^G即_b���.�%�V��`a?Y�).��V%�vz�t>+J�b�i�L :}��b�J[�v}?����7o^����wO��6���9���;�����g�}��݇O���hvN��_~�ϗ��Z�^;s�m�������_L?��p���߿m��� }7�4��7���_���@������q�o\��L?�����o�40�( 6�߸�����#2,��nlV�g��^3��~��7����.q�C���;�_��j�
+���Cu�%�N�np��8�7�m�+r<���?=���?<�H��EeB�5K�0�b�}Ķ���=����W�<t��|�_{��~ڈ[�~5���~<�2�9S�f%g6�D�o�n�\JG���ͻ#�S��*\�P�C�
+��}���_a&��*S��]��Y�ٛ���f�!U �� Zy�}|I�T��U�U�cⱞZ���O3�e�f�:w��
+�kBk�S��g0w�C_1��T��W�F
+�E��'�q���H�$X�Mr̻���)��P%��M��Х���}��d�� f`��!����T��{�Q8�v�%�K #����ІM��r.�m{a`j|}/Ծod�I7%(�;�� pb��&Oy�JG��æ�5A�0e�m��~s����� u�@�֍ Q9si�� .x�ئ�����}�P+8 l/�JP~%4���I52q ��p���E�>� S)�L@NoK��i�8����#G�rVEV�_ ��F�tVWxUz��k�}70��(ʓ�<�O@EB��,����� Msb>�H��L�È�},���z���k�(��C���J�@�h�.�U�-F���)���[lѕ:_x��#"#�;e�t\m��2O6�[E��3��ZOWڹ֝^ߎ�
+��ۛ��/n����D��Oȋ�g�7�k�P#��#9�e����DFa����EKqLY�"Z˙�!퓡N�$�f�-�»�#��UO�0��#�
+�1���uc�G�G�?<tw�'��Ā�s�l��<gLX��r>/U�o�iI&h�b�¹K�� *���NZ���?��d.��A�!6�Ž��xD`�0C�� q�T���}�Qb2R(RVJz(���� �����ε5�ta��Ȧ����$�s�������6�0j,�KL���#J)[��b�n�������I�^��������l�"6t6��� ��a��8�8@o�4�,�/��T�C�o����Jd1~�,t�)Lc
+���~��*��.��۳S=�87U���v�=WK8#�+7L�Q.����
+�k(I��"5����g$��('���lv�(�E
+�}��g�u8���p����%�̥)S�����Z��Ϋ�K��6Md?Q{f�Bk�n�Ze��� G�-���atФt_�+��l�!�eP�*���� �"�>D�)4C��t��G��5��
+�
+Dm��a��RO#�ܰݕY(��kP8J��[��
+@f��� ���
+W���:2iV�>�cQr��2��(>�.�]նZ�¶u��t�N����vJ�����!�Y7�(fu�D�\��Hɩa�S1G���s����*|`S�jա�ඥO�dZ4�hI
+_�4t�:f��uӝw�NR��P�eK�y��+��v�
+gJC�r����ݚ�D�Pj��߈]�� ���!��%57��lq�`��Pl��P���$��g��I��1�N����� Ӭ�p��+����0"G_03­�K 鲫�A��EtAb����&4Q��R>�y�����7����7`���fl ��Db�o��53���EQ�Ws�2ʁ}*� 8C�
+'�m�֣
+�W� ���7l�uN,�r�ϰ1E���?�^A�_��Li���X�ʀ�hRb>���;�@Rn��Vm���sX�2��(cM���`�K�#�cs�m�'P��q�,��呙� `j w��8E3R�����IXT_����%���+o|����u{J�J��4��) {(�N*�dG��b*60�*��J�\���Ĭ��i}=�m�K�c#ܘ�V��i
+z �Sd��5%f�� [�I�A/t����t+ #���?a:��M�ib�Ѝ�re���HW3}�ΰh�r�9�L�;P��iӼ�Kt�{�"B
+h��kɒ�l�WFg�����KK]~?3%̎�#j��!
+P~mT��j?
+��>�E�}�+�>@SN��M眻����
+��L\�pQE���[�1����Kuli6 �04hd<����ߞ��  Ǫ��աjd]�G��P�C|�����(~Ϩ�]D�FO�hX6�]�0$�R(�im /���p4J�駓� ��Y�$�5?��س�B ^���
+EecX~ֹo��r��Po��㡍��G-g� (=Ե|��>��p�8\[�j�l�=6�� a�m8��`0�vZ! ��U�9�-̺����f~�J��i���3?+�U ʸ��K�):ӳFi�#��h��6�8�]/�`cF߰����.I� s��u����j?�����m��r�ش��z,�FS;X�b�z*������ES�H��L?�l�p4��H��56�j_�z|yMN>�z��:.{p`�����9�)��΂e� �S�ק-��co5/��}��J��E���4�<(����t;tи78�=�
endstream
endobj
-273 0 obj
-<</Length 7164/Filter/FlateDecode>>
+282 0 obj
+<</Length 7310/Filter/FlateDecode>>
stream
-x��=k�7r��+FkY�z%��ǝ��K�Yg; �oq>��(@�\t����t�XUdw���6�b�Xo��������W�~������=����:���w?|����A��9D�\�V�CJV9�������]~��A����������W��h�>\{O����?��������S[s��������������{�ٛw���go~��U �i�3Z+k�վ�逧u��2F�O{u�`���.`;��oZ��C����/� ;����
-Y9��v6p�q٨�W��sʚ`����h���O��@p �OM߹M �#\����$��co�s�� 9�#��0i<����d3�B77�P�����<��� ���lg!�
-13������ae8�y�.�Y��$��r���=8��3�LcۭIQy��A������טCC���R� uw0�v9.s׈����0n�9��rx�?p�|���wx��QȜVa�4�t>�lr4hYyAP��a����_����?������6:��g��U�D#ζp t52Z��p_ �����j�l�]`����+^|����ݳ(�5��s��P~
-4
-��2�{�<��@[�=��+�T{�O�B�2�cm~k�>
-���Oذ/N���ְ+ {��G��ύ�#B� {��@h� !�����[�л^`�o X�Z��46[�(�3�B��r~��od"���m@�����K�� ��δ�4�"lwh�
-m�Q�NhȪ ���]�D����bj�a6GU\ȡOL]c�e�F�#Z{�-I��~j�n�)c#�d�\ˉb!x m����p��ȏ�؄�vc��+zx���!m�(�WΗ�HZ������?�Ʒ�>6@m|B+d�@�
- �^f�{J�S�j=���Fq�F��:Yũ���BI�BQ+�vwN���$������5�▍Kt��0��`#���Px�_��Q�Yz�Q�9y� ��+g�$�t B�N�f_����N�1��ږ��)�H����?L�PkPv�O��x�|���™Z��sZ���z�Uۜ"D�i�z���^l|��r 1K�n��#�5�i�t��TG�㈤!|�ۺ� �J��r!��w�ޗ�d�]0��ݼ(��(�9���
-�@w�d�*�X}ӂ�?���ik���n�y
-�rg^�a�$��J��ƍ)�g�A��L{5�,i@嵢i�Y�B�eMAB ���������W-w�I�)�oUT��EC��W.I��AVB=
-��T��t�MV.��ŕ�ܩ> b�񑣋��^sR��\@�|��
-X #yW�d��7H���,��g����+�����qȊn&U̥+{�xAQ�p�4�`17���c!�,?h��:�2�֞wda���{�xLƧӷ�܇�ĩoF��o�Y���l�}�}(��}��������]eDd�J���m�]�Y�����SA�|�c:b~�D��J'��n����H�Qu��G�g>��$͙�R y�U����/4��0�sR��4C�q:�+���m��R��"ج�C�H�� N%�%d�Bt{.1.��#H�v�d�w�ᰗ��.�фkǵ����ɍ�{�T䒍*ELjUV����?�C-���ӷº�H
-��׌�4���
-q��<��ʦ���� 4�� �2 �~V�j���ŴʚwY� N/����
-����z3�jKſ��D%o�ƣ�@��~:��8i{�~��M� Y�n�3)L�8.hdHǯUւN��n�e?�"���B}x%���� "�(?gg�j_�^�T����F �W�$�S�s�� �ϐU�G��x��%er)���+�c���z֧� ��X�O����1����ck��.����ߋ��n �Em �c`Ǡ��vi�ђ�Z'��� Ay �p��
-�^:p�9'����{�,:����p�@8D I3��/�S��`�1N7���Fq�Xo����D��;Q�� N���q�"���)�ڏX������_[�IZ��k���l�k�%b������݇qH�t^E���U� m ���phm�Tyl��s��̯�� 8��l
-��h��O�� a��G~J�l0*��QD\K�����s�c5���� ��0� ��p�e$����G���p@��)����8Tv�㠒'��-1n��(Cz��i���{w��K�
-!*��k*�MGQ\��-1󙤇D\Ѫ��+��v���mF�mP]����K�חcSP��Nƣ͙��Ch*�8*,U���4���񧪊��@!0"�͍�=4^I��FÑ�4����6|����r,Gf$`��:�G�S��ȟ�bo�tڥt8��*��Rj8��>r�8���Ǝ��Y
-h ��� I��f�<��-I(���|"J �Rp� �92�v�ty�e�AC�E<�����@hB"b��T"z?���'K��}'�CH�����fw�sd=�k�j"��{ue������6��8�
-&Cc�`
-�C�
-�R��| �eĆI/`�E�ۚa�����իȟ����NY�w��Z�Јa�!J��i7IS
-#64�|�b9���j��G�L��:p83B��d�!�� �?�JZ7�܊��3 �g+�:ek�$ �J���@t�MV�1������[{E�����o���m��5��G����>��.VLtY3�h�³���7����OrW~���(:����4�g��Id������:���1DZWNTۥ���L<���*!܆n� ��B-�G��f(���Nx1(5N/+ }�<>����G�hI��>�ʮ@ �u�e���=��`kP�Y�0��pT§y1j Y ��84S�O�� Pw��U򾸑��`۸�5<$���V�~�����恢�ZUܔ4�i���5@'��/- �����
-֤����^(h��~��V��KN[ec���
-iY��~����POA�'4"!ݪ��l�>dCl/+]�\���K�N�Qj'l �iKI�B���ʕ���-"1Do�7�5��V9��?ɮ
-oJ❟�
-��HwI yO��yI|ɝ�!��H�)Iy�C�^�˺�`<|����K���Sa8���`an�*Ih{-v1T�cU���T5Ǡ��f���e���d(�[���L(� �|H�����5�e<�MR\;�I�w|�KJO��H��B��npˆ�x~�C�]+Η�I��Ta���֎ݱ��v�ђMf*��n��t���v��O�dMJK%|I��m����W '>���l���������|�[����5|X=�
-��h����5Sc~՞�X�F�E1n`�/��|�8l
-�FnSi���8�O�����&�}��Ex����h�qN �BM�pPQ���8`�`�H��ӑ��8b&Asla�p�/���Yʳ�t����D az<q�nd����:�c�Ŧ���a-�����~��2hG����.�S3 7mD��R����9S�J��N�g%M҇l�:�t��ޙ�/!��y�?,�2U�I�y�ȱMxY���nn0&[�;`5*rM���S�+w� jF��.8W%����^
-��*_Ʃ
-^T{P��Z����n8��#�K�P��q��1_s@�%>+O�P���؎�Z42�)�j���z?�F���J F8�D�b�|� l�_U��ud\r�$�|�{����d�Jg���ٔ�c�P�|�f�`c�\h�lp��� �.ή�`����]ف���+��;l[[�
+x��=k��u��+�W���+Q|��8VlGu�,��[��Q(��V��G1�;�<OrvV�-|���������߿=~�ի_����������������`/�!{��6J�&������o���?����?�����~x���5���������������ڿZ�����>����ן���m�}6��!�S�e�pn�v�9lȰim]hۋ�O�Z+ͺδ��V�����>�&a�k�e��06" P���K<�;�5��)���<JB����p���|m�W���`]X�M�~��*���a�-�]���DWQ�i�V�������7o?������ݫ��8���jB�R����<�s\Ѻ����������� ��fS�-n
+d�B�q!׸� ��]N�ʐ�d��(�d��=l�r��(��~���?���{��B5)e�����BZ0D�s��А5�'oc�����qΦ)����߳3�Aj����t�L�8�C�Q"���f�{��Eh��|^:N ���u]�za��"�P"扰��7�*׶��)�X�Lxʎ.;v�� \����X�3Epd~�a���
+Ժ�}1�ZWn@�|
+?�s�����'`�Qc�]��K�h"Ʋ�-��#צ�v�6�|:���Dg[�
+�@|R����H� �$͞l���ֈz,����:@���TS��&պ�qܵx�RM ��-�tQ($Q8�;v�A 8�n�d����|˂�?��w����"q+€���μ�ʖi�3��q�$�S@�*�"�Ѩ��8`x]҈��Y�TM�\ڡ�b��'�|� ������$�T�)"����!Z]+ ���ABB;
+� ,&�q�!��q1�dV4���1BI TN��j�I0�y���1 �Ua���\��f�&m�5�|~��aa8���q"4�rN����4������{ʡ'��(���vt�Y1Nz� ���,���Z�2IM�������U�5��M�9��ױz�"Z=�ȓ)>�x��N1�d���ut�ދ$с$���h��R����������99�nY%dI^"��87�m�K���2�1�8}4u*%����Ϟ�pKwx)����W��aP�j� Ȑ�����$��X����'H��ʼn&
+��*�I/4��0UJ��8EM� [����{y�Ga���<@=� *��nBqj�@ ��.2�l��FL6�z'�q��o�E����\1%�2p�u���>/!�28��C0֕+L��m�K��R��*:|�V蓱��tr�]�G��ju2>Y����k~ ��C�R �mm[mA6�@�Q��%�����r��n�!�wU�G�f9���,���=�'v'\��ӂ�ح���V�����'�SXc�_���IN*��r���Ѩ�v�o ;-�j��&yJi}�|kX� ��K���-������n2��=�%~�c\��Z�'gj�
+U֊v�
+��#�j�dqn���T�Ь;l���U��Z5W`(�x�7��z�i M6�!7�����FŅ�‘F��~��C/BO��VK���w�r ��k�}<����dJVƼ�8RH8����� ���92��@���ݙrx�|0��4�La�\ޢ���d�q1���5�x�
+'�:�ѠI�n9�]��4�o 1~��>rio��;i��>��7�X��wr��d .���0�a��]
+�W��xRz(�`�v8{W�3������`���u�``  빅� \Rkq�w�rA��a�Ը�F��!3�t�U6xa
+� �g��(\��N<3xA�'^Q>b��u"���6�%�7 ֧����6�S01f����C���Sj5>�� @8����I�ej`�ow��o��#5�jJ�Sy^�����YFO���r��D\mqn+`1:q�f
+�|2D��@8%%��2��T�3�v�&yWn�������g[�'mI������nsH@�w���U�);����'W��Ͷ� g Ԋ�J�wHO�F���1�/{��4a�ʞ1��� �YR��0�5��/:0�$�dSɸ VX�\��} M�]<Y����P�:�<x���`���)��^�I6/�+�d�k�)�M�K���>�n���!��g�R�:(���
+h0>��� R)M��،�}21�O4�N�� �a2�MS�.���LR�Jh�F�r��\�gn��1��
+�@�Tuf���A�-�{��H��{�~��~8�M/��§�U�{�J�ؔ�u���h���9SN{t��Ѩn2�Zg4Q�T�����bz����mʳT/�Z�n�h6Y�����p�~�V�V�Qc�V��*5u D��Q6�-�+W�Foc/��� ��WlP`��B��j�=7���>� p f�R�-����
+U���y;�9j!ws �)հ{�� ���!r�3�ޚ�B��d_����Q��7��ݨ���tq>���JQҾi�3����i����B$Q���[�{N$%Z>��5 W�7��n1������"�s�:�Hɬ�'�������m�RHU��]�L�e��K����T��R �N.�u6�[I�f�-��Z�}S^C�-䇙Q�+FNAY�!P@}��ы0Fz�-�2֒�����++qi2�
+�P���L,�z�Q&�k�éh�sB�a2%�\H��2E� z�+�3P''�v�d2"�H@AW��������h����6|'/��O�vJ���?^�T�8FjBMq���U����ڊ�qL�G0Ķ:�%��L,qW�^bZF���yʓ�3�Ԡh��h��X�&����_wI�Q��ee���l��P�������G��ͻ���w�/��k;��A�� K{Tu��K������z�80����0��x��þǰ��e:ϼ�e'��T�����x;���y�o�AJ��,���=��o X���ʡQ�+��Y��8C������Zqm�qp��zo� pum���؃W�Rg�y���ٰZ��&���j'n؅<�n�w����"ܖ�~��8�Z9����F�}h�q�7$r~�[��� 5|�<������ ������<~���u�V5��Ql�<�d��$5
+�Qk�A]
endstream
endobj
-274 0 obj
-<</Length 954/Filter/FlateDecode>>
+283 0 obj
+<</Length 1691/Filter/FlateDecode>>
stream
-x��XKo1��W�R* �k{�J}x�ȍrh#©+h��������3qR.�f;��7��;���;?��^}�f�����j��I&�`Sɬ��*%,sNqm�d���R��3�yٍ.L���l%�ܰ�j�{�,�� !�n������N�wk/b����U��T
-ŭ�FY�G�~�6��o���lE7��Q��ސV��iV�ZR
-�E�@�pm�h������[�\����[g��J�ؐ�c���P�0%;��X[�� T��&4��i��Z������y�~ǎ�d��# �1���=�j�ávC�G�U8]`��`��
-!C�\�,>����:�<0�
-r�
+x��ZKo7��W�S;���⛻E��S�E��[�ClT=Eh�k-)�p��Z�� [�yq��pW��y������O��|������F5���R5^ 㵖� A �j��d���ׇ�������q�����5��au�Z������NJ�7���~�=,�^ eLg�;� Kb���=� ��h�K��>#�AE �Qj��+=z[���e��n��h�BVqn�L�_GLy 8F9a�������>|�Y�1���1}8�N�մ²!�bp��.Ra�T� B��+�뺧�w��C��N��%����۰*FX�(������ �Xe�sV?G.����c��T����ByS��ֈ�f"��$�N���v<M �\+��?��F�d��։�w��0��uS����\���g�,r����
+�H~�L��4yZu�,���|��2� $����"w�ۃ�ʒqn�x9�Ã�;�`~�L�b��l�
+g0/�����A.�~Y�ɼ'�M��N�_p��1��5�%��%�
+㍴'4B3R"�bחʋ�{���99��
+�D�b j\�A,�v���G�ްTx�%�(-�e�H"� �z�8��o/�|�f���1��*���-��88���%mK|�
+�)�=��0^�g���h_���rJ\$8�K1�"�L0�Z�eí�z����,�����j�nk�3�CӁ�d���M��Y5%��<����BH���1[N�����u���߁���i��4o3h��;��@W��`�i�ssq�{���l�p=�j�#�&/>ʼn���@L��N(�MƩ[U���ux���ZC�q�͑��=φ!A�􂄞��R�0�Ľ˻(�]D�Ѧ. ���:Ι�rD��0=��2�LW;�l�6n�k��x/�i�4s��%P["q�hC�^�s9�� ��������� �׿|�f,�H�(V~y���9�N�±����n�� t<��q,�!QW`A~�A�c鯖��<�z`Ħq`DKkH7�7i'#��3
+ٳ� � �O(�|վ%�֟�� �vBI����o� -_�
+��;*o��_��m�h���6�
endstream
endobj
-275 0 obj
+284 0 obj
<</Length 258/N 1/Range[0 1]/Filter/FlateDecode>>
stream
x�u��J�PFO��U�v�D�D@�`]\�
@@ -1103,7 +1129,7 @@ F��Mk�I���R�B|��&إ�n�ऋ��(�H�r�Tų��9�`�� ըa�&�ʺ���:�l
̵�8+�/<����a�Rkp��ش�A�mW�Q�Ih�� �%��l��E5VW~��d���X��)�ϴ�:׺��b���k#�&�_¤ 3�0�� �I�
endstream
endobj
-276 0 obj
+285 0 obj
<</Length 314/N 3/Range[0 1 0 1 0 1]/Filter/FlateDecode>>
stream
x�}��Kq�?�U�X 94%MQKS��N�#Ԧ��Q�v��B�ˡ�h�Fk ������!
@@ -1111,20 +1137,20 @@ x�}��Kq�?�U�X 94%MQKS��N�#Ԧ��Q�v��B�ˡ�h�Fk ������!
��0l+��ߣ�y7���;�׫���;Q�?V.�_�tF��3L�E�K�)y ��z�80e�IP���k��T�/%[�p
endstream
endobj
-277 0 obj
-<</Creator(Typst 0.15.1)/ModDate(D:20260802002740-03'00)/CreationDate(D:20260802002740-03'00)>>
+286 0 obj
+<</Creator(Typst 0.15.1)/ModDate(D:20260811182720-03'00)/CreationDate(D:20260811182720-03'00)>>
endobj
-278 0 obj
+287 0 obj
<</Length 996/Type/Metadata/Subtype/XML>>
stream
-<?xpacket begin="" id="W5M0MpCehiHzreSzNTczkc9d"?><x:xmpmeta xmlns:x="adobe:ns:meta/" x:xmptk="xmp-writer"><rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"><rdf:Description rdf:about="" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:xmp="http://ns.adobe.com/xap/1.0/" xmlns:xmpMM="http://ns.adobe.com/xap/1.0/mm/" xmlns:xmpTPg="http://ns.adobe.com/xap/1.0/t/pg/" xmlns:pdf="http://ns.adobe.com/pdf/1.3/" ><xmp:CreatorTool>Typst 0.15.1</xmp:CreatorTool><dc:language><rdf:Bag><rdf:li>en</rdf:li></rdf:Bag></dc:language><xmp:ModifyDate>2026-08-02T00:27:40-03:00</xmp:ModifyDate><xmp:CreateDate>2026-08-02T00:27:40-03:00</xmp:CreateDate><xmpTPg:NPages>5</xmpTPg:NPages><dc:format>application/pdf</dc:format><xmpMM:InstanceID>od6Ce8g5ofbkk30tkgkhhg==</xmpMM:InstanceID><xmpMM:DocumentID>od6Ce8g5ofbkk30tkgkhhg==</xmpMM:DocumentID><xmpMM:RenditionClass>proof</xmpMM:RenditionClass><pdf:PDFVersion>1.7</pdf:PDFVersion></rdf:Description></rdf:RDF></x:xmpmeta><?xpacket end="r"?>
+<?xpacket begin="" id="W5M0MpCehiHzreSzNTczkc9d"?><x:xmpmeta xmlns:x="adobe:ns:meta/" x:xmptk="xmp-writer"><rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"><rdf:Description rdf:about="" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:xmp="http://ns.adobe.com/xap/1.0/" xmlns:xmpMM="http://ns.adobe.com/xap/1.0/mm/" xmlns:xmpTPg="http://ns.adobe.com/xap/1.0/t/pg/" xmlns:pdf="http://ns.adobe.com/pdf/1.3/" ><xmp:CreatorTool>Typst 0.15.1</xmp:CreatorTool><dc:language><rdf:Bag><rdf:li>en</rdf:li></rdf:Bag></dc:language><xmp:ModifyDate>2026-08-11T18:27:20-03:00</xmp:ModifyDate><xmp:CreateDate>2026-08-11T18:27:20-03:00</xmp:CreateDate><xmpTPg:NPages>5</xmpTPg:NPages><dc:format>application/pdf</dc:format><xmpMM:InstanceID>JCSPa/4Mr2ZKVhRZ6582Sg==</xmpMM:InstanceID><xmpMM:DocumentID>JCSPa/4Mr2ZKVhRZ6582Sg==</xmpMM:DocumentID><xmpMM:RenditionClass>proof</xmpMM:RenditionClass><pdf:PDFVersion>1.7</pdf:PDFVersion></rdf:Description></rdf:RDF></x:xmpmeta><?xpacket end="r"?>
endstream
endobj
-279 0 obj
-<</Type/Catalog/Pages 1 0 R/Metadata 278 0 R/Lang(en)/StructTreeRoot 11 0 R/MarkInfo<</Marked true/Suspects false>>/ViewerPreferences<</Direction/L2R>>/Outlines 10 0 R>>
+288 0 obj
+<</Type/Catalog/Pages 1 0 R/Metadata 287 0 R/Lang(en)/StructTreeRoot 11 0 R/MarkInfo<</Marked true/Suspects false>>/ViewerPreferences<</Direction/L2R>>/Outlines 10 0 R>>
endobj
xref
-0 280
+0 289
0000000000 65535 f
0000000016 00000 n
0000000101 00000 n
@@ -1138,275 +1164,284 @@ xref
0000000840 00000 n
0000000906 00000 n
0000001109 00000 n
-0000001771 00000 n
-0000004169 00000 n
-0000004955 00000 n
-0000005909 00000 n
-0000006007 00000 n
-0000006078 00000 n
-0000006139 00000 n
-0000006206 00000 n
-0000006288 00000 n
-0000006361 00000 n
-0000006435 00000 n
-0000006517 00000 n
-0000006589 00000 n
-0000006673 00000 n
-0000006745 00000 n
-0000006863 00000 n
-0000006933 00000 n
-0000007003 00000 n
-0000007148 00000 n
-0000007216 00000 n
-0000007288 00000 n
-0000007406 00000 n
-0000007537 00000 n
-0000007605 00000 n
-0000007733 00000 n
-0000007805 00000 n
-0000007875 00000 n
-0000007945 00000 n
-0000008055 00000 n
-0000008123 00000 n
-0000008195 00000 n
-0000008265 00000 n
-0000008335 00000 n
-0000008405 00000 n
-0000008475 00000 n
-0000008545 00000 n
-0000008615 00000 n
-0000008685 00000 n
-0000008839 00000 n
-0000008911 00000 n
-0000008983 00000 n
-0000009083 00000 n
-0000009155 00000 n
-0000009225 00000 n
-0000009295 00000 n
-0000009365 00000 n
-0000009435 00000 n
-0000009505 00000 n
-0000009575 00000 n
-0000009645 00000 n
-0000009715 00000 n
-0000009785 00000 n
-0000009956 00000 n
-0000010026 00000 n
-0000010104 00000 n
-0000010224 00000 n
-0000010291 00000 n
-0000010406 00000 n
+0000001820 00000 n
+0000004250 00000 n
+0000005044 00000 n
+0000006086 00000 n
+0000006240 00000 n
+0000006311 00000 n
+0000006372 00000 n
+0000006439 00000 n
+0000006521 00000 n
+0000006594 00000 n
+0000006668 00000 n
+0000006750 00000 n
+0000006822 00000 n
+0000006906 00000 n
+0000006978 00000 n
+0000007096 00000 n
+0000007166 00000 n
+0000007236 00000 n
+0000007381 00000 n
+0000007449 00000 n
+0000007521 00000 n
+0000007639 00000 n
+0000007770 00000 n
+0000007838 00000 n
+0000007966 00000 n
+0000008038 00000 n
+0000008108 00000 n
+0000008178 00000 n
+0000008288 00000 n
+0000008356 00000 n
+0000008428 00000 n
+0000008498 00000 n
+0000008568 00000 n
+0000008638 00000 n
+0000008708 00000 n
+0000008778 00000 n
+0000008848 00000 n
+0000008918 00000 n
+0000009072 00000 n
+0000009144 00000 n
+0000009216 00000 n
+0000009316 00000 n
+0000009388 00000 n
+0000009458 00000 n
+0000009528 00000 n
+0000009598 00000 n
+0000009668 00000 n
+0000009738 00000 n
+0000009808 00000 n
+0000009878 00000 n
+0000009948 00000 n
+0000010018 00000 n
+0000010088 00000 n
+0000010158 00000 n
+0000010228 00000 n
+0000010298 00000 n
0000010515 00000 n
-0000010633 00000 n
-0000010703 00000 n
-0000010775 00000 n
-0000010845 00000 n
-0000010915 00000 n
-0000011029 00000 n
-0000011117 00000 n
-0000011185 00000 n
-0000011253 00000 n
-0000011339 00000 n
-0000011425 00000 n
-0000011505 00000 n
-0000011591 00000 n
-0000011679 00000 n
-0000011764 00000 n
-0000011857 00000 n
-0000011954 00000 n
-0000012009 00000 n
-0000012078 00000 n
-0000012171 00000 n
-0000012336 00000 n
-0000012421 00000 n
-0000012562 00000 n
-0000012671 00000 n
-0000012812 00000 n
-0000012905 00000 n
-0000013006 00000 n
-0000013061 00000 n
-0000013234 00000 n
-0000013416 00000 n
-0000013542 00000 n
-0000013796 00000 n
-0000013869 00000 n
-0000013942 00000 n
-0000014044 00000 n
-0000014124 00000 n
-0000014197 00000 n
-0000014274 00000 n
-0000014376 00000 n
-0000014451 00000 n
-0000014572 00000 n
-0000014647 00000 n
-0000014768 00000 n
-0000014882 00000 n
-0000014962 00000 n
-0000015090 00000 n
-0000015218 00000 n
-0000015354 00000 n
-0000015434 00000 n
-0000015562 00000 n
-0000015690 00000 n
-0000015818 00000 n
-0000015898 00000 n
-0000016026 00000 n
-0000016154 00000 n
-0000016282 00000 n
-0000016362 00000 n
-0000016490 00000 n
-0000016618 00000 n
-0000016750 00000 n
-0000016830 00000 n
-0000016903 00000 n
-0000017024 00000 n
-0000017097 00000 n
-0000017218 00000 n
-0000017348 00000 n
-0000017428 00000 n
-0000017554 00000 n
-0000017680 00000 n
-0000017806 00000 n
-0000017886 00000 n
-0000018057 00000 n
-0000018168 00000 n
-0000018240 00000 n
-0000018312 00000 n
-0000018386 00000 n
-0000018458 00000 n
-0000018530 00000 n
-0000018602 00000 n
-0000018674 00000 n
-0000018746 00000 n
-0000018920 00000 n
-0000018992 00000 n
-0000019084 00000 n
-0000019156 00000 n
-0000019235 00000 n
-0000019307 00000 n
-0000019379 00000 n
-0000019451 00000 n
-0000019523 00000 n
-0000019598 00000 n
-0000019670 00000 n
-0000019742 00000 n
-0000019897 00000 n
-0000019998 00000 n
-0000020072 00000 n
-0000020144 00000 n
-0000020216 00000 n
-0000020327 00000 n
-0000020437 00000 n
-0000020512 00000 n
-0000020595 00000 n
-0000020669 00000 n
-0000020741 00000 n
-0000020813 00000 n
-0000020885 00000 n
-0000020957 00000 n
-0000021102 00000 n
-0000021175 00000 n
-0000021246 00000 n
-0000021317 00000 n
-0000021388 00000 n
-0000021460 00000 n
-0000021532 00000 n
-0000021604 00000 n
-0000021774 00000 n
-0000021848 00000 n
-0000021920 00000 n
-0000021992 00000 n
-0000022064 00000 n
-0000022136 00000 n
-0000022208 00000 n
-0000022280 00000 n
-0000022352 00000 n
-0000022424 00000 n
-0000022496 00000 n
-0000022687 00000 n
-0000022761 00000 n
-0000022833 00000 n
-0000022905 00000 n
-0000022977 00000 n
-0000023052 00000 n
-0000023124 00000 n
-0000023259 00000 n
-0000023333 00000 n
-0000023405 00000 n
-0000023508 00000 n
-0000023582 00000 n
-0000023654 00000 n
-0000023726 00000 n
-0000023798 00000 n
-0000023870 00000 n
-0000023942 00000 n
-0000024014 00000 n
-0000024089 00000 n
-0000024161 00000 n
-0000024233 00000 n
-0000024435 00000 n
-0000024510 00000 n
-0000024583 00000 n
-0000024656 00000 n
-0000024727 00000 n
-0000024800 00000 n
-0000025200 00000 n
-0000025563 00000 n
-0000025600 00000 n
-0000025637 00000 n
-0000025690 00000 n
-0000025743 00000 n
-0000025795 00000 n
-0000025845 00000 n
-0000025897 00000 n
-0000025950 00000 n
-0000026003 00000 n
-0000026056 00000 n
-0000026179 00000 n
-0000026313 00000 n
-0000026447 00000 n
-0000026570 00000 n
-0000026693 00000 n
-0000026842 00000 n
-0000027409 00000 n
-0000027617 00000 n
-0000027769 00000 n
-0000028644 00000 n
-0000028855 00000 n
-0000028995 00000 n
-0000029211 00000 n
-0000029450 00000 n
-0000029610 00000 n
-0000029816 00000 n
-0000030029 00000 n
-0000030157 00000 n
-0000030285 00000 n
-0000030413 00000 n
-0000030541 00000 n
-0000030669 00000 n
-0000030752 00000 n
-0000031389 00000 n
-0000035839 00000 n
-0000035920 00000 n
-0000036713 00000 n
-0000048023 00000 n
-0000048103 00000 n
-0000048878 00000 n
-0000061414 00000 n
-0000061491 00000 n
-0000061922 00000 n
-0000062394 00000 n
-0000067750 00000 n
-0000074317 00000 n
-0000079777 00000 n
-0000087012 00000 n
-0000088036 00000 n
-0000088379 00000 n
-0000088786 00000 n
-0000088899 00000 n
-0000089972 00000 n
+0000010584 00000 n
+0000010660 00000 n
+0000010783 00000 n
+0000010850 00000 n
+0000010965 00000 n
+0000011074 00000 n
+0000011192 00000 n
+0000011262 00000 n
+0000011334 00000 n
+0000011404 00000 n
+0000011474 00000 n
+0000011588 00000 n
+0000011676 00000 n
+0000011744 00000 n
+0000011812 00000 n
+0000011898 00000 n
+0000011984 00000 n
+0000012064 00000 n
+0000012150 00000 n
+0000012241 00000 n
+0000012326 00000 n
+0000012419 00000 n
+0000012516 00000 n
+0000012571 00000 n
+0000012640 00000 n
+0000012733 00000 n
+0000012898 00000 n
+0000012983 00000 n
+0000013124 00000 n
+0000013233 00000 n
+0000013374 00000 n
+0000013468 00000 n
+0000013570 00000 n
+0000013626 00000 n
+0000013800 00000 n
+0000013982 00000 n
+0000014108 00000 n
+0000014366 00000 n
+0000014439 00000 n
+0000014512 00000 n
+0000014614 00000 n
+0000014694 00000 n
+0000014767 00000 n
+0000014844 00000 n
+0000014946 00000 n
+0000015021 00000 n
+0000015142 00000 n
+0000015217 00000 n
+0000015338 00000 n
+0000015452 00000 n
+0000015532 00000 n
+0000015660 00000 n
+0000015788 00000 n
+0000015924 00000 n
+0000016004 00000 n
+0000016132 00000 n
+0000016260 00000 n
+0000016388 00000 n
+0000016468 00000 n
+0000016596 00000 n
+0000016724 00000 n
+0000016852 00000 n
+0000016932 00000 n
+0000017058 00000 n
+0000017184 00000 n
+0000017312 00000 n
+0000017392 00000 n
+0000017465 00000 n
+0000017586 00000 n
+0000017659 00000 n
+0000017780 00000 n
+0000017910 00000 n
+0000017990 00000 n
+0000018116 00000 n
+0000018243 00000 n
+0000018370 00000 n
+0000018450 00000 n
+0000018621 00000 n
+0000018733 00000 n
+0000018805 00000 n
+0000018877 00000 n
+0000018951 00000 n
+0000019023 00000 n
+0000019095 00000 n
+0000019167 00000 n
+0000019239 00000 n
+0000019311 00000 n
+0000019486 00000 n
+0000019558 00000 n
+0000019650 00000 n
+0000019722 00000 n
+0000019801 00000 n
+0000019873 00000 n
+0000019945 00000 n
+0000020017 00000 n
+0000020089 00000 n
+0000020161 00000 n
+0000020233 00000 n
+0000020305 00000 n
+0000020460 00000 n
+0000020561 00000 n
+0000020635 00000 n
+0000020707 00000 n
+0000020779 00000 n
+0000020890 00000 n
+0000021000 00000 n
+0000021075 00000 n
+0000021158 00000 n
+0000021232 00000 n
+0000021304 00000 n
+0000021376 00000 n
+0000021448 00000 n
+0000021519 00000 n
+0000021753 00000 n
+0000021826 00000 n
+0000021897 00000 n
+0000021969 00000 n
+0000022041 00000 n
+0000022113 00000 n
+0000022185 00000 n
+0000022257 00000 n
+0000022429 00000 n
+0000022503 00000 n
+0000022575 00000 n
+0000022647 00000 n
+0000022719 00000 n
+0000022791 00000 n
+0000022863 00000 n
+0000022935 00000 n
+0000023007 00000 n
+0000023079 00000 n
+0000023151 00000 n
+0000023223 00000 n
+0000023298 00000 n
+0000023370 00000 n
+0000023442 00000 n
+0000023514 00000 n
+0000023763 00000 n
+0000023837 00000 n
+0000023912 00000 n
+0000023984 00000 n
+0000024056 00000 n
+0000024128 00000 n
+0000024200 00000 n
+0000024338 00000 n
+0000024412 00000 n
+0000024484 00000 n
+0000024587 00000 n
+0000024661 00000 n
+0000024733 00000 n
+0000024805 00000 n
+0000024877 00000 n
+0000024950 00000 n
+0000025023 00000 n
+0000025096 00000 n
+0000025173 00000 n
+0000025246 00000 n
+0000025319 00000 n
+0000025535 00000 n
+0000025610 00000 n
+0000025683 00000 n
+0000025754 00000 n
+0000025826 00000 n
+0000025900 00000 n
+0000026466 00000 n
+0000026829 00000 n
+0000026866 00000 n
+0000026903 00000 n
+0000026956 00000 n
+0000027009 00000 n
+0000027061 00000 n
+0000027114 00000 n
+0000027166 00000 n
+0000027219 00000 n
+0000027272 00000 n
+0000027325 00000 n
+0000027448 00000 n
+0000027582 00000 n
+0000027716 00000 n
+0000027839 00000 n
+0000027962 00000 n
+0000028111 00000 n
+0000028678 00000 n
+0000028886 00000 n
+0000029038 00000 n
+0000029913 00000 n
+0000030124 00000 n
+0000030264 00000 n
+0000030480 00000 n
+0000030719 00000 n
+0000030879 00000 n
+0000031085 00000 n
+0000031298 00000 n
+0000031426 00000 n
+0000031554 00000 n
+0000031682 00000 n
+0000031810 00000 n
+0000031938 00000 n
+0000032021 00000 n
+0000032658 00000 n
+0000037108 00000 n
+0000037188 00000 n
+0000037976 00000 n
+0000049040 00000 n
+0000049121 00000 n
+0000049901 00000 n
+0000062507 00000 n
+0000062584 00000 n
+0000063015 00000 n
+0000063487 00000 n
+0000069039 00000 n
+0000075653 00000 n
+0000081181 00000 n
+0000088562 00000 n
+0000090324 00000 n
+0000090667 00000 n
+0000091074 00000 n
+0000091187 00000 n
+0000092260 00000 n
trailer
-<</Size 280/Root 279 0 R/Info 277 0 R/ID[(od6Ce8g5ofbkk30tkgkhhg==)(od6Ce8g5ofbkk30tkgkhhg==)]>>
+<</Size 289/Root 288 0 R/Info 286 0 R/ID[(JCSPa/4Mr2ZKVhRZ6582Sg==)(JCSPa/4Mr2ZKVhRZ6582Sg==)]>>
startxref
-90159
+92447
%%EOF \ No newline at end of file
diff --git a/docs/design.typ b/docs/design.typ
index 38fa6fdb..2492329d 100644
--- a/docs/design.typ
+++ b/docs/design.typ
@@ -69,8 +69,11 @@ graphics when available.)
*Effect* (out, queued): `spawn{pane, cwd}`, `write{pane, bytes}`,
`resize_pty{pane, cols, rows}`, `open_link{url}`, `read_file{path}`,
-`new_file{pane, serial}`, `set_clipboard`, `bell`, `quit`. The core never
-performs IO; it asks. This is what makes the browser build honest instead of a
+`new_file{pane, serial}`, `set_clipboard`, `read_clipboard`, `bell`, `quit`.
+The core never performs IO; it asks — and `read_clipboard` is the one ask with
+an answer coming back, an ordinary `paste` event, or nothing at all when the
+shell cannot read the clipboard (most terminals refuse the OSC 52 read). This
+is what makes the browser build honest instead of a
fork: a wasm shell simply
answers `spawn` differently (or not at all) — the core does not know.
@@ -231,8 +234,11 @@ click-and-type; terminals get splice runs (shift right, never overwrite;
absolute-row anchored), files get real edits. tty: raw pty forwarding
(Ctrl-key toggle, default Ctrl-b, `--tty-toggle`), mouse still usable,
promptClickMove on entry, prompts visible (hidden in the other modes via
-OSC 133). `p` pastes the yank register; yank
-mirrors out via OSC 52.
+OSC 133). `y` fills the yank register and `p` pastes it; neither touches the
+system clipboard, which is helix's five words — `SPC y/Y/p/P/R`, out via
+`set_clipboard` and back via `read_clipboard` — and nothing else, so a delete
+cannot clobber what the desktop was holding. A paste from an outer terminal
+arrives bracketed, as one `paste` event.
*Tag.* Live prefix (mode indicator, cwd or path) + editable tail with the
full modal editor; defaults `New Del` / `Save New Del`; an image tag is
@@ -263,8 +269,9 @@ the tag bar, the gutter and the move box; the selection colors stay fixed
because they encode which button you pressed. `NextColor` browses the ring one
step at a time — at 228 it is no longer how you REACH one —
`Theme <name>` jumps to one and `ThemeSel` (`SPC t t`) lists them all into an
-output buffer whose rows are those very commands — so n/N EXECUTE each row
-instead of looking it and stepping the list wears the themes. Colors toggles
+output buffer whose rows are those very commands — execute a row (Tab, middle
+click) and the theme goes on; n/N select such a row WHOLE, since a command
+line holds no place to pick out of it. Colors toggles
all recolor passes; Debug stats overlay; Dump writes state ZON.
*Web (replay viewer parity).* Embedded dump; focus, border/move drags, wheel,
diff --git a/docs/helix-keys.md b/docs/helix-keys.md
index e43bc6b4..214a1280 100644
--- a/docs/helix-keys.md
+++ b/docs/helix-keys.md
@@ -29,8 +29,8 @@ layer: gap offsets + ranges over the flat text). Differential harness:
collapse) — the checked-in helix goldens are the ground truth, verified
case-by-case by `zig build hxdiff`. Motion-created ranges live in
`pane.vsel` marked IMPLICIT (`vsel.explicit = false`); `v` extend mode,
- `x`/`X`, terminal `n`/`N` (lookStep) and file `n`/`N` (searchStep) set
- EXPLICIT ones. `d`/`c`/`y`/`~`/… act on the active selection either
+ `x`/`X` and `n`/`N` (the look-ring walk, `lookWalk`) set EXPLICIT ones.
+ `d`/`c`/`y`/`~`/… act on the active selection either
way — that is the point of the model. The pardes-specific chords
(normal-mode Enter look / Tab execute)
act on EXPLICIT selections only and fall back to the word under the
@@ -55,7 +55,10 @@ Parity column (phase 5): **helix-verified** = matched field-by-field
(text/mode/cursor/anchor) against the helix goldens by `zig build hxdiff`;
**pardes-specific** = key helix leaves unbound (or a deliberate pardes
binding) — cannot mismatch a golden; **waived** = corpus-covered divergence
-with a reason in `test/hxcases/waivers.jsonl`.
+with a reason in `test/hxcases/waivers.jsonl`; **out of corpus** = helix's
+own key and meaning, but the work leaves the core as an EFFECT the headless
+differential has no shell to perform — the clipboard commands, and nothing
+else.
| Key | Behavior (pardes today) | Notes / quirks vs helix | Parity |
| --- | --- | --- | --- |
@@ -80,9 +83,9 @@ with a reason in `test/hxcases/waivers.jsonl`.
| `x` / `<n>x` | select current line / extend one (n) line(s) down, char-range through the newline, cursor ON the `\n` | col-0 vim-ism removed (phase 5); matches `extend_line_below`, mode stays normal | helix-verified |
| `d` | delete selection (implicit or explicit); bare cursor = the 1-wide selection | always yanks (`Alt-d` noyank in B); terminals: drops typed runs only | helix-verified |
| `c` | change (delete + insert mode); linewise selections open a fresh indented line | same shape as `d` | helix-verified |
-| `y` | yank selection; bare cursor yanks the 1-wide selection (char under cursor) | line-yank vim-ism removed (phase 5); yank keeps selection AND cursor (helix). Also emits `set_clipboard` (OSC 52 out) | helix-verified |
+| `y` | yank selection; bare cursor yanks the 1-wide selection (char under cursor) | line-yank vim-ism removed (phase 5); yank keeps selection AND cursor (helix). Writes the DEFAULT REGISTER and nothing else — the system clipboard is `SPC y`, which is helix's own split and so moves this row TOWARDS helix, not away: a `d` of one character can no longer clobber what the desktop was holding | helix-verified |
| `u` / `U` | undo / redo | restores the pre-edit selection (helix); snapshot granularity, no `Alt-u`/`Alt-U` history walking (skipped) | helix-verified |
-| `p` (normal) | paste the core's yank register after the selection | helix default-register semantics; yank still mirrors OUT via OSC 52 (`set_clipboard`) but `p` never reads the system clipboard back — most terminals refuse the OSC 52 read, which left `p` a silent no-op | helix-verified |
+| `p` (normal) | paste the core's yank register after the selection | helix default-register semantics, and only the register — nothing on this path reads or writes the system clipboard. `SPC p` is the word that does, and on a tty its read is OSC 52, which most terminals refuse: an honest no-op there rather than a paste of the wrong text | helix-verified |
| `Esc` (body normal) | clear a pending modal prefix / exit select mode, keeping the selection, then run `Last`: hop to the pane you were in before this one, whichever kind it was, exactly like `SPC j j` — so held down it alternates between two panes, two files as readily as a file and its shell | Pardes-specific focus binding layered on helix's cleanup. A leader path, tag, topbar or search owns Esc while it is active; raw tty forwards it | pardes-specific (cleanup helix-verified) |
| `Esc` (insert) | back to normal mode, cursor right after the insertion (no vim left-step) | | helix-verified |
| `Enter` (normal) | acme **look** chord: EXPLICIT selection, else file-ish word under cursor | pardes-specific, keep (helix normal-mode Enter unbound). Covers helix `gf`. Implicit motion residue falls back to the cursor word | pardes-specific |
@@ -92,9 +95,11 @@ with a reason in `test/hxcases/waivers.jsonl`.
| `Ctrl-w` + `h/j/k/l`/arrows | directional pane focus prefix — normal/tty modes only | pardes' own window handling (helix window mode skipped, section C). Runs the SAME `Left`/`Down`/`Up`/`Right` builtins `SPC w h/j/k/l` runs; kept alongside the leader because a pane in raw **tty** mode never sees `SPC` (the shell owns it), so this is the only keyboard way out of one. Insert mode owns `Ctrl-w` = delete-word-back, so a tag being TYPED into swallows it; from a tag in normal mode (`:`) it moves focus to the neighbour's BODY, while the bare letters `h/j/k/l` there move to its TAGLINE (next row) | pardes-specific |
| `Alt-n` | new terminal below (any mode) | shadows helix `Alt-n` TS sibling-select — skipped anyway (tree-sitter) | pardes-specific |
| `Alt-c` | move active terminal to a fresh column (any mode) | helix `Alt-c` is change-noyank; the pardes window op wins (do-not-touch contract). `Alt-d` + `i` covers the behavior | waived (`alt-c-window-op`) |
-| `Space` (normal, body) | the pardes LEADER: a key path from here runs a BUILTIN with no arguments — the same builtins the topbar and the tags hold. `SPC k` Kill, `SPC d` Del, `SPC f s` Save, `SPC f n` New (an empty temporary file focused in the calling pane's column), `SPC f f` Find (fd over the pane's directory, results into `+Search`), `SPC f g` Grep (grep -R over the CONTENTS of every pane's directory, the ones another pane already covers dropped, rows relative to the asking pane's own directory, results into `+Search`; like Find it takes an ARGUMENT — `Grep foo` executed, or a selection chorded onto the word, searches that and skips the input), `SPC h t` Tutor, `SPC c n`/`SPC c d` Newcol/Delcol, `SPC t d/c/n/r` Debug/Colors/NextColor/Crt, `SPC t t` ThemeSel (the whole theme ring as `Theme <name>` rows in an output buffer — the one list whose rows are COMMANDS, so n/N execute each row instead of looking it and stepping is a live preview), `SPC t p/l/a` Petscii/Palette/Ascii (an image pane's renderer toggles — the words its tag used to spell out, so the bar stays a bar), `SPC s d`/`SPC s r` Dump/Restore, `SPC w h/j/k/l` Left/Down/Up/Right (directional pane focus — the `Ctrl-w` prefix's four moves as builtins), `SPC j o`/`SPC j i`/`SPC j j`/`SPC j l` Back/Forward/Last/Jumplist (the jump stack: walk it back, walk it forward, hop to the pane before this one — what body-normal Esc runs — and read the stack as a clickable buffer). `?` at ANY depth opens the Help builtin listing what the prefix can still reach (`SPC ?` = all, `SPC h ?` = the docs group), into a `+Help` output buffer. The pending path shows at the right edge of the active pane's tag; Esc — or any unmapped key — abandons it | helix spends Space on pickers/LSP (section C); pardes has neither, and acme's builtins are what a leader is for. Enum-derived: the paths, the Help lines and the execute dispatch all fold out of one `Builtin` enum at comptime. Normal mode on a BODY only — tags are always insert, tty keys belong to the program | pardes-specific |
-| `/` then `n`/`N` (any pane) | pardes' own plain-substring search into a `+Search` output buffer, n/N walk the result rows and look them (EXPLICIT selections) | KEEP, do not touch; not in the corpus (helix `/` is regex search) | pardes-specific |
-| `n`/`N` (terminal panes, no search armed) | lookable-token motion over scrollback (EXPLICIT selections) | KEEP, do not touch | pardes-specific |
+| `Space` (normal, body) | the pardes LEADER: a key path from here runs a BUILTIN with no arguments — the same builtins the topbar and the tags hold. `SPC k` Kill, `SPC d` Del, `SPC f s` Save, `SPC f n` New (an empty temporary file focused in the calling pane's column), `SPC f f` Find (fd over the pane's directory, results into `+Search`), `SPC f g` Grep (grep -R over the CONTENTS of every pane's directory, the ones another pane already covers dropped, rows relative to the asking pane's own directory, results into `+Search`; like Find it takes an ARGUMENT — `Grep foo` executed, or a selection chorded onto the word, searches that and skips the input), `SPC h t` Tutor, `SPC c n`/`SPC c d` Newcol/Delcol, `SPC y/Y/p/P/R` the five clipboard words (next row), `SPC t d/c/n/r` Debug/Colors/NextColor/Crt, `SPC t t` ThemeSel (the whole theme ring as `Theme <name>` rows in an output buffer — rows that are COMMANDS rather than places, so a theme is previewed by EXECUTING one, Tab or a middle click; `n`/`N` do not run them, they step past to the next look-able text on the ring), `SPC t p/l/a` Petscii/Palette/Ascii (an image pane's renderer toggles — the words its tag used to spell out, so the bar stays a bar), `SPC s d`/`SPC s r` Dump/Restore, `SPC w h/j/k/l` Left/Down/Up/Right (directional pane focus — the `Ctrl-w` prefix's four moves as builtins), `SPC j o`/`SPC j i`/`SPC j j`/`SPC j l` Back/Forward/Last/Jumplist (the jump stack: walk it back, walk it forward, hop to the pane before this one — what body-normal Esc runs — and read the stack as a clickable buffer). `?` at ANY depth opens the Help builtin listing what the prefix can still reach (`SPC ?` = all, `SPC h ?` = the docs group), into a `+Help` output buffer. The pending path shows at the right edge of the active pane's tag; Esc — or any unmapped key — abandons it | helix spends Space on pickers/LSP (section C); pardes has neither, and acme's builtins are what a leader is for. Enum-derived: the paths, the Help lines and the execute dispatch all fold out of one `Builtin` enum at comptime. Normal mode on a BODY only — tags are always insert, tty keys belong to the program | pardes-specific |
+| `SPC y` `SPC Y` `SPC p` `SPC P` `SPC R` | helix's clipboard menu on helix's own letters: yank the selection to the system clipboard (`ClipYank`) or the PRIMARY selection alone (`ClipYankMain`), paste the system clipboard after (`ClipPaste`) / before (`ClipPasteBefore`) the selection, replace the selection with it (`ClipReplace`) | the ONLY five words in pardes that touch the desktop's clipboard — `y`/`d`/`c`/`p`/`P`/`R` and the acme cut/paste chords are the internal register alone. Builtins rather than bare chords because a leader path names a builtin: they land in Help's index and are executable words like every other verb. One divergence: pardes keeps a single register VALUE where helix keeps one per range, so `SPC y` at N cursors joins them with newlines (`Pardes.setYank`, the divergence `msel-yank-paste` already waives). On a tty the write is OSC 52 out and the READ is OSC 52 back, which many terminals refuse or gate — so `SPC y` works there and `SPC p` can be a no-op | out of corpus |
+| a paste from the OUTER terminal | one `Event.paste`, spliced in at the cursor | the tty shell enables bracketed paste and coalesces `paste_start`..`paste_end` into a single event; before that the bytes arrived as individual key presses and normal mode RAN them, which is how a pasted `d` deleted a line. The bytes deliberately never enter the yank register — clipboard and default register are separate stores in both directions | pardes-specific |
+| `/` (any pane) | pardes' own plain-substring search into a `+Search` output buffer: the tag takes the pattern, Enter fills the buffer, and its rows are ordinary look targets | KEEP, do not touch; not in the corpus (helix `/` is regex search). The stepping half is the next row | pardes-specific |
+| `n` / `N` (any pane) | MOTION, not a jump: move the SELECTION to the next / previous look-able text and open NOTHING. Enter — the look chord — on what it leaves selected is what opens it | KEEP, do not touch; not in the corpus (helix's `n`/`N` walk regex search hits). The text stepped is the largest whitespace-delimited run `look.resolve` can act on (`look.lookableSpan`, wrapper punctuation peeled off both ends), and the walk is a RING across PANES: every pane that has performed a Look, most recent first (`Pardes.look_src`), then the output buffers that have not, newest first, and only when both are empty the active pane. Exhausting a pane enters the next at its first (forward) / last (backward) span and the end wraps to the start, so `N` is the exact inverse of `n`. What it lands on becomes an EXPLICIT `vsel` with the cursor on its FIRST column, in the pane the walk focuses. ONE motion in every pane kind and every buffer kind — a PDF steps the `+Search` buffer its own search filled, `n` to select the row and Enter to jump. The single thing a buffer may change is the GRAIN of what a step selects, and it changes it with one flag rather than a branch: `output_pane.Traits.commands` makes a step take the WHOLE LINE, because a command list (`ThemeSel`/`FontSel`) holds words to run and there is no path inside `Theme gruvbox` to pick out. Tab on what `n` selected wears the theme, which is the same middle click on the row is. `]d`/`[d` are helix's diagnostic motions, a different binding, and they do still jump to each diagnostic (`docs/lsp.md`) | pardes-specific |
| insert: printable text | file: real edit; terminal: typed run splice | | helix-verified (file) |
| insert: `Enter` | newline; keeps the current full indent levels and adds one 4-space logical tab when the text before the cursor ends in `(`, `[`, `{`, or `)` (including `})`) | plain lines match `insert_newline`; delimiter heuristic is pardes-specific | helix-verified (plain) / pardes-specific (delimiter) |
| insert: `Backspace` (+ `Shift-Backspace`) | delete prev char, joins lines at col 0 | matches `delete_char_backward`; `Ctrl-h` alias in B | helix-verified |
@@ -139,7 +144,7 @@ Phase 2 state added to `Pane`: `count` (accumulator, capped 0xffff),
| Key | Behavior | Notes | Status |
| --- | --- | --- | --- |
| `r<ch>` | replace selection/char with `<ch>`, newlines kept | terminals: replaces the typed-run byte under the cursor if any, else no-op (`runByteAt`) | helix-verified (phase 5) |
-| `R` | replace selection (or cursor char) with the yank register; pasted text becomes the selection, head on its last char | uses the INTERNAL yank (`p.yank`), no clipboard round trip; empty register = no-op; terminals: no-op | helix-verified (phase 5) |
+| `R` | replace selection (or cursor char) with the yank register; pasted text becomes the selection, head on its last char | uses the INTERNAL yank (`p.yank`), no clipboard round trip — `SPC R` is the system-clipboard twin; empty register = no-op; terminals: no-op | helix-verified (phase 5) |
| `~` | switch case of selection/char, selection kept | terminals: run byte only | helix-verified (phase 5) |
| `` ` `` | selection to lowercase | terminals: run byte only | helix-verified (phase 5) |
| ``Alt-` `` | selection to uppercase | terminals: run byte only | helix-verified (phase 5) |
@@ -276,8 +281,8 @@ text.
| Key(s) | Helix behavior | Reason |
| --- | --- | --- |
-| `?`, `*`, `Alt-*` | rsearch / selection-as-pattern | search — pardes has its own `/` n N (plain substring into an output buffer, kept as-is); helix regex search machinery not wanted |
-| `Space` mode, all rows (`f F e . b j g G k s S d D r a h ' w c C Alt-c p P y Y R / ?`) | pickers, LSP actions, clipboard menu, global search, palette | helix's space mode is pickers + LSP + a clipboard menu, none of which exist here — but the KEY is taken: pardes' own leader runs the acme builtins (section A). Clipboard: yank mirrors out via OSC 52, `p` pastes the register |
+| `?`, `*`, `Alt-*` | rsearch / selection-as-pattern | search — pardes has its own `/` (plain substring into an output buffer, kept as-is) and an `n`/`N` that SELECTS the next look-able text instead of walking match hits; helix regex search machinery not wanted |
+| `Space` mode, all rows but the clipboard menu (`f F e . b j g G k s S d D r a h ' w c C Alt-c / ?`) | pickers, LSP actions, global search, palette | helix's space mode is pickers + LSP, neither of which exists here — but the KEY is taken: pardes' own leader runs the acme builtins (section A). The clipboard menu is the half that DOES exist now: `<space>y Y p P R`, helix's letters on helix's leader, in section A |
| Popup `Ctrl-u`/`Ctrl-d`, Completion menu, Signature help tables | LSP popups | LSP |
| Picker table (all rows), Prompt table (all rows) | picker / prompt internals | pickers — pardes' tag line is its own one-line editor |
| `gn` `gp` `ga` `gm` | next/prev/alternate buffer | buffer nav — pardes panes aren't a buffer list |
@@ -288,7 +293,7 @@ text.
| `]f [f ]t [t ]a [a ]c [c ]e [e ]T [T ]x [x` | TS unimpaired jumps | tree-sitter |
| `]g [g ]G [G` | git change jumps | needs VCS diff state |
| `gd gD gy gr gi`, `=`, `]d [d ]D [D`, insert `Ctrl-x` | definition/refs/format/diagnostics/completion | LSP |
-| `"` `<reg>`, insert `Ctrl-r` | register select / insert | registers — single yank register only |
+| `"` `<reg>`, insert `Ctrl-r` | register select / insert | registers — one yank register and no way to name a second; the system clipboard is not spelled as a register here either, it is the five `SPC` commands in A |
| `Q` / `q` | record / replay macro | macros — needs replayable input log |
| `Ctrl-i` `Ctrl-o` `Ctrl-s` (normal) | jumplist forward/back/save | jumplist |
| `Alt-u` / `Alt-U` | undo-history earlier/later | history timeline — linear snapshot u/U covers pardes |
@@ -304,7 +309,7 @@ text.
| `Z` (sticky view mode) | persistent view mode | marginal; `z` one-shots suffice |
| `zm` (view) | align middle horizontally | marginal even with hscroll |
| `.` | repeat last insert | **deferred by decision**: needs recording the insert session's keystrokes and a replay path — a new subsystem; undo is whole-buffer snapshots with no edit log to piggyback on. Revisit after phases 2–5 if the log exists by then for another reason |
-| Select/extend mode section (prose) | `v` turns all motions into extenders, `n`/`N` keep selections | implemented for motions (phase 5: `pane.select` + the fixed anchor, differential-verified — see the `v` row in A); helix's search-`n`/`N` extension doesn't apply (pardes `n`/`N` are its own search/look ops) |
+| Select/extend mode section (prose) | `v` turns all motions into extenders, `n`/`N` keep selections | implemented for motions (phase 5: `pane.select` + the fixed anchor, differential-verified — see the `v` row in A); helix's search-`n`/`N` extension doesn't apply (pardes' `n`/`N` is the look-ring motion, which REPLACES the selection with the span it lands on) |
## Differential testing (phase 5)
diff --git a/docs/lsp.md b/docs/lsp.md
index 097386e6..bce9b2cc 100644
--- a/docs/lsp.md
+++ b/docs/lsp.md
@@ -61,17 +61,20 @@ sub/file.zig:LINE:COL-ENDCOL text
1-based line and column. The second form carries the answer's
RANGE where the protocol gave one on a single line (a token, a symbol's name),
and a look on it SELECTS that span rather than parking at its first cell — so
-`gd` lands on the whole name and `gr` steps references with each one
-highlighted. This is the format `look.zig` already resolves, `runSearch`
-already produces and `n`/`N` already step — so:
+`gd` lands on the whole name, and a `gr` reference stepped to with `n`/`N` and
+opened with Enter arrives with the reference itself selected. This is the
+format `look.zig` already resolves, `runSearch` already produces and `n`/`N`
+already walk — so:
- **one row from a goto** → jump straight there (`lookAt`)
-- **several rows** → an output buffer, which `n`/`N` walk
+- **several rows** → an output buffer, which `n`/`N` walk: a step SELECTS a row
+ and Enter opens it
which means helix's multi-result picker required **no picker code at all**. The
`+Search` buffer *is* the picker. Non-location answers (`hover`, `code_action`,
-`format`) open `+Hover`/`+Lsp` instead and do not arm the stepper — `n` over a
-documentation blurb would step to nowhere.
+`format`) open `+Hover`/`+Lsp` instead, which are prose and not places — `n`/`N`
+find nothing look-able in a documentation blurb and walk straight past it to the
+next pane on the ring.
Rename is deliberately the one exception to rows as presentation. The backend
emits `@edit START END` records through `lsp.edit()`, using half-open byte
@@ -98,7 +101,7 @@ chain says neither, and stops being true the moment the row is read anywhere but
beside its own buffer. `test/snapshots/lsprelpath.snap` pins both directions end
to end — the enum one level up (absolute row) and one level down (`inner/tint.zig`,
a stripped path that still has a separator in it), each with the `n` step that
-opens it, plus a right click.
+selects it and the Enter that opens it, plus a right click.
This is the rule `look.grep` already follows for its own rows (`look.zig`, the
`shown` computation), written a second time; the two are now the same function
diff --git a/docs/macos.md b/docs/macos.md
index 7f695000..ff19ff93 100644
--- a/docs/macos.md
+++ b/docs/macos.md
@@ -61,10 +61,12 @@ removing; it is the encoding being right.
The one real difference is IO. The browser has no ptys, so `src/web.zig`
forwards every effect out to JavaScript as a numbered code plus a byte payload,
and JavaScript performs it. macOS has `forkpty`, `read` and `write` right there,
-so effects never cross the boundary at all: `pardes_tick` drains the core's
-effect queue and performs each one in Zig, the way `drainEffects` in
-`src/tty/tty.zig` does. That is why the runtime struct is two callbacks and not
-twelve.
+so almost no effect crosses the boundary at all: `pardes_tick` drains the
+core's effect queue and performs each one in Zig, the way `drainEffects` in
+`src/tty/tty.zig` does. That is why the runtime struct is three callbacks and
+not twelve — and why two of the three are the clipboard: the pasteboard is
+AppKit's, in both directions, and is the one piece of IO the Zig side cannot
+reach for itself.
## The seam
@@ -100,13 +102,20 @@ is made of and what opens a path from argv or the Dock (`Look <path>`).
it. `pardes_resize` also carries one cell in *physical* pixels, which only the
native PDF placement path reads — pass the backing-store size, not points.
-**Runtime callbacks.** `pardes_runtime_s` is a `userdata` and two functions,
+**Runtime callbacks.** `pardes_runtime_s` is a `userdata` and three functions,
copied by value during init so the struct need not outlive the call. `wakeup`
-means "your state moved, please pump me"; `set_clipboard` fires inside a tick
-when the yank register changes, with the text borrowed for the duration of the
-call. There is no `open_url` callback because the core already opens links
-itself through `/usr/bin/open` (`src/look.zig`), and no file callbacks because
-it owns the filesystem side too.
+means "your state moved, please pump me". `set_clipboard` hands over text to put
+on the pasteboard, borrowed for the duration of the call; it fires inside a tick
+for the five `SPC` clipboard words and for the tag's own `y` chord, and for
+nothing else — an ordinary `y` or `d` writes the core's register and never
+reaches here, which is what stopped deleting a character from clobbering the
+desktop's clipboard. `read_clipboard` is that direction reversed: "give me the
+pasteboard", with no payload either way, because the host answers by calling
+`pardes_paste` — and NSPasteboard being synchronous, that usually happens inside
+the callback itself, before it returns. Both are main thread, inside
+`pardes_tick`. There is no `open_url` callback because the core already opens
+links itself through `/usr/bin/open` (`src/look.zig`), and no file callbacks
+because it owns the filesystem side too.
**Lifecycle.** `pardes_init` returns 0 or an opaque nonzero code,
`pardes_deinit` tears down, `pardes_tick` drains pty output plus the effect
@@ -195,11 +204,14 @@ already-Exec is the only case with nothing to do. The view also needs
system's business and never arrives — and the user needs "Force Click and
haptic feedback" on in System Settings, which nothing in this process can read.
-Twisting two fingers is a dial, and a dial over a list of search hits is `n`.
-`pardes_rotate` takes raw degrees and libpardes quantizes them, one search step
-per 10°, keeping the remainder — the same accumulate-and-spend shape as
-`pardes_scroll`, in Zig for the same reason: it is then unit-tested on a machine
-with no trackpad. AppKit reports counterclockwise as positive and the forward
+Twisting two fingers is a dial, and a dial over a list of look-able places is
+`n`. A notch moves the SELECTION one place along and opens nothing; Enter opens
+the one the dial stopped at, which is what makes the dial worth spinning at all
+— a stepper that opened every place it passed could not be. `pardes_rotate`
+takes raw degrees and libpardes quantizes them, one step per 10°, keeping the
+remainder — the same accumulate-and-spend shape as `pardes_scroll`, in Zig for
+the same reason: it is then unit-tested on a machine with no trackpad. AppKit
+reports counterclockwise as positive and the forward
step is clockwise, so the sign inverts here and nowhere else. The banked
remainder is deliberate hysteresis; a gesture beginning passes 0 to clear it, so
the first degree of a new twist cannot inherit a nearly-complete notch from the
@@ -244,10 +256,11 @@ asserting the machine's timer jitter.
Both halves are goldens. `rotate.snap` turns the dial at 4° per 100 ms (40°/s,
under the floor) and asserts the screen is byte-identical across the release,
then at 12° per 5 ms and asserts it is not. The list it walks is twenty-four
-hits rather than three for a reason worth keeping: `n` at the last match has
-nowhere to go, so on a short list the hardest possible flick and no flick at
-all produce the same screen — a golden that would have passed before momentum
-existed.
+places rather than three for a reason worth keeping, and `n`/`N` becoming a
+RING only sharpened it: a short ring comes round, so a hard flick can stop
+exactly where a single notch would have and the two screens agree — a golden
+that passes before momentum exists. Twenty-four is longer than the cap can
+travel (about eleven), so the fling has nowhere to hide.
## A drop is a click plus Look
@@ -306,8 +319,11 @@ the *word under the pointer* and most words resolve to nothing:
and the screen does not move. The pulse still fires — the gesture worked.
- **Exec** (three fingers) on a builtin name runs it. On ordinary prose it types
that word at a shell, which needs a terminal pane to type into.
-- **`n`/`N`** (twist) steps a results buffer. With no `/pattern`, Grep or Find
- behind it there is nothing to step.
+- **`n`/`N`** (twist) moves the SELECTION to the next look-able place and opens
+ nothing; Enter opens what it landed on. It walks a ring across panes — the
+ ones a Look came from first, then the output buffers none has — so a twist
+ with no results buffer anywhere still steps the pane in front of you. A screen
+ with no filename on it is what has nothing to step.
`PARDES_LOG=1` prints every decoded gesture to stderr — the fingers counted, the
stream it came in on, the button it resolved to, the pressure stage, the
@@ -319,12 +335,13 @@ because guessing at that from a screenshot cost an afternoon.
Every Exec and every Look taps the trackpad. The core arms a one-slot pulse in
the ONE dispatcher — `lookAt` and `execute`, the two functions a middle click, a
-right click, Enter, Tab, a tag chord, `n`/`N` stepping and the `Look`/`Exec`
-builtins all funnel into — and the host takes it once per pump with
-`pardes_take_haptic`. Exec gets `.generic`, the definite tap of something done;
-Look gets `.alignment`, the lighter detent AppKit uses when a dragged guide
-snaps. A pulse, not a queue: five Execs inside one keystroke are one thing the
-hand did.
+right click, Enter, Tab, a tag chord and the `Look`/`Exec` builtins all funnel
+into — and the host takes it once per pump with `pardes_take_haptic`. Exec gets
+`.generic`, the definite tap of something done; Look gets `.alignment`, the
+lighter detent AppKit uses when a dragged guide snaps. A pulse, not a queue:
+five Execs inside one keystroke are one thing the hand did. A twist taps nothing
+now that `n`/`N` only move the selection, and that is the honest report: the
+detent belongs to the Enter that opens, and that is where it fires.
Three details are load-bearing. `execute` arms only at `exec_depth == 0`,
because `Exec ls` re-enters as `ls` and one Tab is one gesture however many
@@ -672,7 +689,7 @@ zig build unit-test -Dplatform=macos
That covers the ABI's Zig side, the effect drain, and the two quantizers the
trackpad depends on — `takeScrollTicks` and `takeRotationNotches` are pure
-functions precisely so that "how many search steps is a 180° twist" is answerable
+functions precisely so that "how many notches is a 180° twist" is answerable
on a machine with no trackpad in it.
The header is kept honest with ghostty's trick. `build.zig` runs `translate-C`
diff --git a/src/builtins.zig b/src/builtins.zig
index f207ed9f..39a147fa 100644
--- a/src/builtins.zig
+++ b/src/builtins.zig
@@ -107,7 +107,7 @@ pub const OutputTraits = struct {
name: []const u8,
steps: bool = false,
jumps: bool = false,
- executes: bool = false,
+ commands: bool = false,
};
/// The enum: field name = struct name, value = index into `all()`. Everything
@@ -297,12 +297,13 @@ pub const Shell = struct {
};
/// ...and the list of what Theme takes, as a buffer you walk. Its rows are
-/// `Theme <name>` COMMANDS rather than locations, so n/N execute them instead
-/// of looking them (output_pane.Traits.executes) and stepping the list wears
-/// each theme in turn — the picker is the list, and there is nothing to
-/// confirm because arriving already applied it.
+/// `Theme <name>` COMMANDS rather than locations, which is one flag on the
+/// buffer (output_pane.Traits.commands) and changes what a step SELECTS: the
+/// whole line, since there is no path inside it to pick out. Tab on what n
+/// selected wears that theme — the same middle click on the row is — so
+/// walking the list with n/Tab is trying them on, and stopping is choosing.
pub const ThemeSel = struct {
- pub const output: OutputTraits = .{ .name = config.themes_buffer, .steps = true, .executes = true };
+ pub const output: OutputTraits = .{ .name = config.themes_buffer, .steps = true, .commands = true };
pub fn run(c: Ctx) void {
output_pane.openThemes(c.p, c.id) catch |err| c.p.reportError(c.id, "themes", err);
}
@@ -368,7 +369,7 @@ pub const Font = struct {
/// unreadable one — and this picker EXECUTES what it steps onto, so listing
/// them would mean the list wearing one on the way past. See fonts.monospaced.
pub const FontSel = struct {
- pub const output: OutputTraits = .{ .name = config.fonts_buffer, .steps = true, .executes = true };
+ pub const output: OutputTraits = .{ .name = config.fonts_buffer, .steps = true, .commands = true };
pub const enabled = pardes.font_picker;
pub fn run(c: Ctx) void {
if (comptime enabled) apply(c) else unreachable;
@@ -455,6 +456,61 @@ pub const Ascii = struct {
}
};
+// ---- the system clipboard ----
+
+// helix's `<space>` clipboard menu, and the ONLY five words in pardes that
+// touch the desktop's clipboard. Everything else — `y`, `d`, `c`, `p`, `P`,
+// `R`, the acme cut/paste chords — lives entirely in the internal register,
+// which is helix's arrangement and, less abstractly, the reason deleting a
+// character no longer throws away whatever you had copied from a browser.
+//
+// They are builtins rather than bare chords because the leader table is the
+// remapping surface and a leader path names a builtin: spelling them here
+// puts them in Help's index, makes them executable words like every other
+// verb, and costs no second mechanism. Their paths ARE helix's letters, on
+// the same leader helix uses — see config.leader_path.
+//
+// The two directions are not symmetric, and cannot be. Writing is a fire-off:
+// the core owns the bytes and the shell copies them out. READING has to leave
+// the core and come back — SDL and NSPasteboard answer inside the same drain,
+// a browser answers a promise later, and a terminal answers over OSC 52 or,
+// far more often, refuses outright. So a paste is a REQUEST (the
+// read_clipboard effect) that may simply never be answered, and a `SPC p`
+// that does nothing in a locked-down terminal is the honest outcome rather
+// than a bug to paper over with the internal register.
+
+pub const ClipYank = struct {
+ pub fn run(c: Ctx) void {
+ c.p.clipYank(c.pane, false);
+ }
+};
+
+/// helix `<space>Y`: the PRIMARY selection alone, where `SPC y` joins every
+/// cursor's. One cursor makes them the same word.
+pub const ClipYankMain = struct {
+ pub fn run(c: Ctx) void {
+ c.p.clipYank(c.pane, true);
+ }
+};
+
+pub const ClipPaste = struct {
+ pub fn run(c: Ctx) void {
+ c.p.clipRequest(c.id, .after);
+ }
+};
+
+pub const ClipPasteBefore = struct {
+ pub fn run(c: Ctx) void {
+ c.p.clipRequest(c.id, .before);
+ }
+};
+
+pub const ClipReplace = struct {
+ pub fn run(c: Ctx) void {
+ c.p.clipRequest(c.id, .replace);
+ }
+};
+
// ---- panes and columns ----
pub const Save = struct {
diff --git a/src/config.zig b/src/config.zig
index 189d6a0e..d6d6813d 100644
--- a/src/config.zig
+++ b/src/config.zig
@@ -109,6 +109,20 @@ pub const leader_path = paths: {
.Lspwhy = "lw",
.Del = "d",
.Kill = "k",
+ // THE CLIPBOARD MENU, on helix's own five letters and nowhere else.
+ // These are the only paths in the table that keep their helix spelling
+ // unprefixed, and they can: `y` `Y` `p` `P` `R` were free at the top
+ // level, and moving them into a group would have made the one thing
+ // here that IS helix's leader stop looking like it.
+ //
+ // Bare `y`/`p`/`P`/`R` remain the DEFAULT register — that split is the
+ // whole design (see builtins.zig's clipboard section), and it is why
+ // an ordinary delete no longer reaches past the editor.
+ .ClipYank = "y",
+ .ClipYankMain = "Y",
+ .ClipPaste = "p",
+ .ClipPasteBefore = "P",
+ .ClipReplace = "R",
// the `f` file group (spacemacs): Save left vim's `w` to join Find and
// New here, which frees `w` for the window group (SPC w h/j/k/l).
.Save = "fs",
@@ -282,6 +296,27 @@ pub const tty_toggle_default: u21 = 'b';
/// means what Escape always means.
pub const tty_toggle_alt: []const Chord = &.{.{ .cp = Key.escape, .shift = true }};
+/// What LEAVING raw tty mode hides on the shell's prompt rows.
+///
+/// A prompt is CHROME. `user@host ~/src $` is redrawn on every keystroke, says
+/// nothing a second time, and is never what you want to select, look at or
+/// edit — so blanking it is most of what turns a scrollback into a readable
+/// document, and pardes has always done it (OSC 133 is how it knows).
+///
+/// What it USED to take with it was the command you had typed at that prompt,
+/// because the two share a grid row and the row was the unit. That command is
+/// content: the one thing on the row worth keeping, and the thing you reach
+/// for `b` to get at in the first place. OSC 133 marks the two separately —
+/// per CELL, not just per row — so `.prompt` blanks the prompt's own cells and
+/// leaves the input sitting in the COLUMNS it really occupies. Those columns
+/// are not cosmetic: clicking the command in normal mode and pressing the
+/// toggle carries the click into the shell's own cursor (promptClickMove),
+/// which counts them.
+///
+/// `.prompt_and_input` is the older behaviour, kept for anyone who wants a
+/// terminal to read as output and nothing else.
+pub const tty_blank: enum { prompt, prompt_and_input } = .prompt;
+
// ---- the tag line and the topbar ----
// The topbar is a HAND-PICKED subset in a fixed order, not a derivation: row 0
@@ -801,14 +836,17 @@ pub const select_regex: []const Chord = &.{.{ .cp = 's' }};
pub const split_regex: []const Chord = &.{.{ .cp = 'S' }};
// ---- edits ----
+//
+// Every one of these reads or writes the DEFAULT register and only that.
+// The system clipboard is five separate words on `SPC y Y p P R`, which is
+// helix's split and the reason `d` cannot silently eat what you copied out of
+// a browser. See leader_path above and builtins.zig's clipboard section.
pub const delete: []const Chord = &.{.{ .cp = 'd' }};
pub const delete_noyank: []const Chord = &.{.{ .cp = 'd', .alt = true }};
pub const change: []const Chord = &.{.{ .cp = 'c' }};
pub const yank: []const Chord = &.{.{ .cp = 'y' }};
pub const replace_with_yank: []const Chord = &.{.{ .cp = 'R' }};
-/// helix: the DEFAULT register, not the system clipboard — most terminals
-/// refuse the OSC 52 read, so a round trip would never come back
pub const paste_after: []const Chord = &.{.{ .cp = 'p' }};
pub const paste_before: []const Chord = &.{.{ .cp = 'P' }};
pub const switch_case: []const Chord = &.{.{ .cp = '~' }};
diff --git a/src/gui/gui.zig b/src/gui/gui.zig
index 7e34a928..82866a30 100644
--- a/src/gui/gui.zig
+++ b/src/gui/gui.zig
@@ -2473,10 +2473,19 @@ fn dispatch(g: *Gui, core: *pardes.Pardes, sev: *const c.SDL_Event) void {
while (tptr[tlen] != 0) : (tlen += 1) {}
if (tlen == 0) return;
const text: []const u8 = tptr[0..tlen];
- const cplen = std.unicode.utf8ByteSequenceLength(text[0]) catch return;
- if (cplen > text.len) return;
- const cp = std.unicode.utf8Decode(text[0..cplen]) catch return;
- core.update(.{ .key = .{ .cp = cp, .text = text[0..cplen], .ctrl = g.live_ctrl, .alt = g.live_alt } });
+ // ONE event is not one codepoint. An IME commit arrives whole —
+ // the entire phrase the candidate window was holding — and so does
+ // anything composed (dead keys, `Ctrl-Shift-u`, a compose-key
+ // sequence that resolves to more than one scalar). Decoding only
+ // text[0] dropped the rest on the floor, silently. Validate the
+ // whole string first so a truncated or malformed sequence costs
+ // nothing rather than half a phrase already forwarded.
+ const view = std.unicode.Utf8View.init(text) catch return;
+ var it = view.iterator();
+ var at: usize = 0;
+ while (it.nextCodepoint()) |cp| : (at = it.i) {
+ core.update(.{ .key = .{ .cp = cp, .text = text[at..it.i], .ctrl = g.live_ctrl, .alt = g.live_alt } });
+ }
},
c.SDL_EVENT_MOUSE_BUTTON_DOWN, c.SDL_EVENT_MOUSE_BUTTON_UP => {
const b = sev.button;
@@ -2959,6 +2968,19 @@ fn drainEffects(
defer gpa.free(z);
_ = c.SDL_SetClipboardText(z.ptr);
},
+ .read_clipboard => {
+ if (g == null) continue;
+ // SDL answers synchronously, so the paste the core is waiting on
+ // lands inside this same drain — nothing to remember, no reply
+ // path to plumb. SDL3 hands over an OWNED copy that is ours to
+ // SDL_free, and reports "no text" as an EMPTY string rather than
+ // null, so the length check is what actually rejects a miss.
+ const raw = c.SDL_GetClipboardText() orelse continue;
+ defer c.SDL_free(raw);
+ const text = std.mem.span(raw);
+ if (text.len == 0) continue;
+ core.update(.{ .paste = text });
+ },
.lsp => |e| if (threads_ok) spawnLsp(core, queue, e),
.pipe => |e| if (threads_ok) spawnPipe(core, io, gpa, queue, pipe_tasks, e),
.watch => |w| {
@@ -3010,6 +3032,15 @@ fn drainEffectsWeb(core: *pardes.Pardes, gpa: std.mem.Allocator, g: *Gui) void {
defer gpa.free(z);
_ = c.SDL_SetClipboardText(z.ptr);
},
+ .read_clipboard => {
+ // emscripten fills SDL's clipboard only from a real paste gesture,
+ // so an empty answer here is the ordinary case and not a failure.
+ const raw = c.SDL_GetClipboardText() orelse continue;
+ defer c.SDL_free(raw);
+ const text = std.mem.span(raw);
+ if (text.len == 0) continue;
+ core.update(.{ .paste = text });
+ },
// look on a URL → a new tab
.open_link => |url| openLinkWeb(gpa, url.slice()),
// nothing to spawn/write/resize/save/dump into, and no filesystem to
diff --git a/src/look.zig b/src/look.zig
index 7169cf8b..36390ec2 100644
--- a/src/look.zig
+++ b/src/look.zig
@@ -225,6 +225,82 @@ test ".pdf Look paths are ordinary files when MuPDF is disabled" {
}
}
+/// Where a look-able word actually SITS inside a run of non-whitespace.
+pub const Span = struct { start: usize, end: usize };
+
+/// The punctuation a path wears in prose and never owns. Two sets, because
+/// the two ends are not alike: a directory may legally END in `/`, and the
+/// `:` that closes `grep -n`'s `main.zig:100:` is junk on the right and
+/// meaningful nowhere on the left.
+const lead_trim = "([{<\"'`*";
+const trail_trim = ")]}>\"'`*,;:.!?";
+
+/// The largest look-able span inside one whitespace-delimited `word`, or null
+/// when nothing in it resolves. This is the whole heuristic behind n/N: split
+/// on whitespace, and take the biggest piece of each run that Look can act on.
+///
+/// TWO resolve attempts at most, which is what keeps a motion across a
+/// screenful of prose from being a hundred realpaths: the run with every
+/// wrapper character peeled off BOTH ends at once, then — only if that found
+/// nothing — the run exactly as written.
+///
+/// PEELED FIRST, which is the ordering that matters. `resolve` is lenient
+/// about a tail it cannot parse (`main.zig:12:3,` yields the FILE and drops
+/// the position, by design), so asking it about the raw run first would
+/// happily answer yes and swallow the comma along with the `:3`. Peeling
+/// first hands it `main.zig:12:3` and the look lands on the column. The raw
+/// run stays as the fallback for the file genuinely named `foo,` or `..`,
+/// where the peel eats something real.
+///
+/// Deliberately NOT a search for the longest resolving substring: that costs
+/// a syscall per prefix to find a path hiding inside a word nobody typed as
+/// one. A run needing a cleverer peel is still one Enter away with the cursor
+/// parked on it.
+///
+/// Direction-free on purpose: n and N ask this the same question about the
+/// same run and get the same span back, which is what lets the two motions be
+/// exact inverses of each other.
+pub fn lookableSpan(word: []const u8, cwd: []const u8, realbuf: *[4096]u8) ?Span {
+ if (word.len == 0) return null;
+ var lo: usize = 0;
+ var hi: usize = word.len;
+ while (lo < hi and std.mem.indexOfScalar(u8, lead_trim, word[lo]) != null) lo += 1;
+ while (hi > lo and std.mem.indexOfScalar(u8, trail_trim, word[hi - 1]) != null) hi -= 1;
+ if (lo < hi and resolve(word[lo..hi], cwd, realbuf) != .none) return .{ .start = lo, .end = hi };
+ // nothing came off, so the peeled attempt WAS the raw one
+ if (lo == 0 and hi == word.len) return null;
+ if (resolve(word, cwd, realbuf) == .none) return null;
+ return .{ .start = 0, .end = word.len };
+}
+
+test "lookableSpan peels prose punctuation off a path, largest first" {
+ if (!platform_has_fs) return;
+ var realbuf: [4096]u8 = undefined;
+ // the bare run resolves whole, wrappers and all left alone
+ try std.testing.expectEqualDeep(
+ @as(?Span, .{ .start = 0, .end = "src/look.zig".len }),
+ lookableSpan("src/look.zig", ".", &realbuf),
+ );
+ // ...and a wrapped one gives back the span INSIDE the wrappers
+ try std.testing.expectEqualDeep(
+ @as(?Span, .{ .start = 1, .end = 1 + "src/look.zig".len }),
+ lookableSpan("(src/look.zig),", ".", &realbuf),
+ );
+ // the `:LINE:COL` tail is part of the span: it is what a look READS
+ try std.testing.expectEqualDeep(
+ @as(?Span, .{ .start = 0, .end = "src/look.zig:12:3".len }),
+ lookableSpan("src/look.zig:12:3,", ".", &realbuf),
+ );
+ // grep -n's trailing delimiter comes off, the line number stays
+ try std.testing.expectEqualDeep(
+ @as(?Span, .{ .start = 0, .end = "src/look.zig:12".len }),
+ lookableSpan("src/look.zig:12:", ".", &realbuf),
+ );
+ try std.testing.expectEqual(@as(?Span, null), lookableSpan("nothing-here", ".", &realbuf));
+ try std.testing.expectEqual(@as(?Span, null), lookableSpan("", ".", &realbuf));
+ try std.testing.expectEqual(@as(?Span, null), lookableSpan("((()))", ".", &realbuf));
+}
+
/// Resolve a looked-at word against the pane's directory. `realbuf` must
/// outlive the returned Target (native paths point into it; web paths are
/// process-lifetime slices in the embedded source archive).
diff --git a/src/macos.zig b/src/macos.zig
index ef68d7e7..dce136f4 100644
--- a/src/macos.zig
+++ b/src/macos.zig
@@ -122,14 +122,15 @@ pub const Image = extern struct {
rgba: [*]const u8,
};
-/// Sync with: pardes_runtime_s. Two callbacks, because everything else the
+/// Sync with: pardes_runtime_s. Three callbacks, because everything else the
/// core asks for it already does itself — it owns the ptys, and look.openLink
-/// hands URLs to /usr/bin/open. Both are optional at the ABI level: a host that
+/// hands URLs to /usr/bin/open. All optional at the ABI level: a host that
/// passes null simply does without, rather than trapping inside the library.
pub const Runtime = extern struct {
userdata: ?*anyopaque = null,
wakeup: ?*const fn (?*anyopaque) callconv(.c) void = null,
set_clipboard: ?*const fn (?*anyopaque, [*]const u8, usize) callconv(.c) void = null,
+ read_clipboard: ?*const fn (?*anyopaque) callconv(.c) void = null,
};
const color_default: u32 = 0x01000000;
@@ -1127,6 +1128,16 @@ fn drainEffects(st: *State, threads_ok: bool) bool {
const y = core.yank orelse continue;
cb(st.runtime.userdata, y.ptr, y.len);
},
+ // The host answers with pardes_paste, which the AppDelegate calls
+ // straight back inside this call: NSPasteboard reads are
+ // synchronous, so the paste event lands here, mid-drain. That is
+ // safe and deliberate — pardes_paste only feeds core.update, and
+ // whatever that queues is picked up by this same loop rather than
+ // waiting a tick. A host with a null callback simply never pastes.
+ .read_clipboard => {
+ const cb = st.runtime.read_clipboard orelse continue;
+ cb(st.runtime.userdata);
+ },
// An empty answer, immediately: the honest reply from a shell with
// no worker, and the only safe one. Tab after a `.` DIVERTS to the
// backend instead of indenting and indents late, when the answer
diff --git a/src/macos/Sources/AppDelegate.swift b/src/macos/Sources/AppDelegate.swift
index cda35ff0..077367a4 100644
--- a/src/macos/Sources/AppDelegate.swift
+++ b/src/macos/Sources/AppDelegate.swift
@@ -162,6 +162,15 @@ final class AppDelegate: NSObject, NSApplicationDelegate, PardesViewDelegate {
let pasteboard = NSPasteboard.general
pasteboard.clearContents()
_ = pasteboard.setString(yank, forType: .string)
+ },
+ read_clipboard: { _ in
+ // Also the main thread, also inside pardes_tick — but this one
+ // answers immediately: NSPasteboard reads are synchronous, so
+ // the paste lands back in the core before this call returns.
+ // No pump, deliberately: the tick that emitted the effect is
+ // still draining and picks up whatever the paste queued.
+ guard let text = NSPasteboard.general.string(forType: .string) else { return }
+ AppDelegate.paste(text)
})
// The real grid, never a placeholder: the core holds each shell's
@@ -590,12 +599,19 @@ final class AppDelegate: NSObject, NSApplicationDelegate, PardesViewDelegate {
func pardesViewRequestsPaste(_ view: PardesView) {
guard let text = NSPasteboard.general.string(forType: .string) else { return }
- // Swift lends a temporary NUL-terminated UTF-8 buffer for the duration
- // of the call, which is exactly as long as the core borrows it.
- pardes_paste(text, text.utf8.count)
+ AppDelegate.paste(text)
pump()
}
+ // Swift lends a temporary NUL-terminated UTF-8 buffer for the duration of
+ // the call, which is exactly as long as the core borrows it. Static, and
+ // pumping is the caller's business: the read_clipboard callback is a C
+ // function pointer that can capture nothing and is already inside a tick,
+ // where the gesture path is not.
+ private static func paste(_ text: String) {
+ pardes_paste(text, text.utf8.count)
+ }
+
// ponytail: one window, no tabs — the core has no multi-window notion, so
// the last window closing really is the end of the process.
func applicationShouldTerminateAfterLastWindowClosed(_ sender: NSApplication) -> Bool {
diff --git a/src/macos/pardes.h b/src/macos/pardes.h
index 1591130e..9a64501a 100644
--- a/src/macos/pardes.h
+++ b/src/macos/pardes.h
@@ -129,7 +129,7 @@ typedef enum {
// ---------------------------------------------------------------- runtime
-// What the host lends the core. Two callbacks, because everything else the
+// What the host lends the core. Three callbacks, because everything else the
// core wants done it already does itself: it owns the ptys, and it opens URLs
// through /usr/bin/open. Copied by value during pardes_init, so the struct
// need only outlive that call.
@@ -145,6 +145,11 @@ typedef struct {
// The yank register changed. `text` is borrowed for the duration of the
// call only. Main thread, inside pardes_tick.
void (*set_clipboard)(void *userdata, const char *text, size_t len);
+
+ // Ask the host for the system clipboard. The host answers by calling
+ // pardes_paste, which may be synchronous inside this call. Main thread,
+ // inside pardes_tick.
+ void (*read_clipboard)(void *userdata);
} pardes_runtime_s;
// ---------------------------------------------------------------- lifecycle
diff --git a/src/output_pane.zig b/src/output_pane.zig
index 8ff98845..37ec6033 100644
--- a/src/output_pane.zig
+++ b/src/output_pane.zig
@@ -83,19 +83,27 @@ pub const Traits = struct {
/// look path resolves, so the buffer IS helix's picker. Prose (a hover
/// blurb, a formatting diff) has nowhere to step to.
steps: bool = false,
- /// ...and what a step DOES with the row it lands on. Off, the row is a
- /// LOCATION and its leading word is LOOKED. On, the row is a COMMAND LINE
- /// and the whole of it is EXECUTED — so walking the list runs each row in
- /// turn, which is what makes a picker over things that take effect
- /// immediately (ThemeSel) a plain list of the words you would have typed.
- /// Both go through the ordinary builtin (config.look_cmd / exec_cmd), so a
- /// row does exactly what the matching mouse button on it would.
+ /// ...and WHAT THE ROWS ARE. Off, each is a LOCATION with a look-able
+ /// `path:LINE:COL` word inside it. On, each is a COMMAND LINE — the whole
+ /// row, exactly as you would have typed it (ThemeSel's `Theme gruvbox`) —
+ /// with no path in it to pick out.
+ ///
+ /// TWO readers, one fact, which is why the column is named for the fact:
+ /// n/N (lookWalk) select the look-able span inside a location row, and
+ /// THE WHOLE LINE of a command row, since the line is
+ /// the unit there. Either way they only select; Enter
+ /// looks what they left, Tab runs it.
+ /// searchStep Looks a location row's leading word and Execs a
+ /// command row whole — still how `]d`/`[d` and acme's
+ /// button-3 arrive somewhere in one gesture.
+ /// Both go through the ordinary builtins (config.look_cmd / exec_cmd), so
+ /// a row does exactly what the matching mouse button on it would.
///
/// Nothing about this is output-pane specific, which is why it is a column
- /// here and not a branch in searchStep: `file_row` answers it too, so a
+ /// here and not a branch in either reader: `file_row` answers it too, so a
/// file pane whose lines happen to be commands is one word away from
/// behaving the same.
- executes: bool = false,
+ commands: bool = false,
/// an answer of exactly ONE row jumps straight there instead of opening
/// this buffer at all — helix: the gotos jump on a single location and
/// show a picker on several, a symbol list is always a picker.
@@ -129,7 +137,7 @@ pub fn traits(o: Origin) Traits {
.name = meta.name,
.steps = meta.steps,
.jumps = meta.jumps,
- .executes = meta.executes,
+ .commands = meta.commands,
};
},
.query => |k| switch (k) {
@@ -358,10 +366,10 @@ pub fn openJumps(p: *Pardes, id: usize) !void {
/// The ThemeSel builtin: the theme ring written out as one `Theme <name>` row
/// per theme — the ordinary builtin with its argument, exactly the line you
-/// would type — into a buffer whose `executes` trait makes n/N RUN each row
-/// rather than look it. So walking the list is trying the themes on, and
-/// stopping on one is choosing it; there is no picker mode, no preview state
-/// and nothing to commit or cancel, because every step already did the thing.
+/// would type — into a buffer whose `commands` trait says the rows are words
+/// and not places. n/N therefore select each row WHOLE and Tab runs it, so
+/// walking the list is trying the themes on and stopping on one is choosing
+/// it: no picker mode, no preview state, nothing to commit or cancel.
///
/// The command's own name comes from the builtin rather than a literal: the
/// word is derived from the struct in exactly one place (builtins.word), and a
diff --git a/src/pardes.zig b/src/pardes.zig
index f95b4e69..ae6c4cbc 100644
--- a/src/pardes.zig
+++ b/src/pardes.zig
@@ -373,8 +373,17 @@ test "MuPDF pane renders, navigates, searches, and round-trips its page" {
const results_id = pane.search_pane orelse return error.MissingPdfSearchResults;
const results = p.panes[results_id].?.file.?.content;
try std.testing.expect(std.mem.indexOf(u8, results, "design.pdf:") != null);
+ // n SELECTS the first result row and opens nothing: the walk's only list
+ // here is the unlooked +Search buffer, so focus lands THERE. Enter is what
+ // jumps, and the document query survives both.
p.update(.{ .key = .{ .cp = 'n' } });
- try std.testing.expect(pane.search_row != null);
+ try std.testing.expectEqual(results_id, p.active);
+ const results_pane = p.panes[results_id].?;
+ try std.testing.expect(results_pane.vsel.active and results_pane.vsel.explicit);
+ try std.testing.expectEqual(@as(i32, 0), results_pane.cur_row);
+ try std.testing.expectEqual(@as(i32, 0), results_pane.cur_col);
+ p.update(.{ .key = .{ .cp = Key.enter } });
+ try std.testing.expectEqual(@as(usize, 0), p.active);
try std.testing.expectEqualStrings("Pardes", pane.pdf.?.search_query);
// Search state is owned and untruncated, and changing pages invalidates
@@ -1255,7 +1264,7 @@ test "PDF builtins and leader paths follow the MuPDF feature gate" {
const traits = output_pane.traits(.{ .cmd = maybe_sections.? });
try std.testing.expectEqualStrings(config.pdf_sections_buffer, traits.name);
try std.testing.expect(traits.steps);
- try std.testing.expect(!traits.executes);
+ try std.testing.expect(!traits.commands);
const help_row = for (builtin_rows) |row| {
if (row.cmd == maybe_sections.?) break row;
} else return error.MissingPdfSectionsHelpRow;
@@ -1431,11 +1440,17 @@ test "PdfSections output, Look, and n/N share exact cached outline destinations"
try std.testing.expectEqual(outline_ptr, pdf_pane.pdf.?.outline.?.entries.ptr);
try std.testing.expectEqual(output_revision, p.panes[output_id].?.file.?.revision);
- // n and N execute the generated row through ordinary Look. The root and
- // child intentionally resolve to the same exact XYZ destination.
+ // n SELECTS the generated row and Enter runs it through ordinary Look, so
+ // the pair is one step of what used to be one keypress. The look is made
+ // FROM the sections buffer, which is what keeps that buffer at the head of
+ // the walk: the next n resumes there even though the jump left focus on
+ // the PDF. The root and child intentionally resolve to the same exact XYZ
+ // destination.
p.active = 0;
p.update(.{ .key = .{ .cp = 'n' } });
- try std.testing.expectEqual(@as(?usize, 0), pdf_pane.search_row);
+ try std.testing.expectEqual(output_id, p.active);
+ try std.testing.expectEqual(@as(i32, 0), output.cur_row);
+ p.update(.{ .key = .{ .cp = Key.enter } });
try std.testing.expectEqual(@as(usize, 1), pdf_pane.pdf.?.page);
const child_destination = pdf_pane.pdf.?.outline.?.entries[1].destination.internal;
const expected_y = @as(f64, @floatFromInt(pdf_pane.pdf.?.page_starts[1])) +
@@ -1443,12 +1458,17 @@ test "PdfSections output, Look, and n/N share exact cached outline destinations"
@as(f64, @floatFromInt(pdf_pane.pdf.?.page_heights[1]));
try std.testing.expectApproxEqAbs(expected_y, pdf_pane.pdf.?.document_scroll_y, 0.001);
p.update(.{ .key = .{ .cp = 'n' } });
- try std.testing.expectEqual(@as(?usize, 1), pdf_pane.search_row);
+ try std.testing.expectEqual(@as(i32, 1), output.cur_row);
+ p.update(.{ .key = .{ .cp = Key.enter } });
try std.testing.expectApproxEqAbs(expected_y, pdf_pane.pdf.?.document_scroll_y, 0.001);
p.update(.{ .key = .{ .cp = 'n' } });
+ p.update(.{ .key = .{ .cp = Key.enter } });
try std.testing.expectEqual(@as(usize, 2), pdf_pane.pdf.?.page);
+ // ...and N is the exact inverse of n: the row it walks back onto is the
+ // one n came from, and looking it lands on the same destination again.
p.update(.{ .key = .{ .cp = 'N' } });
- try std.testing.expectEqual(@as(?usize, 1), pdf_pane.search_row);
+ try std.testing.expectEqual(@as(i32, 1), output.cur_row);
+ p.update(.{ .key = .{ .cp = Key.enter } });
try std.testing.expectEqual(@as(usize, 1), pdf_pane.pdf.?.page);
try std.testing.expectApproxEqAbs(expected_y, pdf_pane.pdf.?.document_scroll_y, 0.001);
@@ -1474,18 +1494,25 @@ test "PdfSections output, Look, and n/N share exact cached outline destinations"
try std.testing.expect(pdf_pane.pdf.?.outline_reveal_pending == null);
try p.setPdfSearchQuery(&pdf_pane.pdf.?, "");
- // Step forward onto the external row: it uses the existing open_link
- // effect and searchStep restores focus to the owning PDF.
- p.active = 0;
+ // Step forward onto the external row: two n's reach it, Enter takes the
+ // existing open_link effect, and a URL look moves focus nowhere — so the
+ // walk is still standing in the buffer, ready for the next n.
+ //
+ // Asked FROM the sections buffer rather than from the PDF, because the two
+ // direct lookAt calls just above put the shell at the head of the ring and
+ // this is a test about the rows, not about the ordering.
+ p.active = output_id;
p.update(.{ .key = .{ .cp = 'n' } });
p.update(.{ .key = .{ .cp = 'n' } });
+ try std.testing.expectEqual(@as(i32, 3), output.cur_row);
+ p.update(.{ .key = .{ .cp = Key.enter } });
var opened = false;
while (p.nextEffect()) |effect| switch (effect) {
.open_link => |uri| opened = std.mem.eql(u8, uri.slice(), "https://example.com/manual"),
else => {},
};
try std.testing.expect(opened);
- try std.testing.expectEqual(@as(usize, 0), p.active);
+ try std.testing.expectEqual(output_id, p.active);
// Missing/hostile coordinates clamp to page space. x affects only a
// layout with horizontal overflow and still does not touch raster state.
@@ -3099,6 +3126,12 @@ pub const Event = union(enum) {
/// with no filesystem (the browser) or no watcher simply never sends one —
/// nothing in the core waits for it.
file_changed: struct { pane: u8, bytes: []const u8 },
+ /// Text from the SYSTEM clipboard, borrowed for this call. Two ways in,
+ /// one handler (applyPaste): SOLICITED, the answer to a `read_clipboard`
+ /// the core emitted for `SPC p` / `SPC P` / `SPC R`, which decides where
+ /// it lands; and UNSOLICITED — an outer terminal's bracketed paste, a
+ /// Cmd-V, the browser's paste event — which means `SPC p`, paste after.
+ /// Neither touches the default register: that is `y`'s alone (helix).
paste: []const u8,
/// One builtin command line, handed to the shell by a pardes launched
/// INSIDE this one (see nested.zig) — `Look /abs/path` and nothing else
@@ -3134,8 +3167,15 @@ pub const Effect = union(enum) {
/// path dump.outPath resolves (acme-style: another instance loads it
/// with -l, or the Restore builtin loads it into this one)
write_dump,
- /// the yank register changed; the shell reads it off the core (OSC 52 out)
+ /// mirror the yank register OUT to the system clipboard; the shell reads
+ /// it off the core (OSC 52 out, SDL_SetClipboardText, NSPasteboard).
+ /// Emitted ONLY by the explicit clipboard commands — see setClipboard.
set_clipboard,
+ /// ...and the other direction: ask the shell to READ the system clipboard.
+ /// The answer comes back as an ordinary `Event.paste`, which the core
+ /// routes to whichever of `SPC p` / `SPC P` / `SPC R` asked for it
+ /// (Pardes.clip_pending). No payload: the bytes travel in the event.
+ read_clipboard,
/// answer a language query OFF the event loop and post the rows back as an
/// `lsp_resp` Event. The shell reads the file's path and content off the
/// core (like save_file) and must SNAPSHOT them before the worker starts —
@@ -3219,6 +3259,15 @@ pub const CharSel = struct {
explicit: bool = false,
};
+/// One position in the n/N walk: a look-able span on one row of one pane,
+/// inclusive of both columns. Also what the walk REMEMBERS having stood on
+/// (Pane.look_at) — see lookStand for why the cursor alone cannot say.
+pub const LookSpot = struct {
+ row: i32,
+ col0: i32,
+ col1: i32,
+};
+
/// ponytail: at most this many cursors at once. helix's `Selection.ranges` is
/// an unbounded Vec; a fixed array keeps a Pane trivially copyable (the undo
/// snapshots memcpy it) and costs nothing at one cursor. The ceiling only
@@ -3718,6 +3767,11 @@ pub const Pane = struct {
prompt: Prompt = .none,
search_pane: ?usize = null,
search_row: ?usize = null,
+ /// Where n/N last stood in this pane, or null when the walk has not been
+ /// here. Distinct from `search_row`, which points into the RESULTS BUFFER
+ /// a search armed on this pane; this one is a place in the pane's own
+ /// text, and n/N step it in every kind of pane.
+ look_at: ?LookSpot = null,
/// The selection an `s`/`S` input was armed on, as gap offsets over the
/// motion surface. Every keystroke re-derives the preview FROM here rather
/// than from the previous preview — which is what helix's regex_prompt
@@ -4346,6 +4400,19 @@ pub const Pardes = struct {
jumps: [MAX_JUMPS]Loc = undefined,
njumps: usize = 0,
jcur: usize = 0,
+ /// THE PANES THAT HAVE LOOKED, oldest first, at most one entry each — the
+ /// spine n/N walks (lookWalkPanes). Serials rather than slots, for the
+ /// same reason the jumplist stores them: a freed slot is reused, and an
+ /// entry naming a dead pane must not resolve to the newcomer sitting in
+ /// its place.
+ ///
+ /// Not the jumplist, though it looks like one. `jumps` records where FOCUS
+ /// has been, and a look moves focus to what it OPENED; this records where
+ /// the look was made FROM, which is the pane holding the list you are
+ /// working through. The two answer different questions and would only
+ /// coincide by accident.
+ look_src: [MAX_PANES]u32 = undefined,
+ n_look_src: usize = 0,
/// hands out Pane.serial; monotonic, never reused
next_serial: u32 = 0,
theme_idx: usize = 0,
@@ -4468,9 +4535,14 @@ pub const Pardes = struct {
effects_head: usize = 0,
effects_len: usize = 0,
- /// modal yank register (gpa-owned); a yank also mirrors out to the system
- /// clipboard via the set_clipboard effect.
+ /// helix's DEFAULT register (gpa-owned): what `y`/`d`/`c` write and
+ /// `p`/`P`/`R` read. Never the system clipboard — `SPC y`/`SPC p` are the
+ /// two commands that cross that line.
yank: ?[]u8 = null,
+ /// a `SPC p`/`SPC P`/`SPC R` waiting on the shell's clipboard read, or
+ /// null. At most one: a second request replaces the first, and any
+ /// keystroke abandons it (update).
+ clip_pending: ?ClipRequest = null,
/// the last serialized dump (gpa-owned), read by the write_dump effect
dump_out: ?[]u8 = null,
/// where the shell wrote the last dump (shell reports back after
@@ -4709,6 +4781,37 @@ pub const Pardes = struct {
} else null;
}
+ /// The slot holding the pane with this serial, if it is still open.
+ pub fn paneBySerial(p: *Pardes, serial: u32) ?usize {
+ return for (p.panes, 0..) |slot, i| {
+ if (slot) |pane| if (pane.serial == serial) break i;
+ } else null;
+ }
+
+ /// `id` just performed a look: put it on top of the walk's spine.
+ ///
+ /// MOVE to the top rather than push, so a pane you keep looking out of
+ /// stays one entry instead of filling the list with itself — the walk's
+ /// order is "which panes, most recent first", not "how many times".
+ /// Dropping the oldest when full can only ever discard a DEAD pane's
+ /// serial: MAX_PANES entries with no duplicates already names every slot
+ /// there is.
+ fn noteLookSource(p: *Pardes, id: usize) void {
+ const pane = p.panes[id] orelse return;
+ var w: usize = 0;
+ for (p.look_src[0..p.n_look_src]) |s| {
+ if (s == pane.serial) continue;
+ p.look_src[w] = s;
+ w += 1;
+ }
+ if (w == p.look_src.len) {
+ std.mem.copyForwards(u32, p.look_src[0 .. w - 1], p.look_src[1..w]);
+ w -= 1;
+ }
+ p.look_src[w] = pane.serial;
+ p.n_look_src = w + 1;
+ }
+
/// chunk arbitrary-length bytes into fixed-size write effects (order kept)
pub fn emitWrite(p: *Pardes, id: usize, bytes: []const u8) void {
var off: usize = 0;
@@ -4830,8 +4933,18 @@ pub const Pardes = struct {
// fight one — at worst it clears something the prompt was already
// hiding.
switch (ev) {
- .key, .mouse => for (p.panes) |slot| {
- if (slot) |pane| pane.msg_len = 0;
+ .key, .mouse => {
+ for (p.panes) |slot| {
+ if (slot) |pane| pane.msg_len = 0;
+ }
+ // ...and the same reasoning bounds a clipboard read in flight.
+ // A terminal that gates or refuses the OSC 52 request never
+ // answers at all, so the request cannot be allowed to sit and
+ // then fire minutes later into whatever pane is focused by
+ // then: it lives exactly until your next keystroke, and a
+ // shell that answers within one round trip (every one but a
+ // refusing tty) is unaffected.
+ p.clip_pending = null;
},
else => {},
}
@@ -4896,11 +5009,7 @@ pub const Pardes = struct {
}
}
},
- .paste => |bytes| {
- // a shell-level paste (bracketed/SDL): load the register, paste
- p.setYank(bytes);
- if (p.panes[p.active]) |pane| p.normalPaste(pane, false);
- },
+ .paste => |bytes| p.applyPaste(bytes),
.command => |line| _ = p.executeBuiltinLine(p.active, line),
.pinch => |scale| p.ov_pinch_scale = scale,
.touch_scroll => |delta| p.ov_touch_scroll_delta = delta,
@@ -4910,6 +5019,11 @@ pub const Pardes = struct {
p.sync();
}
+ /// THE DEFAULT REGISTER, and nothing else. helix: an ordinary `y`/`d`/`c`
+ /// writes here and the system clipboard never hears about it — which is
+ /// also the bug this spelling fixes, because a mirror on every write made
+ /// deleting one character clobber whatever the desktop was holding.
+ /// `SPC y` is the command that crosses over (setClipboard below).
fn setYank(p: *Pardes, text: []const u8) void {
// Inside a multi-selection replay the register collects EVERY range's
// text, in document order — the passes run last-range-first, so each
@@ -4929,6 +5043,84 @@ pub const Pardes = struct {
}
if (p.yank) |y| p.gpa.free(y);
p.yank = p.gpa.dupe(u8, text) catch null;
+ }
+
+ /// ...and the register PLUS the system clipboard, which is the whole
+ /// difference between `y` and `SPC y`.
+ ///
+ /// One mirror per KEYSTROKE rather than per cursor: a multi-selection
+ /// replay runs last-range-first and `multi_first` marks its first pass, so
+ /// emitting there queues exactly one effect — and the shell reads
+ /// `core.yank` when it DRAINS, by which time every later pass has folded
+ /// its range in. That asymmetry used to be a silent hole: the old mirror
+ /// sat past the join's early return, so a multi-cursor yank reached the
+ /// clipboard on one cursor and not on two.
+ fn setClipboard(p: *Pardes, text: []const u8) void {
+ p.setYank(text);
+ if (!p.multi_on or p.multi_first) p.emit(.{ .set_clipboard = {} });
+ }
+
+ /// Where a `SPC p` / `SPC P` / `SPC R` goes once the shell answers.
+ pub const ClipRequest = struct {
+ pane: usize,
+ /// the pane's identity, not its slot: the answer can arrive whole
+ /// keystrokes later (a tty's OSC 52 round trip) and a freed slot is
+ /// reused by an unrelated pane.
+ serial: u32,
+ mode: enum { after, before, replace },
+ };
+
+ /// `SPC p` / `SPC P` / `SPC R`: ask the shell for the system clipboard and
+ /// remember what to do with it. The request is deliberately fire-and-hope
+ /// — a terminal that refuses the OSC 52 read simply never answers, and the
+ /// next keystroke drops the request (see update) rather than letting a
+ /// paste land minutes late in whatever pane is focused by then.
+ pub fn clipRequest(p: *Pardes, id: usize, mode: @FieldType(ClipRequest, "mode")) void {
+ const pane = p.panes[id] orelse return;
+ p.clip_pending = .{ .pane = id, .serial = pane.serial, .mode = mode };
+ p.emit(.read_clipboard);
+ }
+
+ /// The shell answered with system-clipboard text — or the desktop pasted
+ /// into us unasked. Either way the bytes are pasted WITHOUT going through
+ /// the register: helix's clipboard commands and the default register are
+ /// separate stores, and a paste that quietly overwrote your `y` would be
+ /// the same clobbering bug in the other direction.
+ fn applyPaste(p: *Pardes, bytes: []const u8) void {
+ const req = p.clip_pending;
+ p.clip_pending = null;
+ if (bytes.len == 0) return;
+ const id = if (req) |r| r.pane else p.active;
+ const pane = p.panes[id] orelse return;
+ if (req) |r| if (pane.serial != r.serial) return;
+ p.active = id;
+ switch (if (req) |r| r.mode else .after) {
+ .after => p.pasteText(pane, bytes, false),
+ .before => p.pasteText(pane, bytes, true),
+ .replace => p.replaceWithText(pane, bytes),
+ }
+ }
+
+ /// `SPC y` / `SPC Y`: the selection to the system clipboard. `main_only`
+ /// is helix's capital — every cursor's text joined, versus the primary
+ /// selection's alone. A PDF has no editable buffer to replay over, so its
+ /// own selection answers directly.
+ pub fn clipYank(p: *Pardes, pane: *Pane, main_only: bool) void {
+ if (comptime pdf_enabled) if (pane.pdf) |pv| {
+ if (pv.selection_text.len > 0) p.setClipboard(pv.selection_text);
+ return;
+ };
+ // the ordinary `y` path, so what reaches the clipboard is exactly what
+ // the key would have put in the register — including the multi-cursor
+ // join, which is replaySels' business and not a second implementation
+ if (pane.nsel > 0 and !main_only) {
+ p.replaySels(pane, .{ .normal = .{ .edit = .{ .kind = .yank, .count = 1 } } });
+ } else {
+ const others = pane.nsel;
+ pane.nsel = 0;
+ p.normalYank(pane);
+ pane.nsel = others;
+ }
p.emit(.{ .set_clipboard = {} });
}
@@ -5238,8 +5430,16 @@ pub const Pardes = struct {
}
// y — yank what the chord would run: the selection, else the word under
// the cursor. The path is selectable, so this is how you copy it out.
+ //
+ // The ONE register write that still mirrors to the system clipboard
+ // without `SPC` in front of it, and it is not an exception so much as
+ // the only spelling available: a tag is always in insert mode, the
+ // leader is body-normal only, so `SPC y` cannot be pressed here — and
+ // "copy this path somewhere else" is the entire reason the chord
+ // exists. A path that only reached the internal register would be a
+ // key that does nothing you can observe.
if (hit(key, config.tag_yank)) {
- if (p.tagChordText(pane)) |txt| p.setYank(txt);
+ if (p.tagChordText(pane)) |txt| p.setClipboard(txt);
return;
}
// insert entry (one line, so I/A are the tail's ends). The prefix is
@@ -5831,7 +6031,19 @@ pub const Pardes = struct {
const goff: i32 = @intCast(screen.pages.scrollbar().offset);
const vp_row: i32 = pane.gridRow(pane.cur_row) - goff;
if (vp_row >= 0) {
- if (screen.pages.pin(.{ .viewport = .{ .x = @intCast(@max(0, pane.cur_col)), .y = @intCast(vp_row) } })) |click_pin| {
+ // ...and its COLUMN back through the hidden prompt. Outside
+ // tty the prompt row shows the typed command left-hugged at
+ // column 0 (term_pane.promptRow), so a cursor three cells into
+ // what you can see is three cells past the prompt's END on the
+ // real grid — and it is the real grid this pin addresses.
+ var grid_col: i32 = @max(0, pane.cur_col);
+ if (screen.pages.pin(.{ .viewport = .{ .x = 0, .y = @intCast(vp_row) } })) |row_pin| {
+ if (row_pin.rowAndCell().row.semantic_prompt != .none) switch (term_pane.promptCut(row_pin)) {
+ .cut => |cols| grid_col += @intCast(cols),
+ .keep, .blank => {},
+ };
+ }
+ if (screen.pages.pin(.{ .viewport = .{ .x = @intCast(grid_col), .y = @intCast(vp_row) } })) |click_pin| {
const cursor_pin = screen.cursor.page_pin.*;
var pit = cursor_pin.promptIterator(.left_up, null);
if (pit.next()) |prompt_pin| {
@@ -7343,11 +7555,9 @@ pub const Pardes = struct {
},
.pipe_selection => return p.startPipe(pane),
.search => return p.startSearch(pane, config.search_marker),
- .search_step => |direction| {
- const delta: i32 = if (direction == .forward) 1 else -1;
- if (p.searchStep(p.active, delta)) return;
- if (pane.isTerminal()) return p.lookStep(pane, pl, delta);
- },
+ .search_step => |direction| return p.lookWalk(
+ if (direction == .forward) @as(i32, 1) else -1,
+ ),
}
}
@@ -7731,13 +7941,18 @@ pub const Pardes = struct {
try output_pane.fillResults(p, id, dir, from, pat, content, anchor);
}
- /// n/N: step to the next/previous row of this pane's results buffer and
- /// ACT on it — which of the two acme verbs that is comes from the buffer's
- /// own traits, so this is one motion over "a list of things you can run",
- /// not two kinds of stepping. A location list (every search, the jumplist,
- /// every language answer) Looks the leading `path:LINE:COL` word; a command
- /// list (ThemeSel) Execs the whole row. False = no live search: a
- /// terminal's n/N falls back to lookStep, anything else stays put.
+ /// Step to the next/previous row of this pane's results buffer and ACT on
+ /// it — which of the two acme verbs that is comes from the buffer's own
+ /// traits. A location list (every search, every language answer) Looks the
+ /// leading `path:LINE:COL` word; a command list (ThemeSel, FontSel) Execs
+ /// the whole row. False = no live results to step.
+ ///
+ /// n/N used to BE this, and are not any more (lookWalk): stepping a list
+ /// of places now selects and stops, because a step that also opened meant
+ /// you could not walk past a hit without landing on it. What still comes
+ /// through here is what is not n/N at all: `]d`/`[d`, whose whole job is
+ /// to GO to the next diagnostic, and acme's button-3, where clicking a
+ /// word that names nothing searches for it and goes to the first hit.
fn searchStep(p: *Pardes, id: usize, delta: i32) bool {
const pane = p.panes[id] orelse return false;
const rid = pane.search_pane orelse return false;
@@ -7772,7 +7987,7 @@ pub const Pardes = struct {
// clicked row can never drift apart. A command row goes whole (its
// argument is the tail after the name); a location row is cut to the
// leading file-ish word, since the rest of it is the matched text.
- if (tr.executes) {
+ if (tr.commands) {
p.runBuiltin(config.exec_cmd, rid, "", std.mem.trim(u8, ln, " \t\r"));
} else {
var hi: usize = 0;
@@ -7964,59 +8179,260 @@ pub const Pardes = struct {
p.reportError(w.pane, "language response", err);
}
- /// n/N on a terminal pane: a MOTION over lookable tokens. Select the
- /// next/prev whitespace-separated token that look.resolve can turn into a
- /// file/dir (several per line: an ls row hops big.txt -> plain.txt), park
- /// the cursor at its start, open NOTHING — Enter's normal-mode handler
- /// looks the selection. Wraps around when nothing lies in the direction
- /// (fresh out of tty mode the cursor sits below the output, so the first
- /// n lands on the first token). Deliberately only THIS pane's directory,
- /// where the look itself walks every pane's: the motion resolves every
- /// token it steps over, so the other directories would cost tokens ×
- /// panes realpaths on a single keystroke — and a token the motion skips
- /// is still openable by looking it, which is all n/N is a shortcut for.
- fn lookStep(p: *Pardes, pane: *Pane, pl: PaneLines, delta: i32) void {
- _ = p; // a pure motion now: Enter's normal-mode handler does the look
- pane.pinCursor(); // fresh out of tty mode the cursor still tracks the shell
+ // ---- n/N: the walk over look-able text ----
+
+ /// How many rows ONE PRESS may scan, across every pane it visits. A
+ /// shell's motion surface is its whole scrollback and every whitespace run
+ /// on it costs a realpath, so the walk is bounded.
+ ///
+ /// Running out STOPS the walk where it stands rather than treating the
+ /// pane as exhausted and moving on, and that distinction is load-bearing:
+ /// giving up in the middle of a pane and hopping to the next one would
+ /// make the two directions disagree about where a pane ENDS, and n/N have
+ /// to be exact inverses. Not moving is the one failure that always is.
+ /// A pane whose next look-able text is eight thousand rows away is a pane
+ /// to scroll, not to step.
+ const max_look_rows = 8192;
+
+ /// Where a step STARTS inside a pane. `col` null enters the pane at the
+ /// row's edge — every span on it is ahead of you — which is what a hop
+ /// from a neighbouring pane does. `strict` says the column is a position
+ /// the walk itself established, so the span sitting ON it is the one you
+ /// are already at and the step must go past it.
+ const LookFrom = struct { row: i32, col: ?i32, strict: bool = false };
+
+ /// Entering a pane from a neighbour: the first row going forward, the last
+ /// going back. Spelled once because it is exactly what makes the two
+ /// directions inverses across a pane boundary.
+ fn lookEdge(delta: i32) LookFrom {
+ return .{ .row = if (delta > 0) 0 else std.math.maxInt(i32), .col = null };
+ }
+
+ /// Where the walk currently stands in `pane`.
+ ///
+ /// `Pane.look_at` and not the cursor alone, because the cursor cannot
+ /// answer the question. A cursor parked on the first look-able span may
+ /// mean the walk put it there — so the next step is the SECOND span — or
+ /// that the pane simply opened that way, which is every fresh +Search, and
+ /// there the next step must be the FIRST. `search_row` answered the same
+ /// question the same way for the same reason. When the recorded stand no
+ /// longer matches the cursor you have moved it yourself since, and the
+ /// cursor wins: the walk continues from where you are looking.
+ fn lookStand(pane: *Pane) LookFrom {
+ if (pane.look_at) |s| if (s.row == pane.cur_row and s.col0 == pane.cur_col)
+ return .{ .row = s.row, .col = s.col0, .strict = true };
+ return .{ .row = pane.cur_row, .col = pane.cur_col };
+ }
+
+ /// The panes n/N walk, in the order it walks them: every pane that has
+ /// performed a LOOK, most recent first, then the OUTPUT buffers none has,
+ /// newest first — and, only when that comes to nothing at all, the pane
+ /// you are in.
+ ///
+ /// The look history is the spine because looking is what marks a pane as
+ /// the one you are reading things OUT of — the +Search you are stepping,
+ /// the diagnostics list, the shell whose `ls` rows you keep opening. The
+ /// unlooked output buffers come after it so a fresh `/`, which has looked
+ /// at nothing yet, still has somewhere for the first `n` to go: its own
+ /// results. FILO among them, so two searches step the newer list first.
+ ///
+ /// The ACTIVE pane is the fallback and NOT a member, which is the
+ /// difference between n continuing a list and n wandering off it. Look a
+ /// row out of a +Search and focus lands in the file that opened; the next
+ /// n has to go back to the +Search, not start walking the paths that
+ /// happen to be in the source you just opened. Only when nothing has
+ /// looked and no buffer has answered — a shell one minute into a session,
+ /// which is where n/N started life — is the pane in front of you the list.
+ fn lookWalkPanes(p: *Pardes, out: *[MAX_PANES]usize) []const usize {
+ var n: usize = 0;
+ var i = p.n_look_src;
+ while (i > 0) {
+ i -= 1;
+ const id = p.paneBySerial(p.look_src[i]) orelse continue;
+ out[n] = id;
+ n += 1;
+ }
+ const looked = n;
+ for (p.panes, 0..) |slot, id| {
+ const pane = slot orelse continue;
+ const f = pane.file orelse continue;
+ if (f.output == null) continue;
+ for (out[0..looked]) |k| {
+ if (k == id) break;
+ } else {
+ // insertion by serial descending — at most MAX_PANES
+ // comparisons, which is not a sort worth naming
+ var at = n;
+ while (at > looked and p.panes[out[at - 1]].?.serial < pane.serial) : (at -= 1)
+ out[at] = out[at - 1];
+ out[at] = id;
+ n += 1;
+ }
+ }
+ if (n == 0) {
+ if (p.panes[p.active] == null) return out[0..0];
+ out[0] = p.active;
+ n = 1;
+ }
+ return out[0..n];
+ }
+
+ /// The next STEPPABLE span in `pane` from `from`, in `delta`'s direction,
+ /// or null when the pane has none left that way. `budget` is the caller's
+ /// remaining row allowance and is spent here; a null return with a budget
+ /// of zero means GAVE UP, not exhausted (see max_look_rows).
+ ///
+ /// One flag decides what a span IS. In an ordinary pane it is the largest
+ /// look-able run on the row (look.lookableSpan) and a row may hold several
+ /// — an `ls` line hops big.txt -> plain.txt -> sub. In a buffer whose rows
+ /// are COMMANDS (output_pane.Traits.commands: ThemeSel, FontSel) it is the
+ /// WHOLE LINE, because `Theme gruvbox` has no path inside it to pick out
+ /// and the line is the unit you would run. Same motion, same selection,
+ /// same Enter/Tab afterwards; only the grain differs.
+ ///
+ /// Symmetric by construction either way, and that is the whole point: both
+ /// directions ask the same question about the same rows, and both compare
+ /// against `col0` — the column the walk parks the cursor on. So a step
+ /// forward off a span and a step back onto it are the same two positions
+ /// read in the two orders.
+ fn lookSpanIn(p: *Pardes, pane: *Pane, from: LookFrom, delta: i32, budget: *usize) ?LookSpot {
+ const pl = p.paneCursorLines(pane) catch return null;
const nrows: i32 = @intCast(pl.lines.len);
- if (nrows == 0) return;
+ if (nrows == 0) return null;
+ const whole_row = if (pane.file) |*f| output_pane.fileTraits(f.output).commands else false;
+ const dir = paneDir(pane);
var realbuf: [4096]u8 = undefined;
- var k: i32 = 0;
- while (k < nrows) : (k += 1) {
- const r = @mod(pane.cur_row + delta * k, nrows);
+ const start = std.math.clamp(from.row, 0, nrows - 1);
+ var r = start;
+ while (r >= 0 and r < nrows) : (r += delta) {
+ if (budget.* == 0) return null;
+ budget.* -= 1;
const ln = pl.lines[@intCast(r)];
- var hit_t0: usize = 0;
- var hit_t1: usize = 0;
+ var best: ?LookSpot = null;
var i: usize = 0;
while (i < ln.len) {
while (i < ln.len and (ln[i] == ' ' or ln[i] == '\t')) i += 1;
const t0 = i;
- while (i < ln.len and ln[i] != ' ' and ln[i] != '\t') i += 1;
- if (i == t0) break;
- // on the cursor's own row (no wrap yet) only tokens strictly
- // past the cursor count, in the motion's direction
- if (k == 0) {
- if (delta > 0 and @as(i32, @intCast(t0)) <= pane.cur_col) continue;
- if (delta < 0 and @as(i32, @intCast(t0)) >= pane.cur_col) continue;
+ var spot: LookSpot = undefined;
+ if (whole_row) {
+ // one span per row, from its first non-blank cell to its
+ // last: the trailing trim keeps a padded row selecting the
+ // command and not the padding
+ const end = std.mem.trimEnd(u8, ln, " \t\r").len;
+ if (end <= t0) break;
+ i = end;
+ spot = .{ .row = r, .col0 = @intCast(t0), .col1 = @intCast(end - 1) };
+ } else {
+ while (i < ln.len and ln[i] != ' ' and ln[i] != '\t') i += 1;
+ if (i == t0) break;
+ const sp = look.lookableSpan(ln[t0..i], dir, &realbuf) orelse continue;
+ spot = .{
+ .row = r,
+ .col0 = @intCast(t0 + sp.start),
+ .col1 = @intCast(t0 + sp.end - 1),
+ };
}
- if (look.resolve(ln[t0..i], pane.cwdSlice(), &realbuf) == .none) continue;
- hit_t0 = t0;
- hit_t1 = i;
- if (delta > 0) break; // first token forward; keep the last one backward
+ // AFTER the span, never before it, and against `col0` rather
+ // than the whitespace run's start. Those are different columns
+ // the moment a wrapper is peeled: `(mise.toml)` is a run
+ // starting at 0 and a span starting at 1, and a backward step
+ // filtered on the run would find the span it is standing on
+ // still ahead of it and never leave the row. Only the start row
+ // is filtered at all, so the resolves this costs are one row's.
+ if (r == start) if (from.col) |c| {
+ if (delta > 0 and (if (from.strict) spot.col0 <= c else spot.col0 < c)) continue;
+ if (delta < 0 and (if (from.strict) spot.col0 >= c else spot.col0 > c)) continue;
+ };
+ best = spot;
+ if (delta > 0) break; // first one forward; keep the last one back
}
- if (hit_t1 == 0) continue;
- // anchor the selection at the token's end, cursor at its START;
- // EXPLICIT: Enter's look chord acts on it
- pane.vsel = .{ .active = true, .row = r, .col = @intCast(hit_t1 - 1), .explicit = true };
- pane.msel.active = false;
- pane.nsel = 0;
- pane.cur_row = r;
- pane.cur_col = @intCast(hit_t0);
- pane.cur_pinned = true;
- pane.ensureCursorVisible();
- return;
+ if (best) |b| return b;
+ }
+ return null;
+ }
+
+ /// n/N: move the SELECTION to the next/previous look-able text and open
+ /// NOTHING. Enter looks what this leaves selected, and that separation is
+ /// the change: a step is a motion you can take twenty of and then decide,
+ /// where it used to be twenty panes.
+ ///
+ /// The sequence stepped is the concatenation, in lookWalkPanes' order, of
+ /// each pane's look-able spans in document order, AND IT IS A RING. `n` is
+ /// the next position on that ring and `N` the previous one, computed the
+ /// same way from the same state — so x presses one way and x back land
+ /// exactly where you started, across pane boundaries included: a pane
+ /// entered forward is entered at its FIRST span, and leaving it backward
+ /// from that span drops into the previous pane's LAST.
+ ///
+ /// A ring rather than a list with two ends, for two reasons that turn out
+ /// to be one. A shell's cursor sits at the PROMPT, below everything it has
+ /// printed, so a walk that could not come round would have nowhere to go
+ /// on the very first press — which is the case n/N was written for. And a
+ /// ring is still exactly reversible, so nothing is given up for it: acme's
+ /// search has always been one, and this is that.
+ ///
+ /// (One press is not symmetric, and cannot be: from a cursor the walk has
+ /// never stood on, the first step ACQUIRES a position rather than moving
+ /// one — see lookStand. Every press after that is exact.)
+ ///
+ /// No walk state outside the panes themselves, which is what makes this
+ /// robust where the old stepper was not: nothing to go stale when a search
+ /// refills, a pane closes, or you move the cursor and step on from there.
+ ///
+ /// ONE MOTION, EVERYWHERE. Not a pane kind, not a buffer kind, not a mode:
+ /// n/N are this walk in all of them, which is the other half of making
+ /// them trustworthy. A PDF used to step its results buffer and jump; it
+ /// steps the same ring now, which IS that buffer, and Enter does the
+ /// jumping. The single thing any buffer gets to change is the GRAIN of
+ /// what a step selects, and it changes it with one flag rather than a
+ /// branch here: `Traits.commands` makes a row select WHOLE, because a
+ /// ThemeSel line is a word to run and not a place to go (lookSpanIn).
+ ///
+ /// `]d`/`[d` are not n/N. They are helix's diagnostic motions, their job
+ /// is to ARRIVE at the next diagnostic, and they still reach searchStep.
+ fn lookWalk(p: *Pardes, delta: i32) void {
+ var buf: [MAX_PANES]usize = undefined;
+ const order = p.lookWalkPanes(&buf);
+ if (order.len == 0) return;
+ // Start where you ARE when that is somewhere the walk goes; otherwise
+ // at its head, which after a look is the pane you looked FROM — the
+ // look focused what it OPENED, and that is not a walk pane.
+ const at: usize = for (order, 0..) |id, i| {
+ if (id == p.active) break i;
+ } else 0;
+ var from = lookStand(p.panes[order[at]] orelse return);
+ // ...then every OTHER pane once, in the direction of travel, entered
+ // at its edge — and `k == order.len` brings the starting pane round a
+ // second time, from ITS edge, which is the wrap. That bound is also
+ // what makes a screen with nothing look-able on it terminate.
+ var budget: usize = max_look_rows;
+ var k: usize = 0;
+ while (k <= order.len) : (k += 1) {
+ // `+ 2 * len` only so the backward subtraction stays unsigned
+ const idx = (if (delta > 0) at + k else at + 2 * order.len - k) % order.len;
+ const pane = p.panes[order[idx]] orelse continue;
+ if (p.lookSpanIn(pane, from, delta, &budget)) |spot|
+ return p.landLookSpot(order[idx], pane, spot);
+ if (budget == 0) return; // gave up mid-pane: stay put, stay reversible
+ from = lookEdge(delta);
}
- // nothing lookable anywhere: stay put
+ }
+
+ /// Select `spot` and focus its pane. The selection is EXPLICIT so Enter's
+ /// look chord acts on it, with the anchor on the span's last cell and the
+ /// cursor on its FIRST — the same shape the old terminal stepper left, and
+ /// the reason `col0` is the position the walk compares against.
+ fn landLookSpot(p: *Pardes, id: usize, pane: *Pane, spot: LookSpot) void {
+ pane.pinCursor(); // fresh out of tty mode the cursor still tracks the shell
+ pane.vsel = .{ .active = true, .row = spot.row, .col = spot.col1, .explicit = true };
+ pane.msel.active = false;
+ pane.nsel = 0;
+ pane.cur_row = spot.row;
+ pane.cur_col = spot.col0;
+ pane.cur_pinned = true;
+ pane.look_at = spot;
+ p.active = id;
+ pane.ensureCursorVisible();
}
const EditText = struct { text: []u8, row0: i32 };
@@ -8601,13 +9017,20 @@ pub const Pardes = struct {
}
}
- /// helix p/P: a yank ending in '\n' pastes as whole lines below/above
- /// the SELECTION's line span; anything else splices inline at the
- /// selection's outer edge. The paste (repeated <count> times) becomes
- /// the implicit selection, cursor on its last char (linewise: ON the
- /// last pasted line's newline).
+ /// helix p/P: the DEFAULT register, after/before the selection.
fn normalPaste(p: *Pardes, pane: *Pane, before: bool) void {
- const y0 = p.yank orelse return;
+ p.pasteText(pane, p.yank orelse return, before);
+ }
+
+ /// ...and the paste itself, over text from wherever: the register above,
+ /// or the system clipboard `SPC p` asked the shell for, which deliberately
+ /// never passes through the register on its way here.
+ ///
+ /// Text ending in '\n' pastes as whole lines below/above the SELECTION's
+ /// line span; anything else splices inline at the selection's outer edge.
+ /// The paste (repeated <count> times) becomes the implicit selection,
+ /// cursor on its last char (linewise: ON the last pasted line's newline).
+ fn pasteText(p: *Pardes, pane: *Pane, y0: []const u8, before: bool) void {
if (y0.len == 0) return;
p.pushUndo(pane);
pane.select = false;
@@ -8830,11 +9253,15 @@ pub const Pardes = struct {
p.setEditText(pane, new);
}
- /// `R`: replace the selection (or the cursor char) with the yank register;
- /// the pasted text becomes the selection, head on its last char (which
- /// for a trailing-newline yank is the '\n' cell of the last full line)
+ /// `R`: replace the selection (or the cursor char) with the DEFAULT
+ /// register. `SPC R` is the same verb over the system clipboard.
fn normalReplaceYank(p: *Pardes, pane: *Pane) void {
- const y = p.yank orelse return;
+ p.replaceWithText(pane, p.yank orelse return);
+ }
+
+ /// The pasted text becomes the selection, head on its last char (which for
+ /// a trailing-newline `y` is the '\n' cell of the last full line).
+ fn replaceWithText(p: *Pardes, pane: *Pane, y: []const u8) void {
if (y.len == 0) return;
pane.select = false;
const eb = p.editTextEol(pane, selRows(pane)) orelse return;
@@ -11566,9 +11993,13 @@ pub const Pardes = struct {
if (pane.tag_edit) pane.mode = .normal;
},
.search => p.startSearch(pane, config.search_marker),
- .search_step => |direction| {
- _ = p.searchStep(p.active, if (direction == .forward) 1 else -1);
- },
+ // A PDF is not a special case: it steps the same ring every other
+ // pane does, which in practice is the +Search or +PdfSections
+ // buffer its own search filled. n selects the row, Enter jumps to
+ // the page.
+ .search_step => |direction| return p.lookWalk(
+ if (direction == .forward) @as(i32, 1) else -1,
+ ),
else => {},
}
}
@@ -11760,6 +12191,10 @@ pub const Pardes = struct {
pub fn lookAt(p: *Pardes, id: usize, txt: []const u8) void {
const pane = p.panes[id] orelse return;
p.noteHaptic(.look);
+ // ...and this pane is now the head of the n/N walk. Recorded HERE, at
+ // the one dispatcher every look reaches, so a right click, an Enter, a
+ // stepped result row and the word `Look` all count alike.
+ p.noteLookSource(id);
const trimmed = std.mem.trim(u8, txt, " \t\r\n");
// `` @`ls -la` `` names a COMMAND, not a path: run it, and land in the
// pane that answers — looking at a thing means being SHOWN it, and a
@@ -12184,10 +12619,9 @@ pub const Pardes = struct {
var row: i32 = 0;
var skip: i32 = 0;
while (lines.next()) |raw| : (row += 1) {
- const is_prompt = if (pane.mode != .tty)
- if (prompts.next()) |pin| pin.rowAndCell().row.semantic_prompt != .none else false
- else
- false;
+ // stepped for EVERY line, before the skip below, or the
+ // row iterator falls out of step with the dump's lines
+ const prompt_pin = if (pane.mode != .tty) prompts.next() else null;
if (skip > 0) {
skip -= 1;
continue;
@@ -12202,7 +12636,15 @@ pub const Pardes = struct {
skip = o.rows - 1;
continue;
};
- const shown = if (is_prompt) "" else raw;
+ // same rule the motion surface and the body use, so a dump
+ // reloads showing exactly what the pane showed
+ const shown = if (prompt_pin) |pin|
+ if (pin.rowAndCell().row.semantic_prompt != .none)
+ term_pane.promptRow(pin, raw)
+ else
+ raw
+ else
+ raw;
@memcpy(stream_buf[stream_len..][0..shown.len], shown);
stream_len += shown.len;
}
@@ -13814,3 +14256,360 @@ test "hopping between two panes does not grow the jump stack" {
try std.testing.expect(p.active != before);
try std.testing.expectEqual(depth, p.njumps);
}
+
+/// A results buffer with rows we control: three look-able locations and one
+/// row with nothing look-able on it at all. Returns its slot. `pat` is the
+/// recorded pattern and is what keeps two of these APART — fillResults refills
+/// a buffer whose origin, argument and directory all match.
+fn walkFixture(p: *Pardes, id: usize, cwd: []const u8, pat: []const u8) !usize {
+ const rows = try std.fmt.allocPrint(p.gpa,
+ \\build.zig:1:1 first
+ \\(mise.toml) and build.zig.zon:3:2-9 two on one row
+ \\nothing look-able on this row at all
+ \\uucode_config.zig:7:1 last
+ \\
+ , .{});
+ try output_pane.fillResults(p, id, cwd, .search, pat, rows, null);
+ return p.panes[id].?.search_pane orelse error.MissingResults;
+}
+
+test "n/N select look-able text and open nothing" {
+ if (platform == .web) return;
+ const gpa = std.testing.allocator;
+ var cwdbuf: [4096]u8 = undefined;
+ const cwd = std.mem.span(@as([*:0]u8, @ptrCast(std.c.getcwd(&cwdbuf, cwdbuf.len) orelse return)));
+ var pathbuf: [4096]u8 = undefined;
+ const boot = try std.fmt.bufPrint(&pathbuf, "{s}/mise.toml", .{cwd});
+
+ const p = try Pardes.init(gpa, .{ .cols = 100, .rows = 40, .file = boot });
+ defer p.deinit();
+ p.update(.{ .resize = .{ .cols = 100, .rows = 40 } });
+ const rid = try walkFixture(p, p.active, cwd, "one");
+ const rp = p.panes[rid].?;
+ const panes_before = p.freeSlot();
+
+ // Nothing has looked yet, so the walk's list is the one unvisited output
+ // buffer. The first n lands on row 0's leading token, FOCUSES that buffer,
+ // and opens nothing whatsoever.
+ p.update(.{ .key = .{ .cp = 'n' } });
+ try std.testing.expectEqual(rid, p.active);
+ try std.testing.expectEqual(panes_before, p.freeSlot());
+ try std.testing.expectEqual(@as(i32, 0), rp.cur_row);
+ try std.testing.expectEqual(@as(i32, 0), rp.cur_col);
+ // EXPLICIT, anchored on the span's last cell: what Enter's look acts on
+ try std.testing.expect(rp.vsel.active and rp.vsel.explicit);
+ try std.testing.expectEqualStrings("build.zig:1:1", p.currentSelText(rp) orelse "");
+
+ // Row 1 holds TWO: a parenthesised path, whose wrappers are peeled off the
+ // selection, and a `path:LINE:COL-END` whose position tail is kept.
+ p.update(.{ .key = .{ .cp = 'n' } });
+ try std.testing.expectEqual(@as(i32, 1), rp.cur_row);
+ try std.testing.expectEqualStrings("mise.toml", p.currentSelText(rp) orelse "");
+ p.update(.{ .key = .{ .cp = 'n' } });
+ try std.testing.expectEqual(@as(i32, 1), rp.cur_row);
+ try std.testing.expectEqualStrings("build.zig.zon:3:2-9", p.currentSelText(rp) orelse "");
+
+ // Row 2 has nothing to step to and is skipped entirely.
+ p.update(.{ .key = .{ .cp = 'n' } });
+ try std.testing.expectEqual(@as(i32, 3), rp.cur_row);
+ try std.testing.expectEqualStrings("uucode_config.zig:7:1", p.currentSelText(rp) orelse "");
+
+ // Past the last span the ring comes round to the first.
+ p.update(.{ .key = .{ .cp = 'n' } });
+ try std.testing.expectEqual(@as(i32, 0), rp.cur_row);
+
+ // ...and Enter on a selection is what finally opens something.
+ p.update(.{ .key = .{ .cp = Key.enter } });
+ try std.testing.expect(p.freeSlot() != panes_before);
+ try std.testing.expect(std.mem.endsWith(u8, p.panes[p.active].?.file.?.path, "/build.zig"));
+}
+
+test "N is the exact inverse of n, across panes and the ring's seam" {
+ if (platform == .web) return;
+ const gpa = std.testing.allocator;
+ var cwdbuf: [4096]u8 = undefined;
+ const cwd = std.mem.span(@as([*:0]u8, @ptrCast(std.c.getcwd(&cwdbuf, cwdbuf.len) orelse return)));
+ var pathbuf: [4096]u8 = undefined;
+ const boot = try std.fmt.bufPrint(&pathbuf, "{s}/mise.toml", .{cwd});
+
+ const p = try Pardes.init(gpa, .{ .cols = 100, .rows = 40, .file = boot });
+ defer p.deinit();
+ p.update(.{ .resize = .{ .cols = 100, .rows = 40 } });
+
+ // TWO buffers, so the walk has a pane boundary to cross and a seam to wrap
+ // over — the two places a hand-rolled inverse gets it wrong.
+ const first = try walkFixture(p, p.active, cwd, "one");
+ p.update(.{ .key = .{ .cp = 'n', .alt = true } }); // a shell to hang the second off
+ p.sync();
+ const second = try walkFixture(p, p.active, cwd, "two");
+ try std.testing.expect(first != second);
+
+ const Mark = struct { pane: usize, row: i32, col: i32 };
+ const here = struct {
+ fn at(pp: *Pardes) Mark {
+ const pane = pp.panes[pp.active].?;
+ return .{ .pane = pp.active, .row = pane.cur_row, .col = pane.cur_col };
+ }
+ }.at;
+
+ // The FIRST press only acquires a position — before it the cursor is
+ // wherever the shell left it, which is not a place on the ring — so the
+ // symmetry claim starts one step in. Everything after that is exact.
+ p.update(.{ .key = .{ .cp = 'n' } });
+ const base = here(p);
+
+ // Twelve more forward is further than either buffer holds, so the trail
+ // crosses both pane boundaries and wraps over the seam; record every
+ // position it passes through.
+ var trail: [12]Mark = undefined;
+ for (&trail) |*m| {
+ p.update(.{ .key = .{ .cp = 'n' } });
+ m.* = here(p);
+ }
+ // ...and twelve back must retrace it exactly, position by position, ending
+ // on the one the count started from.
+ var i = trail.len;
+ while (i > 0) {
+ i -= 1;
+ p.update(.{ .key = .{ .cp = 'N' } });
+ const want = if (i == 0) base else trail[i - 1];
+ try std.testing.expectEqual(want.pane, p.active);
+ try std.testing.expectEqual(want.row, p.panes[p.active].?.cur_row);
+ try std.testing.expectEqual(want.col, p.panes[p.active].?.cur_col);
+ }
+
+ // The walk visited both buffers rather than circling inside one.
+ var saw_first = false;
+ var saw_second = false;
+ for (trail) |m| {
+ if (m.pane == first) saw_first = true;
+ if (m.pane == second) saw_second = true;
+ }
+ try std.testing.expect(saw_first and saw_second);
+}
+
+test "n/N select a command row whole, and a look puts its pane at the head" {
+ if (platform == .web) return;
+ const gpa = std.testing.allocator;
+ var cwdbuf: [4096]u8 = undefined;
+ const cwd = std.mem.span(@as([*:0]u8, @ptrCast(std.c.getcwd(&cwdbuf, cwdbuf.len) orelse return)));
+ var pathbuf: [4096]u8 = undefined;
+ const boot = try std.fmt.bufPrint(&pathbuf, "{s}/mise.toml", .{cwd});
+
+ const p = try Pardes.init(gpa, .{ .cols = 100, .rows = 40, .file = boot });
+ defer p.deinit();
+ p.update(.{ .resize = .{ .cols = 100, .rows = 40 } });
+
+ // A COMMAND list: its rows are words to run, so a step takes the whole
+ // line — there is no path inside `Theme acme` to pick out.
+ p.runBuiltin(.ThemeSel, p.active, "", null);
+ const tid = p.panes[p.active].?.search_pane orelse return error.MissingThemeList;
+ const tp = p.panes[tid].?;
+ try std.testing.expect(output_pane.fileTraits(tp.file.?.output).commands);
+ p.update(.{ .key = .{ .cp = 'n' } });
+ try std.testing.expectEqual(tid, p.active);
+ const row0 = std.mem.trimEnd(u8, modal.lineSlice(tp.file.?.content, 0), " \t\r");
+ try std.testing.expectEqualStrings(row0, p.currentSelText(tp) orelse "");
+ // ...and Tab RUNS what n selected, which is how a theme is worn now.
+ const theme_before = p.theme_idx;
+ p.update(.{ .key = .{ .cp = 'n' } });
+ p.update(.{ .key = .{ .cp = Key.tab } });
+ try std.testing.expect(p.theme_idx != theme_before);
+
+ // A LOOK is what puts a pane at the head of the walk. Look from the boot
+ // pane and the next n steps THERE, not in the theme list, even though the
+ // look moved focus into whatever it opened.
+ p.runBuiltin(.Look, 0, "", "build.zig");
+ p.sync();
+ try std.testing.expect(p.active != 0);
+ p.update(.{ .key = .{ .cp = 'n' } });
+ try std.testing.expectEqual(@as(usize, 0), p.active);
+}
+
+/// Drain the queue and say whether the shell was asked to do `want`.
+fn drainedEffect(p: *Pardes, want: std.meta.Tag(Effect)) bool {
+ var seen = false;
+ while (p.nextEffect()) |effect| {
+ if (std.meta.activeTag(effect) == want) seen = true;
+ }
+ return seen;
+}
+
+test "only the SPC clipboard commands cross to the system clipboard" {
+ if (platform == .web) return;
+ const gpa = std.testing.allocator;
+ const p = try Pardes.init(gpa, .{ .cols = 80, .rows = 24, .file = "mise.toml" });
+ defer p.deinit();
+ p.update(.{ .resize = .{ .cols = 80, .rows = 24 } });
+ const pane = p.panes[0].?;
+
+ // An ordinary yank fills the DEFAULT REGISTER and asks the shell for
+ // nothing. This is the whole helix split, and the bug it closes: before
+ // it, every y/d/c mirrored out, so deleting one character threw away
+ // whatever the desktop was holding.
+ _ = drainedEffect(p, .set_clipboard);
+ p.update(.{ .key = .{ .cp = 'y' } });
+ try std.testing.expect(p.yank != null and p.yank.?.len > 0);
+ try std.testing.expect(!drainedEffect(p, .set_clipboard));
+ p.update(.{ .key = .{ .cp = 'd' } });
+ try std.testing.expect(!drainedEffect(p, .set_clipboard));
+
+ // `SPC y` is the one that does, and it puts the SAME text there that `y`
+ // put in the register — it is the ordinary yank path plus the mirror.
+ p.update(.{ .key = .{ .cp = ' ' } });
+ p.update(.{ .key = .{ .cp = 'y' } });
+ const yanked = p.yank orelse return error.MissingYank;
+ try std.testing.expect(drainedEffect(p, .set_clipboard));
+
+ // `SPC p` cannot read the clipboard itself: it ASKS, and the answer comes
+ // back as an ordinary paste event whenever (or never — a terminal may
+ // refuse the OSC 52 read, which is a no-op and not a hang).
+ const before = pane.file.?.content.len;
+ p.update(.{ .key = .{ .cp = ' ' } });
+ p.update(.{ .key = .{ .cp = 'p' } });
+ try std.testing.expect(p.clip_pending != null);
+ try std.testing.expect(drainedEffect(p, .read_clipboard));
+ try std.testing.expectEqual(before, pane.file.?.content.len); // nothing yet
+ p.update(.{ .paste = "PASTED" });
+ try std.testing.expect(p.clip_pending == null);
+ try std.testing.expect(std.mem.indexOf(u8, pane.file.?.content, "PASTED") != null);
+ // ...and it did NOT land in the register on its way past, nor echo back
+ // out to the clipboard it came from.
+ try std.testing.expectEqualStrings(yanked, p.yank orelse "");
+ try std.testing.expect(!drainedEffect(p, .set_clipboard));
+
+ // An UNSOLICITED paste — the outer terminal's bracketed paste, a Cmd-V —
+ // is the same event with no request behind it, and means paste after.
+ p.update(.{ .paste = "UNASKED" });
+ try std.testing.expect(std.mem.indexOf(u8, pane.file.?.content, "UNASKED") != null);
+ try std.testing.expectEqualStrings(yanked, p.yank orelse "");
+
+ // A request the shell never answers dies at the next keystroke rather
+ // than firing late into whatever pane is focused by then.
+ p.update(.{ .key = .{ .cp = ' ' } });
+ p.update(.{ .key = .{ .cp = 'P' } });
+ try std.testing.expect(p.clip_pending != null);
+ p.update(.{ .key = .{ .cp = 'l' } });
+ try std.testing.expect(p.clip_pending == null);
+}
+
+test "leaving tty hides the prompt and keeps the command typed at it" {
+ if (platform == .web) return;
+ const gpa = std.testing.allocator;
+ const p = try Pardes.init(gpa, .{ .cols = 80, .rows = 24, .file = "mise.toml" });
+ defer p.deinit();
+ p.update(.{ .resize = .{ .cols = 80, .rows = 24 } });
+ p.update(.{ .key = .{ .cp = 'n', .alt = true } }); // a shell under the doc
+ const shell = p.active;
+ const sp = p.panes[shell].?;
+ try std.testing.expect(sp.isTerminal());
+
+ // Exactly what an OSC 133 shell draws: prompt, then the marker that says
+ // the rest of this row is the user's, then what they typed. One grid row.
+ p.update(.{ .output = .{
+ .pane = @intCast(shell),
+ .bytes = "\x1b]133;A\x1b\\user@box ~/src $ \x1b]133;B\x1b\\grep -rn TODO src/",
+ } });
+ p.sync();
+
+ const rowOf = struct {
+ fn at(pp: *Pardes, pane: *Pane, needle: []const u8) ?[]const u8 {
+ const rows = term_pane.shellRows(pp, pane) catch return null;
+ for (rows) |r| if (std.mem.indexOf(u8, r, needle) != null) return r;
+ return null;
+ }
+ }.at;
+ const bodyRowOf = struct {
+ fn at(pp: *Pardes, pane: *Pane, needle: []const u8) ?[]const u8 {
+ const body = term_pane.bodyText(pp.scratch.allocator(), pane) catch return null;
+ var it = std.mem.splitScalar(u8, body, '\n');
+ while (it.next()) |r| if (std.mem.indexOf(u8, r, needle) != null) return r;
+ return null;
+ }
+ }.at;
+
+ // The BODY is what you look at, and it follows the mode: in tty the pane
+ // is the program's own screen, so the prompt is there.
+ sp.mode = .tty;
+ try std.testing.expectEqualStrings(
+ "user@box ~/src $ grep -rn TODO src/",
+ bodyRowOf(p, sp, "grep") orelse return error.MissingPromptRow,
+ );
+
+ // Out of tty the prompt goes and the command stays — LEFT-HUGGED, so it
+ // lines up with the output below instead of sitting in a bay of blanks
+ // where the prompt used to be.
+ sp.mode = .normal;
+ try std.testing.expectEqualStrings(
+ "grep -rn TODO src/",
+ bodyRowOf(p, sp, "grep") orelse return error.MissingPromptRow,
+ );
+
+ // The MOTION SURFACE cuts either way, and deliberately: it is what the
+ // cursor moves over, and in tty mode nothing moves over it — the keys all
+ // belong to the program.
+ p.shell_rows.stale = true;
+ try std.testing.expectEqualStrings(
+ "grep -rn TODO src/",
+ rowOf(p, sp, "grep") orelse return error.MissingPromptRow,
+ );
+
+ // ...and a prompt with nothing typed at it yet is all chrome, so the whole
+ // row goes, which is what it has always done.
+ p.update(.{ .output = .{
+ .pane = @intCast(shell),
+ .bytes = "\r\n\x1b]133;A\x1b\\user@box ~/src $ \x1b]133;B\x1b\\",
+ } });
+ p.sync();
+ p.shell_rows.stale = true;
+ try std.testing.expect(rowOf(p, sp, "user@box") == null);
+}
+
+test "entering tty walks the shell cursor to the column clicked past the prompt" {
+ if (platform == .web) return;
+ const gpa = std.testing.allocator;
+ const p = try Pardes.init(gpa, .{ .cols = 80, .rows = 24, .file = "mise.toml" });
+ defer p.deinit();
+ p.update(.{ .resize = .{ .cols = 80, .rows = 24 } });
+ p.update(.{ .key = .{ .cp = 'n', .alt = true } });
+ const shell = p.active;
+ const sp = p.panes[shell].?;
+ p.update(.{ .output = .{
+ .pane = @intCast(shell),
+ .bytes = "\x1b]133;A;cl=line\x1b\\prompt> \x1b]133;B\x1b\\0123456789",
+ } });
+ p.sync();
+ sp.mode = .normal;
+ p.shell_rows.stale = true;
+
+ // The command shows LEFT-HUGGED, so its column 3 is the '3'...
+ const rows = try term_pane.shellRows(p, sp);
+ var row: i32 = 0;
+ const at = for (rows, 0..) |r, i| {
+ if (std.mem.indexOf(u8, r, "0123456789") != null) break i;
+ } else return error.MissingInputRow;
+ row = @intCast(at);
+ try std.testing.expectEqualStrings("0123456789", rows[at]);
+
+ // ...but the shell's own cursor lives on the real grid, eight cells
+ // further right, behind the prompt this pane is not showing.
+ sp.cur_row = row;
+ sp.cur_col = 3;
+ sp.cur_pinned = true;
+ while (p.nextEffect()) |_| {}
+ p.enterTty(shell);
+
+ // The walk is arrow keys the shell understands. Seven lefts: readline's
+ // cursor sits past the '9' and the click was on the '3'.
+ var lefts: usize = 0;
+ var rights: usize = 0;
+ while (p.nextEffect()) |effect| switch (effect) {
+ .write => |wr| {
+ if (std.mem.eql(u8, wr.bytes.slice(), "\x1b[D")) lefts += 1;
+ if (std.mem.eql(u8, wr.bytes.slice(), "\x1b[C")) rights += 1;
+ },
+ else => {},
+ };
+ try std.testing.expectEqual(@as(usize, 0), rights);
+ try std.testing.expectEqual(@as(usize, 7), lefts);
+}
diff --git a/src/term_pane.zig b/src/term_pane.zig
index 9f13832f..1243dfa1 100644
--- a/src/term_pane.zig
+++ b/src/term_pane.zig
@@ -18,6 +18,7 @@ const Pane = pardes.Pane;
const EditSnap = pardes.EditSnap;
const Ovl = pardes.Ovl;
const modal = @import("modal.zig");
+const config = @import("config.zig");
/// The memo behind `shellRows`. ONE entry for the editor, because the motion
/// surface is built for the pane the cursor is in and a second pane asking
@@ -78,6 +79,65 @@ const Rows = struct {
rows: [][]const u8,
};
+/// What LEAVING raw tty mode does to one prompt row, decided from its cells
+/// alone. See config.tty_blank for why any of this happens.
+pub const PromptCut = union(enum) {
+ /// show the row exactly as ghostty dumped it
+ keep,
+ /// show nothing at all
+ blank,
+ /// drop this many leading COLUMNS — the prompt — and keep the rest, which
+ /// is what was typed at it
+ cut: usize,
+};
+
+/// The prompt and the command typed at it share a grid row, and OSC 133 marks
+/// them apart CELL by cell (`Cell.semantic_content` is output / input /
+/// prompt). The row flag every caller tests first is only ghostty's "some cell
+/// in here is a prompt cell" index; taking the row on that flag alone is what
+/// used to throw the command away with the prompt.
+pub fn promptCut(pin: ghostty_vt.Pin) PromptCut {
+ if (config.tty_blank == .prompt_and_input) return .blank;
+ const cells = pin.cells(.all);
+ var cols: usize = 0;
+ while (cols < cells.len and cells[cols].semantic_content == .prompt) cols += 1;
+ // Flagged, but with no prompt cells at the FRONT: a right-side prompt, or
+ // a repaint that has moved on. Nothing here is the prompt, so hide nothing.
+ if (cols == 0) return .keep;
+ // ...and all prompt, nothing typed yet: the row is chrome end to end.
+ if (cols >= cells.len) return .blank;
+ return .{ .cut = cols };
+}
+
+/// That decision applied to `raw`, the line ghostty dumped for `pin`'s row.
+/// Always a slice OF `raw` — dropping the prompt is a left-hug, so the command
+/// starts at column 0 with no run of blanks in front of it where the prompt
+/// used to be, and there is nothing to allocate or copy anywhere.
+///
+/// Walking the dump rather than rebuilding the row out of cells keeps ghostty
+/// the single authority on how a cell spells itself — wide glyphs, combining
+/// marks and all. One non-spacer cell is one dumped grapheme, and that is what
+/// makes the cell walk and the byte walk stay in step.
+pub fn promptRow(pin: ghostty_vt.Pin, raw: []const u8) []const u8 {
+ const cols = switch (promptCut(pin)) {
+ .keep => return raw,
+ .blank => return "",
+ .cut => |n| n,
+ };
+ const cells = pin.cells(.all);
+ var at: usize = 0;
+ var col: usize = 0;
+ while (col < cols and at < raw.len) {
+ const cell = &cells[col];
+ var cps: usize = 1;
+ if (pin.grapheme(cell)) |extra| cps += extra.len;
+ for (0..cps) |_| at = modal.nextGrapheme(raw, at);
+ // the tail cell of a wide glyph spells nothing of its own
+ col += if (cell.wide == .wide) @as(usize, 2) else 1;
+ }
+ return std.mem.trimEnd(u8, raw[at..], " \t");
+}
+
/// A terminal's shell rows as the surface sees them: the WHOLE
/// history+active grid, prompt rows blanked (OSC 133), absolute grid rows
/// from 0. The raw material the motion surface is composed from — the
@@ -130,8 +190,10 @@ fn buildRows(alloc: std.mem.Allocator, p: *Pardes, pane: *Pane) !Rows {
var n: usize = 0;
var it = std.mem.splitScalar(u8, full, '\n');
while (it.next()) |raw| {
- const is_prompt = if (pit.next()) |pin| pin.rowAndCell().row.semantic_prompt != .none else false;
- const shown = if (is_prompt) "" else raw;
+ const shown = if (pit.next()) |pin|
+ if (pin.rowAndCell().row.semantic_prompt != .none) promptRow(pin, raw) else raw
+ else
+ raw;
if (n > 0) {
text[at] = '\n';
at += 1;
@@ -159,11 +221,13 @@ pub fn bodyText(arena: std.mem.Allocator, pane: *Pane) ![]const u8 {
var lines = std.mem.splitScalar(u8, raw, '\n');
var n: usize = 0;
while (lines.next()) |ln| {
- const is_prompt = if (pane.mode != .tty)
- if (prompts.next()) |pin| pin.rowAndCell().row.semantic_prompt != .none else false
+ vp[n] = if (pane.mode != .tty)
+ if (prompts.next()) |pin|
+ if (pin.rowAndCell().row.semantic_prompt != .none) promptRow(pin, ln) else ln
+ else
+ ln
else
- false;
- vp[n] = if (is_prompt) "" else ln;
+ ln;
n += 1;
}
std.debug.assert(n == vp.len);
diff --git a/src/tty/tty.zig b/src/tty/tty.zig
index e8e3c1bd..eadc3a9d 100644
--- a/src/tty/tty.zig
+++ b/src/tty/tty.zig
@@ -37,6 +37,13 @@ pub const Command = struct {
winsize: vaxis.Winsize,
mouse: vaxis.Mouse,
paste: []const u8,
+ /// The bracketed-paste brackets. vaxis posts them ONLY because this
+ /// union declares fields with these exact names — its Loop gates every
+ /// event on `@hasField` — and the pasted bytes themselves arrive
+ /// BETWEEN them as ordinary key presses, which the loop accumulates
+ /// into one `.paste` above instead of running as commands.
+ paste_start,
+ paste_end,
/// a language query finished on a worker; rows are lsp-domain-owned
lsp_done: struct { id: u32, rows: []u8 },
/// a selection-filter worker finished; every stdout is gpa-owned
@@ -403,6 +410,15 @@ pub fn run(init: std.process.Init, opts: pardes.Options) !void {
// gtk-enable-primary-paste=false — no mode we request can surface middle
// clicks there (see test/snapshots/ghostty-mid.snap).
try vx.setMouseMode(tty.writer(), true);
+ // Bracketed paste. Without it a paste into pardes-in-a-terminal is just a
+ // flood of key presses: plausible-looking in insert mode, and in normal
+ // mode every pasted character runs as a command. With it the terminal
+ // wraps the bytes in \x1b[200~ / \x1b[201~ and the loop coalesces them.
+ // No defer to switch it back off, for the same reason the mouse modes
+ // above have none: setBracketedPaste records state.bracketed_paste, and
+ // vaxis's resetState — reached from the `defer vx.deinit` above, while the
+ // tty is still open — sends the disable off that flag.
+ try vx.setBracketedPaste(tty.writer(), true);
pardes.image.start(io, allocs.image);
if (comptime pardes.pdf_enabled) pardes.pdf.start(allocs.pdf);
@@ -569,6 +585,16 @@ pub fn run(init: std.process.Init, opts: pardes.Options) !void {
var check_files = false;
var pending: ?@TypeOf(Command.value) = .tick;
+ // Where a bracketed paste is assembled. It has to outlive one drain pass:
+ // the burst arrives over as many passes as the terminal takes to write it,
+ // and the markers are the only thing that says where it ends.
+ var paste_buf: std.Io.Writer.Allocating = .init(gpa);
+ defer paste_buf.deinit();
+ var in_paste = false;
+ // 4 MiB ceiling, past which the tail is dropped rather than grown into. A
+ // paste that large is a mis-click on a file, not an edit, and the core
+ // would have to hold the whole of it as one undo entry.
+ const max_paste_bytes: usize = 4 << 20;
while (!core.quit) {
var event = if (pending) |ev| blk: {
pending = null;
@@ -610,7 +636,31 @@ pub fn run(init: std.process.Init, opts: pardes.Options) !void {
}
core.update(.{ .eof = .{ .pane = @intCast(e.id) } });
},
- .key_press => |key| core.update(.{ .key = .{
+ .key_press => |key| if (in_paste) {
+ // Between the markers a key is DATA, never a command. Same
+ // two inputs as the dispatch below, so a pasted character
+ // is exactly the character the core would have been given.
+ const text = key.text orelse "";
+ const cp = mapKey(effCp(key));
+ const bytes: []const u8 = if (text.len > 0)
+ text
+ else if (cp == pardes.Key.tab)
+ "\t"
+ else if (cp == pardes.Key.enter or (key.mods.ctrl and cp == 'j'))
+ // vaxis gives control bytes no text at all: a line
+ // break inside a paste reaches the ground parser as a
+ // bare CR (-> Key.enter) or, from a terminal that does
+ // not translate them, a bare LF — which that parser
+ // reports as ctrl+j. Nothing in here is a real
+ // keypress, so both of them are just a newline.
+ "\n"
+ else
+ // arrows, F-keys, a stray escape: noise a paste has no
+ // business carrying, dropped rather than smuggled in.
+ "";
+ const room = max_paste_bytes -| paste_buf.written().len;
+ paste_buf.writer.writeAll(bytes[0..@min(bytes.len, room)]) catch {};
+ } else core.update(.{ .key = .{
.cp = mapKey(effCp(key)),
.text = key.text orelse "",
.ctrl = key.mods.ctrl,
@@ -653,6 +703,18 @@ pub fn run(init: std.process.Init, opts: pardes.Options) !void {
core.update(.{ .paste = bytes });
gpa.free(@constCast(bytes));
},
+ .paste_start => {
+ in_paste = true;
+ paste_buf.clearRetainingCapacity();
+ },
+ .paste_end => {
+ in_paste = false;
+ // ONE event for the whole paste — the core borrows the
+ // bytes for the call, exactly like the OSC 52 arm above.
+ const pasted = paste_buf.written();
+ if (pasted.len > 0) core.update(.{ .paste = pasted });
+ paste_buf.clearRetainingCapacity();
+ },
.command => |line| {
core.update(.{ .command = line });
gpa.free(line);
@@ -683,7 +745,12 @@ pub fn run(init: std.process.Init, opts: pardes.Options) !void {
},
}
batch += 1;
- if (stop or output or native_pdf_page_changed or batch >= 64) break;
+ // A paste in flight keeps draining WITHOUT rendering: a hundred
+ // thousand pasted characters are one edit, not a hundred thousand
+ // render-worthy events. That cannot spin — the drain still ends
+ // the moment the queue runs dry (tryEvent below) — so a terminal
+ // which sends paste_start and never paste_end costs one frame.
+ if (stop or output or native_pdf_page_changed or (!in_paste and batch >= 64)) break;
event = (try loop.tryEvent()) orelse break;
}
tz_event.end();
@@ -983,6 +1050,20 @@ fn drainEffects(
// mirror the core's yank register out via OSC 52
if (core.yank) |y| vx.copyToSystemClipboard(tty.writer(), y, gpa) catch {};
},
+ .read_clipboard => {
+ // ...and the other direction, OSC 52 read. The answer arrives on
+ // vaxis's reader thread as an ordinary `.paste` event and reaches
+ // the core through the same path an outer bracketed paste does —
+ // this request is the only wiring it needs. "The answer arrives"
+ // is the optimistic reading: a clipboard READ is an exfiltration
+ // primitive and terminals treat it as one (ghostty prompts by
+ // default, xterm ships it off, a multiplexer or ssh link may eat
+ // it), and a refusal looks exactly like silence. So the core's
+ // pending request is dropped by the next keystroke rather than
+ // pasting minutes late, and `SPC p` in a locked-down terminal
+ // honestly does nothing.
+ vx.requestSystemClipboard(tty.writer()) catch {};
+ },
.lsp => |q| {
if (!threads_ok) continue; // pre-loop drain: nothing to answer to yet
const pane = core.panes[q.pane] orelse continue;
diff --git a/src/tutor.txt b/src/tutor.txt
index 1d51a4ac..fe80c9e3 100644
--- a/src/tutor.txt
+++ b/src/tutor.txt
@@ -164,16 +164,25 @@
edit, select and look in. It is not a document, though, and never takes a
column of its own: it opens BELOW the pane that asked for it, in that
pane's column, be that a file or a shell — and a file you then open from
- its rows goes where files go, not under the list. `n`/`N` step the rows
- and look each one, so the view follows along. Right-clicking a word that names no file in ANY open
- pane's directory searches for it — acme's button 3 — except in tty mode,
- where the click belongs to the program on the other end. On a shell with no
- search armed, n/N instead step the lookable tokens in its output.
+ its rows goes where files go, not under the list. `n`/`N` walk those
+ rows, and walking is ALL they do: a press moves the SELECTION to the
+ next look-able thing and opens nothing, so you can step past nine hits
+ to reach the tenth without opening the nine. Enter — the look chord —
+ opens the one you stopped on. The walk is a RING over PANES and not
+ over one buffer: the panes you have looked out of come first, most
+ recent first, then the output buffers you have not, newest first, and
+ only when there is neither does it step the pane in front of you — so
+ n/N work on a shell that never had a search armed, and off the end
+ they come round to the start. `N` is `n` backwards exactly: ten
+ forward and ten back is where you began.
+ Right-clicking a word that names no file in ANY open pane's
+ directory searches for it — acme's button 3 — except in tty mode,
+ where the click belongs to the program on the other end.
A hit in a file reads `path:LINE:COL-ENDCOL`, the ordinary look target
carrying the SPAN that matched. A hit in a shell or an output buffer has no
file to name, so it reads `@pN:LINE:COL-ENDCOL` — pane N, then the place in
- it. Looking either one goes there and SELECTS the span, which is why n/N
- land ON a hit rather than beside it.
+ it. Looking either one goes there and SELECTS the span, which is why an
+ Enter on a row n/N stepped to lands ON the hit rather than beside it.
The range is part of the PATH syntax and not part of search: type one
anywhere text lives and a look on it selects. `main.zig:412-418` is whole
lines, `main.zig:412:9-21` is columns on one line, `main.zig:412:9-418:1`
@@ -182,8 +191,9 @@
FIND: the "Find" builtin (SPC f f) arms the same tag input, but Enter
walks the pane's DIRECTORY instead of its text — `fd`, in-core — and writes
one matching PATH per row into the same "+Search" buffer. Rows are look
- targets like any other, so n/N step them and each found file opens; the
- match is on the name, plain and case-insensitive, ".git" is skipped.
+ targets like any other, so n/N select them one at a time and Enter
+ opens the one you meant; the match is on the name, plain and
+ case-insensitive, ".git" is skipped.
LAYOUT: columns split the screen; windows stack within a column. Panes
abut with no wasted gap — a pane's own trailing edge (its last column, or
@@ -519,6 +529,10 @@
SPC k Kill (quit) SPC d Del (close this pane)
SPC f s/f f/f n Save / Find / New SPC h t Tutor (this file)
SPC c n / c d Newcol / Delcol
+ SPC y / SPC Y the selection to the SYSTEM clipboard (every
+ cursor's text joined, or the main cursor's alone)
+ SPC p / SPC P paste the system clipboard after / before the
+ selection; SPC R replaces the selection with it
SPC t d/c/n/r Debug / Colors / NextColor / Crt toggles
SPC t p/l/a Petscii / Palette / Ascii: an image pane's
renderer — glyph art instead of pixels, the C64
@@ -530,6 +544,14 @@
SPC j j Last: the pane you were in before this one — what
body-normal ESC runs, so it alternates
+ Those five are helix's own clipboard letters, and the only words that
+ reach the desktop's clipboard at all: ordinary y d c p P R and the
+ 1-2 / 1-3 chords all stay in pardes' own register, so deleting a
+ character can never throw away what you copied from a browser. In a
+ terminal the copy goes out as OSC 52 and the paste asks for it back
+ the same way — plenty of terminals refuse that read, so there SPC y
+ works and SPC p may honestly do nothing.
+
`?` works at ANY depth: SPC ? lists everything, SPC h ? lists only
what the "h" group holds. Help writes into a "+Help" OUTPUT BUFFER,
the same kind of pane "/" search results land in — so it opens below
@@ -565,9 +587,11 @@
k off the TOPMOST tagline = the top bar, j back down)
zt zz zb Ctrl-d/u Ctrl-f Ctrl-w hjkl Alt-n/c
Esc = last document <-> last terminal (body normal)
+ n/N = select the next/prev look-able text, across panes
+ (a ring); Enter opens what you landed on
SPC = the leader: a key path runs a builtin (SPC ? lists
them; SPC k Kill, SPC d Del, SPC f s Save, SPC f f Find,
- SPC f n New,
+ SPC f n New, SPC y/Y/p/P/R the system clipboard,
SPC w hjkl focus, SPC j j the pane before this one)
vs Helix: no multi-cursor; selection is LINE-first (x), plus v chars.
diff --git a/src/web.zig b/src/web.zig
index e17e147e..637fa56f 100644
--- a/src/web.zig
+++ b/src/web.zig
@@ -438,6 +438,10 @@ export fn pardes_effect_next() u32 {
if (s.core.yank) |bytes| putEffect(s, bytes);
break :blk 7;
},
+ // 13, and no payload either way: the browser cannot hand the clipboard
+ // over synchronously, so the answer arrives later as an ordinary
+ // pardes_paste — or never, if the permission prompt says no.
+ .read_clipboard => 13,
.lsp => |e| blk: {
effect_aux0 = e.id;
effect_aux1 = e.pane;
diff --git a/src/web/app.mjs b/src/web/app.mjs
index 3d32a16b..d7a4b6f6 100644
--- a/src/web/app.mjs
+++ b/src/web/app.mjs
@@ -329,6 +329,11 @@ export class PardesRuntime {
download(data, "pardes-dump.zon", "text/plain;charset=utf-8");
} else if (kind === 7) {
navigator.clipboard?.writeText(decoder.decode(data)).catch(() => {});
+ } else if (kind === 13) {
+ // Async and permission-gated, unlike every other effect here: a refused
+ // or unsupported read is simply a paste that never happens, which is
+ // what the core already tolerates from an empty clipboard.
+ navigator.clipboard?.readText().then((text) => this.wasm.pardes_paste(this.writeInput(text))).catch(() => {});
} else if (kind === 10) {
this.running = false;
} else {
diff --git a/test/macos_e2e.swift b/test/macos_e2e.swift
index 42bc8229..16992271 100644
--- a/test/macos_e2e.swift
+++ b/test/macos_e2e.swift
@@ -47,7 +47,7 @@ private struct ScriptError: Error {
let message: String
}
-/// What the two C callbacks reach through `userdata`. A class, because a C
+/// What the three C callbacks reach through `userdata`. A class, because a C
/// function pointer cannot capture: a pointer the runtime struct carries is the
/// only way back into Swift state.
private final class Host {
@@ -177,6 +177,18 @@ private final class Driver: PardesViewDelegate {
yank = String(decoding: bytes, as: UTF8.self)
}
host.clipboard = yank
+ },
+ read_clipboard: { ud in
+ // Main thread, inside pardes_tick, and answered on the spot:
+ // the core asked for the clipboard and pardes_paste hands it
+ // back before this returns. `host.clipboard`, never
+ // NSPasteboard, for the same reason as set_clipboard above.
+ // No pump — the tick that emitted this effect is still
+ // draining and will pick up whatever the paste queued.
+ guard let ud else { return }
+ let host = Unmanaged<Host>.fromOpaque(ud).takeUnretainedValue()
+ let text = host.clipboard ?? ""
+ text.withCString { pardes_paste($0, text.utf8.count) }
})
let rc = pardes_init(&runtime, got.cols, got.rows)
diff --git a/test/snapshots/argv.golden b/test/snapshots/argv.golden
index 1109132c..6cf79be0 100644
--- a/test/snapshots/argv.golden
+++ b/test/snapshots/argv.golden
@@ -94,7 +94,7 @@
== snap dirarg grid=100x30 cursor=4,4
|New Newcol Find Grep Help Tutor Dump NextColor Debug Kill
| /tmp/pardes-snap/argv/cwd/sub New Del
-|
+| ls
| inside.txt
|
|
diff --git a/test/snapshots/boot.golden b/test/snapshots/boot.golden
index d347b7eb..d0e9ba09 100644
--- a/test/snapshots/boot.golden
+++ b/test/snapshots/boot.golden
@@ -1,7 +1,7 @@
== snap boot grid=100x30 cursor=4,4
|New Newcol Find Grep Help Tutor Dump NextColor Debug Kill
| /tmp/pardes-snap/boot/cwd New Del
-|
+| ls
| hello.txt
|
|
diff --git a/test/snapshots/builtins.golden b/test/snapshots/builtins.golden
index a54b8281..61d7bec1 100644
--- a/test/snapshots/builtins.golden
+++ b/test/snapshots/builtins.golden
@@ -96,30 +96,30 @@
| 2 SPC and its keys, a chord, a button, the
| 3 topbar - or the name, executed anywhere.
| 4
-| 5 SPC ? Help topbar
-| 6 SPC c d Delcol
-| 7 SPC c n Newcol topbar
-| 8 SPC d Del
-| 9 SPC f c Config
-| 10 SPC f f Find topbar
-| 11 SPC f g Grep topbar
-| 12 SPC f n New topbar
-| 13 SPC f s Save
-| 14 SPC h t Tutor topbar
-| 15 SPC j i Forward C-i
-| 16 SPC j j Last
-| 17 SPC j l Jumplist
-| 18 SPC j o Back C-o
-| 19 SPC k Kill topbar
-| 20 SPC l D WsDiagnostics
-| 21 SPC l S WsSymbols
-| 22 SPC l a CodeAction
-| 23 SPC l d Diagnostics
-| 24 SPC l h SelectRefs
-| 25 SPC l i Lspinfo
-| 26 SPC l k Hover
-| 27 SPC l r Rename
-| 28 SPC l s Symbols
+| 5 SPC ? Help topbar
+| 6 SPC P ClipPasteBefore
+| 7 SPC R ClipReplace
+| 8 SPC Y ClipYankMain
+| 9 SPC c d Delcol
+| 10 SPC c n Newcol topbar
+| 11 SPC d Del
+| 12 SPC f c Config
+| 13 SPC f f Find topbar
+| 14 SPC f g Grep topbar
+| 15 SPC f n New topbar
+| 16 SPC f s Save
+| 17 SPC h t Tutor topbar
+| 18 SPC j i Forward C-i
+| 19 SPC j j Last
+| 20 SPC j l Jumplist
+| 21 SPC j o Back C-o
+| 22 SPC k Kill topbar
+| 23 SPC l D WsDiagnostics
+| 24 SPC l S WsSymbols
+| 25 SPC l a CodeAction
+| 26 SPC l d Diagnostics
+| 27 SPC l h SelectRefs
+| 28 SPC l i Lspinfo
== snap index-tail grid=120x60 cursor=7,58
|New Newcol Find Grep Help Tutor Dump NextColor Debug Kill
| /tmp/pardes-snap/builtins/cwd/notes.txt Save New Del
@@ -153,34 +153,34 @@
|
|
| /tmp/pardes-snap/builtins/cwd/+Help New Del
-| 26 SPC l k Hover
-| 27 SPC l r Rename
-| 28 SPC l s Symbols
-| 29 SPC l w Lspwhy
-| 30 SPC s d Dump topbar
-| 31 SPC s r Restore
-| 32 SPC t a Ascii
-| 33 SPC t b Tagbottom
-| 34 SPC t c Colors
-| 35 SPC t d Debug topbar
-| 36 SPC t i PdfTint
-| 37 SPC t l Palette
-| 38 SPC t n NextColor topbar
-| 39 SPC t p Petscii
-| 40 SPC t r Crt
-| 41 SPC t s PdfSections
-| 42 SPC t t ThemeSel
-| 43 SPC t w Wrap
-| 44 SPC t z PdfFit
-| 45 SPC w h Left C-w h, C-w left
-| 46 SPC w j Down C-w j, C-w down
-| 47 SPC w k Up C-w k, C-w up
-| 48 SPC w l Right C-w l, C-w right
-| 49 Look enter, right-click
-| 50 Exec tab, middle-click
-| 51 Theme
-| 52 Shell
-| 53
+| 31 SPC l s Symbols
+| 32 SPC l w Lspwhy
+| 33 SPC p ClipPaste
+| 34 SPC s d Dump topbar
+| 35 SPC s r Restore
+| 36 SPC t a Ascii
+| 37 SPC t b Tagbottom
+| 38 SPC t c Colors
+| 39 SPC t d Debug topbar
+| 40 SPC t i PdfTint
+| 41 SPC t l Palette
+| 42 SPC t n NextColor topbar
+| 43 SPC t p Petscii
+| 44 SPC t r Crt
+| 45 SPC t s PdfSections
+| 46 SPC t t ThemeSel
+| 47 SPC t w Wrap
+| 48 SPC t z PdfFit
+| 49 SPC w h Left C-w h, C-w left
+| 50 SPC w j Down C-w j, C-w down
+| 51 SPC w k Up C-w k, C-w up
+| 52 SPC w l Right C-w l, C-w right
+| 53 SPC y ClipYank
+| 54 Look enter, right-click
+| 55 Exec tab, middle-click
+| 56 Theme
+| 57 Shell
+| 58
== snap not-a-picker grid=120x60 cursor=7,58
|New Newcol Find Grep Help Tutor Dump NextColor Debug Kill
| /tmp/pardes-snap/builtins/cwd/notes.txt Save New Del
@@ -214,34 +214,34 @@
|
|
| /tmp/pardes-snap/builtins/cwd/+Help New Del
-| 26 SPC l k Hover
-| 27 SPC l r Rename
-| 28 SPC l s Symbols
-| 29 SPC l w Lspwhy
-| 30 SPC s d Dump topbar
-| 31 SPC s r Restore
-| 32 SPC t a Ascii
-| 33 SPC t b Tagbottom
-| 34 SPC t c Colors
-| 35 SPC t d Debug topbar
-| 36 SPC t i PdfTint
-| 37 SPC t l Palette
-| 38 SPC t n NextColor topbar
-| 39 SPC t p Petscii
-| 40 SPC t r Crt
-| 41 SPC t s PdfSections
-| 42 SPC t t ThemeSel
-| 43 SPC t w Wrap
-| 44 SPC t z PdfFit
-| 45 SPC w h Left C-w h, C-w left
-| 46 SPC w j Down C-w j, C-w down
-| 47 SPC w k Up C-w k, C-w up
-| 48 SPC w l Right C-w l, C-w right
-| 49 Look enter, right-click
-| 50 Exec tab, middle-click
-| 51 Theme
-| 52 Shell
-| 53
+| 31 SPC l s Symbols
+| 32 SPC l w Lspwhy
+| 33 SPC p ClipPaste
+| 34 SPC s d Dump topbar
+| 35 SPC s r Restore
+| 36 SPC t a Ascii
+| 37 SPC t b Tagbottom
+| 38 SPC t c Colors
+| 39 SPC t d Debug topbar
+| 40 SPC t i PdfTint
+| 41 SPC t l Palette
+| 42 SPC t n NextColor topbar
+| 43 SPC t p Petscii
+| 44 SPC t r Crt
+| 45 SPC t s PdfSections
+| 46 SPC t t ThemeSel
+| 47 SPC t w Wrap
+| 48 SPC t z PdfFit
+| 49 SPC w h Left C-w h, C-w left
+| 50 SPC w j Down C-w j, C-w down
+| 51 SPC w k Up C-w k, C-w up
+| 52 SPC w l Right C-w l, C-w right
+| 53 SPC y ClipYank
+| 54 Look enter, right-click
+| 55 Exec tab, middle-click
+| 56 Theme
+| 57 Shell
+| 58
== snap window-group grid=120x60 cursor=7,32
|New Newcol Find Grep Help Tutor Dump NextColor Debug Kill
| /tmp/pardes-snap/builtins/cwd/notes.txt Save New Del
@@ -277,10 +277,10 @@
| /tmp/pardes-snap/builtins/cwd/+Help New Del
| 1 pardes builtins under SPC w
| 2
-| 3 SPC w h Left C-w h, C-w left
-| 4 SPC w j Down C-w j, C-w down
-| 5 SPC w k Up C-w k, C-w up
-| 6 SPC w l Right C-w l, C-w right
+| 3 SPC w h Left C-w h, C-w left
+| 4 SPC w j Down C-w j, C-w down
+| 5 SPC w k Up C-w k, C-w up
+| 6 SPC w l Right C-w l, C-w right
| 7
|
|
@@ -340,27 +340,27 @@
| 2 SPC and its keys, a chord, a button, the
| 3 topbar - or the name, executed anywhere.
| 4
-| 5 SPC ? Help topbar
-| 6 SPC c d Delcol
-| 7 SPC c n Newcol topbar
-| 8 SPC d Del
-| 9 SPC f c Config
-| 10 SPC f f Find topbar
-| 11 SPC f g Grep topbar
-| 12 SPC f n New topbar
-| 13 SPC f s Save
-| 14 SPC h t Tutor topbar
-| 15 SPC j i Forward C-i
-| 16 SPC j j Last
-| 17 SPC j l Jumplist
-| 18 SPC j o Back C-o
-| 19 SPC k Kill topbar
-| 20 SPC l D WsDiagnostics
-| 21 SPC l S WsSymbols
-| 22 SPC l a CodeAction
-| 23 SPC l d Diagnostics
-| 24 SPC l h SelectRefs
-| 25 SPC l i Lspinfo
-| 26 SPC l k Hover
-| 27 SPC l r Rename
-| 28 SPC l s Symbols
+| 5 SPC ? Help topbar
+| 6 SPC P ClipPasteBefore
+| 7 SPC R ClipReplace
+| 8 SPC Y ClipYankMain
+| 9 SPC c d Delcol
+| 10 SPC c n Newcol topbar
+| 11 SPC d Del
+| 12 SPC f c Config
+| 13 SPC f f Find topbar
+| 14 SPC f g Grep topbar
+| 15 SPC f n New topbar
+| 16 SPC f s Save
+| 17 SPC h t Tutor topbar
+| 18 SPC j i Forward C-i
+| 19 SPC j j Last
+| 20 SPC j l Jumplist
+| 21 SPC j o Back C-o
+| 22 SPC k Kill topbar
+| 23 SPC l D WsDiagnostics
+| 24 SPC l S WsSymbols
+| 25 SPC l a CodeAction
+| 26 SPC l d Diagnostics
+| 27 SPC l h SelectRefs
+| 28 SPC l i Lspinfo
diff --git a/test/snapshots/builtins.snap b/test/snapshots/builtins.snap
index f6b5723b..3b8fb684 100644
--- a/test/snapshots/builtins.snap
+++ b/test/snapshots/builtins.snap
@@ -30,10 +30,12 @@ snap index
key g e
stable 700 15000
snap index-tail
-# n/N here must NOT run the rows. ThemeSel's buffer executes what it steps
-# onto, and that is safe because wearing a theme is free; this list holds Kill,
-# Del and Delcol, so stepping it would end the session. Three presses, and the
-# panes and the listing are all where they were.
+# 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
@@ -48,17 +50,20 @@ 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 the picking a stepping
-# picker would have done, minus running the rows you passed.
+# 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, so every row inserted above `SPC h t` in the listing
-# moves Tutor down one and this number with it.
+# moves Tutor down one and this number with it. The five clipboard builtins
+# put three there — SPC P, SPC R and SPC Y, uppercase sorting ahead of the
+# lowercase `SPC h` — which is why this reads 49 and not 46.
key space ?
wait 10000 SPC c n
stable 700 15000
-press middle 20 46
-release middle 20 46
+press middle 20 49
+release middle 20 49
wait 10000 PARDES TUTOR
stable 700 15000
snap tutor-from-index
diff --git a/test/snapshots/chordcut.golden b/test/snapshots/chordcut.golden
index ebe3769a..16d007e2 100644
--- a/test/snapshots/chordcut.golden
+++ b/test/snapshots/chordcut.golden
@@ -1,7 +1,7 @@
== snap opened grid=90x30 cursor=7,2
|New Newcol Find Grep Help Tutor Dump NextColor Debug Kill
| /tmp/pardes-snap/chordcut/cw /tmp/pardes-snap/chordcut/cw /tmp/pardes-snap/chordcut/cw
-| 1 line 1
+| 1 line 1 ls ls
| 2 line 2 f.txt g.txt f.txt g.txt
| 3 line 3
| 4 line 4
@@ -16,7 +16,7 @@
|
|
| /tmp/pardes-snap/chordcut/cw
-|
+| ls
| f.txt g.txt
|
|
@@ -32,7 +32,7 @@
== snap cut grid=90x30 cursor=7,3
|New Newcol Find Grep Help Tutor Dump NextColor Debug Kill
| /tmp/pardes-snap/chordcut/cw /tmp/pardes-snap/chordcut/cw /tmp/pardes-snap/chordcut/cw
-| 1 line 1
+| 1 line 1 ls ls
| 2 2 f.txt g.txt f.txt g.txt
| 3 line 3
| 4 line 4
@@ -47,7 +47,7 @@
|
|
| /tmp/pardes-snap/chordcut/cw
-|
+| ls
| f.txt g.txt
|
|
@@ -63,7 +63,7 @@
== snap copied grid=90x30 cursor=10,4
|New Newcol Find Grep Help Tutor Dump NextColor Debug Kill
| /tmp/pardes-snap/chordcut/cw /tmp/pardes-snap/chordcut/cw /tmp/pardes-snap/chordcut/cw
-| 1 line 1
+| 1 line 1 ls ls
| 2 2 f.txt g.txt f.txt g.txt
| 3 line 3
| 4 line 4
@@ -78,7 +78,7 @@
|
|
| /tmp/pardes-snap/chordcut/cw
-|
+| ls
| f.txt g.txt
|
|
@@ -94,7 +94,7 @@
== snap pointpaste grid=90x30 cursor=16,5
|New Newcol Find Grep Help Tutor Dump NextColor Debug Kill
| /tmp/pardes-snap/chordcut/cw /tmp/pardes-snap/chordcut/cw /tmp/pardes-snap/chordcut/cw
-| 1 line 1
+| 1 line 1 ls ls
| 2 2 f.txt g.txt f.txt g.txt
| 3 line 3
| 4 line 4line
@@ -109,7 +109,7 @@
|
|
| /tmp/pardes-snap/chordcut/cw
-|
+| ls
| f.txt g.txt
|
|
@@ -125,7 +125,7 @@
== snap replaced grid=90x30 cursor=11,6
|New Newcol Find Grep Help Tutor Dump NextColor Debug Kill
| /tmp/pardes-snap/chordcut/cw /tmp/pardes-snap/chordcut/cw /tmp/pardes-snap/chordcut/cw
-| 1 line 1
+| 1 line 1 ls ls
| 2 2 f.txt g.txt f.txt g.txt
| 3 line 3
| 4 line 4line
@@ -140,7 +140,7 @@
|
|
| /tmp/pardes-snap/chordcut/cw
-|
+| ls
| f.txt g.txt
|
|
@@ -156,7 +156,7 @@
== snap cancelexec grid=90x30 cursor=25,3
|New Newcol Find Grep Help Tutor Dump NextColor Debug Kill
| /tmp/pardes-snap/chordcut/cw /tmp/pardes-snap/chordcut/cw /tmp/pardes-snap/chordcut/cw
-| 1 line 1
+| 1 line 1 ls ls
| 2 2echo B''OO g.txt f.txt g.txt f.txt g.txt
| 3 line 3
| 4 line 4line
@@ -171,7 +171,7 @@
|
|
| /tmp/pardes-snap/chordcut/cw
-|
+| ls
| f.txt g.txt
|
|
@@ -187,7 +187,7 @@
== snap execafter grid=90x30 cursor=25,3
|New Newcol Find Grep Help Tutor Dump NextColor Debug Kill
| /tmp/pardes-snap/chordcut/cw /tmp/pardes-snap/chordcut/cw /tmp/pardes-snap/chordcut/cw
-| 1 line 1
+| 1 line 1 ls ls
| 2 2echo B''OO g.txt f.txt g.txt f.txt g.txt
| 3 line 3
| 4 line 4line
@@ -202,7 +202,7 @@
|
|
| /tmp/pardes-snap/chordcut/cw
-|
+| ls
| f.txt g.txt
|
|
@@ -218,7 +218,7 @@
== snap cancellook grid=90x30 cursor=25,3
|New Newcol Find Grep Help Tutor Dump NextColor Debug Kill
| /tmp/pardes-snap/chordcut/cw /tmp/pardes-snap/chordcut/cw /tmp/pardes-snap/chordcut/cw
-| 1 line 1
+| 1 line 1 ls ls
| 2 2echo B''OO g.txt f.txt g.txt f.txt g.txt
| 3 line 3
| 4 line 4line
@@ -233,7 +233,7 @@
|
|
| /tmp/pardes-snap/chordcut/cw
-|
+| ls
| f.txt g.txt
|
|
@@ -249,7 +249,7 @@
== snap lookafter grid=90x30 cursor=7,17
|New Newcol Find Grep Help Tutor Dump NextColor Debug Kill
| /tmp/pardes-snap/chordcut/cw /tmp/pardes-snap/chordcut/cw /tmp/pardes-snap/chordcut/cw
-| 1 line 1
+| 1 line 1 ls ls
| 2 2echo B''OO g.txt f.txt g.txt f.txt g.txt
| 3 line 3
| 4 line 4line
@@ -264,7 +264,7 @@
|
|
| /tmp/pardes-snap/chordcut/cw /tmp/pardes-snap/chordcut/cw
-| 1 line 1
+| 1 line 1 ls
| 2 line 2 f.txt g.txt
| 3
|
@@ -342,7 +342,7 @@
== snap ttyprobe grid=90x30 cursor=44,13
|New Newcol Find Grep Help Tutor Dump NextColor Debug Kill
| /tmp/pardes-snap/chordcut/cw$ /tmp/pardes-snap/chordcut/cw /tmp/pardes-snap/chordcut/cw
-| 1 line 1 $ ls
+| 1 line 1 $ ls ls
| 2 2echo B''OO g.txt f.txt g.txt f.txt g.txt
| 3 line 3 $
| 4 line 4line $
@@ -357,7 +357,7 @@
|
|
| /tmp/pardes-snap/chordcut/cw /tmp/pardes-snap/chordcut/cw
-| 1 line 1
+| 1 line 1 ls
| 2 line 2 f.txt g.txt
| 3
|
@@ -373,7 +373,7 @@
== snap ttyprompt grid=90x30 cursor=38,15
|New Newcol Find Grep Help Tutor Dump NextColor Debug Kill
| /tmp/pardes-snap/chordcut/cw$ /tmp/pardes-snap/chordcut/cw /tmp/pardes-snap/chordcut/cw
-| 1 line 1 $ ls
+| 1 line 1 $ ls ls
| 2 2echo B''OO g.txt f.txt g.txt f.txt g.txt
| 3 line 3 $
| 4 line 4line $
@@ -388,7 +388,7 @@
| $
| $ line
| /tmp/pardes-snap/chordcut/cw /tmp/pardes-snap/chordcut/cw
-| 1 line 1
+| 1 line 1 ls
| 2 line 2 f.txt g.txt
| 3
|
diff --git a/test/snapshots/cmdword.golden b/test/snapshots/cmdword.golden
index f5d6f003..940ce6fb 100644
--- a/test/snapshots/cmdword.golden
+++ b/test/snapshots/cmdword.golden
@@ -48,7 +48,7 @@
|
| /tmp/pardes-snap/cmdword/cwd New Del
| echo ZZ''E
-|
+| echo ZZ''E
| ZZE
|
|
@@ -79,9 +79,9 @@
|
| /tmp/pardes-snap/cmdword/cwd New Del
| echo ZZ''E
-|
+| echo ZZ''E
| ZZE
-|
+| echo ZZ''L
| ZZL
|
|
@@ -110,9 +110,9 @@
|
| /tmp/pardes-snap/cmdword/cwd New Del
| echo ZZ''E
-|
+| echo ZZ''E
| ZZE
-|
+| echo ZZ''L
| ZZL
|
|
@@ -141,11 +141,11 @@
|
| /tmp/pardes-snap/cmdword/cwd New Del
| echo ZZ''E
-|
+| echo ZZ''E
| ZZE
-|
+| echo ZZ''L
| ZZL
-|
+| ls
| cmds.txt p.txt zzmark.txt
|
|
@@ -172,11 +172,11 @@
|
| /tmp/pardes-snap/cmdword/cwd New Del Exec
| echo ZZ''E
-|
+| echo ZZ''E
| ZZE
-|
+| echo ZZ''L
| ZZL
-|
+| ls
| cmds.txt p.txt zzmark.txt
|
|
@@ -203,13 +203,13 @@
|
| /tmp/pardes-snap/cmdword/cwd New Del Exec @`echo ZZ''T`
| echo ZZ''E
-|
+| echo ZZ''E
| ZZE
-|
+| echo ZZ''L
| ZZL
-|
+| ls
| cmds.txt p.txt zzmark.txt
-|
+| echo ZZ''T
| ZZT
|
|
diff --git a/test/snapshots/cornerdrag.golden b/test/snapshots/cornerdrag.golden
index ae933701..a1aa5d03 100644
--- a/test/snapshots/cornerdrag.golden
+++ b/test/snapshots/cornerdrag.golden
@@ -1,7 +1,7 @@
== snap hover-corner grid=100x30 cursor=4,4
|New Newcol Find Grep Help Tutor Dump NextColor Debug Kill
| /tmp/pardes-snap/cornerdrag/cwd New Del ╎ /tmp/pardes-snap/cornerdrag/cwd New Del
-| ╎
+| ls ╎ ls
| w.txt ╎ w.txt
| ╎
| ╎
@@ -16,7 +16,7 @@
| ╎
|╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌
| /tmp/pardes-snap/cornerdrag/cwd New Del ╎
-| ╎
+| ls ╎
| w.txt ╎
| ╎
| ╎
@@ -32,7 +32,7 @@
== snap edge-drag grid=100x30 cursor=4,4
|New Newcol Find Grep Help Tutor Dump NextColor Debug Kill
| /tmp/pardes-snap/cornerdrag╎cwd New Del /tmp/pardes-snap/cornerdrag/cwd New Del
-| ╎
+| ls ╎ ls
| w.txt ╎ w.txt
| ╎
| ╎
@@ -47,7 +47,7 @@
| ╎
| ╎
| /tmp/pardes-snap/cornerdrag╎cwd New Del
-| ╎
+| ls ╎
| w.txt ╎
| ╎
| ╎
@@ -63,7 +63,7 @@
== snap edge-done grid=100x30 cursor=4,4
|New Newcol Find Grep Help Tutor Dump NextColor Debug Kill
| /tmp/pardes-snap/cornerdrag/ /tmp/pardes-snap/cornerdrag/cwd New Del
-|
+| ls ls
| w.txt w.txt
|
|
@@ -78,7 +78,7 @@
|
|
| /tmp/pardes-snap/cornerdrag/
-|
+| ls
| w.txt
|
|
@@ -94,7 +94,7 @@
== snap corner-drag grid=100x30 cursor=4,4
|New Newcol Find Grep Help Tutor Dump NextColor Debug Kill
| /tmp/pardes-snap/cornerdrag/ /tmp/pardes-snap/cornerdrag╎cwd New Del
-| ╎
+| ls ls ╎
| w.txt w.txt ╎
| ╎
| ╎
@@ -109,7 +109,7 @@
| ╎
| ╎
| /tmp/pardes-snap/cornerdrag/ ╎
-| ╎
+| ls ╎
| w.txt ╎
| ╎
| ╎
@@ -125,14 +125,14 @@
== snap corner-done grid=100x30 cursor=4,4
|New Newcol Find Grep Help Tutor Dump NextColor Debug Kill
| /tmp/pardes-snap/cornerdrag/cwd New Del /tmp/pardes-snap/cornerdrag/cwd New De
-|
+| ls ls
| w.txt w.txt
|
|
|
|
| /tmp/pardes-snap/cornerdrag/cwd New Del
-|
+| ls
| w.txt
|
|
@@ -156,14 +156,14 @@
== snap clamp-x grid=100x30 cursor=4,4
|New Newcol Find Grep Help Tutor Dump NextColor Debug Kill
| /tmp/pardes-snap/cornerdrag/cwd New Del /tmp/pardes-snap/cornerdrag/╎wd New De
-| ╎
+| ls ls ╎
| w.txt w.txt ╎
| ╎
| ╎
| ╎
| ╎
| /tmp/pardes-snap/cornerdrag/cwd New Del ╎
-| ╎
+| ls ╎
| w.txt ╎
| ╎
| ╎
@@ -187,14 +187,14 @@
== snap clamp-y grid=100x30 cursor=4,4
|New Newcol Find Grep Help Tutor Dump NextColor Debug Kill
| /tmp/pardes-snap/cornerdrag/cwd New Del ╎ /tmp/pardes-snap/cornerdrag/cwd New De
-| ╎
+| ls ╎ ls
| w.txt ╎ w.txt
| ╎
| ╎
| ╎
| ╎
| /tmp/pardes-snap/cornerdrag/cwd New Del ╎
-| ╎
+| ls ╎
| w.txt ╎
| ╎
| ╎
@@ -218,7 +218,7 @@
== snap clamp-done grid=100x30 cursor=4,4
|New Newcol Find Grep Help Tutor Dump NextColor Debug Kill
| /tmp/pardes-snap/cornerdrag/cwd New Del /tmp/pardes-snap/cornerdrag/cwd New De
-|
+| ls ls
| w.txt w.txt
|
|
diff --git a/test/snapshots/cursorline.golden b/test/snapshots/cursorline.golden
index 3a0f5cd9..ce416b91 100644
--- a/test/snapshots/cursorline.golden
+++ b/test/snapshots/cursorline.golden
@@ -1,7 +1,7 @@
== snap top grid=150x30 cursor=7,2
|New Newcol Find Grep Help Tutor Dump NextColor Debug Kill
| /tmp/pardes-snap/cursorline/cwd/cur.txt Save New /tmp/pardes-snap/cursorline/cwd New Del /tmp/pardes-snap/cursorline/cwd New Del
-| 1 line 1
+| 1 line 1 ls ls
| 2 line 2 cur.txt cur.txt
| 3 line 3
| 4 line 4
@@ -16,7 +16,7 @@
| 13 line 13
| 14 line 14
| 15 line 15 /tmp/pardes-snap/cursorline/cwd New Del
-| 16 line 16
+| 16 line 16 ls
| 17 line 17 cur.txt
| 18 line 18
| 19 line 19
@@ -63,7 +63,7 @@
== snap down3 grid=150x30 cursor=7,5
|New Newcol Find Grep Help Tutor Dump NextColor Debug Kill
| /tmp/pardes-snap/cursorline/cwd/cur.txt Save New /tmp/pardes-snap/cursorline/cwd New Del /tmp/pardes-snap/cursorline/cwd New Del
-| 1 line 1
+| 1 line 1 ls ls
| 2 line 2 cur.txt cur.txt
| 3 line 3
| 4 line 4
@@ -78,7 +78,7 @@
| 13 line 13
| 14 line 14
| 15 line 15 /tmp/pardes-snap/cursorline/cwd New Del
-| 16 line 16
+| 16 line 16 ls
| 17 line 17 cur.txt
| 18 line 18
| 19 line 19
diff --git a/test/snapshots/doccol.golden b/test/snapshots/doccol.golden
index c6d5468a..a18a3546 100644
--- a/test/snapshots/doccol.golden
+++ b/test/snapshots/doccol.golden
@@ -1,7 +1,7 @@
== snap boot grid=100x30 cursor=7,2
|New Newcol Find Grep Help Tutor Dump NextColor Debug Kill
| /tmp/pardes-snap/doccol/cwd/a.txt Save New Del /tmp/pardes-snap/doccol/cwd New Del
-| 1 AAA
+| 1 AAA ls
| a.txt b.txt c.txt
|
|
@@ -32,7 +32,7 @@
== snap two-docs grid=100x30 cursor=7,17
|New Newcol Find Grep Help Tutor Dump NextColor Debug Kill
| /tmp/pardes-snap/doccol/cwd/a.txt Save New Del /tmp/pardes-snap/doccol/cwd New Del
-| 1 AAA
+| 1 AAA ls
| a.txt b.txt c.txt
|
|
@@ -63,7 +63,7 @@
== snap moved grid=100x30 cursor=57,20
|New Newcol Find Grep Help Tutor Dump NextColor Debug Kill
| /tmp/pardes-snap/doccol/cwd/a.txt Save New Del /tmp/pardes-snap/doccol/cwd New Del
-| 1 AAA
+| 1 AAA ls
| a.txt b.txt c.txt
|
|
@@ -94,7 +94,7 @@
== snap worked grid=100x30 cursor=59,21
|New Newcol Find Grep Help Tutor Dump NextColor Debug Kill
| /tmp/pardes-snap/doccol/cwd/a.txt Save New Del /tmp/pardes-snap/doccol/cwd New Del
-| 1 AAA
+| 1 AAA ls
| a.txt b.txt c.txt
|
|
@@ -125,7 +125,7 @@
== snap third grid=100x30 cursor=57,26
|New Newcol Find Grep Help Tutor Dump NextColor Debug Kill
| /tmp/pardes-snap/doccol/cwd/a.txt Save New Del /tmp/pardes-snap/doccol/cwd New Del
-| 1 AAA
+| 1 AAA ls
| a.txt b.txt c.txt
|
|
diff --git a/test/snapshots/dump.golden b/test/snapshots/dump.golden
index 2b81e2f2..1cda1a95 100644
--- a/test/snapshots/dump.golden
+++ b/test/snapshots/dump.golden
@@ -11,14 +11,14 @@
.{
.kind = .terminal,
.tag = "/tmp/pardes-snap/dump/cwd New Del",
- .body = "\nd.txt\n\n\n\n typed-marker\n\n\n\n\n\n\n\n",
+ .body = "ls\nd.txt\n\n\n\n typed-marker\n\n\n\n\n\n\n\n",
.scroll = 0,
.cols = 48,
.rows = 14,
.vweight = 1,
.terminal = .{
.cwd = "/tmp/pardes-snap/dump/cwd",
- .stream = "\nd.txt\n",
+ .stream = "ls\nd.txt\n",
.stream_b64 = <elided>
.cursor = .{ .col = 2, .row = 2 },
},
@@ -28,14 +28,14 @@
.{
.kind = .terminal,
.tag = "/tmp/pardes-snap/dump/cwd New Del",
- .body = "\nd.txt\n\n\n\n\n\n\n\n\n\n\n",
+ .body = "ls\nd.txt\n\n\n\n\n\n\n\n\n\n\n",
.scroll = 0,
.cols = 48,
.rows = 13,
.vweight = 1,
.terminal = .{
.cwd = "/tmp/pardes-snap/dump/cwd",
- .stream = "\nd.txt\n",
+ .stream = "ls\nd.txt\n",
.stream_b64 = <elided>
.cursor = .{ .col = 2, .row = 2 },
},
@@ -45,14 +45,14 @@
.{
.kind = .terminal,
.tag = "/tmp/pardes-snap/dump/cwd New Del",
- .body = "\nd.txt\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",
+ .body = "ls\nd.txt\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",
.scroll = 0,
.cols = 48,
.rows = 28,
.vweight = 1,
.terminal = .{
.cwd = "/tmp/pardes-snap/dump/cwd",
- .stream = "\nd.txt\n",
+ .stream = "ls\nd.txt\n",
.stream_b64 = <elided>
.cursor = .{ .col = 2, .row = 2 },
},
diff --git a/test/snapshots/edit.golden b/test/snapshots/edit.golden
index 58fda8f9..ed7a2a41 100644
--- a/test/snapshots/edit.golden
+++ b/test/snapshots/edit.golden
@@ -1,7 +1,7 @@
== snap inserted grid=100x30 cursor=16,9
|New Newcol Find Grep Help Tutor Dump NextColor Debug Kill
| /tmp/pardes-snap/edit/cwd New Del /tmp/pardes-snap/edit/cwd New Del
-|
+| ls ls
| e.txt e.txt
|
|
@@ -16,7 +16,7 @@
|
|
| /tmp/pardes-snap/edit/cwd New Del
-|
+| ls
| e.txt
|
|
diff --git a/test/snapshots/exec-bigdrag.golden b/test/snapshots/exec-bigdrag.golden
index da0e2467..3cfe6ef9 100644
--- a/test/snapshots/exec-bigdrag.golden
+++ b/test/snapshots/exec-bigdrag.golden
@@ -1,61 +1,61 @@
== snap alive grid=200x60 cursor=119,37
|New Newcol Find Grep Help Tutor Dump NextColor Debug Kill
| /tmp/pardes-snap/exec-bigdrag/cwd New Del /tmp/pardes-snap/exec-bigdrag/cwd New Del
-| bash: line: command not found
-| big.txt
+| ls bash: line: command not found
+| big.txt 4line 2705line 2706line 2707line 2708line 2709line 2710line 2711line 2712line 2713line 2714lin
| bash: 4line: command not found
-|
+| 15line 2716line 2717line 2718line 2719line 2720line 2721line 2722line 2723line 2724line 2725li
| bash: 15line: command not found
-|
+| 726line 2727line 2728line 2729line 2730line 2731line 2732line 2733line 2734line 2735line 2736l
| bash: 726line: command not found
-|
+| 2737line 2738line 2739line 2740line 2741line 2742line 2743line 2744line 2745line 2746line 2747
| bash: 2737line: command not found
-|
+| 2748line 2749line 2750line 2751line 2752line 2753line 2754line 2755line 2756line 2757line 275
| bash: 2748line: command not found
-|
+| e 2759line 2760line 2761line 2762line 2763line 2764line 2765line 2766line 2767line 2768line 27
| bash: e: command not found
-|
+| ne 2770line 2771line 2772line 2773line 2774line 2775line 2776line 2777line 2778line 2779line 2
| bash: ne: command not found
-|
+| ine 2781line 2782line 2783line 2784line 2785line 2786line 2787line 2788line 2789line 2790line
| bash: ine: command not found
-|
+| line 2792line 2793line 2794line 2795line 2796line 2797line 2798line 2799line 2800line 2801line
| bash: line: command not found
-|
+| 2line 2803line 2804line 2805line 2806line 2807line 2808line 2809line 2810line 2811line 2812lin
| bash: 2line: command not found
-|
+| 13line 2814line 2815line 2816line 2817line 2818line 2819line 2820line 2821line 2822line 2823li
| bash: 13line: command not found
-|
+| 824line 2825line 2826line 2827line 2828line 2829line 2830line 2831line 2832line 2833line 2834l
| bash: 824line: command not found
-|
+| 2835line 2836line 2837line 2838line 2839line 2840line 2841line 2842line 2843line 2844line 2845
| bash: 2835line: command not found
-|
+| 2846line 2847line 2848line 2849line 2850line 2851line 2852line 2853line 2854line 2855line 285
| bash: 2846line: command not found
-| /tmp/pardes-snap/exec-bigdrag/cwd New Del
-| bash: e: command not found
-| big.txt
+| /tmp/pardes-snap/exec-bigdrag/cwd New Del e 2857line 2858line 2859line 2860line 2861line 2862line 2863line 2864line 2865line 2866line 28
+| ls bash: e: command not found
+| big.txt ne 2868line 2869line 2870line 2871line 2872line 2873line 2874line 2875line 2876line 2877line 2
| bash: ne: command not found
-|
+| ine 2879line 2880line 2881line 2882line 2883line 2884line 2885line 2886line 2887line 2888line
| bash: ine: command not found
-| echo alive-o''k
+| liecho alive-o''kne 2890line 2891line 2892line 2893line 2894line 2895line 2896line 2897line 2898li
| bash: line: command not found
-|
+| 0line 2901line 2902line 2903line 2904line 2905line 2906line 2907line 2908line 2909line 2910lin
| bash: 0line: command not found
-|
+| 11line 2912line 2913line 2914line 2915line 2916line 2917line 2918line 2919line 2920line 2921li
| bash: 11line: command not found
-|
+| 922line 2923line 2924line 2925line 2926line 2927line 2928line 2929line 2930line 2931line 2932l
| bash: 922line: command not found
-|
+| 2933line 2934line 2935line 2936line 2937line 2938line 2939line 2940line 2941line 2942line 2943
| bash: 2933line: command not found
-|
+| 2944line 2945line 2946line 2947line 2948line 2949line 2950line 2951line 2952line 2953line 295
| bash: 2944line: command not found
-|
+| e 2955line 2956line 2957line 2958line 2959line 2960line 2961line 2962line 2963line 2964line 29
| bash: e: command not found
-|
+| ne 2966line 2967line 2968line 2969line 2970line 2971line 2972line 2973line 2974line 2975line 2
| bash: ne: command not found
-|
+| ine 2977line 2978line 2979line 2980line 2981line 2982line 2983line 2984line 2985line 2986line
| bash: ine: command not found
-|
+| line 2988line 2989line 2990line 2991line 2992line 2993line 2994line 2995line 2996line 2997line
| bash: line: command not found
-|
+| echo alive-o''k
| alive-ok
|
diff --git a/test/snapshots/exec.golden b/test/snapshots/exec.golden
index c3c53696..abc60aec 100644
--- a/test/snapshots/exec.golden
+++ b/test/snapshots/exec.golden
@@ -1,7 +1,7 @@
== snap exec grid=100x30 cursor=16,7
|New Newcol Find Grep Help Tutor Dump NextColor Debug Kill
| /tmp/pardes-snap/exec/cwd New Del /tmp/pardes-snap/exec/cwd New Del
-|
+| ls ls
| e.txt e.txt
|
|
@@ -16,7 +16,7 @@
|
|
| /tmp/pardes-snap/exec/cwd New Del
-|
+| ls
| e.txt
|
|
@@ -32,7 +32,7 @@
== snap kept grid=100x30 cursor=6,2
|New Newcol Find Grep Help Tutor Dump NextColor Debug Kill
| /tmp/pardes-snap/exec/cwd New Del /tmp/pardes-snap/exec/cwd New Del
-| ZZARG
+| ZZARG ls
| ./c.sh e.txt
|
|
@@ -47,7 +47,7 @@
|
|
| /tmp/pardes-snap/exec/cwd New Del
-|
+| ls
| e.txt
|
|
@@ -63,7 +63,7 @@
== snap chord grid=100x30 cursor=6,2
|New Newcol Find Grep Help Tutor Dump NextColor Debug Kill
| /tmp/pardes-snap/exec/cwd New Del /tmp/pardes-snap/exec/cwd New Del
-| ZZARG
+| ZZARG ls
| ./c.sh e.txt
|
|
@@ -78,7 +78,7 @@
|
|
| /tmp/pardes-snap/exec/cwd New Del
-|
+| ls
| e.txt
|
|
@@ -94,7 +94,7 @@
== snap deleted grid=100x30 cursor=4,4
|New Newcol Find Grep Help Tutor Dump NextColor Debug Kill
| /tmp/pardes-snap/exec/cwd New Del /tmp/pardes-snap/exec/cwd New Del
-|
+| ls ls
| e.txt e.txt
|
|
diff --git a/test/snapshots/fileedit.golden b/test/snapshots/fileedit.golden
index ae0a60fe..72e6b713 100644
--- a/test/snapshots/fileedit.golden
+++ b/test/snapshots/fileedit.golden
@@ -1,7 +1,7 @@
== snap edited grid=150x30 cursor=17,2
|New Newcol Find Grep Help Tutor Dump NextColor Debug Kill
| /tmp/pardes-snap/fileedit/cwd/f.txt Save New Del /tmp/pardes-snap/fileedit/cwd New Del /tmp/pardes-snap/fileedit/cwd New Del
-| 1 liEDIT''MEne 1
+| 1 liEDIT''MEne 1 ls ls
| 2 line 2 f.txt f.txt
| 3 line 3
| 4 line 4
@@ -16,7 +16,7 @@
| 13 line 13
| 14 line 14
| 15 line 15 /tmp/pardes-snap/fileedit/cwd New Del
-| 16 line 16
+| 16 line 16 ls
| 17 line 17 f.txt
| 18 line 18
| 19 line 19
@@ -32,7 +32,7 @@
== snap deleted grid=150x30 cursor=7,3
|New Newcol Find Grep Help Tutor Dump NextColor Debug Kill
| /tmp/pardes-snap/fileedit/cwd/f.txt Save New Del /tmp/pardes-snap/fileedit/cwd New Del /tmp/pardes-snap/fileedit/cwd New Del
-| 1 liEDIT''MEne 1
+| 1 liEDIT''MEne 1 ls ls
| 2 line 3 f.txt f.txt
| 3 line 4
| 4 line 5
@@ -47,7 +47,7 @@
| 13 line 14
| 14 line 15
| 15 line 16 /tmp/pardes-snap/fileedit/cwd New Del
-| 16 line 17
+| 16 line 17 ls
| 17 line 18 f.txt
| 18 line 19
| 19 line 20
@@ -63,7 +63,7 @@
== snap undone grid=150x30 cursor=13,3
|New Newcol Find Grep Help Tutor Dump NextColor Debug Kill
| /tmp/pardes-snap/fileedit/cwd/f.txt Save New Del /tmp/pardes-snap/fileedit/cwd New Del /tmp/pardes-snap/fileedit/cwd New Del
-| 1 liEDIT''MEne 1
+| 1 liEDIT''MEne 1 ls ls
| 2 line 2 f.txt f.txt
| 3 line 3
| 4 line 4
@@ -78,7 +78,7 @@
| 13 line 13
| 14 line 14
| 15 line 15 /tmp/pardes-snap/fileedit/cwd New Del
-| 16 line 16
+| 16 line 16 ls
| 17 line 17 f.txt
| 18 line 18
| 19 line 19
diff --git a/test/snapshots/filewatch.golden b/test/snapshots/filewatch.golden
index 3224dd27..f81d5709 100644
--- a/test/snapshots/filewatch.golden
+++ b/test/snapshots/filewatch.golden
@@ -1,7 +1,7 @@
== snap edited grid=150x30 cursor=15,2
|New Newcol Find Grep Help Tutor Dump NextColor Debug Kill
| /tmp/pardes-snap/filewatch/cwd/w.txt Save New De /tmp/pardes-snap/filewatch/cwd New Del /tmp/pardes-snap/filewatch/cwd New Del
-| 1 liMYEDITne 1
+| 1 liMYEDITne 1 ls ls
| 2 line 2 sub w.txt sub w.txt
| 3 /tmp/pardes-snap/filewatch/cwd/sub/s.txt
| 4 line 4
@@ -16,7 +16,7 @@
| 13
|
| /tmp/pardes-snap/filewatch/cwd/sub/s.txt Save Ne /tmp/pardes-snap/filewatch/cwd New Del
-| 1 line 1
+| 1 line 1 ls
| 2 line 2 sub w.txt
| 3 line 3
| 4 line 4
@@ -32,7 +32,7 @@
== snap reloaded grid=150x30 cursor=15,2
|New Newcol Find Grep Help Tutor Dump NextColor Debug Kill
| /tmp/pardes-snap/filewatch/cwd/w.txt Save New De /tmp/pardes-snap/filewatch/cwd New Del /tmp/pardes-snap/filewatch/cwd New Del
-| 1 EXTERNAL
+| 1 EXTERNAL ls ls
| 2 sub w.txt sub w.txt
|
|
@@ -47,7 +47,7 @@
|
| --:--:-- reloaded /tmp/pardes-snap/filewatch/cw
| /tmp/pardes-snap/filewatch/cwd/sub/s.txt Save Ne /tmp/pardes-snap/filewatch/cwd New Del
-| 1 line 1
+| 1 line 1 ls
| 2 line 2 sub w.txt
| 3 line 3
| 4 line 4
@@ -63,7 +63,7 @@
== snap reloaded_sub grid=150x30 cursor=15,2
|New Newcol Find Grep Help Tutor Dump NextColor Debug Kill
| /tmp/pardes-snap/filewatch/cwd/w.txt Save New De /tmp/pardes-snap/filewatch/cwd New Del /tmp/pardes-snap/filewatch/cwd New Del
-| 1 EXTERNAL
+| 1 EXTERNAL ls ls
| 2 sub w.txt sub w.txt
|
|
@@ -78,7 +78,7 @@
|
| --:--:-- reloaded /tmp/pardes-snap/filewatch/cw
| /tmp/pardes-snap/filewatch/cwd/sub/s.txt Save Ne /tmp/pardes-snap/filewatch/cwd New Del
-| 1 RENAMED
+| 1 RENAMED ls
| 2 sub w.txt
|
|
@@ -94,7 +94,7 @@
== snap undone grid=150x30 cursor=15,2
|New Newcol Find Grep Help Tutor Dump NextColor Debug Kill
| /tmp/pardes-snap/filewatch/cwd/w.txt Save New De /tmp/pardes-snap/filewatch/cwd New Del /tmp/pardes-snap/filewatch/cwd New Del
-| 1 liMYEDITne 1
+| 1 liMYEDITne 1 ls ls
| 2 line 2 sub w.txt sub w.txt
| 3 /tmp/pardes-snap/filewatch/cwd/sub/s.txt
| 4 line 4
@@ -109,7 +109,7 @@
| 13
|
| /tmp/pardes-snap/filewatch/cwd/sub/s.txt Save Ne /tmp/pardes-snap/filewatch/cwd New Del
-| 1 RENAMED
+| 1 RENAMED ls
| 2 sub w.txt
|
|
diff --git a/test/snapshots/find.golden b/test/snapshots/find.golden
index 0a33df22..30f9a2ab 100644
--- a/test/snapshots/find.golden
+++ b/test/snapshots/find.golden
@@ -162,7 +162,7 @@
| 1 sub/ZQMARK-beta.txt
| 2 sub/nest/zqmark-gamma.txt
| 3 zqmark-alpha.txt
-== snap first grid=120x40 cursor=7,2
+== snap first grid=120x40 cursor=7,20
|New Newcol Find Grep Help Tutor Dump NextColor Debug Kill
| /tmp/pardes-snap/find/cwd/here.txt Save New Del
| 1 Find
@@ -205,8 +205,8 @@
| 3 zqmark-alpha.txt
== style first
|0: 0-56 #949494,#121212, 57-119 d,#121212,
-|1: 0-1 #ffffff,#626262, 2-99 #949494,#121212, 100-119 d,#121212,
-|2: 0-0 d,#444444, 1-1 d,#080808, 2-6 #949494,#121212, 7-10 #bdbdbd,#080808, 11-119 d,#080808,
+|1: 0-1 #ffffff,#262626, 2-99 #949494,#121212, 100-119 d,#121212,
+|2: 0-0 d,#444444, 1-1 d,#080808, 2-6 #626262,#080808, 7-10 #bdbdbd,#080808, 11-119 d,#080808,
|3: 0-0 d,#444444, 1-1 d,#080808, 2-6 #626262,#080808, 7-119 d,#080808,
|4: 0-0 d,#444444, 1-1 d,#080808, 2-6 #626262,#080808, 7-119 d,#080808,
|5: 0-0 d,#444444, 1-1 d,#080808, 2-6 #626262,#080808, 7-119 d,#080808,
@@ -223,8 +223,8 @@
|16: 0-0 d,#444444, 1-1 d,#080808, 2-6 #626262,#080808, 7-119 d,#080808,
|17: 0-0 d,#444444, 1-1 d,#080808, 2-6 #626262,#080808, 7-119 d,#080808,
|18: 0-0 d,#444444, 1-1 d,#080808, 2-6 #626262,#080808, 7-119 d,#080808,
-|19: 0-1 #ffffff,#262626, 2-99 #949494,#121212, 100-119 d,#121212,
-|20: 0-0 d,#444444, 1-1 d,#080808, 2-6 #626262,#080808, 7-15 #bdbdbd,#080808, 16-119 d,#080808,
+|19: 0-1 #ffffff,#626262, 2-99 #949494,#121212, 100-119 d,#121212,
+|20: 0-0 d,#444444, 1-1 d,#080808, 2-6 #949494,#121212, 7-15 #bdbdbd,#080808, 16-119 d,#080808,
|21: 0-0 d,#444444, 1-1 d,#080808, 2-6 #626262,#080808, 7-119 d,#080808,
|22: 0-0 d,#444444, 1-1 d,#080808, 2-6 #626262,#080808, 7-119 d,#080808,
|23: 0-0 d,#444444, 1-1 d,#080808, 2-6 #626262,#080808, 7-119 d,#080808,
@@ -241,10 +241,10 @@
|34: 0-0 d,#444444, 1-1 d,#080808, 2-6 #626262,#080808, 7-119 d,#080808,
|35: 0-0 d,#444444, 1-1 d,#080808, 2-6 #626262,#080808, 7-119 d,#080808,
|36: 0-1 #ffffff,#262626, 2-99 #949494,#121212, 100-119 d,#121212,
-|37: 0-0 d,#444444, 1-1 d,#080808, 2-6 #626262,#080808, 7-119 #080808,#80a0ff,
+|37: 0-0 d,#444444, 1-1 d,#080808, 2-6 #626262,#080808, 7-25 #bdbdbd,#080808, 26-119 d,#080808,
|38: 0-0 d,#444444, 1-1 d,#080808, 2-6 #626262,#080808, 7-31 #bdbdbd,#080808, 32-119 d,#080808,
|39: 0-0 d,#121212, 1-1 d,#080808, 2-6 #626262,#080808, 7-22 #bdbdbd,#080808, 23-119 d,#080808,
-== snap second grid=120x40 cursor=7,2
+== snap second grid=120x40 cursor=7,29
|New Newcol Find Grep Help Tutor Dump NextColor Debug Kill
| /tmp/pardes-snap/find/cwd/here.txt Save New Del
| 1 Find
@@ -255,8 +255,6 @@
|
|
|
-| /tmp/pardes-snap/find/cwd/sub/nest/zqmark-gamma.txt Save New Del
-| 1 gamma body
|
|
|
@@ -264,10 +262,10 @@
|
|
|
-| /tmp/pardes-snap/find/cwd/sub/ZQMARK-beta.txt Save New Del
-| 1 beta body
|
|
+| /tmp/pardes-snap/find/cwd/sub/ZQMARK-beta.txt Save New Del
+| 1 beta body
|
|
|
@@ -275,6 +273,8 @@
|
|
|
+| /tmp/pardes-snap/find/cwd/sub/nest/zqmark-gamma.txt Save New Del
+| 1 gamma body
|
|
|
@@ -285,19 +285,15 @@
| 1 sub/ZQMARK-beta.txt
| 2 sub/nest/zqmark-gamma.txt
| 3 zqmark-alpha.txt
-== snap third grid=120x40 cursor=7,2
+== snap third grid=120x40 cursor=7,33
|New Newcol Find Grep Help Tutor Dump NextColor Debug Kill
| /tmp/pardes-snap/find/cwd/here.txt Save New Del
| 1 Find
|
|
|
-| /tmp/pardes-snap/find/cwd/zqmark-alpha.txt Save New Del
-| 1 alpha body
|
|
-| /tmp/pardes-snap/find/cwd/sub/nest/zqmark-gamma.txt Save New Del
-| 1 gamma body
|
|
|
@@ -305,12 +301,12 @@
|
|
|
-| /tmp/pardes-snap/find/cwd/sub/ZQMARK-beta.txt Save New Del
-| 1 beta body
|
|
|
|
+| /tmp/pardes-snap/find/cwd/sub/ZQMARK-beta.txt Save New Del
+| 1 beta body
|
|
|
@@ -318,27 +314,27 @@
|
|
|
+| /tmp/pardes-snap/find/cwd/sub/nest/zqmark-gamma.txt Save New Del
+| 1 gamma body
|
|
+| /tmp/pardes-snap/find/cwd/zqmark-alpha.txt Save New Del
+| 1 alpha body
|
|
| /tmp/pardes-snap/find/cwd/+Search New Del
-| 1 sub/ZQMARK-beta.txt
| 2 sub/nest/zqmark-gamma.txt
| 3 zqmark-alpha.txt
-== snap back grid=120x40 cursor=7,2
+| 4
+== snap back grid=120x40 cursor=7,29
|New Newcol Find Grep Help Tutor Dump NextColor Debug Kill
| /tmp/pardes-snap/find/cwd/here.txt Save New Del
| 1 Find
|
|
|
-| /tmp/pardes-snap/find/cwd/zqmark-alpha.txt Save New Del
-| 1 alpha body
|
|
-| /tmp/pardes-snap/find/cwd/sub/nest/zqmark-gamma.txt Save New Del
-| 1 gamma body
|
|
|
@@ -346,12 +342,12 @@
|
|
|
-| /tmp/pardes-snap/find/cwd/sub/ZQMARK-beta.txt Save New Del
-| 1 beta body
|
|
|
|
+| /tmp/pardes-snap/find/cwd/sub/ZQMARK-beta.txt Save New Del
+| 1 beta body
|
|
|
@@ -359,27 +355,26 @@
|
|
|
+| /tmp/pardes-snap/find/cwd/sub/nest/zqmark-gamma.txt Save New Del
+| 1 gamma body
|
|
+| /tmp/pardes-snap/find/cwd/zqmark-alpha.txt Save New Del
+| 1 alpha body
|
|
| /tmp/pardes-snap/find/cwd/+Search New Del
| 1 sub/ZQMARK-beta.txt
| 2 sub/nest/zqmark-gamma.txt
| 3 zqmark-alpha.txt
-== snap word grid=120x40 cursor=9,5
+== snap word grid=120x40 cursor=7,29
|New Newcol Find Grep Help Tutor Dump NextColor Debug Kill
| /tmp/pardes-snap/find/cwd/here.txt Save New Del
| 1 Find
|
|
-| Find /
-| /tmp/pardes-snap/find/cwd/zqmark-alpha.txt Save New Del
-| 1 alpha body
|
|
-| /tmp/pardes-snap/find/cwd/sub/nest/zqmark-gamma.txt Save New Del
-| 1 gamma body
|
|
|
@@ -387,12 +382,13 @@
|
|
|
-| /tmp/pardes-snap/find/cwd/sub/ZQMARK-beta.txt Save New Del
-| 1 beta body
|
|
|
|
+| Find /
+| /tmp/pardes-snap/find/cwd/sub/ZQMARK-beta.txt Save New Del
+| 1 beta body
|
|
|
@@ -400,27 +396,27 @@
|
|
|
+| /tmp/pardes-snap/find/cwd/sub/nest/zqmark-gamma.txt Save New Del
+| 1 gamma body
|
|
+| /tmp/pardes-snap/find/cwd/zqmark-alpha.txt Save New Del
+| 1 alpha body
|
|
| /tmp/pardes-snap/find/cwd/+Search New Del
| 1 sub/ZQMARK-beta.txt
| 2 sub/nest/zqmark-gamma.txt
| 3 zqmark-alpha.txt
-== snap cancel grid=120x40 cursor=7,2
+== snap cancel grid=120x40 cursor=7,38
|New Newcol Find Grep Help Tutor Dump NextColor Debug Kill
| /tmp/pardes-snap/find/cwd/here.txt Save New Del
| 1 Find
|
|
|
-| /tmp/pardes-snap/find/cwd/zqmark-alpha.txt Save New Del
-| 1 alpha body
|
|
-| /tmp/pardes-snap/find/cwd/sub/nest/zqmark-gamma.txt Save New Del
-| 1 gamma body
|
|
|
@@ -428,12 +424,12 @@
|
|
|
-| /tmp/pardes-snap/find/cwd/sub/ZQMARK-beta.txt Save New Del
-| 1 beta body
-|
|
|
|
+| Find /
+| /tmp/pardes-snap/find/cwd/sub/ZQMARK-beta.txt Save New Del
+| 1 beta body
|
|
|
@@ -441,27 +437,25 @@
|
|
|
+| /tmp/pardes-snap/find/cwd/sub/nest/zqmark-gamma.txt Save New Del
+| 1 gamma body
|
|
+| /tmp/pardes-snap/find/cwd/zqmark-alpha.txt Save New Del
+| 1 alpha body
|
|
| /tmp/pardes-snap/find/cwd/+Search New Del
| 1 sub/ZQMARK-beta.txt
| 2 sub/nest/zqmark-gamma.txt
| 3 zqmark-alpha.txt
-== snap nomatch grid=120x40 cursor=7,2
+== snap nomatch grid=120x40 cursor=7,38
|New Newcol Find Grep Help Tutor Dump NextColor Debug Kill
-| /tmp/pardes-snap/find/cwd/here.txt Save New Del
+| /tmp/pardes-snap/find/cwd/here.txt Save New Del Find /
| 1 Find
|
-| /tmp/pardes-snap/find/cwd/+Search New Del
-| 1
-| /tmp/pardes-snap/find/cwd/zqmark-alpha.txt Save New Del
-| 1 alpha body
|
|
-| /tmp/pardes-snap/find/cwd/sub/nest/zqmark-gamma.txt Save New Del
-| 1 gamma body
|
|
|
@@ -469,12 +463,14 @@
|
|
|
-| /tmp/pardes-snap/find/cwd/sub/ZQMARK-beta.txt Save New Del
-| 1 beta body
|
|
|
|
+| /tmp/pardes-snap/find/cwd/+Search New Del
+| 1
+| /tmp/pardes-snap/find/cwd/sub/ZQMARK-beta.txt Save New Del
+| 1 beta body
|
|
|
@@ -482,27 +478,25 @@
|
|
|
+| /tmp/pardes-snap/find/cwd/sub/nest/zqmark-gamma.txt Save New Del
+| 1 gamma body
|
|
+| /tmp/pardes-snap/find/cwd/zqmark-alpha.txt Save New Del
+| 1 alpha body
|
|
| /tmp/pardes-snap/find/cwd/+Search New Del
-| 1 sub/ZQMARK-beta.txt
| 2 sub/nest/zqmark-gamma.txt
| 3 zqmark-alpha.txt
+| 4
== snap refit grid=120x40 cursor=7,2
|New Newcol Find Grep Help Tutor Dump NextColor Debug Kill
-| /tmp/pardes-snap/find/cwd/here.txt Save New Del
+| /tmp/pardes-snap/find/cwd/here.txt Save New Del Find /
| 1 Find
|
-| /tmp/pardes-snap/find/cwd/+Search New Del
-| 1
-| /tmp/pardes-snap/find/cwd/zqmark-alpha.txt Save New Del
-| 1 alpha body
|
|
-| /tmp/pardes-snap/find/cwd/sub/nest/zqmark-gamma.txt Save New Del
-| 1 gamma body
|
|
|
@@ -510,12 +504,14 @@
|
|
|
-| /tmp/pardes-snap/find/cwd/sub/ZQMARK-beta.txt Save New Del
-| 1 beta body
|
|
|
|
+| /tmp/pardes-snap/find/cwd/+Search New Del
+| 1
+| /tmp/pardes-snap/find/cwd/sub/ZQMARK-beta.txt Save New Del
+| 1 beta body
|
|
|
@@ -523,27 +519,23 @@
|
|
|
+| /tmp/pardes-snap/find/cwd/sub/nest/zqmark-gamma.txt Save New Del
+| 1 gamma body
|
|
+| /tmp/pardes-snap/find/cwd/zqmark-alpha.txt Save New Del
+| 1 alpha body
|
|
| /tmp/pardes-snap/find/cwd/+Search New Del
-| 1 sub/ZQMARK-beta.txt
| 2 sub/nest/zqmark-gamma.txt
| 3 zqmark-alpha.txt
-== snap topbar grid=120x40 cursor=12,7
+| 4
+== snap topbar grid=120x40 cursor=12,33
|New Newcol Find Grep Help Tutor Dump NextColor Debug Kill
-| /tmp/pardes-snap/find/cwd/here.txt Save New Del
+| /tmp/pardes-snap/find/cwd/here.txt Save New Del Find /
| 1 Find
|
-| /tmp/pardes-snap/find/cwd/+Search New Del
-| 1
-| /tmp/pardes-snap/find/cwd/zqmark-alpha.txt Save New Del
-| 1 alpha body
-| /tmp/pardes-snap/find/cwd/+Search New Del
-| 1 zqmark-alpha.txt
-| /tmp/pardes-snap/find/cwd/sub/nest/zqmark-gamma.txt Save New Del
-| 1 gamma body
|
|
|
@@ -551,14 +543,16 @@
|
|
|
-| /tmp/pardes-snap/find/cwd/sub/ZQMARK-beta.txt Save New Del
-| 1 beta body
|
|
|
|
|
|
+| /tmp/pardes-snap/find/cwd/+Search New Del
+| 1
+| /tmp/pardes-snap/find/cwd/sub/ZQMARK-beta.txt Save New Del
+| 1 beta body
|
|
|
@@ -566,9 +560,15 @@
|
|
|
+| /tmp/pardes-snap/find/cwd/sub/nest/zqmark-gamma.txt Save New Del
+| 1 gamma body
|
|
+| /tmp/pardes-snap/find/cwd/zqmark-alpha.txt Save New Del
+| 1 alpha body
+| /tmp/pardes-snap/find/cwd/+Search New Del
+| 1 zqmark-alpha.txt
| /tmp/pardes-snap/find/cwd/+Search New Del
-| 1 sub/ZQMARK-beta.txt
| 2 sub/nest/zqmark-gamma.txt
| 3 zqmark-alpha.txt
+| 4
diff --git a/test/snapshots/find.snap b/test/snapshots/find.snap
index 1fd36aa6..8f288525 100644
--- a/test/snapshots/find.snap
+++ b/test/snapshots/find.snap
@@ -1,11 +1,13 @@
# The Find builtin (SPC f f) = `fd`, in-core: it arms the SAME tag input `/`
# does, but Enter walks the pane's DIRECTORY instead of its text and writes one
# matching path per row into a "+Search" OUTPUT BUFFER. Every row is therefore
-# an ordinary look target, which is the whole point: n/N step the rows and look
-# them with no code of their own, opening each found file, and focus returns to
-# the pane that owns the search so the next n keeps stepping. The walk skips
-# .git, matches the NAME case-insensitively, and sorts (readdir order is not
-# stable). `SPC f s` is Save, which moved out of `w` to make this group.
+# an ordinary look target, which is the whole point: n/N SELECT the next/prev
+# one with no code of their own, and the look chord — Enter, the same one that
+# opens a path anywhere else — is what OPENS it. Focus then follows the file
+# that opened, but the look was made FROM the results buffer, so the next n
+# resumes stepping that same list. The walk skips .git, matches the NAME
+# case-insensitively, and sorts (readdir order is not stable). `SPC f s` is
+# Save, which moved out of `w` to make this group.
dirmk sub
dirmk sub/nest
dirmk .git
@@ -35,25 +37,30 @@ key enter
wait 10000 zqmark-alpha.txt
stable 700 15000
snap results
-# n looks row 1 — a path, so the file OPENS — and focus comes back here. The
-# look comes FROM the results buffer, but that is an output pane and not a
+# n SELECTS row 1 and Enter looks it — a path, so the file OPENS. The look
+# comes FROM the results buffer, but that is an output pane and not a
# document, so the file joins the docs above it (below here.txt) instead of
# stacking under the list: the +Search stays at the foot of the column.
key n
+key enter
wait 10000 beta body
stable 700 15000
snap first
snapstyle first
key n
+key enter
wait 10000 gamma body
stable 700 15000
snap second
key n
+key enter
wait 10000 alpha body
stable 700 15000
snap third
-# N walks back up: the file is already open, so the look just focuses it
+# N walks back up one row; Enter looks it, and the file is already open, so
+# the look just focuses it
key N
+key enter
stable 700 15000
snap back
# executing the WORD Find (middle-click in a body) arms the same input — the
@@ -66,23 +73,39 @@ key esc
settle 100
stable 400 5000
snap cancel
-# a no-match walk opens an empty list; n then has nowhere to go. The list is
-# exactly as tall as its results — one blank row plus its tag — and it stacks
-# above the earlier one, whose height is untouched.
+# every search is asked from a PANE, and both a look and now a step leave you
+# somewhere else — so click back into here.txt first. That is not bookkeeping:
+# a search never refills the buffer it was asked FROM (fillResults skips it),
+# so `owned by here.txt` is the whole premise of the two steps below.
+press left 8 3
+release left 8 3
+stable 400 5000
+# a no-match walk opens an empty list of its own. It is exactly as tall as its
+# results — one blank row plus its tag — and it stacks above the earlier one,
+# whose height is untouched.
key space
key f
key f
text zzqq
key enter
stable 700 10000
+# n does not stop on the empty list, because the walk is a RING across panes
+# rather than one buffer's rows: with nothing look-able here it carries on
+# into the list that DOES have some — the zqm one — and resumes it one row
+# past where the N above left it. Nothing opens; only the selection moved.
key n
stable 400 5000
snap nomatch
# ... and asking for `zqm` AGAIN re-arms the list it ALREADY filled instead of
-# stacking an identical twin under the empty one — even though n/N were armed
-# on the zzqq list, so the reuse is by what a buffer HOLDS (this search, this
-# pattern, this directory), not by which one the pane happens to point at. The
-# frame is therefore the `results` frame unchanged, down to the byte.
+# stacking an identical twin under the empty one — even though the step above
+# left the cursor sitting in the zqm list, so the reuse is by what a buffer
+# HOLDS (this search, this pattern, this directory), not by which one anything
+# happens to point at. Asked from here.txt again (the click, as above), and
+# the LIST it rewrites is therefore the `nomatch` frame unchanged, down to the
+# byte — only the cursor comes back with it.
+press left 8 3
+release left 8 3
+stable 400 5000
key space
key f
key f
@@ -94,10 +117,12 @@ snap refit
# Find is a TOPBAR word too (row 1, its own column, next to Grep): the same
# builtin the leader path runs, reached with the mouse. Chorded — a selection
# held when it runs IS the argument — so dragging over `alpha` and clicking
-# Find walks for that name with nothing typed and no input armed.
-press left 8 8
-drag left 13 8
-release left 13 8
+# Find walks for that name with nothing typed and no input armed. Row 34 is
+# `alpha body`: the three found files stack in the order the looks above
+# OPENED them, which is beta, gamma, alpha down the column.
+press left 8 34
+drag left 13 34
+release left 13 34
stable 400 5000
press middle 12 1
release middle 12 1
diff --git a/test/snapshots/fsearch.golden b/test/snapshots/fsearch.golden
index f0c89e1b..bbe7df83 100644
--- a/test/snapshots/fsearch.golden
+++ b/test/snapshots/fsearch.golden
@@ -1,7 +1,7 @@
== snap opened grid=180x30 cursor=7,2
|New Newcol Find Grep Help Tutor Dump NextColor Debug Kill
| /tmp/pardes-snap/fsearch/cwd/g.txt Save New Del /tmp/pardes-snap/fsearch/cwd New Del /tmp/pardes-snap/fsearch/cwd New Del
-| 1 l1
+| 1 l1 ls ls
| 2 MARK a g.txt g.txt
| 3 l3
| 4 l4
@@ -16,7 +16,7 @@
|
|
| /tmp/pardes-snap/fsearch/cwd New Del
-|
+| ls
| g.txt
|
|
@@ -32,7 +32,7 @@
== snap typing grid=180x30 cursor=8,29
|New Newcol Find Grep Help Tutor Dump NextColor Debug Kill
| /tmp/pardes-snap/fsearch/cwd/g.txt Save New Del /tmp/pardes-snap/fsearch/cwd New Del /tmp/pardes-snap/fsearch/cwd New Del
-| 1 l1
+| 1 l1 ls ls
| 2 MARK a g.txt g.txt
| 3 l3
| 4 l4
@@ -47,7 +47,7 @@
|
|
| /tmp/pardes-snap/fsearch/cwd New Del
-|
+| ls
| g.txt
|
|
@@ -63,7 +63,7 @@
== snap results grid=180x30 cursor=7,2
|New Newcol Find Grep Help Tutor Dump NextColor Debug Kill
| /tmp/pardes-snap/fsearch/cwd/g.txt Save New Del /tmp/pardes-snap/fsearch/cwd New Del /tmp/pardes-snap/fsearch/cwd New Del
-| 1 l1
+| 1 l1 ls ls
| 2 MARK a g.txt g.txt
| 3 l3
| 4 l4
@@ -78,7 +78,7 @@
|
|
| /tmp/pardes-snap/fsearch/cwd New Del
-|
+| ls
| g.txt
|
|
@@ -94,7 +94,7 @@
== snap first grid=180x30 cursor=10,3
|New Newcol Find Grep Help Tutor Dump NextColor Debug Kill
| /tmp/pardes-snap/fsearch/cwd/g.txt Save New Del /tmp/pardes-snap/fsearch/cwd New Del /tmp/pardes-snap/fsearch/cwd New Del
-| 1 l1
+| 1 l1 ls ls
| 2 MARK a g.txt g.txt
| 3 l3
| 4 l4
@@ -109,7 +109,7 @@
|
|
| /tmp/pardes-snap/fsearch/cwd New Del
-|
+| ls
| g.txt
|
|
@@ -150,13 +150,13 @@
|24: 0-0 d,#444444, 1-1 d,#080808, 2-6 #626262,#080808, 7-59 d,#080808, 60-60 d,#444444, 61-61 d,#080808, 62-119 #bdbdbd,#080808, 120-120 d,#444444, 121-121 d,#080808, 122-179 #bdbdbd,#080808,
|25: 0-0 d,#444444, 1-1 d,#080808, 2-6 #626262,#080808, 7-59 d,#080808, 60-60 d,#444444, 61-61 d,#080808, 62-119 #bdbdbd,#080808, 120-120 d,#444444, 121-121 d,#080808, 122-179 #bdbdbd,#080808,
|26: 0-1 #ffffff,#262626, 2-48 #949494,#121212, 49-59 d,#121212, 60-60 d,#444444, 61-61 d,#080808, 62-119 #bdbdbd,#080808, 120-120 d,#444444, 121-121 d,#080808, 122-179 #bdbdbd,#080808,
-|27: 0-0 d,#444444, 1-1 d,#080808, 2-6 #626262,#080808, 7-59 #080808,#80a0ff, 60-60 d,#444444, 61-61 d,#080808, 62-119 #bdbdbd,#080808, 120-120 d,#444444, 121-121 d,#080808, 122-179 #bdbdbd,#080808,
+|27: 0-0 d,#444444, 1-1 d,#080808, 2-6 #626262,#080808, 7-24 #bdbdbd,#080808, 25-59 d,#080808, 60-60 d,#444444, 61-61 d,#080808, 62-119 #bdbdbd,#080808, 120-120 d,#444444, 121-121 d,#080808, 122-179 #bdbdbd,#080808,
|28: 0-0 d,#444444, 1-1 d,#080808, 2-6 #626262,#080808, 7-24 #bdbdbd,#080808, 25-59 d,#080808, 60-60 d,#444444, 61-61 d,#080808, 62-119 #bdbdbd,#080808, 120-120 d,#444444, 121-121 d,#080808, 122-179 #bdbdbd,#080808,
|29: 0-0 d,#121212, 1-1 d,#080808, 2-6 #626262,#080808, 7-25 #bdbdbd,#080808, 26-59 d,#080808, 60-60 d,#444444, 61-61 d,#080808, 62-119 #bdbdbd,#080808, 120-120 d,#444444, 121-121 d,#080808, 122-179 #bdbdbd,#080808,
== snap second grid=180x30 cursor=10,7
|New Newcol Find Grep Help Tutor Dump NextColor Debug Kill
| /tmp/pardes-snap/fsearch/cwd/g.txt Save New Del /tmp/pardes-snap/fsearch/cwd New Del /tmp/pardes-snap/fsearch/cwd New Del
-| 1 l1
+| 1 l1 ls ls
| 2 MARK a g.txt g.txt
| 3 l3
| 4 l4
@@ -171,7 +171,7 @@
|
|
| /tmp/pardes-snap/fsearch/cwd New Del
-|
+| ls
| g.txt
|
|
@@ -187,7 +187,7 @@
== snap third grid=180x30 cursor=10,11
|New Newcol Find Grep Help Tutor Dump NextColor Debug Kill
| /tmp/pardes-snap/fsearch/cwd/g.txt Save New Del /tmp/pardes-snap/fsearch/cwd New Del /tmp/pardes-snap/fsearch/cwd New Del
-| 1 l1
+| 1 l1 ls ls
| 2 MARK a g.txt g.txt
| 3 l3
| 4 l4
@@ -202,7 +202,7 @@
|
|
| /tmp/pardes-snap/fsearch/cwd New Del
-|
+| ls
| g.txt
|
|
@@ -212,13 +212,13 @@
|
|
| /tmp/pardes-snap/fsearch/cwd/+Search New Del
-| 1 g.txt:2:1-4 MARK a
| 2 g.txt:6:1-4 MARK b
| 3 g.txt:10:1-4 MARK c
+| 4
== snap back grid=180x30 cursor=10,7
|New Newcol Find Grep Help Tutor Dump NextColor Debug Kill
| /tmp/pardes-snap/fsearch/cwd/g.txt Save New Del /tmp/pardes-snap/fsearch/cwd New Del /tmp/pardes-snap/fsearch/cwd New Del
-| 1 l1
+| 1 l1 ls ls
| 2 MARK a g.txt g.txt
| 3 l3
| 4 l4
@@ -233,7 +233,7 @@
|
|
| /tmp/pardes-snap/fsearch/cwd New Del
-|
+| ls
| g.txt
|
|
@@ -249,7 +249,7 @@
== snap cancel grid=180x30 cursor=10,7
|New Newcol Find Grep Help Tutor Dump NextColor Debug Kill
| /tmp/pardes-snap/fsearch/cwd/g.txt Save New Del /tmp/pardes-snap/fsearch/cwd New Del /tmp/pardes-snap/fsearch/cwd New Del
-| 1 l1
+| 1 l1 ls ls
| 2 MARK a g.txt g.txt
| 3 l3
| 4 l4
@@ -264,7 +264,7 @@
|
|
| /tmp/pardes-snap/fsearch/cwd New Del
-|
+| ls
| g.txt
|
|
@@ -277,10 +277,10 @@
| 1 g.txt:2:1-4 MARK a
| 2 g.txt:6:1-4 MARK b
| 3 g.txt:10:1-4 MARK c
-== snap nomatch grid=180x30 cursor=10,7
+== snap nomatch grid=180x30 cursor=7,28
|New Newcol Find Grep Help Tutor Dump NextColor Debug Kill
| /tmp/pardes-snap/fsearch/cwd/g.txt Save New Del /tmp/pardes-snap/fsearch/cwd New Del /tmp/pardes-snap/fsearch/cwd New Del
-| 1 l1
+| 1 l1 ls ls
| 2 MARK a g.txt g.txt
| 3 l3
| 4 l4
@@ -295,7 +295,7 @@
|
|
| /tmp/pardes-snap/fsearch/cwd New Del
-|
+| ls
| g.txt
|
|
@@ -305,6 +305,6 @@
| /tmp/pardes-snap/fsearch/cwd/+Search New Del
| 1
| /tmp/pardes-snap/fsearch/cwd/+Search New Del
-| 1 g.txt:2:1-4 MARK a
| 2 g.txt:6:1-4 MARK b
| 3 g.txt:10:1-4 MARK c
+| 4
diff --git a/test/snapshots/fsearch.snap b/test/snapshots/fsearch.snap
index af1363dd..b9b7ddf4 100644
--- a/test/snapshots/fsearch.snap
+++ b/test/snapshots/fsearch.snap
@@ -1,11 +1,11 @@
# `/` file search: the pattern types into the tag (persistent, no popup);
# Enter searches the buffer in-core and writes `path:LINE:COL-ENDCOL text` into
# a +Search OUTPUT BUFFER (a file pane with no file behind it — no Save in its
-# tag); n/N select the next/prev row there and look it, so the file pane
-# scrolls to the hit AND SELECTS IT — the row names the match's whole span, not
-# just where it starts. Esc abandons the input; a no-match search opens an EMPTY buffer
-# (every search gets its own, stacked under the pane) and leaves n with
-# nowhere to go.
+# tag); n/N SELECT the next/prev row there and open nothing, and Enter — the
+# look chord — is what scrolls the file pane to the hit AND SELECTS IT: the row
+# names the match's whole span, not just where it starts. Esc abandons the
+# input; a no-match search opens an EMPTY buffer (every search gets its own,
+# stacked under the pane) with nothing in it for n to stop on.
file g.txt l1\nMARK a\nl3\nl4\nl5\nMARK b\nl7\nl8\nl9\nMARK c\nl11\nl12
start 30 180 -n 3
wait 8000 g.txt
@@ -34,21 +34,25 @@ key enter
wait 10000 g.txt:2:1-4 MARK
stable 700 10000
snap results
-# n selects result 1 in the results buffer, scrolls the file to line 2 and
-# selects the four cells the pattern matched there — the styles below are what
-# prove the second half of that
+# n selects result 1 and Enter looks it: the file scrolls to line 2 and the
+# four cells the pattern matched there come up selected — the styles below are
+# what prove the second half of that
key n
+key enter
stable 700 15000
snap first
snapstyle first
key n
+key enter
stable 700 15000
snap second
key n
+key enter
stable 700 15000
snap third
-# N walks back up to result 2 (line 6)
+# N walks back up to result 2 (line 6), Enter looks it
key N
+key enter
stable 700 15000
snap back
# Esc abandons the input: the tag tail is restored
@@ -58,7 +62,8 @@ key esc
settle 100
stable 400 5000
snap cancel
-# a no-match search: n has nowhere to go (nothing changes, no crash)
+# a no-match search: nothing in the empty list for n to stop on, so the ring
+# carries it back into the list that has rows and it resumes there
key /
text zzqq
key enter
diff --git a/test/snapshots/ghostty-mid.golden b/test/snapshots/ghostty-mid.golden
index d951915c..39da0f5b 100644
--- a/test/snapshots/ghostty-mid.golden
+++ b/test/snapshots/ghostty-mid.golden
@@ -1,9 +1,9 @@
== snap ghostty-mid grid=100x30 cursor=4,6
|New Newcol Find Grep Help Tutor Dump NextColor Debug Kill
| /tmp/pardes-snap/ghostty-mid/cwd New Del /tmp/pardes-snap/ghostty-mid/cwd New Del
-| ZZPAD
+| ZZPAD ls
| ./g.sh g.txt
-|
+| ./g.sh
| GHOSTOK
|
|
@@ -16,7 +16,7 @@
|
|
| /tmp/pardes-snap/ghostty-mid/cwd New Del
-|
+| ls
| g.txt
|
|
diff --git a/test/snapshots/grep.golden b/test/snapshots/grep.golden
index a8252249..846ab703 100644
--- a/test/snapshots/grep.golden
+++ b/test/snapshots/grep.golden
@@ -1,7 +1,7 @@
== snap opened grid=180x30 cursor=7,2
|New Newcol Find Grep Help Tutor Dump NextColor Debug Kill
| /tmp/pardes-snap/grep/cwd/a.txt Save New Del /tmp/pardes-snap/grep/cwd New Del /tmp/pardes-snap/grep/cwd New Del
-| 1 hello TARGET one
+| 1 hello TARGET one ls ls
| 2 nothing here a.txt noise.txt sub a.txt noise.txt sub
| 3 last TARGET line
|
@@ -16,7 +16,7 @@
|
|
| /tmp/pardes-snap/grep/cwd New Del
-|
+| ls
| a.txt noise.txt sub
|
|
@@ -32,7 +32,7 @@
== snap typing grid=180x30 cursor=15,29
|New Newcol Find Grep Help Tutor Dump NextColor Debug Kill
| /tmp/pardes-snap/grep/cwd/a.txt Save New Del /tmp/pardes-snap/grep/cwd New Del /tmp/pardes-snap/grep/cwd New Del
-| 1 hello TARGET one
+| 1 hello TARGET one ls ls
| 2 nothing here a.txt noise.txt sub a.txt noise.txt sub
| 3 last TARGET line
|
@@ -47,7 +47,7 @@
|
|
| /tmp/pardes-snap/grep/cwd New Del
-|
+| ls
| a.txt noise.txt sub
|
|
@@ -63,7 +63,7 @@
== snap results grid=180x30 cursor=7,2
|New Newcol Find Grep Help Tutor Dump NextColor Debug Kill
| /tmp/pardes-snap/grep/cwd/a.txt Save New Del /tmp/pardes-snap/grep/cwd New Del /tmp/pardes-snap/grep/cwd New Del
-| 1 hello TARGET one
+| 1 hello TARGET one ls ls
| 2 nothing here a.txt noise.txt sub a.txt noise.txt sub
| 3 last TARGET line
|
@@ -78,7 +78,7 @@
|
|
| /tmp/pardes-snap/grep/cwd New Del
-|
+| ls
| a.txt noise.txt sub
|
|
@@ -94,7 +94,7 @@
== snap first grid=180x30 cursor=18,2
|New Newcol Find Grep Help Tutor Dump NextColor Debug Kill
| /tmp/pardes-snap/grep/cwd/a.txt Save New Del /tmp/pardes-snap/grep/cwd New Del /tmp/pardes-snap/grep/cwd New Del
-| 1 hello TARGET one
+| 1 hello TARGET one ls ls
| 2 nothing here a.txt noise.txt sub a.txt noise.txt sub
| 3 last TARGET line
|
@@ -109,7 +109,7 @@
|
|
| /tmp/pardes-snap/grep/cwd New Del
-|
+| ls
| a.txt noise.txt sub
|
|
@@ -122,10 +122,10 @@
| 1 a.txt:1:7-12 hello TARGET one
| 2 a.txt:3:6-11 last TARGET line
| 3 sub/b.txt:2:1-6 TARGET inside sub
-== snap opened-hit grid=180x30 cursor=17,4
+== snap opened-hit grid=180x30 cursor=12,16
|New Newcol Find Grep Help Tutor Dump NextColor Debug Kill
| /tmp/pardes-snap/grep/cwd/a.txt Save New Del /tmp/pardes-snap/grep/cwd New Del /tmp/pardes-snap/grep/cwd New Del
-| 1 hello TARGET one
+| 1 hello TARGET one ls ls
| 2 nothing here a.txt noise.txt sub a.txt noise.txt sub
| 3 last TARGET line
|
@@ -140,7 +140,7 @@
| /tmp/pardes-snap/grep/cwd/sub/b.txt Save New Del
| 1 deep
| 2 TARGET inside sub /tmp/pardes-snap/grep/cwd New Del
-|
+| ls
| a.txt noise.txt sub
|
|
@@ -150,13 +150,13 @@
|
|
| /tmp/pardes-snap/grep/cwd/+Search New Del
-| 1 a.txt:1:7-12 hello TARGET one
| 2 a.txt:3:6-11 last TARGET line
| 3 sub/b.txt:2:1-6 TARGET inside sub
-== snap nomatch grid=180x30 cursor=17,4
+| 4
+== snap nomatch grid=180x30 cursor=37,28
|New Newcol Find Grep Help Tutor Dump NextColor Debug Kill
| /tmp/pardes-snap/grep/cwd/a.txt Save New Del /tmp/pardes-snap/grep/cwd New Del /tmp/pardes-snap/grep/cwd New Del
-| 1 hello TARGET one
+| 1 hello TARGET one ls ls
| 2 nothing here a.txt noise.txt sub a.txt noise.txt sub
| 3 last TARGET line
|
@@ -166,28 +166,28 @@
|
|
|
-| /tmp/pardes-snap/grep/cwd/+Search New Del
-| 1
+|
+|
| /tmp/pardes-snap/grep/cwd/sub/b.txt Save New Del
| 1 deep
| 2 TARGET inside sub /tmp/pardes-snap/grep/cwd New Del
-|
+| ls
| a.txt noise.txt sub
|
|
|
|
|
-|
-|
+| /tmp/pardes-snap/grep/cwd/sub/+Search New Del
+| 1
| /tmp/pardes-snap/grep/cwd/+Search New Del
-| 1 a.txt:1:7-12 hello TARGET one
| 2 a.txt:3:6-11 last TARGET line
| 3 sub/b.txt:2:1-6 TARGET inside sub
+| 4
== snap chordsel grid=180x30 cursor=19,2
|New Newcol Find Grep Help Tutor Dump NextColor Debug Kill
| /tmp/pardes-snap/grep/cwd/a.txt Save New Del /tmp/pardes-snap/grep/cwd New Del /tmp/pardes-snap/grep/cwd New Del
-| 1 hello TARGET one
+| 1 hello TARGET one ls ls
| 2 nothing here a.txt noise.txt sub a.txt noise.txt sub
| 3 last TARGET line
|
@@ -197,28 +197,28 @@
|
|
|
-| /tmp/pardes-snap/grep/cwd/+Search New Del
-| 1
+|
+|
| /tmp/pardes-snap/grep/cwd/sub/b.txt Save New Del
| 1 deep
| 2 TARGET inside sub /tmp/pardes-snap/grep/cwd New Del
-|
+| ls
| a.txt noise.txt sub
|
|
|
|
|
-|
-|
+| /tmp/pardes-snap/grep/cwd/sub/+Search New Del
+| 1
| /tmp/pardes-snap/grep/cwd/+Search New Del
-| 1 a.txt:1:7-12 hello TARGET one
| 2 a.txt:3:6-11 last TARGET line
| 3 sub/b.txt:2:1-6 TARGET inside sub
+| 4
== snap chord grid=180x30 cursor=19,2
|New Newcol Find Grep Help Tutor Dump NextColor Debug Kill
| /tmp/pardes-snap/grep/cwd/a.txt Save New Del /tmp/pardes-snap/grep/cwd New Del /tmp/pardes-snap/grep/cwd New Del
-| 1 hello TARGET one
+| 1 hello TARGET one ls ls
| 2 nothing here a.txt noise.txt sub a.txt noise.txt sub
| 3 last TARGET line
|
@@ -228,21 +228,21 @@
|
|
|
-| /tmp/pardes-snap/grep/cwd/+Search New Del
-| 1
+|
+|
| /tmp/pardes-snap/grep/cwd/sub/b.txt Save New Del
| 1 deep
| 2 TARGET inside sub /tmp/pardes-snap/grep/cwd New Del
-|
+| ls
| a.txt noise.txt sub
|
|
|
|
|
-|
-|
+| /tmp/pardes-snap/grep/cwd/sub/+Search New Del
+| 1
| /tmp/pardes-snap/grep/cwd/+Search New Del
-| 1 a.txt:1:7-12 hello TARGET one
| 2 a.txt:3:6-11 last TARGET line
| 3 sub/b.txt:2:1-6 TARGET inside sub
+| 4
diff --git a/test/snapshots/grep.snap b/test/snapshots/grep.snap
index 817f613f..1d3efc9e 100644
--- a/test/snapshots/grep.snap
+++ b/test/snapshots/grep.snap
@@ -6,8 +6,9 @@
# looking it SELECTS the hit — with the path RELATIVE to the directory
# of the pane that asked — the same directory its results buffer is named in,
# so the short name resolves; only a hit from outside that tree stays absolute.
-# n/N walk the rows like any other result list, and a row pointing into a file
-# nothing has open yet opens it.
+# n/N SELECT the next/prev row like any other result list and open nothing;
+# Enter looks what they leave selected, and a row pointing into a file nothing
+# has open yet opens it.
dirmk sub
file a.txt hello TARGET one\nnothing here\nlast TARGET line
file sub/b.txt deep\nTARGET inside sub
@@ -44,25 +45,32 @@ key enter
wait 10000 sub/b.txt:2:1
stable 700 15000
snap results
-# n looks the first row: absolute path, line 1, columns 7..12 (`TARGET`), and
-# those six cells come up selected
+# n selects the first row and Enter looks it: absolute path, line 1, columns
+# 7..12 (`TARGET`), and those six cells come up selected
key n
+key enter
stable 700 15000
snap first
-# ...and stepping on into sub/b.txt opens the file nothing had open
+# ...and stepping on into sub/b.txt, then looking it, opens the file nothing
+# had open
key n
+key enter
stable 700 15000
key n
+key enter
wait 10000 TARGET inside sub
stable 700 15000
snap opened-hit
-# a pattern nothing holds: an empty list of its own, n has nowhere to go.
-# Armed from the LEADER, not the topbar word: the n above left the hit
-# SELECTED in a.txt (a ranged result row is one a look selects), and a topbar
-# execute chords whatever is selected into its argument — so a middle-click
-# here would run `Grep TARGET` and never ask for a pattern at all. The leader
-# path runs the builtin with no argument, which is what this step is about; the
-# chord itself is the last two snaps below.
+# a pattern nothing holds: an empty list of its own, with nothing in it for n
+# to stop on — so the ring carries that step back into the TARGET list. The
+# look above is why both of those read the way they do: it left the cursor in
+# sub/b.txt, so the empty list is named in sub/ rather than cwd/, and it left
+# the hit SELECTED there (a ranged result row is one a look selects).
+# Armed from the LEADER, not the topbar word, because of that selection: a
+# topbar execute chords whatever is selected into its argument, so a
+# middle-click here would run `Grep TARGET` and never ask for a pattern at
+# all. The leader path runs the builtin with no argument, which is what this
+# step is about; the chord itself is the last two snaps below.
key space
key f
key g
diff --git a/test/snapshots/hscroll.golden b/test/snapshots/hscroll.golden
index 959dac81..3aad04d8 100644
--- a/test/snapshots/hscroll.golden
+++ b/test/snapshots/hscroll.golden
@@ -1,7 +1,7 @@
== snap opened grid=90x30 cursor=7,2
|New Newcol Find Grep Help Tutor Dump NextColor Debug Kill
| /tmp/pardes-snap/hscroll/cwd /tmp/pardes-snap/hscroll/cwd /tmp/pardes-snap/hscroll/cwd
-| 1 short1 END_A_MARKER_WAY
+| 1 short1 END_A_MARKER_WAY ls ls
| wide.txt wide.txt
|
|
@@ -16,7 +16,7 @@
|
|
| /tmp/pardes-snap/hscroll/cwd
-|
+| ls
| wide.txt
|
|
@@ -32,7 +32,7 @@
== snap wheeled grid=90x30 cursor=7,2
|New Newcol Find Grep Help Tutor Dump NextColor Debug Kill
| /tmp/pardes-snap/hscroll/cwd /tmp/pardes-snap/hscroll/cwd /tmp/pardes-snap/hscroll/cwd
-| 1 ND_A_MARKER_WAY_OUT_RIG
+| 1 ND_A_MARKER_WAY_OUT_RIG ls ls
| wide.txt wide.txt
|
|
@@ -47,7 +47,7 @@
|
|
| /tmp/pardes-snap/hscroll/cwd
-|
+| ls
| wide.txt
|
|
@@ -63,7 +63,7 @@
== snap clamped grid=90x30 cursor=7,2
|New Newcol Find Grep Help Tutor Dump NextColor Debug Kill
| /tmp/pardes-snap/hscroll/cwd /tmp/pardes-snap/hscroll/cwd /tmp/pardes-snap/hscroll/cwd
-| 1 short1 END_A_MARKER_WAY
+| 1 short1 END_A_MARKER_WAY ls ls
| wide.txt wide.txt
|
|
@@ -78,7 +78,7 @@
|
|
| /tmp/pardes-snap/hscroll/cwd
-|
+| ls
| wide.txt
|
|
@@ -94,7 +94,7 @@
== snap dollar grid=90x30 cursor=26,2
|New Newcol Find Grep Help Tutor Dump NextColor Debug Kill
| /tmp/pardes-snap/hscroll/cwd /tmp/pardes-snap/hscroll/cwd /tmp/pardes-snap/hscroll/cwd
-| 1 padpadpadpadpad_TAIL
+| 1 padpadpadpadpad_TAIL ls ls
| wide.txt wide.txt
|
|
@@ -109,7 +109,7 @@
|
|
| /tmp/pardes-snap/hscroll/cwd
-|
+| ls
| wide.txt
|
|
@@ -125,7 +125,7 @@
== snap zero grid=90x30 cursor=7,2
|New Newcol Find Grep Help Tutor Dump NextColor Debug Kill
| /tmp/pardes-snap/hscroll/cwd /tmp/pardes-snap/hscroll/cwd /tmp/pardes-snap/hscroll/cwd
-| 1 short1 END_A_MARKER_WAY
+| 1 short1 END_A_MARKER_WAY ls ls
| wide.txt wide.txt
|
|
@@ -140,7 +140,7 @@
|
|
| /tmp/pardes-snap/hscroll/cwd
-|
+| ls
| wide.txt
|
|
diff --git a/test/snapshots/images.golden b/test/snapshots/images.golden
index 4d54e9bf..e02ec8d6 100644
--- a/test/snapshots/images.golden
+++ b/test/snapshots/images.golden
@@ -1,7 +1,7 @@
== snap img-open grid=150x30 cursor=11,7
|New Newcol Find Grep Help Tutor Dump NextColor Debug Kill
| img /tmp/pardes-snap/images/cwd/pic.ppm New Del /tmp/pardes-snap/images/cwd New Del /tmp/pardes-snap/images/cwd New Del
-|
+| ls ls
| pic.ppm pic.ppm
| 4*🬹~F~N🬰|G🬏▚Y~KF🬴s<fcSf🬰b^🬘J%🬝ZH|S_"Z}╲%'"qA🬗a🬝🬻
| 8jDStG▄40e~.>>T&zZ/🬻iTY=`S~╳bkZR37v🬦🬵d4QHZ8X▛▟
@@ -16,7 +16,7 @@
| 🬆f│Q_V🬗wGx🬱=5▛5*&V🬟🬄ZrXGz2🬝🬻█
| !🬷W🬐(🬭]7x_>▗er🬯~▚di🬬4jY:🬝▟
| gU~🬧3▙bjr\C#kKMpffAjps🬝🬻 /tmp/pardes-snap/images/cwd New Del
-| *🬯G"🬣▟d🬮▀zJ🬪EHV▟╳9}y▛▄
+| *🬯G"🬣▟d🬮▀zJ🬪EHV▟╳9}y▛▄ ls
| ``))~RyJ🬴jA~w=hLpX🬝🬻█ pic.ppm
| 4x▀J"TG7=y-QZ🬙╲~▛🬻
| 🬯/+╳f9ZG🬕+{QN_🬝🬹
@@ -94,7 +94,7 @@
== snap no-ascii grid=150x30 cursor=11,7
|New Newcol Find Grep Help Tutor Dump NextColor Debug Kill
| img /tmp/pardes-snap/images/cwd/pic.ppm New Del /tmp/pardes-snap/images/cwd New Del /tmp/pardes-snap/images/cwd New Del
-|
+| ls ls
| pic.ppm pic.ppm
| ╳╱╱🬻🬫🬴🬸│🬜🬴🬬█▗╲│█🬷█🬴🬙🬋─🬬🬋╳🬺🬲│█🬫▜▞│🬪🬝🬴🬝🬸╲🬣██🬛🬸🬛🬸│🬻
| 🬝🬺┼─▜🬱🬬🬻🬸🬔╲█🬻╱██🬝╲▙🬻🬹▙▀🬺╲┼🬺╳🬷▜─🬙█││🬴🬎🬹╲█🬺▜🬴─▙🬻╲
@@ -109,7 +109,7 @@
| 🬎╱│─██🬳▀🬪🬺🬎│▜█🬴🬸🬻🬆🬜▟█🬻🬬▀🬺╱▜🬵
| │▟▐🬻█🬬🬥🬬🬕█🬻🬴┼🬑🬝🬬▞╱▟🬬╱🬝▜🬣█╳█
| 🬰█│🬧🬰▛╱🬬╲─🬬█┼🬩█🬬▜─🬴│🬝🬲─🬵 /tmp/pardes-snap/images/cwd New Del
-| 🬴🬷🬰🬐🬸▘╱🬍▄│╲▞█╳╱▟╱🬝🬛🬬🬶🬻█
+| 🬴🬷🬰🬐🬸▘╱🬍▄│╲▞█╳╱▟╱🬝🬛🬬🬶🬻█ ls
| ███╱█🬺🬺█🬇▙🬸🬫🬙█🬴▙🬝╱🬺╱ pic.ppm
| █╱▙🬺█▜╱█🬬▜█🬕╲🬩╲█🬝│
| 🬌🬸🬴🬴█▄🬬▙▛🬫🬔┼╳█🬺╳█
@@ -125,7 +125,7 @@
== snap tag-edit grid=150x30 cursor=45,1
|New Newcol Find Grep Help Tutor Dump NextColor Debug Kill
| img /tmp/pardes-snap/images/cwd/pic.ppmZork New /tmp/pardes-snap/images/cwd New Del /tmp/pardes-snap/images/cwd New Del
-|
+| ls ls
| pic.ppm pic.ppm
| ╳╱╱🬻🬫🬴🬸│🬜🬴🬬█▗╲│█🬷█🬴🬙🬋─🬬🬋╳🬺🬲│█🬫▜▞│🬪🬝🬴🬝🬸╲🬣██🬛🬸🬛🬸│🬻
| 🬝🬺┼─▜🬱🬬🬻🬸🬔╲█🬻╱██🬝╲▙🬻🬹▙▀🬺╲┼🬺╳🬷▜─🬙█││🬴🬎🬹╲█🬺▜🬴─▙🬻╲
@@ -140,7 +140,7 @@
| 🬎╱│─██🬳▀🬪🬺🬎│▜█🬴🬸🬻🬆🬜▟█🬻🬬▀🬺╱▜🬵
| │▟▐🬻█🬬🬥🬬🬕█🬻🬴┼🬑🬝🬬▞╱▟🬬╱🬝▜🬣█╳█
| 🬰█│🬧🬰▛╱🬬╲─🬬█┼🬩█🬬▜─🬴│🬝🬲─🬵 /tmp/pardes-snap/images/cwd New Del
-| 🬴🬷🬰🬐🬸▘╱🬍▄│╲▞█╳╱▟╱🬝🬛🬬🬶🬻█
+| 🬴🬷🬰🬐🬸▘╱🬍▄│╲▞█╳╱▟╱🬝🬛🬬🬶🬻█ ls
| ███╱█🬺🬺█🬇▙🬸🬫🬙█🬴▙🬝╱🬺╱ pic.ppm
| █╱▙🬺█▜╱█🬬▜█🬕╲🬩╲█🬝│
| 🬌🬸🬴🬴█▄🬬▙▛🬫🬔┼╳█🬺╳█
diff --git a/test/snapshots/jumps.golden b/test/snapshots/jumps.golden
index a557ce1f..5e8cbbab 100644
--- a/test/snapshots/jumps.golden
+++ b/test/snapshots/jumps.golden
@@ -32,7 +32,7 @@
== snap to-shell grid=150x30 cursor=79,4
|New Newcol Find Grep Help Tutor Dump NextColor Debug Kill
| /tmp/pardes-snap/jumps/cwd/big.txt Save New Del /tmp/pardes-snap/jumps/cwd New Del
-| 1 line 1
+| 1 line 1 ls
| 2 line 2 big.txt
| 3 line 3
| 4 line 4
@@ -63,7 +63,7 @@
== snap to-file grid=150x30 cursor=7,2
|New Newcol Find Grep Help Tutor Dump NextColor Debug Kill
| /tmp/pardes-snap/jumps/cwd/big.txt Save New Del /tmp/pardes-snap/jumps/cwd New Del
-| 1 line 1
+| 1 line 1 ls
| 2 line 2 big.txt
| 3 line 3
| 4 line 4
@@ -94,7 +94,7 @@
== snap goto-100 grid=150x30 cursor=7,26
|New Newcol Find Grep Help Tutor Dump NextColor Debug Kill
| /tmp/pardes-snap/jumps/cwd/big.txt Save New Del /tmp/pardes-snap/jumps/cwd New Del
-| 76 line 76
+| 76 line 76 ls
| 77 line 77 big.txt
| 78 line 78
| 79 line 79
@@ -125,7 +125,7 @@
== snap back-in-file grid=150x30 cursor=7,2
|New Newcol Find Grep Help Tutor Dump NextColor Debug Kill
| /tmp/pardes-snap/jumps/cwd/big.txt Save New Del /tmp/pardes-snap/jumps/cwd New Del
-| 1 line 1
+| 1 line 1 ls
| 2 line 2 big.txt
| 3 line 3
| 4 line 4
@@ -156,7 +156,7 @@
== snap back-to-shell grid=150x30 cursor=79,4
|New Newcol Find Grep Help Tutor Dump NextColor Debug Kill
| /tmp/pardes-snap/jumps/cwd/big.txt Save New Del /tmp/pardes-snap/jumps/cwd New Del
-| 1 line 1
+| 1 line 1 ls
| 2 line 2 big.txt
| 3 line 3
| 4 line 4
@@ -187,7 +187,7 @@
== snap forward-file grid=150x30 cursor=7,2
|New Newcol Find Grep Help Tutor Dump NextColor Debug Kill
| /tmp/pardes-snap/jumps/cwd/big.txt Save New Del /tmp/pardes-snap/jumps/cwd New Del
-| 1 line 1
+| 1 line 1 ls
| 2 line 2 big.txt
| 3 line 3
| 4 line 4
@@ -218,7 +218,7 @@
== snap forward-100 grid=150x30 cursor=7,16
|New Newcol Find Grep Help Tutor Dump NextColor Debug Kill
| /tmp/pardes-snap/jumps/cwd/big.txt Save New Del /tmp/pardes-snap/jumps/cwd New Del
-| 86 line 86
+| 86 line 86 ls
| 87 line 87 big.txt
| 88 line 88
| 89 line 89
@@ -249,7 +249,7 @@
== snap last grid=150x30 cursor=79,4
|New Newcol Find Grep Help Tutor Dump NextColor Debug Kill
| /tmp/pardes-snap/jumps/cwd/big.txt Save New Del /tmp/pardes-snap/jumps/cwd New Del
-| 86 line 86
+| 86 line 86 ls
| 87 line 87 big.txt
| 88 line 88
| 89 line 89
@@ -280,7 +280,7 @@
== snap last-back grid=150x30 cursor=7,16
|New Newcol Find Grep Help Tutor Dump NextColor Debug Kill
| /tmp/pardes-snap/jumps/cwd/big.txt Save New Del /tmp/pardes-snap/jumps/cwd New Del
-| 86 line 86
+| 86 line 86 ls
| 87 line 87 big.txt
| 88 line 88
| 89 line 89
@@ -311,7 +311,7 @@
== snap jumplist grid=150x30 cursor=7,16
|New Newcol Find Grep Help Tutor Dump NextColor Debug Kill
| /tmp/pardes-snap/jumps/cwd/big.txt Save New Del /tmp/pardes-snap/jumps/cwd New Del
-| 86 line 86
+| 86 line 86 ls
| 87 line 87 big.txt
| 88 line 88
| 89 line 89
@@ -339,10 +339,10 @@
| 2 /tmp/pardes-snap/jumps/cwd/big.txt:1:1 line 1
| 3 @p1:3:3 /tmp/pardes-snap/jumps/cwd
| 4 /tmp/pardes-snap/jumps/cwd/big.txt:100:1 line 100
-== snap step1-shell grid=150x30 cursor=7,16
+== snap step1-shell grid=150x30 cursor=79,4
|New Newcol Find Grep Help Tutor Dump NextColor Debug Kill
| /tmp/pardes-snap/jumps/cwd/big.txt Save New Del /tmp/pardes-snap/jumps/cwd New Del
-| 86 line 86
+| 86 line 86 ls
| 87 line 87 big.txt
| 88 line 88
| 89 line 89
@@ -372,7 +372,7 @@
| 4 /tmp/pardes-snap/jumps/cwd/big.txt:100:1 line 100
== style step1-shell
|0: 0-56 #949494,#121212, 57-149 d,#121212,
-|1: 0-1 #ffffff,#626262, 2-54 #949494,#121212, 55-74 d,#121212, 75-76 #ffffff,#262626, 77-129 #949494,#121212, 130-149 d,#121212,
+|1: 0-1 #ffffff,#262626, 2-54 #949494,#121212, 55-74 d,#121212, 75-76 #ffffff,#626262, 77-129 #949494,#121212, 130-149 d,#121212,
|2: 0-0 d,#121212, 1-1 d,#080808, 2-6 #626262,#080808, 7-13 #bdbdbd,#080808, 14-74 d,#080808, 75-75 d,#444444, 76-76 d,#080808, 77-149 #bdbdbd,#080808,
|3: 0-0 d,#121212, 1-1 d,#080808, 2-6 #626262,#080808, 7-13 #bdbdbd,#080808, 14-74 d,#080808, 75-75 d,#444444, 76-76 d,#080808, 77-149 #bdbdbd,#080808,
|4: 0-0 d,#121212, 1-1 d,#080808, 2-6 #626262,#080808, 7-13 #bdbdbd,#080808, 14-74 d,#080808, 75-75 d,#444444, 76-76 d,#080808, 77-149 #bdbdbd,#080808,
@@ -387,7 +387,7 @@
|13: 0-0 d,#121212, 1-1 d,#080808, 2-6 #626262,#080808, 7-13 #bdbdbd,#080808, 14-74 d,#080808, 75-75 d,#444444, 76-76 d,#080808, 77-149 #bdbdbd,#080808,
|14: 0-0 d,#121212, 1-1 d,#080808, 2-6 #626262,#080808, 7-13 #bdbdbd,#080808, 14-74 d,#080808, 75-75 d,#444444, 76-76 d,#080808, 77-149 #bdbdbd,#080808,
|15: 0-0 d,#121212, 1-1 d,#080808, 2-6 #626262,#080808, 7-13 #bdbdbd,#080808, 14-74 d,#080808, 75-75 d,#444444, 76-76 d,#080808, 77-149 #bdbdbd,#080808,
-|16: 0-0 d,#121212, 1-1 d,#080808, 2-6 #949494,#121212, 7-14 #bdbdbd,#080808, 15-74 d,#080808, 75-75 d,#444444, 76-76 d,#080808, 77-149 #bdbdbd,#080808,
+|16: 0-0 d,#121212, 1-1 d,#080808, 2-6 #626262,#080808, 7-14 #bdbdbd,#080808, 15-74 d,#080808, 75-75 d,#444444, 76-76 d,#080808, 77-149 #bdbdbd,#080808,
|17: 0-0 d,#121212, 1-1 d,#080808, 2-6 #626262,#080808, 7-14 #bdbdbd,#080808, 15-74 d,#080808, 75-75 d,#444444, 76-76 d,#080808, 77-149 #bdbdbd,#080808,
|18: 0-0 d,#121212, 1-1 d,#080808, 2-6 #626262,#080808, 7-14 #bdbdbd,#080808, 15-74 d,#080808, 75-75 d,#444444, 76-76 d,#080808, 77-149 #bdbdbd,#080808,
|19: 0-0 d,#121212, 1-1 d,#080808, 2-6 #626262,#080808, 7-14 #bdbdbd,#080808, 15-74 d,#080808, 75-75 d,#444444, 76-76 d,#080808, 77-149 #bdbdbd,#080808,
@@ -397,14 +397,14 @@
|23: 0-0 d,#121212, 1-1 d,#080808, 2-6 #626262,#080808, 7-14 #bdbdbd,#080808, 15-74 d,#080808, 75-75 d,#444444, 76-76 d,#080808, 77-149 #bdbdbd,#080808,
|24: 0-0 d,#121212, 1-1 d,#080808, 2-6 #626262,#080808, 7-14 #bdbdbd,#080808, 15-74 d,#080808, 75-75 d,#444444, 76-76 d,#080808, 77-149 #bdbdbd,#080808,
|25: 0-1 #ffffff,#262626, 2-54 #949494,#121212, 55-74 d,#121212, 75-75 d,#444444, 76-76 d,#080808, 77-149 #bdbdbd,#080808,
-|26: 0-0 d,#444444, 1-1 d,#080808, 2-6 #626262,#080808, 7-74 #080808,#80a0ff, 75-75 d,#444444, 76-76 d,#080808, 77-149 #bdbdbd,#080808,
+|26: 0-0 d,#444444, 1-1 d,#080808, 2-6 #626262,#080808, 7-40 #bdbdbd,#080808, 41-74 d,#080808, 75-75 d,#444444, 76-76 d,#080808, 77-149 #bdbdbd,#080808,
|27: 0-0 d,#444444, 1-1 d,#080808, 2-6 #626262,#080808, 7-51 #bdbdbd,#080808, 52-74 d,#080808, 75-75 d,#444444, 76-76 d,#080808, 77-149 #bdbdbd,#080808,
|28: 0-0 d,#444444, 1-1 d,#080808, 2-6 #626262,#080808, 7-40 #bdbdbd,#080808, 41-74 d,#080808, 75-75 d,#444444, 76-76 d,#080808, 77-149 #bdbdbd,#080808,
|29: 0-0 d,#121212, 1-1 d,#080808, 2-6 #626262,#080808, 7-55 #bdbdbd,#080808, 56-74 d,#080808, 75-75 d,#444444, 76-76 d,#080808, 77-149 #bdbdbd,#080808,
== snap step2-file grid=150x30 cursor=7,2
|New Newcol Find Grep Help Tutor Dump NextColor Debug Kill
| /tmp/pardes-snap/jumps/cwd/big.txt Save New Del /tmp/pardes-snap/jumps/cwd New Del
-| 1 line 1
+| 1 line 1 ls
| 2 line 2 big.txt
| 3 line 3
| 4 line 4
@@ -435,7 +435,7 @@
== snap step4-line100 grid=150x30 cursor=7,13
|New Newcol Find Grep Help Tutor Dump NextColor Debug Kill
| /tmp/pardes-snap/jumps/cwd/big.txt Save New Del /tmp/pardes-snap/jumps/cwd New Del
-| 89 line 89
+| 89 line 89 ls
| 90 line 90 big.txt
| 91 line 91
| 92 line 92
@@ -459,14 +459,14 @@
| 110 line 110
| 111 line 111
| /tmp/pardes-snap/jumps/cwd/+Jumps New Del
-| 1 @p1:3:3 /tmp/pardes-snap/jumps/cwd
| 2 /tmp/pardes-snap/jumps/cwd/big.txt:1:1 line 1
| 3 @p1:3:3 /tmp/pardes-snap/jumps/cwd
| 4 /tmp/pardes-snap/jumps/cwd/big.txt:100:1 line 100
-== snap step-back grid=150x30 cursor=7,13
+| 5
+== snap step-back grid=150x30 cursor=79,4
|New Newcol Find Grep Help Tutor Dump NextColor Debug Kill
| /tmp/pardes-snap/jumps/cwd/big.txt Save New Del /tmp/pardes-snap/jumps/cwd New Del
-| 89 line 89
+| 89 line 89 ls
| 90 line 90 big.txt
| 91 line 91
| 92 line 92
@@ -490,14 +490,14 @@
| 110 line 110
| 111 line 111
| /tmp/pardes-snap/jumps/cwd/+Jumps New Del
-| 1 @p1:3:3 /tmp/pardes-snap/jumps/cwd
| 2 /tmp/pardes-snap/jumps/cwd/big.txt:1:1 line 1
| 3 @p1:3:3 /tmp/pardes-snap/jumps/cwd
| 4 /tmp/pardes-snap/jumps/cwd/big.txt:100:1 line 100
+| 5
== snap look-row grid=150x30 cursor=7,13
|New Newcol Find Grep Help Tutor Dump NextColor Debug Kill
| /tmp/pardes-snap/jumps/cwd/big.txt Save New Del /tmp/pardes-snap/jumps/cwd New Del
-| 89 line 89
+| 89 line 89 ls
| 90 line 90 big.txt
| 91 line 91
| 92 line 92
@@ -521,7 +521,7 @@
| 110 line 110
| 111 line 111
| /tmp/pardes-snap/jumps/cwd/+Jumps New Del
-| 1 @p1:3:3 /tmp/pardes-snap/jumps/cwd
| 2 /tmp/pardes-snap/jumps/cwd/big.txt:1:1 line 1
| 3 @p1:3:3 /tmp/pardes-snap/jumps/cwd
| 4 /tmp/pardes-snap/jumps/cwd/big.txt:100:1 line 100
+| 5
diff --git a/test/snapshots/jumps.snap b/test/snapshots/jumps.snap
index 1e2a9075..db131bd4 100644
--- a/test/snapshots/jumps.snap
+++ b/test/snapshots/jumps.snap
@@ -64,36 +64,58 @@ snap last-back
key space j l
stable 700 15000
snap jumplist
-# n/N step the rows and look them, exactly as they do a +Search: the stepped
-# row is selected in the buffer (snapstyle) and the pane it names follows.
-# Row 1 is the shell (no path, so `@pN`), row 2 the file at line 1, row 4 the
-# file at line 100 — so the body visibly rides the list.
+# n/N select the next/prev look-able span and Enter looks it, exactly as they
+# do a +Search: the stepped span is selected in the buffer (snapstyle) and the
+# Enter after it moves the pane the row names. Row 1 is the shell (no path, so
+# `@pN`), row 2 the file at line 1, row 4 the file at line 100 — so the body
+# visibly rides the list.
#
-# ponytail: stepping onto an `@pN` row selects it but does NOT focus that pane —
-# the cursor stays where it was, which is why step1-shell's header is still the
-# file's. Only rows with a PATH move focus. Nothing tested this before, because
-# until the swap above the shell never survived on the stack to be listed at
-# all. Fix belongs in the location-list step, next to the path case.
+# SPANS, not rows, and this buffer is the one place in the suite where the two
+# differ: an `@pN` row's trailing text is the pane's DIRECTORY, which is a
+# look-able word of its own, so row 1 and row 3 each hold TWO stops and
+# reaching the next row takes two steps. A file row's text is its content line
+# (`line 1`), which resolves to nothing, so those hold one. Stepping words
+# rather than rows is what makes the walk the same motion in a results buffer
+# and in the middle of a paragraph, and this is the price of that.
+#
+# An `@pN` row moves focus like any other, which it did not use to: the STEP
+# only selects now, and the look Enter runs goes to the pane by the same route
+# a path takes.
key n
+key enter
stable 700 15000
snap step1-shell
snapstyle step1-shell
+# past the directory on row 1, then onto row 2
+key n
+stable 400 5000
key n
+key enter
stable 700 15000
snap step2-file
+# row 3 is the shell again, both its spans, and then row 4
key n
-stable 700 15000
+stable 400 5000
key n
+stable 400 5000
+key n
+key enter
stable 700 15000
snap step4-line100
+# N is the exact inverse: the same two spans of row 3 in the other order, so
+# two presses land back on its location and Enter follows it to the shell
+key N
+stable 400 5000
key N
+key enter
stable 700 15000
snap step-back
# and an ordinary LOOK on a row goes there too — the leading word IS a
# location, so the right-click look resolves it like any other path. Row 4
-# again, this time by clicking it: the buffer's four rows are the last four
-# screen rows, so row 4 is the bottom one.
-press right 16 30
-release right 16 30
+# again, this time by clicking it: the walk above scrolled the list by one, so
+# the last four screen rows are its rows 2 through 5 and row 4 is the second
+# from the bottom.
+press right 16 29
+release right 16 29
stable 700 15000
snap look-row
diff --git a/test/snapshots/layout-close.golden b/test/snapshots/layout-close.golden
index e809621e..5e4faba0 100644
--- a/test/snapshots/layout-close.golden
+++ b/test/snapshots/layout-close.golden
@@ -1,19 +1,19 @@
== snap built grid=140x40 cursor=4,16
|New Newcol Find Grep Help Tutor Dump NextColor Debug Kill
| /tmp/pardes-snap/layout-close/cwd New Del /tmp/pardes-snap/layout-close/cwd New Del
-|
+| ls ls
| marker.txt marker.txt
|
| /tmp/pardes-snap/layout-close/cwd New Del
-|
+| ls
| marker.txt
|
| /tmp/pardes-snap/layout-close/cwd New Del
-|
+| ls
| marker.txt
|
| /tmp/pardes-snap/layout-close/cwd New Del
-|
+| ls
| marker.txt
|
|
@@ -21,7 +21,7 @@
|
|
| /tmp/pardes-snap/layout-close/cwd New Del
-|
+| ls
| marker.txt
|
|
@@ -42,15 +42,15 @@
== snap altc grid=140x40 cursor=98,4
|New Newcol Find Grep Help Tutor Dump NextColor Debug Kill
| /tmp/pardes-snap/layout-close/cwd New Del /tmp/pardes-snap/layout-close/cwd New Del /tmp/pardes-snap/layout-close/cwd New Del
-|
+| ls ls ls
| marker.txt marker.txt marker.txt
|
| /tmp/pardes-snap/layout-close/cwd New Del
-|
+| ls
| marker.txt
|
| /tmp/pardes-snap/layout-close/cwd New Del
-|
+| ls
| marker.txt
|
|
@@ -62,7 +62,7 @@
|
|
| /tmp/pardes-snap/layout-close/cwd New Del
-|
+| ls
| marker.txt
|
|
@@ -83,7 +83,7 @@
== snap del grid=140x40 cursor=98,4
|New Newcol Find Grep Help Tutor Dump NextColor Debug Kill
| /tmp/pardes-snap/layout-close/cwd New Del /tmp/pardes-snap/layout-close/cwd New Del /tmp/pardes-snap/layout-close/cwd New Del
-|
+| ls ls ls
| marker.txt marker.txt marker.txt
|
|
@@ -91,7 +91,7 @@
|
|
| /tmp/pardes-snap/layout-close/cwd New Del
-|
+| ls
| marker.txt
|
|
@@ -103,7 +103,7 @@
|
|
| /tmp/pardes-snap/layout-close/cwd New Del
-|
+| ls
| marker.txt
|
|
@@ -124,7 +124,7 @@
== snap exit grid=140x40 cursor=98,4
|New Newcol Find Grep Help Tutor Dump NextColor Debug Kill
| /tmp/pardes-snap/layout-close/cwd New Del /tmp/pardes-snap/layout-close/cwd New Del /tmp/pardes-snap/layout-close/cwd New Del
-|
+| ls ls ls
| marker.txt marker.txt marker.txt
|
|
@@ -144,7 +144,7 @@
|
|
| /tmp/pardes-snap/layout-close/cwd New Del
-|
+| ls
| marker.txt
|
|
@@ -165,7 +165,7 @@
== snap colclose grid=140x40 cursor=4,7
|New Newcol Find Grep Help Tutor Dump NextColor Debug Kill
| /tmp/pardes-snap/layout-close/cwd New Del /tmp/pardes-snap/layout-close/cwd New Del
-|
+| ls ls
| marker.txt marker.txt
|
|
@@ -185,7 +185,7 @@
|
|
| /tmp/pardes-snap/layout-close/cwd New Del
-|
+| ls
| marker.txt
|
|
diff --git a/test/snapshots/layout-open.golden b/test/snapshots/layout-open.golden
index 9631f223..cb6c5f6a 100644
--- a/test/snapshots/layout-open.golden
+++ b/test/snapshots/layout-open.golden
@@ -1,7 +1,7 @@
== snap before grid=100x30 cursor=2,8
|New Newcol Find Grep Help Tutor Dump NextColor Debug Kill
| /tmp/pardes-snap/layout-open/cwd New Del /tmp/pardes-snap/layout-open/cwd New Del
-|
+| ls ls
| sub sub
|
|
@@ -16,7 +16,7 @@
|
|
| /tmp/pardes-snap/layout-open/cwd New Del
-|
+| ls
| sub
|
|
@@ -32,11 +32,11 @@
== snap altn-left grid=100x30 cursor=4,8
|New Newcol Find Grep Help Tutor Dump NextColor Debug Kill
| /tmp/pardes-snap/layout-open/cwd New Del /tmp/pardes-snap/layout-open/cwd New Del
-|
+| ls ls
| sub sub
|
| /tmp/pardes-snap/layout-open/cwd New Del
-|
+| ls
| sub
|
|
@@ -47,7 +47,7 @@
|
|
| /tmp/pardes-snap/layout-open/cwd New Del
-|
+| ls
| sub
|
|
@@ -63,11 +63,11 @@
== snap altn-right grid=100x30 cursor=54,8
|New Newcol Find Grep Help Tutor Dump NextColor Debug Kill
| /tmp/pardes-snap/layout-open/cwd New Del /tmp/pardes-snap/layout-open/cwd New Del
-|
+| ls ls
| sub sub
|
| /tmp/pardes-snap/layout-open/cwd New Del /tmp/pardes-snap/layout-open/cwd New Del
-|
+| ls ls
| sub sub
|
|
@@ -78,7 +78,7 @@
|
|
| /tmp/pardes-snap/layout-open/cwd New Del
-|
+| ls
| sub
|
|
@@ -94,11 +94,11 @@
== snap file-open grid=100x30 cursor=7,2
|New Newcol Find Grep Help Tutor Dump NextColor Debug Kill
| /tmp/pardes-snap/layout-open/cw /tmp/pardes-snap/layout-open/cw /tmp/pardes-snap/layout-open/cwd
-| 1 echo 'TTY'OK
+| 1 echo 'TTY'OK ls ls
| sub sub
|
| /tmp/pardes-snap/layout-open/cw /tmp/pardes-snap/layout-open/cwd
-|
+| ls ls
| sub sub
|
|
@@ -109,7 +109,7 @@
|
|
| /tmp/pardes-snap/layout-open/cw
-|
+| ls
| sub
|
|
@@ -125,22 +125,22 @@
== snap ttydir grid=100x30 cursor=7,2
|New Newcol Find Grep Help Tutor Dump NextColor Debug Kill
| /tmp/pardes-snap/layout-open/cw /tmp/pardes-snap/layout-open/cw /tmp/pardes-snap/layout-open/cwd
-| 1 echo 'TTY'OK
+| 1 echo 'TTY'OK ls ls
| sub sub
|
| /tmp/pardes-snap/layout-open/cw /tmp/pardes-snap/layout-open/cwd
-|
+| ls ls
| sub sub
|
| /tmp/pardes-snap/layout-open/cwd
| echo 'TTY'OK
-|
+| echo 'TTY'OK
| TTYOK
|
|
|
| /tmp/pardes-snap/layout-open/cw
-|
+| ls
| sub
|
|
diff --git a/test/snapshots/leader.golden b/test/snapshots/leader.golden
index d58e8d6c..10907b99 100644
--- a/test/snapshots/leader.golden
+++ b/test/snapshots/leader.golden
@@ -189,20 +189,20 @@
| 2 SPC and its keys, a chord, a button, the
| 3 topbar - or the name, executed anywhere.
| 4
-| 5 SPC ? Help topbar
-| 6 SPC c d Delcol
-| 7 SPC c n Newcol topbar
-| 8 SPC d Del
-| 9 SPC f c Config
-| 10 SPC f f Find topbar
-| 11 SPC f g Grep topbar
-| 12 SPC f n New topbar
-| 13 SPC f s Save
-| 14 SPC h t Tutor topbar
-| 15 SPC j i Forward C-i
-| 16 SPC j j Last
-| 17 SPC j l Jumplist
-| 18 SPC j o Back C-o
+| 5 SPC ? Help topbar
+| 6 SPC P ClipPasteBefore
+| 7 SPC R ClipReplace
+| 8 SPC Y ClipYankMain
+| 9 SPC c d Delcol
+| 10 SPC c n Newcol topbar
+| 11 SPC d Del
+| 12 SPC f c Config
+| 13 SPC f f Find topbar
+| 14 SPC f g Grep topbar
+| 15 SPC f n New topbar
+| 16 SPC f s Save
+| 17 SPC h t Tutor topbar
+| 18 SPC j i Forward C-i
== snap help-group grid=100x40 cursor=7,22
|New Newcol Find Grep Help Tutor Dump NextColor Debug Kill
| /tmp/pardes-snap/leader/cwd/cmds.txt Save New Del
@@ -228,7 +228,7 @@
| /tmp/pardes-snap/leader/cwd/+Help New Del
| 1 pardes builtins under SPC h
| 2
-| 3 SPC h t Tutor topbar
+| 3 SPC h t Tutor topbar
| 4
|
|
@@ -269,7 +269,7 @@
| /tmp/pardes-snap/leader/cwd/+Help New Del
| 1 pardes builtins under SPC h
| 2
-| 3 SPC h t Tutor topbar
+| 3 SPC h t Tutor topbar
| 4
|
|
@@ -310,7 +310,7 @@
| /tmp/pardes-snap/leader/cwd/+Help New Del
| 1 pardes builtins under SPC h
| 2
-| 3 SPC h t Tutor topbar
+| 3 SPC h t Tutor topbar
| 4
|
|
@@ -353,20 +353,20 @@
| 2 SPC and its keys, a chord, a button, the
| 3 topbar - or the name, executed anywhere.
| 4
-| 5 SPC ? Help topbar
-| 6 SPC c d Delcol
-| 7 SPC c n Newcol topbar
-| 8 SPC d Del
-| 9 SPC f c Config
-| 10 SPC f f Find topbar
-| 11 SPC f g Grep topbar
-| 12 SPC f n New topbar
-| 13 SPC f s Save
-| 14 SPC h t Tutor topbar
-| 15 SPC j i Forward C-i
-| 16 SPC j j Last
-| 17 SPC j l Jumplist
-| 18 SPC j o Back C-o
+| 5 SPC ? Help topbar
+| 6 SPC P ClipPasteBefore
+| 7 SPC R ClipReplace
+| 8 SPC Y ClipYankMain
+| 9 SPC c d Delcol
+| 10 SPC c n Newcol topbar
+| 11 SPC d Del
+| 12 SPC f c Config
+| 13 SPC f f Find topbar
+| 14 SPC f g Grep topbar
+| 15 SPC f n New topbar
+| 16 SPC f s Save
+| 17 SPC h t Tutor topbar
+| 18 SPC j i Forward C-i
== snap help-toggles grid=100x40 cursor=7,22
|New Newcol Find Grep Help Tutor Dump NextColor Debug Kill
| /tmp/pardes-snap/leader/cwd/cmds.txt Save New Del
@@ -395,10 +395,10 @@
| 3 SPC t a Ascii
| 4 SPC t b Tagbottom
| 5 SPC t c Colors
-| 6 SPC t d Debug topbar
+| 6 SPC t d Debug topbar
| 7 SPC t i PdfTint
| 8 SPC t l Palette
-| 9 SPC t n NextColor topbar
+| 9 SPC t n NextColor topbar
| 10 SPC t p Petscii
| 11 SPC t r Crt
| 12 SPC t s PdfSections
@@ -433,10 +433,10 @@
| /tmp/pardes-snap/leader/cwd/+Help New Del
| 1 pardes builtins under SPC w
| 2
-| 3 SPC w h Left C-w h, C-w left
-| 4 SPC w j Down C-w j, C-w down
-| 5 SPC w k Up C-w k, C-w up
-| 6 SPC w l Right C-w l, C-w right
+| 3 SPC w h Left C-w h, C-w left
+| 4 SPC w j Down C-w j, C-w down
+| 5 SPC w k Up C-w k, C-w up
+| 6 SPC w l Right C-w l, C-w right
| 7
|
|
diff --git a/test/snapshots/load.golden b/test/snapshots/load.golden
index 7b6bfab5..c33b79cd 100644
--- a/test/snapshots/load.golden
+++ b/test/snapshots/load.golden
@@ -1,7 +1,7 @@
== snap loaded grid=100x30 cursor=4,15
|New Newcol Find Grep Help Tutor Dump NextColor Debug Kill
| /tmp/pardes-snap/load/cwd New Del /tmp/pardes-snap/load/cwd New Del
-|
+| echo LOAD''MARK; seq 1 40 ls
| LOADMARK d.txt
| 1
| 2
@@ -16,7 +16,7 @@
| 11
| 12
| /tmp/pardes-snap/load/cwd New Del
-|
+| ls
| d.txt
|
|
diff --git a/test/snapshots/look-center.golden b/test/snapshots/look-center.golden
index 199379a1..da1fbfed 100644
--- a/test/snapshots/look-center.golden
+++ b/test/snapshots/look-center.golden
@@ -1,7 +1,7 @@
== snap center-open grid=150x30 cursor=7,16
|New Newcol Find Grep Help Tutor Dump NextColor Debug Kill
| /tmp/pardes-snap/look-center/cwd/big.txt Save Ne /tmp/pardes-snap/look-center/cwd New Del /tmp/pardes-snap/look-center/cwd New Del
-| 86 line 86
+| 86 line 86 ls ls
| 87 line 87 big.txt big.txt
| 88 line 88
| 89 line 89
@@ -16,7 +16,7 @@
| 98 line 98
| 99 line 99
| 100 line 100 /tmp/pardes-snap/look-center/cwd New Del
-| 101 line 101
+| 101 line 101 ls
| 102 line 102 big.txt
| 103 line 103
| 104 line 104
@@ -32,7 +32,7 @@
== snap center-dedup grid=150x30 cursor=17,14
|New Newcol Find Grep Help Tutor Dump NextColor Debug Kill
| /tmp/pardes-snap/look-center/cwd/big.txt Save Ne /tmp/pardes-snap/look-center/cwd New Del /tmp/pardes-snap/look-center/cwd New Del
-| 86 line 86
+| 86 line 86 ls ls
| 87 line 87 big.txt big.txt
| 88 line 88
| 89 line 89
@@ -47,7 +47,7 @@
| 98 line 98
| 99 line 99
| 100 line 100 /tmp/pardes-snap/look-center/cwd New Del
-| 101 line 101
+| 101 line 101 ls
| 102 line 102 big.txt
| 103 line 103
| 104 line 104
@@ -63,7 +63,7 @@
== snap center-clamp grid=150x30 cursor=29,14
|New Newcol Find Grep Help Tutor Dump NextColor Debug Kill
| /tmp/pardes-snap/look-center/cwd/big.txt Save Ne /tmp/pardes-snap/look-center/cwd New Del /tmp/pardes-snap/look-center/cwd New Del
-| 86 line 86
+| 86 line 86 ls ls
| 87 line 87 big.txt big.txt
| 88 line 88
| 89 line 89
@@ -78,7 +78,7 @@
| 98 line 98
| 99 line 99
| 100 line 100 /tmp/pardes-snap/look-center/cwd New Del
-| 101 line 101
+| 101 line 101 ls
| 102 line 102 big.txt
| 103 line 103
| 104 line 104
diff --git a/test/snapshots/look-dir.golden b/test/snapshots/look-dir.golden
index a29b1cf1..9ee71ba3 100644
--- a/test/snapshots/look-dir.golden
+++ b/test/snapshots/look-dir.golden
@@ -1,11 +1,11 @@
== snap dir-open grid=100x30 cursor=4,8
|New Newcol Find Grep Help Tutor Dump NextColor Debug Kill
| /tmp/pardes-snap/look-dir/cwd New Del /tmp/pardes-snap/look-dir/cwd New Del
-|
+| ls ls
| sub top.txt sub top.txt
|
| /tmp/pardes-snap/look-dir/cwd/sub New Del
-|
+| ls
| inner.txt
|
|
@@ -16,7 +16,7 @@
|
|
| /tmp/pardes-snap/look-dir/cwd New Del
-|
+| ls
| sub top.txt
|
|
diff --git a/test/snapshots/look-file-1col.golden b/test/snapshots/look-file-1col.golden
index 09af247f..1e957fb8 100644
--- a/test/snapshots/look-file-1col.golden
+++ b/test/snapshots/look-file-1col.golden
@@ -1,7 +1,7 @@
== snap file-open-1col grid=100x30 cursor=7,16
|New Newcol Find Grep Help Tutor Dump NextColor Debug Kill
| /tmp/pardes-snap/look-file-1col/cwd/big.txt Save /tmp/pardes-snap/look-file-1col/cwd New Del
-| 26 line 26
+| 26 line 26 ls
| 27 line 27 big.txt
| 28 line 28
| 29 line 29
diff --git a/test/snapshots/look-file.golden b/test/snapshots/look-file.golden
index b95cd54c..fa674003 100644
--- a/test/snapshots/look-file.golden
+++ b/test/snapshots/look-file.golden
@@ -1,7 +1,7 @@
== snap file-open grid=150x30 cursor=7,16
|New Newcol Find Grep Help Tutor Dump NextColor Debug Kill
| /tmp/pardes-snap/look-file/cwd/big.txt Save New /tmp/pardes-snap/look-file/cwd New Del /tmp/pardes-snap/look-file/cwd New Del
-| 26 line 26
+| 26 line 26 ls ls
| 27 line 27 big.txt big.txt
| 28 line 28
| 29 line 29
@@ -16,7 +16,7 @@
| 38 line 38
| 39 line 39
| 40 line 40 /tmp/pardes-snap/look-file/cwd New Del
-| 41 line 41
+| 41 line 41 ls
| 42 line 42 big.txt
| 43 line 43
| 44 line 44
diff --git a/test/snapshots/lookloaded.golden b/test/snapshots/lookloaded.golden
index 311d7a66..1d09b582 100644
--- a/test/snapshots/lookloaded.golden
+++ b/test/snapshots/lookloaded.golden
@@ -1,7 +1,7 @@
== snap file-open grid=100x30 cursor=7,16
|New Newcol Find Grep Help Tutor Dump NextColor Debug Kill
| /tmp/pardes-snap/lookloaded/cwd /tmp/pardes-snap/lookloaded/cwd /tmp/pardes-snap/lookloaded/cwd
-| 26 line 26
+| 26 line 26 ls ls
| 27 line 27 big.txt big.txt
| 28 line 28
| 29 line 29
@@ -16,7 +16,7 @@
| 38 line 38
| 39 line 39
| 40 line 40 /tmp/pardes-snap/lookloaded/cwd
-| 41 line 41
+| 41 line 41 ls
| 42 line 42 big.txt
| 43 line 43
| 44 line 44
@@ -32,9 +32,9 @@
== snap removed grid=100x30 cursor=37,6
|New Newcol Find Grep Help Tutor Dump NextColor Debug Kill
| /tmp/pardes-snap/lookloaded/cwd /tmp/pardes-snap/lookloaded/cwd /tmp/pardes-snap/lookloaded/cwd
-| 26 line 26
+| 26 line 26 ls ls
| 27 line 27 big.txt big.txt
-| 28 line 28
+| 28 line 28 rm big.txt; echo GO''NE
| 29 line 29 GONE
| 30 line 30
| 31 line 31 big.txt:40 big.txt:10
@@ -47,7 +47,7 @@
| 38 line 38
| 39 line 39
| 40 line 40 /tmp/pardes-snap/lookloaded/cwd
-| 41 line 41
+| 41 line 41 ls
| 42 line 42 big.txt
| 43 line 43
| 44 line 44
@@ -63,9 +63,9 @@
== snap look-noFS grid=100x30 cursor=7,11
|New Newcol Find Grep Help Tutor Dump NextColor Debug Kill
| /tmp/pardes-snap/lookloaded/cwd /tmp/pardes-snap/lookloaded/cwd /tmp/pardes-snap/lookloaded/cwd
-| 1 line 1
+| 1 line 1 ls ls
| 2 line 2 big.txt big.txt
-| 3 line 3
+| 3 line 3 rm big.txt; echo GO''NE
| 4 line 4 GONE
| 5 line 5
| 6 line 6 big.txt:40 big.txt:10
@@ -78,7 +78,7 @@
| 13 line 13
| 14 line 14
| 15 line 15 /tmp/pardes-snap/lookloaded/cwd
-| 16 line 16
+| 16 line 16 ls
| 17 line 17 big.txt
| 18 line 18
| 19 line 19
diff --git a/test/snapshots/lookpanes.golden b/test/snapshots/lookpanes.golden
index d049ff5a..302f357e 100644
--- a/test/snapshots/lookpanes.golden
+++ b/test/snapshots/lookpanes.golden
@@ -1,11 +1,11 @@
== snap shells grid=130x50 cursor=122,3
|New Newcol Find Grep Help Tutor Dump NextColor Debug Kill
| /tmp/pardes-snap/lookpanes/cwd/beta/bmark.txt Save New Del /tmp/pardes-snap/lookpanes/cwd New Del
-| 1 both.txt
+| 1 both.txt ls
| 2 b-marker alpha beta zzboot.txt zqonly.txt pick.txt twin.txt
|
| /tmp/pardes-snap/lookpanes/cwd/alpha New Del
-|
+| ls
| amark.txt both.txt pick.txt twin.txt zqonly.txt
|
|
@@ -52,11 +52,11 @@
== snap other-dir grid=130x50 cursor=7,27
|New Newcol Find Grep Help Tutor Dump NextColor Debug Kill
| /tmp/pardes-snap/lookpanes/cwd/beta/bmark.txt Save New Del /tmp/pardes-snap/lookpanes/cwd New Del
-| 1 both.txt
+| 1 both.txt ls
| 2 b-marker alpha beta zzboot.txt zqonly.txt pick.txt twin.txt
|
| /tmp/pardes-snap/lookpanes/cwd/alpha New Del
-|
+| ls
| amark.txt both.txt pick.txt twin.txt zqonly.txt
|
|
@@ -103,11 +103,11 @@
== snap clicked-wins grid=130x50 cursor=7,15
|New Newcol Find Grep Help Tutor Dump NextColor Debug Kill
| /tmp/pardes-snap/lookpanes/cwd/beta/bmark.txt Save New Del /tmp/pardes-snap/lookpanes/cwd New Del
-| 1 both.txt
+| 1 both.txt ls
| 2 b-marker alpha beta zzboot.txt zqonly.txt pick.txt twin.txt
|
| /tmp/pardes-snap/lookpanes/cwd/alpha New Del
-|
+| ls
| amark.txt both.txt pick.txt twin.txt zqonly.txt
|
|
@@ -154,11 +154,11 @@
== snap mru-alpha grid=130x50 cursor=7,21
|New Newcol Find Grep Help Tutor Dump NextColor Debug Kill
| /tmp/pardes-snap/lookpanes/cwd/beta/bmark.txt Save New Del /tmp/pardes-snap/lookpanes/cwd New Del
-| 1 both.txt
+| 1 both.txt ls
| 2 b-marker alpha beta zzboot.txt zqonly.txt pick.txt twin.txt
|
| /tmp/pardes-snap/lookpanes/cwd/alpha New Del
-|
+| ls
| amark.txt both.txt pick.txt twin.txt zqonly.txt
|
|
@@ -205,11 +205,11 @@
== snap mru-beta grid=130x50 cursor=7,9
|New Newcol Find Grep Help Tutor Dump NextColor Debug Kill
| /tmp/pardes-snap/lookpanes/cwd/beta/bmark.txt Save New Del /tmp/pardes-snap/lookpanes/cwd New Del
-| 1 both.txt
+| 1 both.txt ls
| 2 b-marker alpha beta zzboot.txt zqonly.txt pick.txt twin.txt
|
| /tmp/pardes-snap/lookpanes/cwd/alpha New Del
-|
+| ls
| amark.txt both.txt pick.txt twin.txt zqonly.txt
| /tmp/pardes-snap/lookpanes/cwd/beta/twin.txt Save New Del
| 1 TWIN-FROM-BETA
diff --git a/test/snapshots/lookrange.golden b/test/snapshots/lookrange.golden
index 6e292431..d1fc0bea 100644
--- a/test/snapshots/lookrange.golden
+++ b/test/snapshots/lookrange.golden
@@ -368,7 +368,7 @@
|25: 0-0 d,#444444, 1-1 d,#080808, 2-6 #626262,#080808, 7-149 d,#080808,
|26: 0-0 d,#444444, 1-1 d,#080808, 2-6 #626262,#080808, 7-149 d,#080808,
|27: 0-1 #ffffff,#262626, 2-129 #949494,#121212, 130-149 d,#121212,
-|28: 0-0 d,#444444, 1-1 d,#080808, 2-6 #626262,#080808, 7-149 #080808,#80a0ff,
+|28: 0-0 d,#444444, 1-1 d,#080808, 2-6 #626262,#080808, 7-30 #bdbdbd,#080808, 31-149 d,#080808,
|29: 0-0 d,#121212, 1-1 d,#080808, 2-6 #626262,#080808, 7-30 #bdbdbd,#080808, 31-149 d,#080808,
== snap hit2 grid=150x30 cursor=17,22
|New Newcol Find Grep Help Tutor Dump NextColor Debug Kill
@@ -431,7 +431,7 @@
|26: 0-0 d,#444444, 1-1 d,#080808, 2-6 #626262,#080808, 7-149 d,#080808,
|27: 0-1 #ffffff,#262626, 2-129 #949494,#121212, 130-149 d,#121212,
|28: 0-0 d,#444444, 1-1 d,#080808, 2-6 #626262,#080808, 7-30 #bdbdbd,#080808, 31-149 d,#080808,
-|29: 0-0 d,#121212, 1-1 d,#080808, 2-6 #626262,#080808, 7-149 #080808,#80a0ff,
+|29: 0-0 d,#121212, 1-1 d,#080808, 2-6 #626262,#080808, 7-30 #bdbdbd,#080808, 31-149 d,#080808,
== snap back grid=150x30 cursor=15,22
|New Newcol Find Grep Help Tutor Dump NextColor Debug Kill
| /tmp/pardes-snap/lookrange/cwd/look.txt Save New Del
@@ -492,5 +492,5 @@
|25: 0-0 d,#444444, 1-1 d,#080808, 2-6 #626262,#080808, 7-149 d,#080808,
|26: 0-0 d,#444444, 1-1 d,#080808, 2-6 #626262,#080808, 7-149 d,#080808,
|27: 0-1 #ffffff,#262626, 2-129 #949494,#121212, 130-149 d,#121212,
-|28: 0-0 d,#444444, 1-1 d,#080808, 2-6 #626262,#080808, 7-149 #080808,#80a0ff,
+|28: 0-0 d,#444444, 1-1 d,#080808, 2-6 #626262,#080808, 7-30 #bdbdbd,#080808, 31-149 d,#080808,
|29: 0-0 d,#121212, 1-1 d,#080808, 2-6 #626262,#080808, 7-30 #bdbdbd,#080808, 31-149 d,#080808,
diff --git a/test/snapshots/lookrange.snap b/test/snapshots/lookrange.snap
index d1a86e0c..29f88d7f 100644
--- a/test/snapshots/lookrange.snap
+++ b/test/snapshots/lookrange.snap
@@ -6,7 +6,8 @@
# r.txt:7:4-9 line 7, columns 4 through 9
# r.txt:3:2-5:3 line 3 column 2 through line 5 column 3
# ...and only then presses `/`, whose result rows are exactly this syntax —
-# which is how n/N step to a hit with the matched text selected.
+# which is how n/N select a hit and Enter lands on it with the matched text
+# selected.
#
# `snapstyle` is the assertion that matters: the grid TEXT after a ranged look
# is the same text a plain `:LINE:COL` look leaves, so the selection only shows
@@ -47,8 +48,8 @@ stable 700 15000
snap stale
snapstyle stale
# --- and now the first consumer. The look above left r.txt focused, so `/`
-# arms on it: the rows it writes carry the match's span, and n/N therefore step
-# to each hit with the word itself selected.
+# arms on it: the rows it writes carry the match's span, so n selects a row
+# and the Enter after it goes to that hit with the word itself selected.
key /
text NEEDLE
key enter
@@ -56,15 +57,18 @@ wait 10000 r.txt:7:4-9 gg NEEDLE
stable 700 15000
snap results
key n
+key enter
stable 700 15000
snap hit1
snapstyle hit1
key n
+key enter
stable 700 15000
snap hit2
snapstyle hit2
-# N walks back onto the first hit, still selected
+# N walks back onto the first hit; Enter looks it, still selected
key N
+key enter
stable 700 15000
snap back
snapstyle back
diff --git a/test/snapshots/lsp.snap b/test/snapshots/lsp.snap
index 79acaee8..2eb17735 100644
--- a/test/snapshots/lsp.snap
+++ b/test/snapshots/lsp.snap
@@ -36,14 +36,15 @@ key k
stable 700 15000
snap hover
# SPC l s lists the file's own symbols. Several rows, so it opens a +Search
-# buffer — which IS the picker: n steps a row and looks it, exactly as the Find
-# and `/` results already do, with no picker code of its own.
+# buffer — which IS the picker: n selects a row and Enter looks it, exactly as
+# the Find and `/` results already do, with no picker code of its own.
key space
key l
key s
stable 700 15000
snap symbols
key n
+key enter
stable 700 15000
snap step
# gd on something with no declaration behind it (a keyword) answers nothing,
diff --git a/test/snapshots/lspcomplete.snap b/test/snapshots/lspcomplete.snap
index 8b7854cd..8baa870e 100644
--- a/test/snapshots/lspcomplete.snap
+++ b/test/snapshots/lspcomplete.snap
@@ -87,9 +87,11 @@ snap refill
key esc
settle 100
# Several rows, so the buffer IS the picker and n walks it; completion does not
-# jump the way a goto with one row does. The first step looks row 1 and lands
-# SELECTING `verdigris` on line 2 of a.zig.
+# jump the way a goto with one row does. The first step selects row 1, and the
+# Enter after it looks that row and lands SELECTING `verdigris` on line 2 of
+# a.zig.
key n
+key enter
stable 700 15000
snap step
# A pane the backend does not speak: same keystrokes, same dot before the
diff --git a/test/snapshots/lsprelpath.golden b/test/snapshots/lsprelpath.golden
index 885860b3..4fd48958 100644
--- a/test/snapshots/lsprelpath.golden
+++ b/test/snapshots/lsprelpath.golden
@@ -33,7 +33,7 @@
| /tmp/pardes-snap/lsprelpath/cwd/sub/+Search New Del
| 1 /tmp/pardes-snap/lsprelpath/cwd/shade.zig:2:5-13 verdigris verdigris,
| 2 /tmp/pardes-snap/lsprelpath/cwd/shade.zig:3:5-12 cinnabar cinnabar,
-== snap abslook grid=100x34 cursor=16,6
+== snap abslook grid=100x34 cursor=19,18
|New Newcol Find Grep Help Tutor Dump NextColor Debug Kill
| /tmp/pardes-snap/lsprelpath/cwd/sub/parent.zig Save New Del
| 1 const shade = @import("../shade.zig");
@@ -70,12 +70,12 @@
| 2 /tmp/pardes-snap/lsprelpath/cwd/shade.zig:3:5-12 cinnabar cinnabar,
== style abslook
|0: 0-56 #949494,#121212, 57-99 d,#121212,
-|1: 0-1 #ffffff,#626262, 2-79 #949494,#121212, 80-99 d,#121212,
+|1: 0-1 #ffffff,#262626, 2-79 #949494,#121212, 80-99 d,#121212,
|2: 0-0 d,#444444, 1-1 d,#080808, 2-6 #626262,#080808, 7-20 #bdbdbd,#080808, 21-27 #cf87e8,#080808,b 28-28 #bdbdbd,#080808, 29-42 #e3c78a,#080808, 43-44 #bdbdbd,#080808, 45-99 d,#080808,
|3: 0-0 d,#444444, 1-1 d,#080808, 2-6 #626262,#080808, 7-99 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-38 #bdbdbd,#080808, 39-99 d,#080808,
|5: 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-23 #cf87e8,#080808,b 24-29 #bdbdbd,#080808, 30-99 d,#080808,
-|6: 0-0 d,#444444, 1-1 d,#080808, 2-6 #949494,#121212, 7-15 #bdbdbd,#080808, 16-99 d,#080808,
+|6: 0-0 d,#444444, 1-1 d,#080808, 2-6 #626262,#080808, 7-15 #bdbdbd,#080808, 16-99 d,#080808,
|7: 0-0 d,#444444, 1-1 d,#080808, 2-6 #626262,#080808, 7-12 #bdbdbd,#080808, 13-99 d,#080808,
|8: 0-0 d,#444444, 1-1 d,#080808, 2-6 #626262,#080808, 7-7 #bdbdbd,#080808, 8-99 d,#080808,
|9: 0-0 d,#444444, 1-1 d,#080808, 2-6 #626262,#080808, 7-99 d,#080808,
@@ -85,9 +85,9 @@
|13: 0-0 d,#444444, 1-1 d,#080808, 2-6 #626262,#080808, 7-99 d,#080808,
|14: 0-0 d,#444444, 1-1 d,#080808, 2-6 #626262,#080808, 7-99 d,#080808,
|15: 0-0 d,#444444, 1-1 d,#080808, 2-6 #626262,#080808, 7-99 d,#080808,
-|16: 0-1 #ffffff,#262626, 2-79 #949494,#121212, 80-99 d,#121212,
+|16: 0-1 #ffffff,#626262, 2-79 #949494,#121212, 80-99 d,#121212,
|17: 0-0 d,#444444, 1-1 d,#080808, 2-6 #626262,#080808, 7-24 #bdbdbd,#080808, 25-28 #cf87e8,#080808,b 29-30 #bdbdbd,#080808, 31-99 d,#080808,
-|18: 0-0 d,#444444, 1-1 d,#080808, 2-6 #626262,#080808, 7-10 #bdbdbd,#080808, 11-19 #080808,#80a0ff, 20-20 #bdbdbd,#080808, 21-99 d,#080808,
+|18: 0-0 d,#444444, 1-1 d,#080808, 2-6 #949494,#121212, 7-10 #bdbdbd,#080808, 11-19 #080808,#80a0ff, 20-20 #bdbdbd,#080808, 21-99 d,#080808,
|19: 0-0 d,#444444, 1-1 d,#080808, 2-6 #626262,#080808, 7-19 #bdbdbd,#080808, 20-99 d,#080808,
|20: 0-0 d,#444444, 1-1 d,#080808, 2-6 #626262,#080808, 7-8 #bdbdbd,#080808, 9-99 d,#080808,
|21: 0-0 d,#444444, 1-1 d,#080808, 2-6 #626262,#080808, 7-99 d,#080808,
@@ -101,7 +101,7 @@
|29: 0-0 d,#444444, 1-1 d,#080808, 2-6 #626262,#080808, 7-99 d,#080808,
|30: 0-0 d,#444444, 1-1 d,#080808, 2-6 #626262,#080808, 7-99 d,#080808,
|31: 0-1 #ffffff,#262626, 2-79 #949494,#121212, 80-99 d,#121212,
-|32: 0-0 d,#444444, 1-1 d,#080808, 2-6 #626262,#080808, 7-99 #080808,#80a0ff,
+|32: 0-0 d,#444444, 1-1 d,#080808, 2-6 #626262,#080808, 7-76 #bdbdbd,#080808, 77-99 d,#080808,
|33: 0-0 d,#121212, 1-1 d,#080808, 2-6 #626262,#080808, 7-74 #bdbdbd,#080808, 75-99 d,#080808,
== snap subrow grid=100x34 cursor=16,6
|New Newcol Find Grep Help Tutor Dump NextColor Debug Kill
@@ -138,7 +138,7 @@
| /tmp/pardes-snap/lsprelpath/cwd/sub/+Search New Del
| 1 inner/tint.zig:2:5-9 ochre ochre,
| 2 inner/tint.zig:3:5-10 indigo indigo,
-== snap sublook grid=100x34 cursor=16,6
+== snap sublook grid=100x34 cursor=15,18
|New Newcol Find Grep Help Tutor Dump NextColor Debug Kill
| /tmp/pardes-snap/lsprelpath/cwd/sub/subdir.zig Save New Del
| 1 const tint = @import("inner/tint.zig");
@@ -175,12 +175,12 @@
| 2 inner/tint.zig:3:5-10 indigo indigo,
== style sublook
|0: 0-56 #949494,#121212, 57-99 d,#121212,
-|1: 0-1 #ffffff,#626262, 2-79 #949494,#121212, 80-99 d,#121212,
+|1: 0-1 #ffffff,#262626, 2-79 #949494,#121212, 80-99 d,#121212,
|2: 0-0 d,#444444, 1-1 d,#080808, 2-6 #626262,#080808, 7-19 #bdbdbd,#080808, 20-26 #cf87e8,#080808,b 27-27 #bdbdbd,#080808, 28-43 #e3c78a,#080808, 44-45 #bdbdbd,#080808, 46-99 d,#080808,
|3: 0-0 d,#444444, 1-1 d,#080808, 2-6 #626262,#080808, 7-99 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-99 d,#080808,
|5: 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-23 #cf87e8,#080808,b 24-29 #bdbdbd,#080808, 30-99 d,#080808,
-|6: 0-0 d,#444444, 1-1 d,#080808, 2-6 #949494,#121212, 7-15 #bdbdbd,#080808, 16-99 d,#080808,
+|6: 0-0 d,#444444, 1-1 d,#080808, 2-6 #626262,#080808, 7-15 #bdbdbd,#080808, 16-99 d,#080808,
|7: 0-0 d,#444444, 1-1 d,#080808, 2-6 #626262,#080808, 7-12 #bdbdbd,#080808, 13-99 d,#080808,
|8: 0-0 d,#444444, 1-1 d,#080808, 2-6 #626262,#080808, 7-7 #bdbdbd,#080808, 8-99 d,#080808,
|9: 0-0 d,#444444, 1-1 d,#080808, 2-6 #626262,#080808, 7-99 d,#080808,
@@ -190,9 +190,9 @@
|13: 0-0 d,#444444, 1-1 d,#080808, 2-6 #626262,#080808, 7-99 d,#080808,
|14: 0-0 d,#444444, 1-1 d,#080808, 2-6 #626262,#080808, 7-99 d,#080808,
|15: 0-0 d,#444444, 1-1 d,#080808, 2-6 #626262,#080808, 7-99 d,#080808,
-|16: 0-1 #ffffff,#262626, 2-79 #949494,#121212, 80-99 d,#121212,
+|16: 0-1 #ffffff,#626262, 2-79 #949494,#121212, 80-99 d,#121212,
|17: 0-0 d,#444444, 1-1 d,#080808, 2-6 #626262,#080808, 7-23 #bdbdbd,#080808, 24-27 #cf87e8,#080808,b 28-29 #bdbdbd,#080808, 30-99 d,#080808,
-|18: 0-0 d,#444444, 1-1 d,#080808, 2-6 #626262,#080808, 7-10 #bdbdbd,#080808, 11-15 #080808,#80a0ff, 16-16 #bdbdbd,#080808, 17-99 d,#080808,
+|18: 0-0 d,#444444, 1-1 d,#080808, 2-6 #949494,#121212, 7-10 #bdbdbd,#080808, 11-15 #080808,#80a0ff, 16-16 #bdbdbd,#080808, 17-99 d,#080808,
|19: 0-0 d,#444444, 1-1 d,#080808, 2-6 #626262,#080808, 7-17 #bdbdbd,#080808, 18-99 d,#080808,
|20: 0-0 d,#444444, 1-1 d,#080808, 2-6 #626262,#080808, 7-8 #bdbdbd,#080808, 9-99 d,#080808,
|21: 0-0 d,#444444, 1-1 d,#080808, 2-6 #626262,#080808, 7-99 d,#080808,
@@ -206,7 +206,7 @@
|29: 0-0 d,#444444, 1-1 d,#080808, 2-6 #626262,#080808, 7-99 d,#080808,
|30: 0-0 d,#444444, 1-1 d,#080808, 2-6 #626262,#080808, 7-99 d,#080808,
|31: 0-1 #ffffff,#262626, 2-79 #949494,#121212, 80-99 d,#121212,
-|32: 0-0 d,#444444, 1-1 d,#080808, 2-6 #626262,#080808, 7-99 #080808,#80a0ff,
+|32: 0-0 d,#444444, 1-1 d,#080808, 2-6 #626262,#080808, 7-40 #bdbdbd,#080808, 41-99 d,#080808,
|33: 0-0 d,#121212, 1-1 d,#080808, 2-6 #626262,#080808, 7-43 #bdbdbd,#080808, 44-99 d,#080808,
== snap clicked grid=100x34 cursor=16,19
|New Newcol Find Grep Help Tutor Dump NextColor Debug Kill
diff --git a/test/snapshots/lsprelpath.snap b/test/snapshots/lsprelpath.snap
index dce26d1e..1ff6f549 100644
--- a/test/snapshots/lsprelpath.snap
+++ b/test/snapshots/lsprelpath.snap
@@ -19,10 +19,10 @@
# strip that took the basename instead would produce a row that
# resolves to nothing.
#
-# `n` is the assertion in both, not the row text: it looks row 1 and the right
-# file opens with the member SELECTED on its own line. The style capture is
-# where that selection shows, because focus goes back to the pane that asked,
-# so the opened pane's cursor is not in the snap header.
+# `n` and the Enter after it are the assertion in both, not the row text: the
+# step selects row 1, the look opens the right file with the member SELECTED
+# on its own line, and focus follows what opened — so the snap header's cursor
+# is that pane's, and the style capture is where the selection itself shows.
dirmk sub
dirmk sub/inner
file shade.zig pub const Shade = enum {\n verdigris,\n cinnabar,\n};\n
@@ -50,6 +50,7 @@ settle 100
# An absolute row has to keep resolving — it is the spelling every row had
# before this, and the one every hit outside the tree still has.
key n
+key enter
stable 700 15000
snap abslook
snapstyle abslook
@@ -71,6 +72,7 @@ snap subrow
key esc
settle 100
key n
+key enter
stable 700 15000
snap sublook
snapstyle sublook
diff --git a/test/snapshots/modal.golden b/test/snapshots/modal.golden
index 0a30d313..93ab4143 100644
--- a/test/snapshots/modal.golden
+++ b/test/snapshots/modal.golden
@@ -1,10 +1,10 @@
== snap top grid=100x30 cursor=2,2
|New Newcol Find Grep Help Tutor Dump NextColor Debug Kill
| /tmp/pardes-snap/modal/cwd New Del /tmp/pardes-snap/modal/cwd New Del
-|
+| ls ls
| words.txt words.txt
-|
-|
+| printf 'one two three\nfour five six\nseven ei
+| ght nine\n'
| one two three
| four five six
| seven eight nine
@@ -16,7 +16,7 @@
|
|
| /tmp/pardes-snap/modal/cwd New Del
-|
+| ls
| words.txt
|
|
@@ -29,13 +29,13 @@
|
|
|
-== snap moved grid=100x30 cursor=5,6
+== snap moved grid=100x30 cursor=8,4
|New Newcol Find Grep Help Tutor Dump NextColor Debug Kill
| /tmp/pardes-snap/modal/cwd New Del /tmp/pardes-snap/modal/cwd New Del
-|
+| ls ls
| words.txt words.txt
-|
-|
+| printf 'one two three\nfour five six\nseven ei
+| ght nine\n'
| one two three
| four five six
| seven eight nine
@@ -47,7 +47,7 @@
|
|
| /tmp/pardes-snap/modal/cwd New Del
-|
+| ls
| words.txt
|
|
@@ -60,13 +60,13 @@
|
|
|
-== snap xsel grid=100x30 cursor=15,6
+== snap xsel grid=100x30 cursor=48,4
|New Newcol Find Grep Help Tutor Dump NextColor Debug Kill
| /tmp/pardes-snap/modal/cwd New Del /tmp/pardes-snap/modal/cwd New Del
-|
+| ls ls
| words.txt words.txt
-|
-|
+| printf 'one two three\nfour five six\nseven ei
+| ght nine\n'
| one two three
| four five six
| seven eight nine
@@ -78,7 +78,7 @@
|
|
| /tmp/pardes-snap/modal/cwd New Del
-|
+| ls
| words.txt
|
|
@@ -96,9 +96,9 @@
|1: 0-1 #ffffff,#626262, 2-35 #949494,#121212, 36-49 d,#121212, 50-51 #ffffff,#262626, 52-85 #949494,#121212, 86-99 d,#121212,
|2: 0-0 d,#444444, 1-1 d,#080808, 2-49 #bdbdbd,#080808, 50-50 d,#444444, 51-51 d,#080808, 52-99 #bdbdbd,#080808,
|3: 0-0 d,#444444, 1-1 d,#080808, 2-49 #bdbdbd,#080808, 50-50 d,#444444, 51-51 d,#080808, 52-99 #bdbdbd,#080808,
-|4: 0-0 d,#444444, 1-1 d,#080808, 2-49 #bdbdbd,#080808, 50-50 d,#444444, 51-51 d,#080808, 52-99 #bdbdbd,#080808,
+|4: 0-0 d,#444444, 1-1 d,#080808, 2-48 #080808,#80a0ff, 49-49 #bdbdbd,#080808, 50-50 d,#444444, 51-51 d,#080808, 52-99 #bdbdbd,#080808,
|5: 0-0 d,#444444, 1-1 d,#080808, 2-49 #bdbdbd,#080808, 50-50 d,#444444, 51-51 d,#080808, 52-99 #bdbdbd,#080808,
-|6: 0-0 d,#444444, 1-1 d,#080808, 2-15 #080808,#80a0ff, 16-49 #bdbdbd,#080808, 50-50 d,#444444, 51-51 d,#080808, 52-99 #bdbdbd,#080808,
+|6: 0-0 d,#444444, 1-1 d,#080808, 2-49 #bdbdbd,#080808, 50-50 d,#444444, 51-51 d,#080808, 52-99 #bdbdbd,#080808,
|7: 0-0 d,#444444, 1-1 d,#080808, 2-49 #bdbdbd,#080808, 50-50 d,#444444, 51-51 d,#080808, 52-99 #bdbdbd,#080808,
|8: 0-0 d,#444444, 1-1 d,#080808, 2-49 #bdbdbd,#080808, 50-50 d,#444444, 51-51 d,#080808, 52-99 #bdbdbd,#080808,
|9: 0-0 d,#444444, 1-1 d,#080808, 2-49 #bdbdbd,#080808, 50-50 d,#444444, 51-51 d,#080808, 52-99 #bdbdbd,#080808,
@@ -122,13 +122,13 @@
|27: 0-0 d,#444444, 1-1 d,#080808, 2-49 #bdbdbd,#080808, 50-50 d,#444444, 51-51 d,#080808, 52-99 #bdbdbd,#080808,
|28: 0-0 d,#444444, 1-1 d,#080808, 2-49 #bdbdbd,#080808, 50-50 d,#444444, 51-51 d,#080808, 52-99 #bdbdbd,#080808,
|29: 0-0 d,#444444, 1-1 d,#080808, 2-49 #bdbdbd,#080808, 50-50 d,#444444, 51-51 d,#080808, 52-99 #bdbdbd,#080808,
-== snap xsel2 grid=100x30 cursor=15,7
+== snap xsel2 grid=100x30 cursor=13,5
|New Newcol Find Grep Help Tutor Dump NextColor Debug Kill
| /tmp/pardes-snap/modal/cwd New Del /tmp/pardes-snap/modal/cwd New Del
-|
+| ls ls
| words.txt words.txt
-|
-|
+| printf 'one two three\nfour five six\nseven ei
+| ght nine\n'
| one two three
| four five six
| seven eight nine
@@ -140,7 +140,7 @@
|
|
| /tmp/pardes-snap/modal/cwd New Del
-|
+| ls
| words.txt
|
|
@@ -153,13 +153,13 @@
|
|
|
-== snap yanked grid=100x30 cursor=15,7
+== snap yanked grid=100x30 cursor=13,5
|New Newcol Find Grep Help Tutor Dump NextColor Debug Kill
| /tmp/pardes-snap/modal/cwd New Del /tmp/pardes-snap/modal/cwd New Del
-|
+| ls ls
| words.txt words.txt
-|
-|
+| printf 'one two three\nfour five six\nseven ei
+| ght nine\n'
| one two three
| four five six
| seven eight nine
@@ -171,7 +171,7 @@
|
|
| /tmp/pardes-snap/modal/cwd New Del
-|
+| ls
| words.txt
|
|
@@ -184,13 +184,13 @@
|
|
|
-== snap vsel grid=100x30 cursor=16,8
+== snap vsel grid=100x30 cursor=14,6
|New Newcol Find Grep Help Tutor Dump NextColor Debug Kill
| /tmp/pardes-snap/modal/cwd New Del /tmp/pardes-snap/modal/cwd New Del
-|
+| ls ls
| words.txt words.txt
-|
-|
+| printf 'one two three\nfour five six\nseven ei
+| ght nine\n'
| one two three
| four five six
| seven eight nine
@@ -202,7 +202,7 @@
|
|
| /tmp/pardes-snap/modal/cwd New Del
-|
+| ls
| words.txt
|
|
@@ -220,11 +220,11 @@
|1: 0-1 #ffffff,#626262, 2-35 #949494,#121212, 36-49 d,#121212, 50-51 #ffffff,#262626, 52-85 #949494,#121212, 86-99 d,#121212,
|2: 0-0 d,#444444, 1-1 d,#080808, 2-49 #bdbdbd,#080808, 50-50 d,#444444, 51-51 d,#080808, 52-99 #bdbdbd,#080808,
|3: 0-0 d,#444444, 1-1 d,#080808, 2-49 #bdbdbd,#080808, 50-50 d,#444444, 51-51 d,#080808, 52-99 #bdbdbd,#080808,
-|4: 0-0 d,#444444, 1-1 d,#080808, 2-49 #bdbdbd,#080808, 50-50 d,#444444, 51-51 d,#080808, 52-99 #bdbdbd,#080808,
-|5: 0-0 d,#444444, 1-1 d,#080808, 2-49 #bdbdbd,#080808, 50-50 d,#444444, 51-51 d,#080808, 52-99 #bdbdbd,#080808,
-|6: 0-0 d,#444444, 1-1 d,#080808, 2-49 #080808,#80a0ff, 50-50 d,#444444, 51-51 d,#080808, 52-99 #bdbdbd,#080808,
-|7: 0-0 d,#444444, 1-1 d,#080808, 2-49 #080808,#80a0ff, 50-50 d,#444444, 51-51 d,#080808, 52-99 #bdbdbd,#080808,
-|8: 0-0 d,#444444, 1-1 d,#080808, 2-16 #080808,#80a0ff, 17-49 #bdbdbd,#080808, 50-50 d,#444444, 51-51 d,#080808, 52-99 #bdbdbd,#080808,
+|4: 0-0 d,#444444, 1-1 d,#080808, 2-49 #080808,#80a0ff, 50-50 d,#444444, 51-51 d,#080808, 52-99 #bdbdbd,#080808,
+|5: 0-0 d,#444444, 1-1 d,#080808, 2-49 #080808,#80a0ff, 50-50 d,#444444, 51-51 d,#080808, 52-99 #bdbdbd,#080808,
+|6: 0-0 d,#444444, 1-1 d,#080808, 2-14 #080808,#80a0ff, 15-49 #bdbdbd,#080808, 50-50 d,#444444, 51-51 d,#080808, 52-99 #bdbdbd,#080808,
+|7: 0-0 d,#444444, 1-1 d,#080808, 2-49 #bdbdbd,#080808, 50-50 d,#444444, 51-51 d,#080808, 52-99 #bdbdbd,#080808,
+|8: 0-0 d,#444444, 1-1 d,#080808, 2-49 #bdbdbd,#080808, 50-50 d,#444444, 51-51 d,#080808, 52-99 #bdbdbd,#080808,
|9: 0-0 d,#444444, 1-1 d,#080808, 2-49 #bdbdbd,#080808, 50-50 d,#444444, 51-51 d,#080808, 52-99 #bdbdbd,#080808,
|10: 0-0 d,#444444, 1-1 d,#080808, 2-49 #bdbdbd,#080808, 50-50 d,#444444, 51-51 d,#080808, 52-99 #bdbdbd,#080808,
|11: 0-0 d,#444444, 1-1 d,#080808, 2-49 #bdbdbd,#080808, 50-50 d,#444444, 51-51 d,#080808, 52-99 #bdbdbd,#080808,
@@ -246,14 +246,14 @@
|27: 0-0 d,#444444, 1-1 d,#080808, 2-49 #bdbdbd,#080808, 50-50 d,#444444, 51-51 d,#080808, 52-99 #bdbdbd,#080808,
|28: 0-0 d,#444444, 1-1 d,#080808, 2-49 #bdbdbd,#080808, 50-50 d,#444444, 51-51 d,#080808, 52-99 #bdbdbd,#080808,
|29: 0-0 d,#444444, 1-1 d,#080808, 2-49 #bdbdbd,#080808, 50-50 d,#444444, 51-51 d,#080808, 52-99 #bdbdbd,#080808,
-== snap typed grid=100x30 cursor=7,6
+== snap typed grid=100x30 cursor=7,4
|New Newcol Find Grep Help Tutor Dump NextColor Debug Kill
| /tmp/pardes-snap/modal/cwd New Del /tmp/pardes-snap/modal/cwd New Del
-|
+| ls ls
| words.txt words.txt
-|
-|
-| TYPEDone two three
+| TYPEDprintf 'one two three\nfour five six\nseven
+| ght nine\n'
+| one two three
| four five six
| seven eight nine
|
@@ -264,7 +264,7 @@
|
|
| /tmp/pardes-snap/modal/cwd New Del
-|
+| ls
| words.txt
|
|
@@ -277,13 +277,13 @@
|
|
|
-== snap undone grid=100x30 cursor=16,8
+== snap undone grid=100x30 cursor=14,6
|New Newcol Find Grep Help Tutor Dump NextColor Debug Kill
| /tmp/pardes-snap/modal/cwd New Del /tmp/pardes-snap/modal/cwd New Del
-|
+| ls ls
| words.txt words.txt
-|
-|
+| printf 'one two three\nfour five six\nseven ei
+| ght nine\n'
| one two three
| four five six
| seven eight nine
@@ -295,7 +295,7 @@
|
|
| /tmp/pardes-snap/modal/cwd New Del
-|
+| ls
| words.txt
|
|
@@ -308,14 +308,14 @@
|
|
|
-== snap redone grid=100x30 cursor=7,6
+== snap redone grid=100x30 cursor=7,4
|New Newcol Find Grep Help Tutor Dump NextColor Debug Kill
| /tmp/pardes-snap/modal/cwd New Del /tmp/pardes-snap/modal/cwd New Del
-|
+| ls ls
| words.txt words.txt
-|
-|
-| TYPEDone two three
+| TYPEDprintf 'one two three\nfour five six\nseven
+| ght nine\n'
+| one two three
| four five six
| seven eight nine
|
@@ -326,7 +326,7 @@
|
|
| /tmp/pardes-snap/modal/cwd New Del
-|
+| ls
| words.txt
|
|
@@ -342,11 +342,11 @@
== snap bottom grid=100x30 cursor=2,9
|New Newcol Find Grep Help Tutor Dump NextColor Debug Kill
| /tmp/pardes-snap/modal/cwd New Del /tmp/pardes-snap/modal/cwd New Del
-|
+| ls ls
| words.txt words.txt
-|
-|
-| TYPEDone two three
+| TYPEDprintf 'one two three\nfour five six\nseven
+| ght nine\n'
+| one two three
| four five six
| seven eight nine
|
@@ -357,7 +357,7 @@
|
|
| /tmp/pardes-snap/modal/cwd New Del
-|
+| ls
| words.txt
|
|
diff --git a/test/snapshots/multicursor.golden b/test/snapshots/multicursor.golden
index 0e66f357..764ca170 100644
--- a/test/snapshots/multicursor.golden
+++ b/test/snapshots/multicursor.golden
@@ -1,7 +1,7 @@
== snap three-cursors grid=150x30 cursor=7,4
|New Newcol Find Grep Help Tutor Dump NextColor Debug Kill
| /tmp/pardes-snap/multicursor/cwd/f.txt Save New /tmp/pardes-snap/multicursor/cwd New Del /tmp/pardes-snap/multicursor/cwd New Del
-| 1 line 1
+| 1 line 1 ls ls
| 2 line 2 f.txt f.txt
| 3 line 3
| 4 line 4
@@ -16,7 +16,7 @@
| 13
|
| /tmp/pardes-snap/multicursor/cwd New Del
-|
+| ls
| f.txt
|
|
@@ -63,7 +63,7 @@
== snap edited-at-three grid=150x30 cursor=9,4
|New Newcol Find Grep Help Tutor Dump NextColor Debug Kill
| /tmp/pardes-snap/multicursor/cwd/f.txt Save New /tmp/pardes-snap/multicursor/cwd New Del /tmp/pardes-snap/multicursor/cwd New Del
-| 1 >>line 1
+| 1 >>line 1 ls ls
| 2 >>line 2 f.txt f.txt
| 3 >>line 3
| 4 line 4
@@ -78,7 +78,7 @@
| 13
|
| /tmp/pardes-snap/multicursor/cwd New Del
-|
+| ls
| f.txt
|
|
@@ -94,7 +94,7 @@
== snap three-selections grid=150x30 cursor=8,4
|New Newcol Find Grep Help Tutor Dump NextColor Debug Kill
| /tmp/pardes-snap/multicursor/cwd/f.txt Save New /tmp/pardes-snap/multicursor/cwd New Del /tmp/pardes-snap/multicursor/cwd New Del
-| 1 >>line 1
+| 1 >>line 1 ls ls
| 2 >>line 2 f.txt f.txt
| 3 >>line 3
| 4 line 4
@@ -109,7 +109,7 @@
| 13
|
| /tmp/pardes-snap/multicursor/cwd New Del
-|
+| ls
| f.txt
|
|
@@ -156,7 +156,7 @@
== snap keep-primary grid=150x30 cursor=8,4
|New Newcol Find Grep Help Tutor Dump NextColor Debug Kill
| /tmp/pardes-snap/multicursor/cwd/f.txt Save New /tmp/pardes-snap/multicursor/cwd New Del /tmp/pardes-snap/multicursor/cwd New Del
-| 1 >>line 1
+| 1 >>line 1 ls ls
| 2 >>line 2 f.txt f.txt
| 3 >>line 3
| 4 line 4
@@ -171,7 +171,7 @@
| 13
|
| /tmp/pardes-snap/multicursor/cwd New Del
-|
+| ls
| f.txt
|
|
diff --git a/test/snapshots/nested.golden b/test/snapshots/nested.golden
index 7b9ee1b5..b685a144 100644
--- a/test/snapshots/nested.golden
+++ b/test/snapshots/nested.golden
@@ -66,7 +66,7 @@
| $ $(readlink /proc/$PPID/exe) nestdir
| $
| /tmp/pardes-snap/nested/cwd/nestdir New Del
-|
+| ls
| inside-nested.txt
|
|
diff --git a/test/snapshots/psearch.golden b/test/snapshots/psearch.golden
index 25af2036..a3305345 100644
--- a/test/snapshots/psearch.golden
+++ b/test/snapshots/psearch.golden
@@ -1,7 +1,7 @@
== snap output grid=140x30 cursor=4,8
|New Newcol Find Grep Help Tutor Dump NextColor Debug Kill
| /tmp/pardes-snap/psearch/cwd New Del
-|
+| printf 'x MA''RK a\nzz\nx MA''RK b\nzz\nx MA''RK c\n'
| x MARK a
| zz
| x MARK b
@@ -32,7 +32,7 @@
== snap typing grid=140x30 cursor=8,29
|New Newcol Find Grep Help Tutor Dump NextColor Debug Kill
| /tmp/pardes-snap/psearch/cwd New Del
-|
+| printf 'x MA''RK a\nzz\nx MA''RK b\nzz\nx MA''RK c\n'
| x MARK a
| zz
| x MARK b
@@ -63,7 +63,7 @@
== snap results grid=140x30 cursor=4,8
|New Newcol Find Grep Help Tutor Dump NextColor Debug Kill
| /tmp/pardes-snap/psearch/cwd New Del
-|
+| printf 'x MA''RK a\nzz\nx MA''RK b\nzz\nx MA''RK c\n'
| x MARK a
| zz
| x MARK b
@@ -94,7 +94,7 @@
== snap first grid=140x30 cursor=7,3
|New Newcol Find Grep Help Tutor Dump NextColor Debug Kill
| /tmp/pardes-snap/psearch/cwd New Del
-|
+| printf 'x MA''RK a\nzz\nx MA''RK b\nzz\nx MA''RK c\n'
| x MARK a
| zz
| x MARK b
@@ -150,13 +150,13 @@
|24: 0-0 d,#444444, 1-1 d,#080808, 2-139 #bdbdbd,#080808,
|25: 0-0 d,#444444, 1-1 d,#080808, 2-139 #bdbdbd,#080808,
|26: 0-1 #ffffff,#262626, 2-119 #949494,#121212, 120-139 d,#121212,
-|27: 0-0 d,#444444, 1-1 d,#080808, 2-6 #626262,#080808, 7-139 #080808,#80a0ff,
+|27: 0-0 d,#444444, 1-1 d,#080808, 2-6 #626262,#080808, 7-24 #bdbdbd,#080808, 25-139 d,#080808,
|28: 0-0 d,#444444, 1-1 d,#080808, 2-6 #626262,#080808, 7-24 #bdbdbd,#080808, 25-139 d,#080808,
|29: 0-0 d,#121212, 1-1 d,#080808, 2-6 #626262,#080808, 7-24 #bdbdbd,#080808, 25-139 d,#080808,
== snap second grid=140x30 cursor=7,5
|New Newcol Find Grep Help Tutor Dump NextColor Debug Kill
| /tmp/pardes-snap/psearch/cwd New Del
-|
+| printf 'x MA''RK a\nzz\nx MA''RK b\nzz\nx MA''RK c\n'
| x MARK a
| zz
| x MARK b
@@ -187,7 +187,7 @@
== snap back grid=140x30 cursor=7,3
|New Newcol Find Grep Help Tutor Dump NextColor Debug Kill
| /tmp/pardes-snap/psearch/cwd New Del
-|
+| printf 'x MA''RK a\nzz\nx MA''RK b\nzz\nx MA''RK c\n'
| x MARK a
| zz
| x MARK b
@@ -215,10 +215,10 @@
| 1 @p0:2:3-6 x MARK a
| 2 @p0:4:3-6 x MARK b
| 3 @p0:6:3-6 x MARK c
-== snap nomatch grid=140x30 cursor=7,3
+== snap nomatch grid=140x30 cursor=7,28
|New Newcol Find Grep Help Tutor Dump NextColor Debug Kill
| /tmp/pardes-snap/psearch/cwd New Del
-|
+| printf 'x MA''RK a\nzz\nx MA''RK b\nzz\nx MA''RK c\n'
| x MARK a
| zz
| x MARK b
@@ -280,7 +280,7 @@
== snap rightsearch grid=140x30 cursor=7,5
|New Newcol Find Grep Help Tutor Dump NextColor Debug Kill
| /tmp/pardes-snap/psearch/cwd New Del
-|
+| printf 'x MA''RK a\nzz\nx MA''RK b\nzz\nx MA''RK c\n'
| x MARK a
| zz
| x MARK b
diff --git a/test/snapshots/psearch.snap b/test/snapshots/psearch.snap
index 11316ea9..1b9eac61 100644
--- a/test/snapshots/psearch.snap
+++ b/test/snapshots/psearch.snap
@@ -2,9 +2,10 @@
# the shell's own scrollback (the plain text view Look reads, prompt rows
# hidden). Results land in a +Search OUTPUT BUFFER — a file pane with no file
# behind it, so its tag has no Save — and point at `@p0:LINE:COL-ENDCOL`, the
-# look target that names a live pane, since a terminal has no path. n/N walk
-# the buffer and look each row, scrolling the terminal to that line of its
-# scrollback and selecting the span the row names.
+# look target that names a live pane, since a terminal has no path. n/N SELECT
+# the next/prev row in the buffer and open nothing; Enter — the look chord —
+# is what scrolls the terminal to that line of its scrollback and selects the
+# span the row names.
# PLACEMENT, and this script is the proof: an output buffer is NOT a document
# — it is the result list of the pane that asked for it — so even here, with no
# doc pane in the session for it to join, it does NOT take a column of its own.
@@ -35,21 +36,27 @@ key enter
wait 10000 @p0:2:3
stable 700 15000
snap results
-# n looks result 1: the terminal's cursor lands on that scrollback line, on
-# the matched SPAN (cols 3..6, past the leading "x ") — not the start of the
-# line, and selected rather than merely parked on
+# n selects result 1 and Enter looks it: the terminal's cursor lands on that
+# scrollback line, on the matched SPAN (cols 3..6, past the leading "x ") —
+# not the start of the line, and selected rather than merely parked on
key n
+key enter
stable 700 15000
snap first
snapstyle first
key n
+key enter
stable 700 15000
snap second
-# N walks back
+# N walks back one row, Enter looks it
key N
+key enter
stable 700 15000
snap back
-# a no-match search opens an empty buffer of its own; n has nowhere to go
+# a no-match search opens an empty buffer of its own — and n does not stop
+# there. The walk is a RING across panes, not one buffer's rows, so with
+# nothing look-able in the empty list it carries on into the one that does
+# have rows and resumes it a row past where the N above left off.
key /
text zzqq
key enter
@@ -62,6 +69,12 @@ snap nomatch
# so the buffer stays empty. Col 5 row 4 is the `M` of the first `x MARK a`,
# in the shell's body in both modes (normal hides the prompt row, leaving it
# blank, so the output rows sit at the same place either way).
+# The left click first is the price of the step above: it left the cursor in
+# the results buffer, and c-b is read by the ACTIVE pane — there is no tty
+# behind a +Search to toggle.
+press left 5 4
+release left 5 4
+stable 400 5000
key c-b
stable 600 8000
press right 5 4
diff --git a/test/snapshots/respawn.golden b/test/snapshots/respawn.golden
index be7be117..fe565d56 100644
--- a/test/snapshots/respawn.golden
+++ b/test/snapshots/respawn.golden
@@ -1,7 +1,7 @@
== snap respawn grid=100x30 cursor=4,8
|New Newcol Find Grep Help Tutor Dump NextColor Debug Kill
| /tmp/pardes-snap/respawn/cwd New Del /tmp/pardes-snap/respawn/cwd New Del
-|
+| ls ls
|
|$ /tmp/pardes-snap/respawn/cwd New Del
| $ ls
diff --git a/test/snapshots/restore.golden b/test/snapshots/restore.golden
index dea5e81f..ee9eae46 100644
--- a/test/snapshots/restore.golden
+++ b/test/snapshots/restore.golden
@@ -32,8 +32,8 @@
== snap restored grid=100x30 cursor=4,5
|New Newcol Find Grep Help Tutor Dump NextColor Debug Kill
| /tmp/pardes-snap/restore/cwd New Del
-|
-|
+| ls
+| echo KEEP''ME
| KEEPME
|
|
diff --git a/test/snapshots/rsearch.golden b/test/snapshots/rsearch.golden
index 953634af..99820250 100644
--- a/test/snapshots/rsearch.golden
+++ b/test/snapshots/rsearch.golden
@@ -1,7 +1,7 @@
== snap opened grid=180x30 cursor=7,2
|New Newcol Find Grep Help Tutor Dump NextColor Debug Kill
| /tmp/pardes-snap/rsearch/cwd/code.txt Save New Del /tmp/pardes-snap/rsearch/cwd New Del /tmp/pardes-snap/rsearch/cwd New Del
-| 1 run count_x now
+| 1 run count_x now ls ls
| 2 open sub/dep.txt:3 here code.txt sub code.txt sub
| 3 count_x again
| 4 pick two words
@@ -16,7 +16,7 @@
|
|
| /tmp/pardes-snap/rsearch/cwd New Del
-|
+| ls
| code.txt sub
|
|
@@ -32,7 +32,7 @@
== snap search grid=180x30 cursor=13,4
|New Newcol Find Grep Help Tutor Dump NextColor Debug Kill
| /tmp/pardes-snap/rsearch/cwd/code.txt Save New Del /tmp/pardes-snap/rsearch/cwd New Del /tmp/pardes-snap/rsearch/cwd New Del
-| 1 run count_x now
+| 1 run count_x now ls ls
| 2 open sub/dep.txt:3 here code.txt sub code.txt sub
| 3 count_x again
| 4 pick two words
@@ -47,7 +47,7 @@
|
|
| /tmp/pardes-snap/rsearch/cwd New Del
-|
+| ls
| code.txt sub
|
|
@@ -63,7 +63,7 @@
== snap select grid=180x30 cursor=14,5
|New Newcol Find Grep Help Tutor Dump NextColor Debug Kill
| /tmp/pardes-snap/rsearch/cwd/code.txt Save New Del /tmp/pardes-snap/rsearch/cwd New Del /tmp/pardes-snap/rsearch/cwd New Del
-| 1 run count_x now
+| 1 run count_x now ls ls
| 2 open sub/dep.txt:3 here code.txt sub code.txt sub
| 3 count_x again
| 4 pick two words
@@ -78,7 +78,7 @@
|
|
| /tmp/pardes-snap/rsearch/cwd New Del
-|
+| ls
| code.txt sub
|
|
@@ -94,7 +94,7 @@
== snap path-open grid=180x30 cursor=7,16
|New Newcol Find Grep Help Tutor Dump NextColor Debug Kill
| /tmp/pardes-snap/rsearch/cwd/code.txt Save New Del /tmp/pardes-snap/rsearch/cwd New Del /tmp/pardes-snap/rsearch/cwd New Del
-| 1 run count_x now
+| 1 run count_x now ls ls
| 2 open sub/dep.txt:3 here code.txt sub code.txt sub
| 3 count_x again
| 4 pick two words
@@ -109,7 +109,7 @@
| 1 d1
| 2 d2
| 3 DEPTARGET /tmp/pardes-snap/rsearch/cwd New Del
-| 4 d4
+| 4 d4 ls
| 5 d5 code.txt sub
| 6 d6
|
@@ -125,7 +125,7 @@
== snap step1 grid=180x30 cursor=13,4
|New Newcol Find Grep Help Tutor Dump NextColor Debug Kill
| /tmp/pardes-snap/rsearch/cwd/code.txt Save New Del /tmp/pardes-snap/rsearch/cwd New Del /tmp/pardes-snap/rsearch/cwd New Del
-| 1 run count_x now
+| 1 run count_x now ls ls
| 2 open sub/dep.txt:3 here code.txt sub code.txt sub
| 3 count_x again
| 4 pick two words
@@ -140,7 +140,7 @@
| 1 d1
| 2 d2
| 3 DEPTARGET /tmp/pardes-snap/rsearch/cwd New Del
-| 4 d4
+| 4 d4 ls
| 5 d5 code.txt sub
| 6 d6
|
@@ -156,7 +156,7 @@
== snap step2 grid=180x30 cursor=17,2
|New Newcol Find Grep Help Tutor Dump NextColor Debug Kill
| /tmp/pardes-snap/rsearch/cwd/code.txt Save New Del /tmp/pardes-snap/rsearch/cwd New Del /tmp/pardes-snap/rsearch/cwd New Del
-| 1 run count_x now
+| 1 run count_x now ls ls
| 2 open sub/dep.txt:3 here code.txt sub code.txt sub
| 3 count_x again
| 4 pick two words
@@ -171,7 +171,7 @@
| 1 d1
| 2 d2
| 3 DEPTARGET /tmp/pardes-snap/rsearch/cwd New Del
-| 4 d4
+| 4 d4 ls
| 5 d5 code.txt sub
| 6 d6
|
@@ -187,7 +187,7 @@
== snap step3 grid=180x30 cursor=17,2
|New Newcol Find Grep Help Tutor Dump NextColor Debug Kill
| /tmp/pardes-snap/rsearch/cwd/code.txt Save New Del /tmp/pardes-snap/rsearch/cwd New Del /tmp/pardes-snap/rsearch/cwd New Del
-| 1 run count_x now
+| 1 run count_x now ls ls
| 2 open sub/dep.txt:3 here code.txt sub code.txt sub
| 3 count_x again
| 4 pick two words
@@ -202,7 +202,7 @@
| 1 d1
| 2 d2
| 3 DEPTARGET /tmp/pardes-snap/rsearch/cwd New Del
-| 4 d4
+| 4 d4 ls
| 5 d5 code.txt sub
| 6 d6
|
@@ -218,7 +218,7 @@
== snap selclick grid=180x30 cursor=14,5
|New Newcol Find Grep Help Tutor Dump NextColor Debug Kill
| /tmp/pardes-snap/rsearch/cwd/code.txt Save New Del /tmp/pardes-snap/rsearch/cwd New Del /tmp/pardes-snap/rsearch/cwd New Del
-| 1 run count_x now
+| 1 run count_x now ls ls
| 2 open sub/dep.txt:3 here code.txt sub code.txt sub
| 3 count_x again
| 4 pick two words
@@ -233,7 +233,7 @@
| 1 d1
| 2 d2
| 3 DEPTARGET /tmp/pardes-snap/rsearch/cwd New Del
-| 4 d4
+| 4 d4 ls
| 5 d5 code.txt sub
| 6 d6
|
@@ -249,7 +249,7 @@
== snap outside grid=180x30 cursor=20,5
|New Newcol Find Grep Help Tutor Dump NextColor Debug Kill
| /tmp/pardes-snap/rsearch/cwd/code.txt Save New Del /tmp/pardes-snap/rsearch/cwd New Del /tmp/pardes-snap/rsearch/cwd New Del
-| 1 run count_x now
+| 1 run count_x now ls ls
| 2 open sub/dep.txt:3 here code.txt sub code.txt sub
| 3 count_x again
| 4 pick two words
@@ -264,7 +264,7 @@
| 1 d1
| 2 d2
| 3 DEPTARGET /tmp/pardes-snap/rsearch/cwd New Del
-| 4 d4
+| 4 d4 ls
| 5 d5 code.txt sub
| 6 d6
|
diff --git a/test/snapshots/scroll.golden b/test/snapshots/scroll.golden
index cd2167ba..55dd47c7 100644
--- a/test/snapshots/scroll.golden
+++ b/test/snapshots/scroll.golden
@@ -1,7 +1,7 @@
== snap bottom grid=100x30 cursor=4,15
|New Newcol Find Grep Help Tutor Dump NextColor Debug Kill
| /tmp/pardes-snap/scroll/cwd New Del /tmp/pardes-snap/scroll/cwd New Del
-| 188
+| 188 ls
| 189 s.txt
| 190
| 191
@@ -16,7 +16,7 @@
| 200
|
| /tmp/pardes-snap/scroll/cwd New Del
-|
+| ls
| s.txt
|
|
@@ -32,7 +32,7 @@
== snap wheel3 grid=100x30 cursor=4,15
|New Newcol Find Grep Help Tutor Dump NextColor Debug Kill
| /tmp/pardes-snap/scroll/cwd New Del /tmp/pardes-snap/scroll/cwd New Del
-| 185
+| 185 ls
| 186 s.txt
| 187
| 188
@@ -47,7 +47,7 @@
| 197
| 198
| /tmp/pardes-snap/scroll/cwd New Del
-|
+| ls
| s.txt
|
|
@@ -63,7 +63,7 @@
== snap gutter-up grid=100x30 cursor=4,15
|New Newcol Find Grep Help Tutor Dump NextColor Debug Kill
| /tmp/pardes-snap/scroll/cwd New Del /tmp/pardes-snap/scroll/cwd New Del
-| 178
+| 178 ls
| 179 s.txt
| 180
| 181
@@ -78,7 +78,7 @@
| 190
| 191
| /tmp/pardes-snap/scroll/cwd New Del
-|
+| ls
| s.txt
|
|
@@ -94,7 +94,7 @@
== snap gutter-down grid=100x30 cursor=4,15
|New Newcol Find Grep Help Tutor Dump NextColor Debug Kill
| /tmp/pardes-snap/scroll/cwd New Del /tmp/pardes-snap/scroll/cwd New Del
-| 180
+| 180 ls
| 181 s.txt
| 182
| 183
@@ -109,7 +109,7 @@
| 192
| 193
| /tmp/pardes-snap/scroll/cwd New Del
-|
+| ls
| s.txt
|
|
@@ -125,7 +125,7 @@
== snap wheel-down grid=100x30 cursor=4,15
|New Newcol Find Grep Help Tutor Dump NextColor Debug Kill
| /tmp/pardes-snap/scroll/cwd New Del /tmp/pardes-snap/scroll/cwd New Del
-| 181
+| 181 ls
| 182 s.txt
| 183
| 184
@@ -140,7 +140,7 @@
| 193
| 194
| /tmp/pardes-snap/scroll/cwd New Del
-|
+| ls
| s.txt
|
|
diff --git a/test/snapshots/scrolloff.golden b/test/snapshots/scrolloff.golden
index 90c84196..265d427d 100644
--- a/test/snapshots/scrolloff.golden
+++ b/test/snapshots/scrolloff.golden
@@ -1,84 +1,84 @@
== snap top grid=150x11 cursor=7,2
|New Newcol Find Grep Help Tutor Dump NextColor Debug Kill
| /tmp/pardes-snap/scrolloff/cwd/g.txt Save New De /tmp/pardes-snap/scrolloff/cwd New Del /tmp/pardes-snap/scrolloff/cwd New Del
-| 1 line 1
+| 1 line 1 ls ls
| 2 line 2 g.txt g.txt
| 3 line 3
| 4 line 4
| 5 line 5 /tmp/pardes-snap/scrolloff/cwd New Del
-| 6 line 6
+| 6 line 6 ls
| 7 line 7 g.txt
| 8 line 8
| 9 line 9
== snap edge grid=150x11 cursor=7,7
|New Newcol Find Grep Help Tutor Dump NextColor Debug Kill
| /tmp/pardes-snap/scrolloff/cwd/g.txt Save New De /tmp/pardes-snap/scrolloff/cwd New Del /tmp/pardes-snap/scrolloff/cwd New Del
-| 1 line 1
+| 1 line 1 ls ls
| 2 line 2 g.txt g.txt
| 3 line 3
| 4 line 4
| 5 line 5 /tmp/pardes-snap/scrolloff/cwd New Del
-| 6 line 6
+| 6 line 6 ls
| 7 line 7 g.txt
| 8 line 8
| 9 line 9
== snap scrolled1 grid=150x11 cursor=7,7
|New Newcol Find Grep Help Tutor Dump NextColor Debug Kill
| /tmp/pardes-snap/scrolloff/cwd/g.txt Save New De /tmp/pardes-snap/scrolloff/cwd New Del /tmp/pardes-snap/scrolloff/cwd New Del
-| 2 line 2
+| 2 line 2 ls ls
| 3 line 3 g.txt g.txt
| 4 line 4
| 5 line 5
| 6 line 6 /tmp/pardes-snap/scrolloff/cwd New Del
-| 7 line 7
+| 7 line 7 ls
| 8 line 8 g.txt
| 9 line 9
| 10 line 10
== snap jdown grid=150x11 cursor=7,7
|New Newcol Find Grep Help Tutor Dump NextColor Debug Kill
| /tmp/pardes-snap/scrolloff/cwd/g.txt Save New De /tmp/pardes-snap/scrolloff/cwd New Del /tmp/pardes-snap/scrolloff/cwd New Del
-| 6 line 6
+| 6 line 6 ls ls
| 7 line 7 g.txt g.txt
| 8 line 8
| 9 line 9
| 10 line 10 /tmp/pardes-snap/scrolloff/cwd New Del
-| 11 line 11
+| 11 line 11 ls
| 12 line 12 g.txt
| 13 line 13
| 14 line 14
== snap end grid=150x11 cursor=7,9
|New Newcol Find Grep Help Tutor Dump NextColor Debug Kill
| /tmp/pardes-snap/scrolloff/cwd/g.txt Save New De /tmp/pardes-snap/scrolloff/cwd New Del /tmp/pardes-snap/scrolloff/cwd New Del
-| 33 line 33
+| 33 line 33 ls ls
| 34 line 34 g.txt g.txt
| 35 line 35
| 36 line 36
| 37 line 37 /tmp/pardes-snap/scrolloff/cwd New Del
-| 38 line 38
+| 38 line 38 ls
| 39 line 39 g.txt
| 40 line 40
| 41
== snap kup grid=150x11 cursor=7,5
|New Newcol Find Grep Help Tutor Dump NextColor Debug Kill
| /tmp/pardes-snap/scrolloff/cwd/g.txt Save New De /tmp/pardes-snap/scrolloff/cwd New Del /tmp/pardes-snap/scrolloff/cwd New Del
-| 29 line 29
+| 29 line 29 ls ls
| 30 line 30 g.txt g.txt
| 31 line 31
| 32 line 32
| 33 line 33 /tmp/pardes-snap/scrolloff/cwd New Del
-| 34 line 34
+| 34 line 34 ls
| 35 line 35 g.txt
| 36 line 36
| 37 line 37
== snap top2 grid=150x11 cursor=7,2
|New Newcol Find Grep Help Tutor Dump NextColor Debug Kill
| /tmp/pardes-snap/scrolloff/cwd/g.txt Save New De /tmp/pardes-snap/scrolloff/cwd New Del /tmp/pardes-snap/scrolloff/cwd New Del
-| 1 line 1
+| 1 line 1 ls ls
| 2 line 2 g.txt g.txt
| 3 line 3
| 4 line 4
| 5 line 5 /tmp/pardes-snap/scrolloff/cwd New Del
-| 6 line 6
+| 6 line 6 ls
| 7 line 7 g.txt
| 8 line 8
| 9 line 9
diff --git a/test/snapshots/selarg.golden b/test/snapshots/selarg.golden
index 174ead70..5c81a3a0 100644
--- a/test/snapshots/selarg.golden
+++ b/test/snapshots/selarg.golden
@@ -16,7 +16,7 @@
|
|
| /tmp/pardes-snap/selarg/cwd New Del
-|
+| ls
| s.txt
|
|
@@ -33,7 +33,7 @@
|New Newcol Find Grep Help Tutor Dump NextColor Debug Kill
| /tmp/pardes-snap/selarg/cwd New Del /tmp/pardes-snap/selarg/cwd New Del
| ZZARG ZZVEE ./c.sh
-|
+| ./c.sh ZZARG
| CHORDARG:ZZARG
|
|
@@ -47,7 +47,7 @@
|
|
| /tmp/pardes-snap/selarg/cwd New Del
-|
+| ls
| s.txt
|
|
@@ -64,9 +64,9 @@
|New Newcol Find Grep Help Tutor Dump NextColor Debug Kill
| /tmp/pardes-snap/selarg/cwd New Del /tmp/pardes-snap/selarg/cwd New Del
| ZZARG ZZVEE ./c.sh
-|
+| ./c.sh ZZARG
| CHORDARG:ZZARG
-|
+| ./c.sh ZZVEE
| CHORDARG:ZZVEE
|
|
@@ -78,7 +78,7 @@
|
|
| /tmp/pardes-snap/selarg/cwd New Del
-|
+| ls
| s.txt
|
|
diff --git a/test/snapshots/shellset.golden b/test/snapshots/shellset.golden
index 5cf503f7..8753d0d3 100644
--- a/test/snapshots/shellset.golden
+++ b/test/snapshots/shellset.golden
@@ -43,7 +43,7 @@
== snap fallback-shell grid=90x20 cursor=49,4
|New Newcol Find Grep Help Tutor Dump NextColor Debug Kill
| /tmp/pardes-snap/shellset/cwd/cmd.txt Save /tmp/pardes-snap/shellset/cwd New Del
-| 1 Shell zznosuchshell
+| 1 Shell zznosuchshell ls
| cmd.txt zmarkfile.txt
|
|
diff --git a/test/snapshots/shrinktag.golden b/test/snapshots/shrinktag.golden
index 2ab4565c..bde1836e 100644
--- a/test/snapshots/shrinktag.golden
+++ b/test/snapshots/shrinktag.golden
@@ -1,7 +1,7 @@
== snap before grid=100x30 cursor=2,8
|New Newcol Find Grep Help Tutor Dump NextColor Debug Kill
| /tmp/pardes-snap/shrinktag/cwd New Del /tmp/pardes-snap/shrinktag/cwd New Del
-|
+| ls ls
| w.txt w.txt
|
|
@@ -16,7 +16,7 @@
|
|
| /tmp/pardes-snap/shrinktag/cwd New Del
-|
+| ls
| w.txt
|
|
@@ -32,8 +32,8 @@
== snap shrunk grid=100x30 cursor=2,8
|New Newcol Find Grep Help Tutor Dump NextColor Debug Kill
| /tmp/pardes-snap/shrinktag/cwd New Del /tmp/pardes-snap/shrinktag/cwd New Del
-| /tmp/pardes-snap/shrinktag/cwd New Del
-| w.txt
+| /tmp/pardes-snap/shrinktag/cwd New Del ls
+| ls w.txt
| w.txt
|
|
@@ -63,8 +63,8 @@
== snap move-preview grid=100x30 cursor=2,8
|New Newcol Find Grep Help Tutor Dump NextColor Debug Kill
| /tmp/pardes-snap/shrinktag/cwd New Del /tmp/pardes-snap/shrinktag/cwd New Del
-| /tmp/pardes-snap/shrinktag/cwd New Del
-| w.txt
+| /tmp/pardes-snap/shrinktag/cwd New Del ls
+| ls w.txt
| w.txt
|
|
@@ -94,7 +94,7 @@
== snap restored grid=100x30 cursor=2,8
|New Newcol Find Grep Help Tutor Dump NextColor Debug Kill
| /tmp/pardes-snap/shrinktag/cwd New Del /tmp/pardes-snap/shrinktag/cwd New Del
-|
+| ls ls
| w.txt w.txt
|
|
@@ -109,7 +109,7 @@
|
|
| /tmp/pardes-snap/shrinktag/cwd New Del
-|
+| ls
| w.txt
|
|
@@ -125,7 +125,7 @@
== snap bottom-shrunk grid=100x30 cursor=2,8
|New Newcol Find Grep Help Tutor Dump NextColor Debug Kill
| /tmp/pardes-snap/shrinktag/cwd New Del /tmp/pardes-snap/shrinktag/cwd New Del
-|
+| ls ls
| w.txt w.txt
|
|
diff --git a/test/snapshots/splitparent.golden b/test/snapshots/splitparent.golden
index 281fb5ef..3cc2e6bc 100644
--- a/test/snapshots/splitparent.golden
+++ b/test/snapshots/splitparent.golden
@@ -1,8 +1,8 @@
== snap shrunk grid=100x30 cursor=4,3
|New Newcol Find Grep Help Tutor Dump NextColor Debug Kill
| /tmp/pardes-snap/splitparent/cwd New Del /tmp/pardes-snap/splitparent/cwd New Del
-| /tmp/pardes-snap/splitparent/cwd New Del
-|
+| /tmp/pardes-snap/splitparent/cwd New Del ls
+| ls
|
|
|
@@ -32,11 +32,11 @@
== snap swap-parent grid=100x30 cursor=4,7
|New Newcol Find Grep Help Tutor Dump NextColor Debug Kill
| /tmp/pardes-snap/splitparent/cwd New Del /tmp/pardes-snap/splitparent/cwd New Del
-| /tmp/pardes-snap/splitparent/cwd New Del
-|
+| /tmp/pardes-snap/splitparent/cwd New Del ls
+| ls
|
| /tmp/pardes-snap/splitparent/cwd New Del
-|
+| ls
|
|
|
@@ -69,11 +69,11 @@
== snap regrown grid=100x30 cursor=54,18
|New Newcol Find Grep Help Tutor Dump NextColor Debug Kill
| /tmp/pardes-snap/splitparent/cwd New Del /tmp/pardes-snap/splitparent/cwd New Del
-| /tmp/pardes-snap/splitparent/cwd New Del
-|
+| /tmp/pardes-snap/splitparent/cwd New Del ls
+| ls
|
| /tmp/pardes-snap/splitparent/cwd New Del
-|
+| ls
|
|
|
@@ -84,7 +84,7 @@
|
|
| /tmp/pardes-snap/splitparent/cwd New Del
-|
+| ls
|
|
|
diff --git a/test/snapshots/syntax.golden b/test/snapshots/syntax.golden
index ac220610..5d6b85c7 100644
--- a/test/snapshots/syntax.golden
+++ b/test/snapshots/syntax.golden
@@ -1,7 +1,7 @@
== snap zig-open grid=150x30 cursor=7,2
|New Newcol Find Grep Help Tutor Dump NextColor Debug Kill
| /tmp/pardes-snap/syntax/cwd/demo.zig Save New De /tmp/pardes-snap/syntax/cwd New Del /tmp/pardes-snap/syntax/cwd New Del
-| 1 const std = @import("std"); // greet
+| 1 const std = @import("std"); // greet ls ls
| 2 pub fn main() void { demo.zig demo.zig
| 3 var x: u32 = 42;
| 4 _ = x;
@@ -16,7 +16,7 @@
|
|
| /tmp/pardes-snap/syntax/cwd New Del
-|
+| ls
| demo.zig
|
|
@@ -63,7 +63,7 @@
== style colors-off
|0: 0-56 #949494,#121212, 57-149 d,#121212,
|1: 0-1 #ffffff,#626262, 2-49 #949494,#121212, 50-51 #ffffff,#262626, 52-86 #949494,#121212, 87-99 d,#121212, 100-101 #ffffff,#262626, 102-136 #949494,#121212, 137-149 d,#121212,
-|2: 0-0 d,#444444, 1-1 d,#080808, 2-6 #949494,#121212, 7-42 #bdbdbd,#080808, 43-49 d,#080808, 50-50 d,#444444, 51-99 d,#080808, 100-100 d,#444444, 101-149 d,#080808,
+|2: 0-0 d,#444444, 1-1 d,#080808, 2-6 #949494,#121212, 7-42 #bdbdbd,#080808, 43-49 d,#080808, 50-50 d,#444444, 51-51 d,#080808, 52-53 #bdbdbd,#080808, 54-99 d,#080808, 100-100 d,#444444, 101-101 d,#080808, 102-103 #bdbdbd,#080808, 104-149 d,#080808,
|3: 0-0 d,#444444, 1-1 d,#080808, 2-6 #626262,#080808, 7-26 #bdbdbd,#080808, 27-49 d,#080808, 50-50 d,#444444, 51-51 d,#080808, 52-59 #bdbdbd,#080808, 60-99 d,#080808, 100-100 d,#444444, 101-101 d,#080808, 102-109 #bdbdbd,#080808, 110-149 d,#080808,
|4: 0-0 d,#444444, 1-1 d,#080808, 2-6 #626262,#080808, 7-26 #bdbdbd,#080808, 27-49 d,#080808, 50-50 d,#444444, 51-99 d,#080808, 100-100 d,#444444, 101-149 d,#080808,
|5: 0-0 d,#444444, 1-1 d,#080808, 2-6 #626262,#080808, 7-16 #bdbdbd,#080808, 17-49 d,#080808, 50-50 d,#444444, 51-99 d,#080808, 100-100 d,#444444, 101-149 d,#080808,
@@ -78,7 +78,7 @@
|14: 0-0 d,#444444, 1-1 d,#080808, 2-6 #626262,#080808, 7-49 d,#080808, 50-50 d,#444444, 51-99 d,#080808, 100-100 d,#444444, 101-149 d,#080808,
|15: 0-0 d,#444444, 1-1 d,#080808, 2-6 #626262,#080808, 7-49 d,#080808, 50-50 d,#444444, 51-99 d,#080808, 100-100 d,#444444, 101-149 d,#080808,
|16: 0-0 d,#444444, 1-1 d,#080808, 2-6 #626262,#080808, 7-49 d,#080808, 50-51 #ffffff,#262626, 52-86 #949494,#121212, 87-99 d,#121212, 100-100 d,#444444, 101-149 d,#080808,
-|17: 0-0 d,#444444, 1-1 d,#080808, 2-6 #626262,#080808, 7-49 d,#080808, 50-50 d,#444444, 51-99 d,#080808, 100-100 d,#444444, 101-149 d,#080808,
+|17: 0-0 d,#444444, 1-1 d,#080808, 2-6 #626262,#080808, 7-49 d,#080808, 50-50 d,#444444, 51-51 d,#080808, 52-53 #bdbdbd,#080808, 54-99 d,#080808, 100-100 d,#444444, 101-149 d,#080808,
|18: 0-0 d,#444444, 1-1 d,#080808, 2-6 #626262,#080808, 7-49 d,#080808, 50-50 d,#444444, 51-51 d,#080808, 52-59 #bdbdbd,#080808, 60-99 d,#080808, 100-100 d,#444444, 101-149 d,#080808,
|19: 0-0 d,#444444, 1-1 d,#080808, 2-6 #626262,#080808, 7-49 d,#080808, 50-50 d,#444444, 51-99 d,#080808, 100-100 d,#444444, 101-149 d,#080808,
|20: 0-0 d,#444444, 1-1 d,#080808, 2-6 #626262,#080808, 7-49 d,#080808, 50-50 d,#444444, 51-99 d,#080808, 100-100 d,#444444, 101-149 d,#080808,
diff --git a/test/snapshots/tag.golden b/test/snapshots/tag.golden
index f24790d2..13cb2e72 100644
--- a/test/snapshots/tag.golden
+++ b/test/snapshots/tag.golden
@@ -1,7 +1,7 @@
== snap tag-focus grid=150x30 cursor=39,1
|New Newcol Find Grep Help Tutor Dump NextColor Debug Kill
| /tmp/pardes-snap/tag/cwd New Del /tmp/pardes-snap/tag/cwd New Del
-|
+| ls ls
| t.txt t.txt
|
|
@@ -16,7 +16,7 @@
|
|
| /tmp/pardes-snap/tag/cwd New Del
-|
+| ls
| t.txt
|
|
@@ -32,7 +32,7 @@
== snap tag-typed grid=150x30 cursor=45,1
|New Newcol Find Grep Help Tutor Dump NextColor Debug Kill
| /tmp/pardes-snap/tag/cwd t.txt New Del /tmp/pardes-snap/tag/cwd New Del
-|
+| ls ls
| t.txt t.txt
|
|
@@ -47,7 +47,7 @@
|
|
| /tmp/pardes-snap/tag/cwd New Del
-|
+| ls
| t.txt
|
|
@@ -63,7 +63,7 @@
== snap tag-del grid=150x30 cursor=41,1
|New Newcol Find Grep Help Tutor Dump NextColor Debug Kill
| /tmp/pardes-snap/tag/cwd t New Del /tmp/pardes-snap/tag/cwd New Del
-|
+| ls ls
| t.txt t.txt
|
|
@@ -78,7 +78,7 @@
|
|
| /tmp/pardes-snap/tag/cwd New Del
-|
+| ls
| t.txt
|
|
@@ -94,7 +94,7 @@
== snap tag-exit grid=150x30 cursor=4,4
|New Newcol Find Grep Help Tutor Dump NextColor Debug Kill
| /tmp/pardes-snap/tag/cwd t.txt New Del /tmp/pardes-snap/tag/cwd New Del
-|
+| ls ls
| t.txt t.txt
|
|
@@ -109,7 +109,7 @@
|
|
| /tmp/pardes-snap/tag/cwd New Del
-|
+| ls
| t.txt
|
|
@@ -125,7 +125,7 @@
== snap tag-look grid=150x30 cursor=7,2
|New Newcol Find Grep Help Tutor Dump NextColor Debug Kill
| /tmp/pardes-snap/tag/cwd/t.txt Save New Del /tmp/pardes-snap/tag/cwd t.txt /tmp/pardes-snap/tag/cwd New Del
-| 1 ZZLOOKED
+| 1 ZZLOOKED ls ls
| t.txt t.txt
|
|
@@ -140,7 +140,7 @@
|
|
| /tmp/pardes-snap/tag/cwd New Del
-|
+| ls
| t.txt
|
|
diff --git a/test/snapshots/tagalign.golden b/test/snapshots/tagalign.golden
index a9dda3c7..867d4c2a 100644
--- a/test/snapshots/tagalign.golden
+++ b/test/snapshots/tagalign.golden
@@ -16,7 +16,7 @@
|
|
| /tmp/pardes-snap/tagalign/cwd New Del
-|
+| ls
| deep
|
|
@@ -47,7 +47,7 @@
|
|
| /tmp/pardes-snap/tagalign/cwd New Del
-|
+| ls
| deep
|
|
@@ -78,7 +78,7 @@
|
|
| /tmp/pardes-snap/tagalign/cwd New Del
-|
+| ls
| deep
|
|
@@ -109,7 +109,7 @@
|
|
| /tmp/pardes-snap/tagalign/cwd New Del
-|
+| ls
| deep
|
|
@@ -125,7 +125,7 @@
== snap alone grid=100x30 cursor=4,4
|New Newcol Find Grep Help Tutor Dump NextColor Debug Kill
| /tmp/pardes-snap/tagalign/cwd New Del
-|
+| ls
| deep
|
|
diff --git a/test/snapshots/tagalign2col.golden b/test/snapshots/tagalign2col.golden
index d5d22935..2db32f08 100644
--- a/test/snapshots/tagalign2col.golden
+++ b/test/snapshots/tagalign2col.golden
@@ -1,7 +1,7 @@
== snap onecol grid=160x30 cursor=7,2
|New Newcol Find Grep Help Tutor Dump NextColor Debug Kill
| /tmp/pardes-snap/tagalign2col/cwd/deep/proj/document.txt Save New Del /tmp/pardes-snap/tagalign2col/cwd New Del
-| 1 alpha
+| 1 alpha ls
| 2 beta deep
| 3 gamma
|
@@ -32,7 +32,7 @@
== snap aligned grid=160x30 cursor=4,19
|New Newcol Find Grep Help Tutor Dump NextColor Debug Kill
| /tmp/pardes-snap/tagalign2col/cwd/deep/proj/document.txt Save New Del /tmp/pardes-snap/tagalign2col/cwd New Del
-| 1 alpha
+| 1 alpha ls
| 2 beta deep
| 3 gamma
|
@@ -47,7 +47,7 @@
|
|
| /tmp/pardes-snap/tagalign2col/cwd New Del
-|
+| ls
| deep
|
|
@@ -63,7 +63,7 @@
== snap widened grid=160x30 cursor=4,19
|New Newcol Find Grep Help Tutor Dump NextColor Debug Kill
| /tmp/pardes-snap/tagalign2col/cwd/deep/proj/document.txt Save New Del ╎ /tmp/pardes-snap/tagalign2col/cwd New Del
-| 1 alpha ╎
+| 1 alpha ╎ ls
| 2 beta ╎ deep
| 3 gamma ╎
| ╎
@@ -78,7 +78,7 @@
| ╎
| ╎
| /tmp/pardes-snap/tagalign2col/cwd New Del ╎
-| ╎
+| ls ╎
| deep ╎
| ╎
| ╎
diff --git a/test/snapshots/tagbottomimage.golden b/test/snapshots/tagbottomimage.golden
index 72b31809..9ba62909 100644
--- a/test/snapshots/tagbottomimage.golden
+++ b/test/snapshots/tagbottomimage.golden
@@ -1,7 +1,7 @@
== snap img-top grid=150x30 cursor=11,7
|New Newcol Find Grep Help Tutor Dump NextColor Debug Kill
| img /tmp/pardes-snap/tagbottomimage/cwd/pic.ppm New Del /tmp/pardes-snap/tagbottomimage/cwd New Del
-| (f🬱]0V7R*%m🬶🬁G🬬tN#XR9q🬢tC#f/🬜_GR(🬞🬙tCRp$o*7^+[#H7s🬢YDZ🬝▟
+| (f🬱]0V7R*%m🬶🬁G🬬tN#XR9q🬢tC#f/🬜_GR(🬞🬙tCRp$o*7^+[#H7s🬢YDZ🬝▟ ls
| iU)dSotT[r27T"\*Fh▐🬅g,🬰p🬛▙🬲&*3/9xy🬛▀0kCg▛🬱C,>C}PC06m🬝▟█ pic.ppm
| "S▄;$gs,Xa▟T🬔s▖┼W▘?by🬋🬭uCR3/A3🬶lO▖▞🬃🬘╳🬟#=🬺🬕yoaJ@>4🬝🬵
| ─m!fAAD🬒jW>7JkR▄▜🬫🬞🬢FWx╲▟2ZT🬥/▖jteR?q🬶^🬅▀_@N─u4🬹🬝🬹
@@ -31,7 +31,7 @@
| 🬝🬹
== snap img-bottom grid=150x30 cursor=11,7
|New Newcol Find Grep Help Tutor Dump NextColor Debug Kill
-| (f🬱]0V7R*%m🬶🬁G🬬tN#XR9q🬢tC#f/🬜_GR(🬞🬙tCRp$o*7^+[#H7s🬢YDZ🬝▟
+| (f🬱]0V7R*%m🬶🬁G🬬tN#XR9q🬢tC#f/🬜_GR(🬞🬙tCRp$o*7^+[#H7s🬢YDZ🬝▟ ls
| iU)dSotT[r27T"\*Fh▐🬅g,🬰p🬛▙🬲&*3/9xy🬛▀0kCg▛🬱C,>C}PC06m🬝▟█ pic.ppm
| "S▄;$gs,Xa▟T🬔s▖┼W▘?by🬋🬭uCR3/A3🬶lO▖▞🬃🬘╳🬟#=🬺🬕yoaJ@>4🬝🬵
| ─m!fAAD🬒jW>7JkR▄▜🬫🬞🬢FWx╲▟2ZT🬥/▖jteR?q🬶^🬅▀_@N─u4🬹🬝🬹
@@ -93,7 +93,7 @@
|29: 0-1 #ffffff,#626262, 2-56 #949494,#121212, 57-74 d,#121212, 75-76 #ffffff,#262626, 77-129 #949494,#121212, 130-149 d,#121212,
== snap search-prompt grid=150x30 cursor=6,28
|New Newcol Find Grep Help Tutor Dump NextColor Debug Kill
-| (f🬱]0V7R*%m🬶🬁G🬬tN#XR9q🬢tC#f/🬜_GR(🬞🬙tCRp$o*7^+[#H7s🬢YDZ🬝▟
+| (f🬱]0V7R*%m🬶🬁G🬬tN#XR9q🬢tC#f/🬜_GR(🬞🬙tCRp$o*7^+[#H7s🬢YDZ🬝▟ ls
| iU)dSotT[r27T"\*Fh▐🬅g,🬰p🬛▙🬲&*3/9xy🬛▀0kCg▛🬱C,>C}PC06m🬝▟█ pic.ppm
| "S▄;$gs,Xa▟T🬔s▖┼W▘?by🬋🬭uCR3/A3🬶lO▖▞🬃🬘╳🬟#=🬺🬕yoaJ@>4🬝🬵
| ─m!fAAD🬒jW>7JkR▄▜🬫🬞🬢FWx╲▟2ZT🬥/▖jteR?q🬶^🬅▀_@N─u4🬹🬝🬹
@@ -124,7 +124,7 @@
| img /tmp/pardes-snap/tagbottomimage/cwd/pic.ppm New Del /tmp/pardes-snap/tagbottomimage/cwd New Del
== snap del-image grid=150x30 cursor=5,6
|New Newcol Find Grep Help Tutor Dump NextColor Debug Kill
-|
+| ls
| pic.ppm
|
|
diff --git a/test/snapshots/tagnav.golden b/test/snapshots/tagnav.golden
index 1c9186be..075cf45d 100644
--- a/test/snapshots/tagnav.golden
+++ b/test/snapshots/tagnav.golden
@@ -1,7 +1,7 @@
== snap start grid=100x30 cursor=7,2
|New Newcol Find Grep Help Tutor Dump NextColor Debug Kill
| /tmp/pardes-snap/tagnav/cwd/w.txt Save New Del /tmp/pardes-snap/tagnav/cwd New Del
-| 1 alpha
+| 1 alpha ls
| 2 beta w.txt
| 3 gamma
|
@@ -16,7 +16,7 @@
|
|
| /tmp/pardes-snap/tagnav/cwd New Del
-|
+| ls
| w.txt
|
|
@@ -32,7 +32,7 @@
== snap colon grid=100x30 cursor=36,1
|New Newcol Find Grep Help Tutor Dump NextColor Debug Kill
| /tmp/pardes-snap/tagnav/cwd/w.txt Save New Del /tmp/pardes-snap/tagnav/cwd New Del
-| 1 alpha
+| 1 alpha ls
| 2 beta w.txt
| 3 gamma
|
@@ -47,7 +47,7 @@
|
|
| /tmp/pardes-snap/tagnav/cwd New Del
-|
+| ls
| w.txt
|
|
@@ -63,7 +63,7 @@
== snap right-tag grid=100x30 cursor=80,1
|New Newcol Find Grep Help Tutor Dump NextColor Debug Kill
| /tmp/pardes-snap/tagnav/cwd/w.txt Save New Del /tmp/pardes-snap/tagnav/cwd New Del
-| 1 alpha
+| 1 alpha ls
| 2 beta w.txt
| 3 gamma
|
@@ -78,7 +78,7 @@
|
|
| /tmp/pardes-snap/tagnav/cwd New Del
-|
+| ls
| w.txt
|
|
@@ -94,7 +94,7 @@
== snap left-tag grid=100x30 cursor=36,1
|New Newcol Find Grep Help Tutor Dump NextColor Debug Kill
| /tmp/pardes-snap/tagnav/cwd/w.txt Save New Del /tmp/pardes-snap/tagnav/cwd New Del
-| 1 alpha
+| 1 alpha ls
| 2 beta w.txt
| 3 gamma
|
@@ -109,7 +109,7 @@
|
|
| /tmp/pardes-snap/tagnav/cwd New Del
-|
+| ls
| w.txt
|
|
@@ -125,7 +125,7 @@
== snap down-tag grid=100x30 cursor=41,16
|New Newcol Find Grep Help Tutor Dump NextColor Debug Kill
| /tmp/pardes-snap/tagnav/cwd/w.txt Save New Del /tmp/pardes-snap/tagnav/cwd New Del
-| 1 alpha
+| 1 alpha ls
| 2 beta w.txt
| 3 gamma
|
@@ -140,7 +140,7 @@
|
|
| /tmp/pardes-snap/tagnav/cwd New Del
-|
+| ls
| w.txt
|
|
@@ -156,7 +156,7 @@
== snap up-tag grid=100x30 cursor=36,1
|New Newcol Find Grep Help Tutor Dump NextColor Debug Kill
| /tmp/pardes-snap/tagnav/cwd/w.txt Save New Del /tmp/pardes-snap/tagnav/cwd New Del
-| 1 alpha
+| 1 alpha ls
| 2 beta w.txt
| 3 gamma
|
@@ -171,7 +171,7 @@
|
|
| /tmp/pardes-snap/tagnav/cwd New Del
-|
+| ls
| w.txt
|
|
@@ -187,7 +187,7 @@
== snap up-edge grid=100x30 cursor=0,0
|New Newcol Find Grep Help Tutor Dump NextColor Debug Kill
| /tmp/pardes-snap/tagnav/cwd/w.txt Save New Del /tmp/pardes-snap/tagnav/cwd New Del
-| 1 alpha
+| 1 alpha ls
| 2 beta w.txt
| 3 gamma
|
@@ -202,7 +202,7 @@
|
|
| /tmp/pardes-snap/tagnav/cwd New Del
-|
+| ls
| w.txt
|
|
@@ -218,7 +218,7 @@
== snap topbar-word grid=100x30 cursor=3,0
|New Newcol Find Grep Help Tutor Dump NextColor Debug Kill
| /tmp/pardes-snap/tagnav/cwd/w.txt Save New Del /tmp/pardes-snap/tagnav/cwd New Del
-| 1 alpha
+| 1 alpha ls
| 2 beta w.txt
| 3 gamma
|
@@ -233,7 +233,7 @@
|
|
| /tmp/pardes-snap/tagnav/cwd New Del
-|
+| ls
| w.txt
|
|
@@ -249,7 +249,7 @@
== snap topbar-graphemes grid=100x30 cursor=5,0
|New Newcol Find Grep Help Tutor Dump NextColor Debug Kill
| /tmp/pardes-snap/tagnav/cwd/w.txt Save New Del /tmp/pardes-snap/tagnav/cwd New Del
-| 1 alpha
+| 1 alpha ls
| 2 beta w.txt
| 3 gamma
|
@@ -264,7 +264,7 @@
|
|
| /tmp/pardes-snap/tagnav/cwd New Del
-|
+| ls
| w.txt
|
|
@@ -280,7 +280,7 @@
== snap back-down grid=100x30 cursor=36,1
|New Newcol Find Grep Help Tutor Dump NextColor Debug Kill
| /tmp/pardes-snap/tagnav/cwd/w.txt Save New Del /tmp/pardes-snap/tagnav/cwd New Del
-| 1 alpha
+| 1 alpha ls
| 2 beta w.txt
| 3 gamma
|
@@ -295,7 +295,7 @@
|
|
| /tmp/pardes-snap/tagnav/cwd New Del
-|
+| ls
| w.txt
|
|
@@ -311,7 +311,7 @@
== snap arrows-still-motion grid=100x30 cursor=38,1
|New Newcol Find Grep Help Tutor Dump NextColor Debug Kill
| /tmp/pardes-snap/tagnav/cwd/w.txt Save New Del /tmp/pardes-snap/tagnav/cwd New Del
-| 1 alpha
+| 1 alpha ls
| 2 beta w.txt
| 3 gamma
|
@@ -326,7 +326,7 @@
|
|
| /tmp/pardes-snap/tagnav/cwd New Del
-|
+| ls
| w.txt
|
|
@@ -342,7 +342,7 @@
== snap back-to-body grid=100x30 cursor=7,2
|New Newcol Find Grep Help Tutor Dump NextColor Debug Kill
| /tmp/pardes-snap/tagnav/cwd/w.txt Save New Del /tmp/pardes-snap/tagnav/cwd New Del
-| 1 alpha
+| 1 alpha ls
| 2 beta w.txt
| 3 gamma
|
@@ -357,7 +357,7 @@
|
|
| /tmp/pardes-snap/tagnav/cwd New Del
-|
+| ls
| w.txt
|
|
@@ -388,7 +388,7 @@
|
|
| /tmp/pardes-snap/tagnav/cwd New Del
-|
+| ls
| w.txt
|
|
@@ -404,7 +404,7 @@
== snap tty-tag grid=100x30 cursor=80,1
|New Newcol Find Grep Help Tutor Dump NextColor Debug Kill
| /tmp/pardes-snap/tagnav/cwd/w.txt Save New Del $ /tmp/pardes-snap/tagnav/cwd New Del
-| 1 alpha
+| 1 alpha ls
| 2 beta w.txt
| 3 gamma
|
@@ -419,7 +419,7 @@
|
|
| /tmp/pardes-snap/tagnav/cwd New Del
-|
+| ls
| w.txt
|
|
@@ -450,7 +450,7 @@
|
|
| /tmp/pardes-snap/tagnav/cwd New Del
-|
+| ls
| w.txt
|
|
@@ -481,7 +481,7 @@
|
|
| /tmp/pardes-snap/tagnav/cwd New Del
-|
+| ls
| w.txt
|
|
@@ -512,7 +512,7 @@
|
|
| /tmp/pardes-snap/tagnav/cwd New Del
-|
+| ls
| w.txt
|
|
@@ -543,7 +543,7 @@
|
|
| /tmp/pardes-snap/tagnav/cwd New Del
-|
+| ls
| w.txt
|
|
@@ -574,7 +574,7 @@
|
|
| /tmp/pardes-snap/tagnav/cwd New Del
-|
+| ls
| w.txt
|
|
@@ -590,7 +590,7 @@
== snap topbar-restored grid=100x30 cursor=7,2
|New Newcol Find Grep Help Tutor Dump NextColor Debug Kill
| /tmp/pardes-snap/tagnav/cwd/w.txt Save New Del /tmp/pardes-snap/tagnav/cwd New Del
-| 1 alpha
+| 1 alpha ls
| 2 beta w.txt
| 3 gamma
|
@@ -605,7 +605,7 @@
|
|
| /tmp/pardes-snap/tagnav/cwd New Del
-|
+| ls
| w.txt
|
|
diff --git a/test/snapshots/theme.golden b/test/snapshots/theme.golden
index b7d8d384..d1941f9b 100644
--- a/test/snapshots/theme.golden
+++ b/test/snapshots/theme.golden
@@ -1,7 +1,7 @@
== snap helix grid=100x30 cursor=4,4
|New Newcol Find Grep Help Tutor Dump NextColor Debug Kill
| /tmp/pardes-snap/theme/cwd New Del /tmp/pardes-snap/theme/cwd New Del
-|
+| ls ls
| t.txt t.txt
|
|
@@ -16,7 +16,7 @@
|
|
| /tmp/pardes-snap/theme/cwd New Del
-|
+| ls
| t.txt
|
|
@@ -63,7 +63,7 @@
== snap dark grid=100x30 cursor=4,4
|New Newcol Find Grep Help Tutor Dump NextColor Debug Kill
| /tmp/pardes-snap/theme/cwd New Del /tmp/pardes-snap/theme/cwd New Del
-|
+| ls ls
| t.txt t.txt
|
|
@@ -78,7 +78,7 @@
|
|
| /tmp/pardes-snap/theme/cwd New Del
-|
+| ls
| t.txt
|
|
@@ -125,7 +125,7 @@
== snap acme grid=100x30 cursor=4,4
|New Newcol Find Grep Help Tutor Dump NextColor Debug Kill
| /tmp/pardes-snap/theme/cwd New Del /tmp/pardes-snap/theme/cwd New Del
-|
+| ls ls
| t.txt t.txt
|
|
@@ -140,7 +140,7 @@
|
|
| /tmp/pardes-snap/theme/cwd New Del
-|
+| ls
| t.txt
|
|
@@ -187,7 +187,7 @@
== snap colors-off grid=100x30 cursor=4,4
|New Newcol Find Grep Help Tutor Dump NextColor Debug Kill
| /tmp/pardes-snap/theme/cwd New Del /tmp/pardes-snap/theme/cwd New Del
-|
+| ls ls
| t.txt t.txt
|
|
@@ -202,7 +202,7 @@
|
|
| /tmp/pardes-snap/theme/cwd New Del
-|
+| ls
| t.txt
|
|
@@ -218,7 +218,7 @@
== style colors-off
|0: 0-56 #000000,#eaffff, 57-99 d,#eaffff,
|1: 0-1 #ffffff,#6e4fd0, 2-35 #000000,#eaffff, 36-49 d,#eaffff, 50-51 #ffffff,#383c54, 52-85 #000000,#eaffff, 86-99 d,#eaffff,
-|2: 0-99 d,#ffffea,
+|2: 0-1 d,#ffffea, 2-3 #000000,#ffffea, 4-51 d,#ffffea, 52-53 #000000,#ffffea, 54-99 d,#ffffea,
|3: 0-1 d,#ffffea, 2-6 #000000,#ffffea, 7-51 d,#ffffea, 52-56 #000000,#ffffea, 57-99 d,#ffffea,
|4: 0-99 d,#ffffea,
|5: 0-99 d,#ffffea,
@@ -233,7 +233,7 @@
|14: 0-99 d,#ffffea,
|15: 0-99 d,#ffffea,
|16: 0-1 #ffffff,#383c54, 2-35 #000000,#eaffff, 36-49 d,#eaffff, 50-99 d,#ffffea,
-|17: 0-99 d,#ffffea,
+|17: 0-1 d,#ffffea, 2-3 #000000,#ffffea, 4-99 d,#ffffea,
|18: 0-1 d,#ffffea, 2-6 #000000,#ffffea, 7-99 d,#ffffea,
|19: 0-99 d,#ffffea,
|20: 0-99 d,#ffffea,
@@ -249,7 +249,7 @@
== snap generated grid=100x30 cursor=4,4
|New Newcol Find Grep Help Tutor Dump NextColor Debug Kill
| /tmp/pardes-snap/theme/cwd New Del /tmp/pardes-snap/theme/cwd New Del
-|
+| ls ls
| t.txt t.txt
|
|
@@ -264,7 +264,7 @@
|
|
| /tmp/pardes-snap/theme/cwd New Del
-|
+| ls
| t.txt
|
|
diff --git a/test/snapshots/themesel.golden b/test/snapshots/themesel.golden
index 08d5a271..7303ea55 100644
--- a/test/snapshots/themesel.golden
+++ b/test/snapshots/themesel.golden
@@ -60,7 +60,7 @@
| 11 Theme andromeda
| 12 Theme ao
| 13 Theme ashen
-== snap step-helix grid=100x30 cursor=7,2
+== snap step-helix grid=100x30 cursor=7,17
|New Newcol Find Grep Help Tutor Dump NextColor Debug Kill
| /tmp/pardes-snap/themesel/cwd/t.txt Save New Del
| 1 line 1
@@ -93,8 +93,8 @@
| 13 Theme ashen
== style step-helix
|0: 0-56 #949494,#121212, 57-99 d,#121212,
-|1: 0-1 #ffffff,#626262, 2-79 #949494,#121212, 80-99 d,#121212,
-|2: 0-0 d,#444444, 1-1 d,#080808, 2-6 #949494,#121212, 7-12 #bdbdbd,#080808, 13-99 d,#080808,
+|1: 0-1 #ffffff,#262626, 2-79 #949494,#121212, 80-99 d,#121212,
+|2: 0-0 d,#444444, 1-1 d,#080808, 2-6 #626262,#080808, 7-12 #bdbdbd,#080808, 13-99 d,#080808,
|3: 0-0 d,#444444, 1-1 d,#080808, 2-6 #626262,#080808, 7-12 #bdbdbd,#080808, 13-99 d,#080808,
|4: 0-0 d,#444444, 1-1 d,#080808, 2-6 #626262,#080808, 7-12 #bdbdbd,#080808, 13-99 d,#080808,
|5: 0-0 d,#444444, 1-1 d,#080808, 2-6 #626262,#080808, 7-12 #bdbdbd,#080808, 13-99 d,#080808,
@@ -108,8 +108,8 @@
|13: 0-0 d,#121212, 1-1 d,#080808, 2-6 #626262,#080808, 7-13 #bdbdbd,#080808, 14-99 d,#080808,
|14: 0-0 d,#121212, 1-1 d,#080808, 2-6 #626262,#080808, 7-13 #bdbdbd,#080808, 14-99 d,#080808,
|15: 0-0 d,#121212, 1-1 d,#080808, 2-6 #626262,#080808, 7-13 #bdbdbd,#080808, 14-99 d,#080808,
-|16: 0-1 #ffffff,#262626, 2-79 #949494,#121212, 80-99 d,#121212,
-|17: 0-0 d,#444444, 1-1 d,#080808, 2-6 #626262,#080808, 7-99 #080808,#80a0ff,
+|16: 0-1 #ffffff,#626262, 2-79 #949494,#121212, 80-99 d,#121212,
+|17: 0-0 d,#444444, 1-1 d,#080808, 2-6 #949494,#121212, 7-17 #bdbdbd,#080808, 18-99 d,#080808,
|18: 0-0 d,#121212, 1-1 d,#080808, 2-6 #626262,#080808, 7-16 #bdbdbd,#080808, 17-99 d,#080808,
|19: 0-0 d,#121212, 1-1 d,#080808, 2-6 #626262,#080808, 7-16 #bdbdbd,#080808, 17-99 d,#080808,
|20: 0-0 d,#121212, 1-1 d,#080808, 2-6 #626262,#080808, 7-16 #bdbdbd,#080808, 17-99 d,#080808,
@@ -122,7 +122,7 @@
|27: 0-0 d,#121212, 1-1 d,#080808, 2-6 #626262,#080808, 7-21 #bdbdbd,#080808, 22-99 d,#080808,
|28: 0-0 d,#121212, 1-1 d,#080808, 2-6 #626262,#080808, 7-14 #bdbdbd,#080808, 15-99 d,#080808,
|29: 0-0 d,#121212, 1-1 d,#080808, 2-6 #626262,#080808, 7-17 #bdbdbd,#080808, 18-99 d,#080808,
-== snap step-dark grid=100x30 cursor=7,2
+== snap step-dark grid=100x30 cursor=7,18
|New Newcol Find Grep Help Tutor Dump NextColor Debug Kill
| /tmp/pardes-snap/themesel/cwd/t.txt Save New Del
| 1 line 1
@@ -155,8 +155,8 @@
| 13 Theme ashen
== style step-dark
|0: 0-56 #969696,#2c2a3e, 57-99 d,#2c2a3e,
-|1: 0-1 #ffffff,#6e4fd0, 2-79 #969696,#2c2a3e, 80-99 d,#2c2a3e,
-|2: 0-0 d,#525252, 1-1 d,d, 2-6 #969696,#2c2a3e, 7-99 d,d,
+|1: 0-1 #ffffff,#383c54, 2-79 #969696,#2c2a3e, 80-99 d,#2c2a3e,
+|2: 0-0 d,#525252, 1-1 d,d, 2-6 #5a5a5a,d, 7-99 d,d,
|3: 0-0 d,#525252, 1-1 d,d, 2-6 #5a5a5a,d, 7-99 d,d,
|4: 0-0 d,#525252, 1-1 d,d, 2-6 #5a5a5a,d, 7-99 d,d,
|5: 0-0 d,#525252, 1-1 d,d, 2-6 #5a5a5a,d, 7-99 d,d,
@@ -170,9 +170,9 @@
|13: 0-0 d,#2a2a2a, 1-1 d,d, 2-6 #5a5a5a,d, 7-99 d,d,
|14: 0-0 d,#2a2a2a, 1-1 d,d, 2-6 #5a5a5a,d, 7-99 d,d,
|15: 0-0 d,#2a2a2a, 1-1 d,d, 2-6 #5a5a5a,d, 7-99 d,d,
-|16: 0-1 #ffffff,#383c54, 2-79 #969696,#2c2a3e, 80-99 d,#2c2a3e,
+|16: 0-1 #ffffff,#6e4fd0, 2-79 #969696,#2c2a3e, 80-99 d,#2c2a3e,
|17: 0-0 d,#525252, 1-1 d,d, 2-6 #5a5a5a,d, 7-99 d,d,
-|18: 0-0 d,#2a2a2a, 1-1 d,d, 2-6 #5a5a5a,d, 7-99 #d8c8a8,#4a3a1e,
+|18: 0-0 d,#2a2a2a, 1-1 d,d, 2-6 #969696,#2c2a3e, 7-99 d,d,
|19: 0-0 d,#2a2a2a, 1-1 d,d, 2-6 #5a5a5a,d, 7-99 d,d,
|20: 0-0 d,#2a2a2a, 1-1 d,d, 2-6 #5a5a5a,d, 7-99 d,d,
|21: 0-0 d,#2a2a2a, 1-1 d,d, 2-6 #5a5a5a,d, 7-99 d,d,
@@ -184,7 +184,7 @@
|27: 0-0 d,#2a2a2a, 1-1 d,d, 2-6 #5a5a5a,d, 7-99 d,d,
|28: 0-0 d,#2a2a2a, 1-1 d,d, 2-6 #5a5a5a,d, 7-99 d,d,
|29: 0-0 d,#2a2a2a, 1-1 d,d, 2-6 #5a5a5a,d, 7-99 d,d,
-== snap step-acme grid=100x30 cursor=7,2
+== snap step-acme grid=100x30 cursor=7,19
|New Newcol Find Grep Help Tutor Dump NextColor Debug Kill
| /tmp/pardes-snap/themesel/cwd/t.txt Save New Del
| 1 line 1
@@ -217,8 +217,8 @@
| 13 Theme ashen
== style step-acme
|0: 0-56 #000000,#eaffff, 57-99 d,#eaffff,
-|1: 0-1 #ffffff,#6e4fd0, 2-79 #000000,#eaffff, 80-99 d,#eaffff,
-|2: 0-1 d,#ffffea, 2-6 #000000,#eaffff, 7-12 #000000,#ffffea, 13-99 d,#ffffea,
+|1: 0-1 #ffffff,#383c54, 2-79 #000000,#eaffff, 80-99 d,#eaffff,
+|2: 0-1 d,#ffffea, 2-6 #999980,#ffffea, 7-12 #000000,#ffffea, 13-99 d,#ffffea,
|3: 0-1 d,#ffffea, 2-6 #999980,#ffffea, 7-12 #000000,#ffffea, 13-99 d,#ffffea,
|4: 0-1 d,#ffffea, 2-6 #999980,#ffffea, 7-12 #000000,#ffffea, 13-99 d,#ffffea,
|5: 0-1 d,#ffffea, 2-6 #999980,#ffffea, 7-12 #000000,#ffffea, 13-99 d,#ffffea,
@@ -232,10 +232,10 @@
|13: 0-0 d,#99994c, 1-1 d,#ffffea, 2-6 #999980,#ffffea, 7-13 #000000,#ffffea, 14-99 d,#ffffea,
|14: 0-0 d,#99994c, 1-1 d,#ffffea, 2-6 #999980,#ffffea, 7-13 #000000,#ffffea, 14-99 d,#ffffea,
|15: 0-0 d,#99994c, 1-1 d,#ffffea, 2-6 #999980,#ffffea, 7-13 #000000,#ffffea, 14-99 d,#ffffea,
-|16: 0-1 #ffffff,#383c54, 2-79 #000000,#eaffff, 80-99 d,#eaffff,
+|16: 0-1 #ffffff,#6e4fd0, 2-79 #000000,#eaffff, 80-99 d,#eaffff,
|17: 0-1 d,#ffffea, 2-6 #999980,#ffffea, 7-17 #000000,#ffffea, 18-99 d,#ffffea,
|18: 0-0 d,#99994c, 1-1 d,#ffffea, 2-6 #999980,#ffffea, 7-16 #000000,#ffffea, 17-99 d,#ffffea,
-|19: 0-0 d,#99994c, 1-1 d,#ffffea, 2-6 #999980,#ffffea, 7-99 #000000,#eeee9e,
+|19: 0-0 d,#99994c, 1-1 d,#ffffea, 2-6 #000000,#eaffff, 7-16 #000000,#ffffea, 17-99 d,#ffffea,
|20: 0-0 d,#99994c, 1-1 d,#ffffea, 2-6 #999980,#ffffea, 7-16 #000000,#ffffea, 17-99 d,#ffffea,
|21: 0-0 d,#99994c, 1-1 d,#ffffea, 2-6 #999980,#ffffea, 7-22 #000000,#ffffea, 23-99 d,#ffffea,
|22: 0-0 d,#99994c, 1-1 d,#ffffea, 2-6 #999980,#ffffea, 7-24 #000000,#ffffea, 25-99 d,#ffffea,
@@ -246,7 +246,7 @@
|27: 0-0 d,#99994c, 1-1 d,#ffffea, 2-6 #999980,#ffffea, 7-21 #000000,#ffffea, 22-99 d,#ffffea,
|28: 0-0 d,#99994c, 1-1 d,#ffffea, 2-6 #999980,#ffffea, 7-14 #000000,#ffffea, 15-99 d,#ffffea,
|29: 0-0 d,#99994c, 1-1 d,#ffffea, 2-6 #999980,#ffffea, 7-17 #000000,#ffffea, 18-99 d,#ffffea,
-== snap step-generated grid=100x30 cursor=7,2
+== snap step-generated grid=100x30 cursor=7,20
|New Newcol Find Grep Help Tutor Dump NextColor Debug Kill
| /tmp/pardes-snap/themesel/cwd/t.txt Save New Del
| 1 line 1
@@ -279,8 +279,8 @@
| 13 Theme ashen
== style step-generated
|0: 0-56 #e0e0e0,#1e262e, 57-99 d,#1e262e,
-|1: 0-1 #000000,#ffa060, 2-79 #e0e0e0,#1e262e, 80-99 d,#1e262e,
-|2: 0-0 d,#303840, 1-1 d,#161e26, 2-6 #e0e0e0,#1e262e, 7-12 #e0e0e0,#161e26, 13-99 d,#161e26,
+|1: 0-1 #ffffff,#303840, 2-79 #e0e0e0,#1e262e, 80-99 d,#1e262e,
+|2: 0-0 d,#303840, 1-1 d,#161e26, 2-6 #303840,#161e26, 7-12 #e0e0e0,#161e26, 13-99 d,#161e26,
|3: 0-0 d,#303840, 1-1 d,#161e26, 2-6 #303840,#161e26, 7-12 #e0e0e0,#161e26, 13-99 d,#161e26,
|4: 0-0 d,#303840, 1-1 d,#161e26, 2-6 #303840,#161e26, 7-12 #e0e0e0,#161e26, 13-99 d,#161e26,
|5: 0-0 d,#303840, 1-1 d,#161e26, 2-6 #303840,#161e26, 7-12 #e0e0e0,#161e26, 13-99 d,#161e26,
@@ -294,11 +294,11 @@
|13: 0-0 d,#1e262e, 1-1 d,#161e26, 2-6 #303840,#161e26, 7-13 #e0e0e0,#161e26, 14-99 d,#161e26,
|14: 0-0 d,#1e262e, 1-1 d,#161e26, 2-6 #303840,#161e26, 7-13 #e0e0e0,#161e26, 14-99 d,#161e26,
|15: 0-0 d,#1e262e, 1-1 d,#161e26, 2-6 #303840,#161e26, 7-13 #e0e0e0,#161e26, 14-99 d,#161e26,
-|16: 0-1 #ffffff,#303840, 2-79 #e0e0e0,#1e262e, 80-99 d,#1e262e,
+|16: 0-1 #000000,#ffa060, 2-79 #e0e0e0,#1e262e, 80-99 d,#1e262e,
|17: 0-0 d,#303840, 1-1 d,#161e26, 2-6 #303840,#161e26, 7-17 #e0e0e0,#161e26, 18-99 d,#161e26,
|18: 0-0 d,#1e262e, 1-1 d,#161e26, 2-6 #303840,#161e26, 7-16 #e0e0e0,#161e26, 17-99 d,#161e26,
|19: 0-0 d,#1e262e, 1-1 d,#161e26, 2-6 #303840,#161e26, 7-16 #e0e0e0,#161e26, 17-99 d,#161e26,
-|20: 0-0 d,#1e262e, 1-1 d,#161e26, 2-6 #303840,#161e26, 7-99 #e0e0e0,#303840,
+|20: 0-0 d,#1e262e, 1-1 d,#161e26, 2-6 #e0e0e0,#1e262e, 7-16 #e0e0e0,#161e26, 17-99 d,#161e26,
|21: 0-0 d,#1e262e, 1-1 d,#161e26, 2-6 #303840,#161e26, 7-22 #e0e0e0,#161e26, 23-99 d,#161e26,
|22: 0-0 d,#1e262e, 1-1 d,#161e26, 2-6 #303840,#161e26, 7-24 #e0e0e0,#161e26, 25-99 d,#161e26,
|23: 0-0 d,#1e262e, 1-1 d,#161e26, 2-6 #303840,#161e26, 7-25 #e0e0e0,#161e26, 26-99 d,#161e26,
@@ -308,7 +308,7 @@
|27: 0-0 d,#1e262e, 1-1 d,#161e26, 2-6 #303840,#161e26, 7-21 #e0e0e0,#161e26, 22-99 d,#161e26,
|28: 0-0 d,#1e262e, 1-1 d,#161e26, 2-6 #303840,#161e26, 7-14 #e0e0e0,#161e26, 15-99 d,#161e26,
|29: 0-0 d,#1e262e, 1-1 d,#161e26, 2-6 #303840,#161e26, 7-17 #e0e0e0,#161e26, 18-99 d,#161e26,
-== snap step-back grid=100x30 cursor=7,2
+== snap step-back grid=100x30 cursor=7,19
|New Newcol Find Grep Help Tutor Dump NextColor Debug Kill
| /tmp/pardes-snap/themesel/cwd/t.txt Save New Del
| 1 line 1
@@ -341,8 +341,8 @@
| 13 Theme ashen
== style step-back
|0: 0-56 #000000,#eaffff, 57-99 d,#eaffff,
-|1: 0-1 #ffffff,#6e4fd0, 2-79 #000000,#eaffff, 80-99 d,#eaffff,
-|2: 0-1 d,#ffffea, 2-6 #000000,#eaffff, 7-12 #000000,#ffffea, 13-99 d,#ffffea,
+|1: 0-1 #ffffff,#383c54, 2-79 #000000,#eaffff, 80-99 d,#eaffff,
+|2: 0-1 d,#ffffea, 2-6 #999980,#ffffea, 7-12 #000000,#ffffea, 13-99 d,#ffffea,
|3: 0-1 d,#ffffea, 2-6 #999980,#ffffea, 7-12 #000000,#ffffea, 13-99 d,#ffffea,
|4: 0-1 d,#ffffea, 2-6 #999980,#ffffea, 7-12 #000000,#ffffea, 13-99 d,#ffffea,
|5: 0-1 d,#ffffea, 2-6 #999980,#ffffea, 7-12 #000000,#ffffea, 13-99 d,#ffffea,
@@ -356,10 +356,10 @@
|13: 0-0 d,#99994c, 1-1 d,#ffffea, 2-6 #999980,#ffffea, 7-13 #000000,#ffffea, 14-99 d,#ffffea,
|14: 0-0 d,#99994c, 1-1 d,#ffffea, 2-6 #999980,#ffffea, 7-13 #000000,#ffffea, 14-99 d,#ffffea,
|15: 0-0 d,#99994c, 1-1 d,#ffffea, 2-6 #999980,#ffffea, 7-13 #000000,#ffffea, 14-99 d,#ffffea,
-|16: 0-1 #ffffff,#383c54, 2-79 #000000,#eaffff, 80-99 d,#eaffff,
+|16: 0-1 #ffffff,#6e4fd0, 2-79 #000000,#eaffff, 80-99 d,#eaffff,
|17: 0-1 d,#ffffea, 2-6 #999980,#ffffea, 7-17 #000000,#ffffea, 18-99 d,#ffffea,
|18: 0-0 d,#99994c, 1-1 d,#ffffea, 2-6 #999980,#ffffea, 7-16 #000000,#ffffea, 17-99 d,#ffffea,
-|19: 0-0 d,#99994c, 1-1 d,#ffffea, 2-6 #999980,#ffffea, 7-99 #000000,#eeee9e,
+|19: 0-0 d,#99994c, 1-1 d,#ffffea, 2-6 #000000,#eaffff, 7-16 #000000,#ffffea, 17-99 d,#ffffea,
|20: 0-0 d,#99994c, 1-1 d,#ffffea, 2-6 #999980,#ffffea, 7-16 #000000,#ffffea, 17-99 d,#ffffea,
|21: 0-0 d,#99994c, 1-1 d,#ffffea, 2-6 #999980,#ffffea, 7-22 #000000,#ffffea, 23-99 d,#ffffea,
|22: 0-0 d,#99994c, 1-1 d,#ffffea, 2-6 #999980,#ffffea, 7-24 #000000,#ffffea, 25-99 d,#ffffea,
diff --git a/test/snapshots/themesel.snap b/test/snapshots/themesel.snap
index d714fa84..cff136f1 100644
--- a/test/snapshots/themesel.snap
+++ b/test/snapshots/themesel.snap
@@ -1,10 +1,14 @@
# RULE: a results buffer is a list of things you can RUN, and its traits say
-# which verb runs them. Every list before this one held LOCATIONS, so stepping
-# a row with n/N Looks it. `SPC t t` (ThemeSel) opens the first one whose rows
-# are COMMANDS — `Theme <name>`, exactly the line you would type — so n/N Exec
-# each row instead. Walking the list therefore wears the themes as you pass
-# them, and picking one is stopping on it: there is no preview state, nothing
-# to confirm and nothing to cancel, because arriving already did it.
+# what a ROW IS. Every list before this one held LOCATIONS — a row with a
+# `path:LINE:COL` word inside it — so n/N select that word and Enter Looks it.
+# `SPC t t` (ThemeSel) opens the first one whose rows are COMMANDS: `Theme
+# <name>`, exactly the line you would type, with no path in it to pick out, so
+# n/N select the WHOLE ROW. One motion, two grains, and the same split either
+# way — the step only SELECTS, and Tab (Exec, or the middle button, which is
+# the same builtin) is what RUNS what it left. Walking the list therefore
+# wears nothing as you pass; the theme changes on the Tab, and picking one is
+# running it and stopping. There is still no preview state, nothing to confirm
+# and nothing to cancel: the row you ran is the theme you have.
#
# Both halves of the ring are in the buffer: the three pardes ships with come
# first (helix, dark, acme), then everything tools/gen_themes.zig exported from
@@ -16,25 +20,29 @@ start 30 100 t.txt
wait 8000 t.txt
stable 700 20000
snap boot
-# SPC t t: the list lands below the pane that asked, focus stays HERE — n/N are
-# read in this pane and they step the buffer they just armed.
+# SPC t t: the list lands below the pane that asked, focus stays HERE — but a
+# fresh output buffer is where the walk's ring starts, so the first n goes
+# into the list and every one after it carries on down it.
key space t t
wait 10000 Theme helix
stable 700 15000
snap list
-# n selects row 1 and runs it: `Theme helix`, which is already the boot theme,
-# so only the selection moves. That is the honest first step — an idempotent
-# command has to be safe to step onto.
+# n selects row 1 whole and Tab runs it: `Theme helix`, which is already the
+# boot theme, so only the selection moves. That is the honest first step — an
+# idempotent command has to be safe to run.
key n
+key tab
stable 700 15000
snap step-helix
snapstyle step-helix
# ...and now the theme really does change under the cursor, one row at a time
key n
+key tab
stable 700 15000
snap step-dark
snapstyle step-dark
key n
+key tab
stable 700 15000
snap step-acme
snapstyle step-acme
@@ -43,24 +51,27 @@ snapstyle step-acme
# vendored first. That is the point of sorting: the ring is the same everywhere
# whatever order the directory read handed the files over in.
key n
+key tab
stable 700 15000
snap step-generated
snapstyle step-generated
-# N walks back the same way, running the row it lands on — so the theme
-# rewinds too
+# N walks back the same way — it is the exact inverse of n — and the Tab after
+# it runs the row it lands on, so the theme rewinds too
key N
+key tab
stable 700 15000
snap step-back
snapstyle step-back
-# PICKING is just stopping. Walk down into the list and explicitly Del it: the
-# theme the last step left behind is still on. Body-normal Esc is Last,
-# so it deliberately leaves this document-like output buffer open.
-key space w j
-stable 400 5000
+# PICKING is just stopping: the theme the last Tab ran is still on, and the
+# list is closed with an explicit Del. No window move is needed to get there —
+# the walk lands IN the pane it steps, so the cursor has been in the list
+# since the first n. Body-normal Esc is Last, so it deliberately leaves this
+# document-like output buffer open.
# ...and the WHOLE ring is in there, all 228 rows: `ge` to the last line, which
# only reaches `Theme zenburn` if nothing truncated the buffer on the way in. It
-# is an ordinary file pane, so it scrolls like one; a motion is not a step, so
-# no theme is run and the one step-back chose is still on.
+# is an ordinary file pane, so it scrolls like one; a motion runs nothing and
+# neither does a step, so no theme changes here and the one the last Tab chose
+# is still on.
key g e
stable 700 15000
snap tail
diff --git a/test/snapshots/tinywin.golden b/test/snapshots/tinywin.golden
index 6e085aa9..36d1af12 100644
--- a/test/snapshots/tinywin.golden
+++ b/test/snapshots/tinywin.golden
@@ -3,16 +3,16 @@
|$ /tmp/pardes-snap/tinywin/cwd New Del
| $
| /tmp/pardes-snap/tinywin/cwd New Del
-|
+| ls
|
| /tmp/pardes-snap/tinywin/cwd New Del
-|
+| ls
|
| /tmp/pardes-snap/tinywin/cwd New Del
-|
+| ls
|
| /tmp/pardes-snap/tinywin/cwd New Del
-|
+| ls
|
|
|
@@ -36,18 +36,18 @@
== snap columns grid=100x30 cursor=79,3
|New Newcol Find Grep Help Tutor Dump NextColor Debug Kill
|$ /tmp/pardes-snap/tinywi /tmp/pardes-snap/tinywi /tmp/pardes-snap/tinywi /tmp/pardes-snap/tinywi
-| $
+| $ ls ls ls
| /tmp/pardes-snap/tinywi
-|
+| ls
|
| /tmp/pardes-snap/tinywi
-|
+| ls
|
| /tmp/pardes-snap/tinywi
-|
+| ls
|
| /tmp/pardes-snap/tinywi
-|
+| ls
|
|
|
diff --git a/test/snapshots/topbarexec.golden b/test/snapshots/topbarexec.golden
index ed996103..bed96fbd 100644
--- a/test/snapshots/topbarexec.golden
+++ b/test/snapshots/topbarexec.golden
@@ -1,7 +1,7 @@
== snap selected grid=90x20 cursor=14,3
|New Newcol Find Grep Help Tutor Dump NextColor Debug Kill
| /tmp/pardes-snap/topbarexec/cwd New Del /tmp/pardes-snap/topbarexec/cwd New Del
-|
+| ls ls
| zmarkfile.txt zmarkfile.txt
|
|
@@ -11,7 +11,7 @@
|
|
| /tmp/pardes-snap/topbarexec/cwd New Del
-|
+| ls
| zmarkfile.txt
|
|
@@ -22,7 +22,7 @@
== snap noarg-runs grid=90x20 cursor=14,3
|New Newcol Find Grep Help Tutor Dump NextColor Debug Kill
| /tmp/pardes-snap/topbarexec/cwd New Del /tmp/pardes-s╭────────────────────────────╮
-| │pardes resizes=1 │
+| ls ls │pardes resizes=1 │
| zmarkfile.txt zmarkfile.txt│terms 3 cols 2 │
| │active #0 43x9 │
| │scroll 0/9 │
@@ -32,7 +32,7 @@
|
|
| /tmp/pardes-snap/topbarexec/cwd New Del
-|
+| ls
| zmarkfile.txt
|
|
@@ -43,7 +43,7 @@
== snap arg-still-spliced grid=90x20 cursor=14,3
|New Newcol Find Grep Help Tutor Dump NextColor Debug Kill
| /tmp/pardes-snap/topbarexec/cwd New Del /tmp/pardes-snap/topbarexec/cwd New Del
-|
+| ls ls
| zmarkfile.txt zmarkfile.txt
|
|
@@ -53,7 +53,7 @@
| /tmp/pardes-snap/topbarexec/cwd/+Search New
| 1 zmarkfile.txt
| /tmp/pardes-snap/topbarexec/cwd New Del
-|
+| ls
| zmarkfile.txt
|
|
diff --git a/test/snapshots/tty.golden b/test/snapshots/tty.golden
index f15afcb9..3b4d08c1 100644
--- a/test/snapshots/tty.golden
+++ b/test/snapshots/tty.golden
@@ -1,7 +1,7 @@
== snap tty-on grid=100x30 cursor=4,4
|New Newcol Find Grep Help Tutor Dump NextColor Debug Kill
|$ /tmp/pardes-snap/tty/cwd New Del /tmp/pardes-snap/tty/cwd New Del
-| $ ls
+| $ ls ls
| m.txt m.txt
| $
|
@@ -16,7 +16,7 @@
|
|
| /tmp/pardes-snap/tty/cwd New Del
-|
+| ls
| m.txt
|
|
@@ -32,7 +32,7 @@
== snap tty-echo grid=100x30 cursor=4,6
|New Newcol Find Grep Help Tutor Dump NextColor Debug Kill
|$ /tmp/pardes-snap/tty/cwd New Del /tmp/pardes-snap/tty/cwd New Del
-| $ ls
+| $ ls ls
| m.txt m.txt
| $ echo SNAP''OK
| SNAPOK
@@ -47,7 +47,7 @@
|
|
| /tmp/pardes-snap/tty/cwd New Del
-|
+| ls
| m.txt
|
|
@@ -63,9 +63,9 @@
== snap tty-off grid=100x30 cursor=4,6
|New Newcol Find Grep Help Tutor Dump NextColor Debug Kill
| /tmp/pardes-snap/tty/cwd New Del /tmp/pardes-snap/tty/cwd New Del
-|
+| ls ls
| m.txt m.txt
-|
+| echo SNAP''OK
| SNAPOK
|
|
@@ -78,7 +78,7 @@
|
|
| /tmp/pardes-snap/tty/cwd New Del
-|
+| ls
| m.txt
|
|
@@ -94,7 +94,7 @@
== snap shift-esc-on grid=100x30 cursor=4,6
|New Newcol Find Grep Help Tutor Dump NextColor Debug Kill
|$ /tmp/pardes-snap/tty/cwd New Del /tmp/pardes-snap/tty/cwd New Del
-| $ ls
+| $ ls ls
| m.txt m.txt
| $ echo SNAP''OK
| SNAPOK
@@ -109,7 +109,7 @@
|
|
| /tmp/pardes-snap/tty/cwd New Del
-|
+| ls
| m.txt
|
|
@@ -125,7 +125,7 @@
== snap shift-esc-nodoc grid=100x30 cursor=4,6
|New Newcol Find Grep Help Tutor Dump NextColor Debug Kill
|$ /tmp/pardes-snap/tty/cwd New Del /tmp/pardes-snap/tty/cwd New Del
-| $ ls
+| $ ls ls
| m.txt m.txt
| $ echo SNAP''OK
| SNAPOK
@@ -140,7 +140,7 @@
|
|
| /tmp/pardes-snap/tty/cwd New Del
-|
+| ls
| m.txt
|
|
@@ -156,9 +156,9 @@
== snap ctrl-b-off grid=100x30 cursor=4,6
|New Newcol Find Grep Help Tutor Dump NextColor Debug Kill
| /tmp/pardes-snap/tty/cwd New Del /tmp/pardes-snap/tty/cwd New Del
-|
+| ls ls
| m.txt m.txt
-|
+| echo SNAP''OK
| SNAPOK
|
|
@@ -171,7 +171,7 @@
|
|
| /tmp/pardes-snap/tty/cwd New Del
-|
+| ls
| m.txt
|
|
diff --git a/test/snapshots/ttyclick.golden b/test/snapshots/ttyclick.golden
index a2d579ec..149073f7 100644
--- a/test/snapshots/ttyclick.golden
+++ b/test/snapshots/ttyclick.golden
@@ -1,7 +1,7 @@
== snap tty-bodyclick grid=100x30 cursor=4,4
|New Newcol Find Grep Help Tutor Dump NextColor Debug Kill
|$ /tmp/pardes-snap/ttyclick/cwd New Del /tmp/pardes-snap/ttyclick/cwd New Del
-| $ ls
+| $ ls ls
| probe.txt probe.txt
| $
|
@@ -16,7 +16,7 @@
|
|
| /tmp/pardes-snap/ttyclick/cwd New Del
-|
+| ls
| probe.txt
|
|
@@ -32,7 +32,7 @@
== snap tty-tagedit grid=100x30 cursor=39,1
|New Newcol Find Grep Help Tutor Dump NextColor Debug Kill
|$ /tmp/pardes-snap/ttyclick/cwd New Del /tmp/pardes-snap/ttyclick/cwd New Del
-|
+| ls ls
| probe.txt probe.txt
|
|
@@ -47,7 +47,7 @@
|
|
| /tmp/pardes-snap/ttyclick/cwd New Del
-|
+| ls
| probe.txt
|
|
@@ -63,7 +63,7 @@
== snap tty-tagexit grid=100x30 cursor=4,4
|New Newcol Find Grep Help Tutor Dump NextColor Debug Kill
|$ /tmp/pardes-snap/ttyclick/cwd New Del /tmp/pardes-snap/ttyclick/cwd New Del
-| $ ls
+| $ ls ls
| probe.txt probe.txt
| $
|
@@ -78,7 +78,7 @@
|
|
| /tmp/pardes-snap/ttyclick/cwd New Del
-|
+| ls
| probe.txt
|
|
@@ -94,7 +94,7 @@
== snap ins-bodyclick grid=100x30 cursor=11,3
|New Newcol Find Grep Help Tutor Dump NextColor Debug Kill
|^ /tmp/pardes-snap/ttyclick/cwd New Del /tmp/pardes-snap/ttyclick/cwd New Del
-|
+| ls ls
| probe.txt probe.txt
|
|
@@ -109,7 +109,7 @@
|
|
| /tmp/pardes-snap/ttyclick/cwd New Del
-|
+| ls
| probe.txt
|
|
diff --git a/test/snapshots/ttyedit.golden b/test/snapshots/ttyedit.golden
index 37982bb4..c0a190d8 100644
--- a/test/snapshots/ttyedit.golden
+++ b/test/snapshots/ttyedit.golden
@@ -1,10 +1,10 @@
== snap before grid=100x30 cursor=7,6
|New Newcol Find Grep Help Tutor Dump NextColor Debug Kill
| /tmp/pardes-snap/ttyedit/cwd New Del /tmp/pardes-snap/ttyedit/cwd New Del
-|
+| ls ls
| words.txt words.txt
-|
-|
+| printf 'one two three\nfour five six\nseven ei
+| ght nine\n'
| one two three
| four five six
| seven eight nine
@@ -16,7 +16,7 @@
|
|
| /tmp/pardes-snap/ttyedit/cwd New Del
-|
+| ls
| words.txt
|
|
@@ -32,10 +32,10 @@
== snap split grid=100x30 cursor=2,7
|New Newcol Find Grep Help Tutor Dump NextColor Debug Kill
|^ /tmp/pardes-snap/ttyedit/cwd New Del /tmp/pardes-snap/ttyedit/cwd New Del
-|
+| ls ls
| words.txt words.txt
-|
-|
+| printf 'one two three\nfour five six\nseven ei
+| ght nine\n'
| one t
| wo three
| four five six
@@ -47,7 +47,7 @@
|
|
| /tmp/pardes-snap/ttyedit/cwd New Del
-|
+| ls
| words.txt
|
|
@@ -63,10 +63,10 @@
== snap opened grid=100x30 cursor=6,8
|New Newcol Find Grep Help Tutor Dump NextColor Debug Kill
| /tmp/pardes-snap/ttyedit/cwd New Del /tmp/pardes-snap/ttyedit/cwd New Del
-|
+| ls ls
| words.txt words.txt
-|
-|
+| printf 'one two three\nfour five six\nseven ei
+| ght nine\n'
| one t
| wo three
| OPEN
@@ -78,7 +78,7 @@
|
|
| /tmp/pardes-snap/ttyedit/cwd New Del
-|
+| ls
| words.txt
|
|
@@ -94,10 +94,10 @@
== snap joined grid=100x30 cursor=10,7
|New Newcol Find Grep Help Tutor Dump NextColor Debug Kill
| /tmp/pardes-snap/ttyedit/cwd New Del /tmp/pardes-snap/ttyedit/cwd New Del
-|
+| ls ls
| words.txt words.txt
-|
-|
+| printf 'one two three\nfour five six\nseven ei
+| ght nine\n'
| one t
| wo threeOPEN
| four five six
@@ -109,7 +109,7 @@
|
|
| /tmp/pardes-snap/ttyedit/cwd New Del
-|
+| ls
| words.txt
|
|
@@ -125,10 +125,10 @@
== snap undone grid=100x30 cursor=7,6
|New Newcol Find Grep Help Tutor Dump NextColor Debug Kill
| /tmp/pardes-snap/ttyedit/cwd New Del /tmp/pardes-snap/ttyedit/cwd New Del
-|
+| ls ls
| words.txt words.txt
-|
-|
+| printf 'one two three\nfour five six\nseven ei
+| ght nine\n'
| one two three
| four five six
| seven eight nine
@@ -140,7 +140,7 @@
|
|
| /tmp/pardes-snap/ttyedit/cwd New Del
-|
+| ls
| words.txt
|
|
diff --git a/test/snapshots/ttyfollow.golden b/test/snapshots/ttyfollow.golden
index b21549a0..4fcc0741 100644
--- a/test/snapshots/ttyfollow.golden
+++ b/test/snapshots/ttyfollow.golden
@@ -1,7 +1,7 @@
== snap held-pre grid=100x30 cursor=4,15
|New Newcol Find Grep Help Tutor Dump NextColor Debug Kill
| /tmp/pardes-snap/ttyfollow/cwd New Del /tmp/pardes-snap/ttyfollow/cwd New Del
-| 185
+| 185 ls
| 186 s.txt
| 187
| 188
@@ -16,7 +16,7 @@
| 197
| 198
| /tmp/pardes-snap/ttyfollow/cwd New Del
-|
+| ls
| s.txt
|
|
@@ -47,7 +47,7 @@
| 197
| 198
| /tmp/pardes-snap/ttyfollow/cwd New Del
-|
+| ls
| s.txt
|
|
@@ -78,7 +78,7 @@
| 300
| $
| /tmp/pardes-snap/ttyfollow/cwd New Del
-|
+| ls
| s.txt
|
|
diff --git a/test/snapshots/ttyhelp.golden b/test/snapshots/ttyhelp.golden
index a580263b..7895d83e 100644
--- a/test/snapshots/ttyhelp.golden
+++ b/test/snapshots/ttyhelp.golden
@@ -38,28 +38,28 @@
| 2 SPC and its keys, a chord, a button, the
| 3 topbar - or the name, executed anywhere.
| 4
-| 5 SPC ? Help topbar
-| 6 SPC c d Delcol
-| 7 SPC c n Newcol topbar
-| 8 SPC d Del
-| 9 SPC f c Config
-| 10 SPC f f Find topbar
-| 11 SPC f g Grep topbar
-| 12 SPC f n New topbar
-| 13 SPC f s Save
-| 14 SPC h t Tutor topbar
-| 15 SPC j i Forward C-i
-| 16 SPC j j Last
-| 17 SPC j l Jumplist
-| 18 SPC j o Back C-o
-| 19 SPC k Kill topbar
-| 20 SPC l D WsDiagnostics
-| 21 SPC l S WsSymbols
-| 22 SPC l a CodeAction
-| 23 SPC l d Diagnostics
-| 24 SPC l h SelectRefs
-| 25 SPC l i Lspinfo
-| 26 SPC l k Hover
+| 5 SPC ? Help topbar
+| 6 SPC P ClipPasteBefore
+| 7 SPC R ClipReplace
+| 8 SPC Y ClipYankMain
+| 9 SPC c d Delcol
+| 10 SPC c n Newcol topbar
+| 11 SPC d Del
+| 12 SPC f c Config
+| 13 SPC f f Find topbar
+| 14 SPC f g Grep topbar
+| 15 SPC f n New topbar
+| 16 SPC f s Save
+| 17 SPC h t Tutor topbar
+| 18 SPC j i Forward C-i
+| 19 SPC j j Last
+| 20 SPC j l Jumplist
+| 21 SPC j o Back C-o
+| 22 SPC k Kill topbar
+| 23 SPC l D WsDiagnostics
+| 24 SPC l S WsSymbols
+| 25 SPC l a CodeAction
+| 26 SPC l d Diagnostics
== snap leaderworks grid=100x30 cursor=7,4
|New Newcol Find Grep Help Tutor Dump NextColor Debug Kill
|$ /tmp/pardes-snap/ttyhelp/cwd New Del
@@ -69,25 +69,25 @@
| 2 SPC and its keys, a chord, a button, the
| 3 topbar - or the name, executed anywhere.
| 4
-| 5 SPC ? Help topbar
-| 6 SPC c d Delcol
-| 7 SPC c n Newcol topbar
-| 8 SPC d Del
-| 9 SPC f c Config
-| 10 SPC f f Find topbar
-| 11 SPC f g Grep topbar
-| 12 SPC f n New topbar
-| 13 SPC f s Save
-| 14 SPC h t Tutor topbar
-| 15 SPC j i Forward C-i
-| 16 SPC j j Last
-| 17 SPC j l Jumplist
-| 18 SPC j o Back C-o
-| 19 SPC k Kill topbar
-| 20 SPC l D WsDiagnostics
-| 21 SPC l S WsSymbols
-| 22 SPC l a CodeAction
-| 23 SPC l d Diagnostics
-| 24 SPC l h SelectRefs
-| 25 SPC l i Lspinfo
-| 26 SPC l k Hover
+| 5 SPC ? Help topbar
+| 6 SPC P ClipPasteBefore
+| 7 SPC R ClipReplace
+| 8 SPC Y ClipYankMain
+| 9 SPC c d Delcol
+| 10 SPC c n Newcol topbar
+| 11 SPC d Del
+| 12 SPC f c Config
+| 13 SPC f f Find topbar
+| 14 SPC f g Grep topbar
+| 15 SPC f n New topbar
+| 16 SPC f s Save
+| 17 SPC h t Tutor topbar
+| 18 SPC j i Forward C-i
+| 19 SPC j j Last
+| 20 SPC j l Jumplist
+| 21 SPC j o Back C-o
+| 22 SPC k Kill topbar
+| 23 SPC l D WsDiagnostics
+| 24 SPC l S WsSymbols
+| 25 SPC l a CodeAction
+| 26 SPC l d Diagnostics
diff --git a/test/snapshots/ttylook.golden b/test/snapshots/ttylook.golden
index 41e16c99..bf3785cc 100644
--- a/test/snapshots/ttylook.golden
+++ b/test/snapshots/ttylook.golden
@@ -1,7 +1,7 @@
== snap tok1 grid=120x30 cursor=2,3
|New Newcol Find Grep Help Tutor Dump NextColor Debug Kill
| /tmp/pardes-snap/ttylook/cwd New Del /tmp/pardes-snap/ttylook/cwd New Del
-|
+| ls ls
| big.txt plain.txt sub big.txt plain.txt sub
|
|
@@ -16,7 +16,7 @@
|
|
| /tmp/pardes-snap/ttylook/cwd New Del
-|
+| ls
| big.txt plain.txt sub
|
|
@@ -63,7 +63,7 @@
== snap tok2 grid=120x30 cursor=11,3
|New Newcol Find Grep Help Tutor Dump NextColor Debug Kill
| /tmp/pardes-snap/ttylook/cwd New Del /tmp/pardes-snap/ttylook/cwd New Del
-|
+| ls ls
| big.txt plain.txt sub big.txt plain.txt sub
|
|
@@ -78,7 +78,7 @@
|
|
| /tmp/pardes-snap/ttylook/cwd New Del
-|
+| ls
| big.txt plain.txt sub
|
|
@@ -94,7 +94,7 @@
== snap tokback grid=120x30 cursor=2,3
|New Newcol Find Grep Help Tutor Dump NextColor Debug Kill
| /tmp/pardes-snap/ttylook/cwd New Del /tmp/pardes-snap/ttylook/cwd New Del
-|
+| ls ls
| big.txt plain.txt sub big.txt plain.txt sub
|
|
@@ -109,7 +109,7 @@
|
|
| /tmp/pardes-snap/ttylook/cwd New Del
-|
+| ls
| big.txt plain.txt sub
|
|
@@ -125,7 +125,7 @@
== snap insert grid=120x30 cursor=4,3
|New Newcol Find Grep Help Tutor Dump NextColor Debug Kill
| /tmp/pardes-snap/ttylook/cwd New Del /tmp/pardes-snap/ttylook/cwd New Del
-|
+| ls ls
| nnbig.txt plain.txt sub big.txt plain.txt sub
|
|
@@ -140,7 +140,7 @@
|
|
| /tmp/pardes-snap/ttylook/cwd New Del
-|
+| ls
| big.txt plain.txt sub
|
|
@@ -156,7 +156,7 @@
== snap tok3 grid=120x30 cursor=22,3
|New Newcol Find Grep Help Tutor Dump NextColor Debug Kill
| /tmp/pardes-snap/ttylook/cwd New Del /tmp/pardes-snap/ttylook/cwd New Del
-|
+| ls ls
| big.txt plain.txt sub big.txt plain.txt sub
|
|
@@ -171,7 +171,7 @@
|
|
| /tmp/pardes-snap/ttylook/cwd New Del
-|
+| ls
| big.txt plain.txt sub
|
|
@@ -187,11 +187,11 @@
== snap diropen grid=120x30 cursor=4,7
|New Newcol Find Grep Help Tutor Dump NextColor Debug Kill
| /tmp/pardes-snap/ttylook/cwd New Del /tmp/pardes-snap/ttylook/cwd New Del
-|
+| ls ls
| big.txt plain.txt sub big.txt plain.txt sub
|
| /tmp/pardes-snap/ttylook/cwd/sub New Del
-|
+| ls
|
|
|
@@ -202,7 +202,7 @@
|
|
| /tmp/pardes-snap/ttylook/cwd New Del
-|
+| ls
| big.txt plain.txt sub
|
|
@@ -215,14 +215,14 @@
|
|
|
-== snap noop grid=120x30 cursor=4,7
+== snap noop grid=120x30 cursor=2,3
|New Newcol Find Grep Help Tutor Dump NextColor Debug Kill
| /tmp/pardes-snap/ttylook/cwd New Del /tmp/pardes-snap/ttylook/cwd New Del
-|
+| ls ls
| big.txt plain.txt sub big.txt plain.txt sub
|
| /tmp/pardes-snap/ttylook/cwd/sub New Del
-|
+| ls
|
|
|
@@ -233,7 +233,7 @@
|
|
| /tmp/pardes-snap/ttylook/cwd New Del
-|
+| ls
| big.txt plain.txt sub
|
|
@@ -249,11 +249,11 @@
== snap fileopen grid=120x30 cursor=7,2
|New Newcol Find Grep Help Tutor Dump NextColor Debug Kill
| /tmp/pardes-snap/ttylook/cwd/big.txt S /tmp/pardes-snap/ttylook/cwd New Del /tmp/pardes-snap/ttylook/cwd New Del
-| 1 line 1
+| 1 line 1 ls ls
| 2 line 2 big.txt plain.txt sub big.txt plain.txt sub
| 3 line 3
| 4 line 4 /tmp/pardes-snap/ttylook/cwd/sub New D
-| 5 line 5
+| 5 line 5 ls
| 6 line 6
| 7 line 7
| 8 line 8
@@ -264,7 +264,7 @@
| 13 line 13
| 14 line 14
| 15 line 15 /tmp/pardes-snap/ttylook/cwd New Del
-| 16 line 16
+| 16 line 16 ls
| 17 line 17 big.txt plain.txt sub
| 18 line 18
| 19 line 19
diff --git a/test/snapshots/ttylook.snap b/test/snapshots/ttylook.snap
index cc746970..66b178d7 100644
--- a/test/snapshots/ttylook.snap
+++ b/test/snapshots/ttylook.snap
@@ -2,9 +2,10 @@
# whitespace-separated token that look resolves — several per line, so the
# greet ls row hops big.txt -> plain.txt -> sub — moving the cursor to the
# token start and opening NOTHING. Return looks the selection (dir -> shell
-# +ls there, file -> pane) and navigation continues in what opened. The first
-# n wraps from the prompt row to the first token; insert-mode n still types;
-# with nothing lookable n is a no-op.
+# +ls there, file -> pane) and focus follows what opened. The first n wraps
+# from the prompt row to the first token; insert-mode n still types; and a
+# pane with nothing look-able in it never traps the walk, because the walk is
+# a RING ACROSS PANES rather than a scan of the one you are in.
lines big.txt 40
file plain.txt just text
dirmk sub
@@ -44,7 +45,10 @@ snap tok3
key enter
stable 700 15000
snap diropen
-# the fresh pane's dir is empty: n has nothing lookable, stays put
+# the fresh pane's dir is empty, and that is not where n stops: the ring is
+# spined on the panes that have LOOKED, so the step leaves this shell for the
+# one it was looked out of. That pane's cursor is on its last token (`sub`),
+# so the walk runs off the end and comes round to its first — big.txt.
key n
stable 400 5000
snap noop
diff --git a/test/snapshots/ttyprompt.golden b/test/snapshots/ttyprompt.golden
new file mode 100644
index 00000000..c479f463
--- /dev/null
+++ b/test/snapshots/ttyprompt.golden
@@ -0,0 +1,93 @@
+== snap greeted grid=100x30 cursor=4,4
+|New Newcol Find Grep Help Tutor Dump NextColor Debug Kill
+| /tmp/pardes-snap/ttyprompt/cwd New Del /tmp/pardes-snap/ttyprompt/cwd New Del
+| ls ls
+| probe.txt probe.txt
+|
+|
+|
+|
+|
+|
+|
+|
+|
+|
+|
+|
+| /tmp/pardes-snap/ttyprompt/cwd New Del
+| ls
+| probe.txt
+|
+|
+|
+|
+|
+|
+|
+|
+|
+|
+|
+== snap in-tty grid=100x30 cursor=17,4
+|New Newcol Find Grep Help Tutor Dump NextColor Debug Kill
+|$ /tmp/pardes-snap/ttyprompt/cwd New Del /tmp/pardes-snap/ttyprompt/cwd New Del
+| $ ls ls
+| probe.txt probe.txt
+| $ echo ABCDEFGH
+|
+|
+|
+|
+|
+|
+|
+|
+|
+|
+|
+| /tmp/pardes-snap/ttyprompt/cwd New Del
+| ls
+| probe.txt
+|
+|
+|
+|
+|
+|
+|
+|
+|
+|
+|
+== snap out-of-tty grid=100x30 cursor=17,4
+|New Newcol Find Grep Help Tutor Dump NextColor Debug Kill
+| /tmp/pardes-snap/ttyprompt/cwd New Del /tmp/pardes-snap/ttyprompt/cwd New Del
+| ls ls
+| probe.txt probe.txt
+| echo ABCDEFGH
+|
+|
+|
+|
+|
+|
+|
+|
+|
+|
+|
+| /tmp/pardes-snap/ttyprompt/cwd New Del
+| ls
+| probe.txt
+|
+|
+|
+|
+|
+|
+|
+|
+|
+|
+|
diff --git a/test/snapshots/ttyprompt.snap b/test/snapshots/ttyprompt.snap
new file mode 100644
index 00000000..9cb377bf
--- /dev/null
+++ b/test/snapshots/ttyprompt.snap
@@ -0,0 +1,35 @@
+# Leaving raw tty hides the shell's PROMPT and keeps the command typed at it.
+#
+# The two share one grid row, so blanking the row used to take the command with
+# the prompt and a shell out of tty read as output only. OSC 133 marks the row
+# CELL by cell, so config.tty_blank = .prompt cuts the prompt's own columns and
+# left-hugs what is left: the command lands at column 0, in line with the
+# output under it, rather than in a bay of blanks the prompt used to fill.
+#
+# `.prompt_and_input` is the old behaviour and blanks the whole row; it is a
+# comptime choice, so what THIS script pins is the default.
+file probe.txt marker
+start 30 100 -n 3
+wait 8000 probe.txt
+stable 700 20000
+# the greeting `ls` was typed at a prompt and already shows the rule: the
+# command is there, the prompt in front of it is not
+snap greeted
+# into tty and type a command WITHOUT submitting it, so the shell is sitting at
+# a prompt with input on it — the case the old behaviour erased
+key c-b
+stable 600 8000
+text echo ABCDEFGH
+stable 600 8000
+snap in-tty
+# ...and out: the prompt goes, `echo ABCDEFGH` stays, hugging the left edge
+key c-b
+stable 600 8000
+snap out-of-tty
+# The columns still have to reach the shell, and they do: the modal cursor's
+# column on a hidden-prompt row is short by exactly the prompt's width, so
+# enterTty adds it back before asking ghostty to walk the shell's own cursor
+# there. That arithmetic is pinned by the "entering tty walks the shell cursor"
+# unit test, which can put a pinned cursor on a known column; a click here
+# cannot, because leaving tty unpins and a body click on a terminal does not
+# pin it again.
diff --git a/test/snapshots/tutor.golden b/test/snapshots/tutor.golden
index 8bfb47fe..9973f04b 100644
--- a/test/snapshots/tutor.golden
+++ b/test/snapshots/tutor.golden
@@ -1,7 +1,7 @@
== snap tutor grid=150x30 cursor=7,2
|New Newcol Find Grep Help Tutor Dump NextColor Debug Kill
| /Tutor Save New Del /tmp/pardes-snap/tutor/cwd New Del /tmp/pardes-snap/tutor/cwd New Del
-| 1
+| 1 ls ls
| 2 PARDES TUTO↩
| R
| 3 tmux + vi + acme, fro↩
@@ -16,7 +16,7 @@
| 8
| 9
| 10 ==========================================↩ /tmp/pardes-snap/tutor/cwd New Del
-| =======================
+| ======================= ls
| 11 = INTRODUCTION ↩
| =
| 12 ==========================================↩
diff --git a/test/snapshots/winch.golden b/test/snapshots/winch.golden
index 125aae6d..cc613460 100644
--- a/test/snapshots/winch.golden
+++ b/test/snapshots/winch.golden
@@ -1,7 +1,7 @@
== snap storm grid=100x30 cursor=4,6
|New Newcol Find Grep Help Tutor Dump NextColor Debug Kill
|$ /tmp/pardes-snap/winch/cwd New Del /tmp/pardes-snap/winch/cwd New Del
-| $ ls
+| $ ls ls
| $ for i in $(seq 600); do kill -WINCH $PPID; don
| e; echo SUR''VIVED
| SURVIVED
@@ -16,7 +16,7 @@
|
|
| /tmp/pardes-snap/winch/cwd New Del
-|
+| ls
|
|
|
@@ -32,7 +32,7 @@
== snap resized grid=106x34 cursor=4,6
|New Newcol Find Grep Help Tutor Dump NextColor Debug Kill
|$ /tmp/pardes-snap/winch/cwd New Del /tmp/pardes-snap/winch/cwd New Del
-| $ ls
+| $ ls ls
| $ for i in $(seq 600); do kill -WINCH $PPID; done;
| echo SUR''VIVED
| SURVIVED
@@ -49,7 +49,7 @@
|
|
| /tmp/pardes-snap/winch/cwd New Del
-|
+| ls
|
|
|
diff --git a/test/snapshots/windownav.golden b/test/snapshots/windownav.golden
index ab8b76ec..0b27a26d 100644
--- a/test/snapshots/windownav.golden
+++ b/test/snapshots/windownav.golden
@@ -1,7 +1,7 @@
== snap start grid=100x30 cursor=7,2
|New Newcol Find Grep Help Tutor Dump NextColor Debug Kill
| /tmp/pardes-snap/windownav/cwd/w.txt Save New De /tmp/pardes-snap/windownav/cwd New Del
-| 1 alpha
+| 1 alpha ls
| 2 beta w.txt
| 3 gamma
|
@@ -32,7 +32,7 @@
== snap to-term grid=100x30 cursor=54,4
|New Newcol Find Grep Help Tutor Dump NextColor Debug Kill
| /tmp/pardes-snap/windownav/cwd/w.txt Save New De /tmp/pardes-snap/windownav/cwd New Del
-| 1 alpha
+| 1 alpha ls
| 2 beta w.txt
| 3 gamma
|
@@ -63,7 +63,7 @@
== snap back-to-file grid=100x30 cursor=7,2
|New Newcol Find Grep Help Tutor Dump NextColor Debug Kill
| /tmp/pardes-snap/windownav/cwd/w.txt Save New De /tmp/pardes-snap/windownav/cwd New Del
-| 1 alpha
+| 1 alpha ls
| 2 beta w.txt
| 3 gamma
|
@@ -94,7 +94,7 @@
== snap esc-to-term grid=100x30 cursor=54,4
|New Newcol Find Grep Help Tutor Dump NextColor Debug Kill
| /tmp/pardes-snap/windownav/cwd/w.txt Save New De /tmp/pardes-snap/windownav/cwd New Del
-| 1 alpha
+| 1 alpha ls
| 2 beta w.txt
| 3 gamma
|
@@ -125,7 +125,7 @@
== snap esc-back-to-file grid=100x30 cursor=7,2
|New Newcol Find Grep Help Tutor Dump NextColor Debug Kill
| /tmp/pardes-snap/windownav/cwd/w.txt Save New De /tmp/pardes-snap/windownav/cwd New Del
-| 1 alpha
+| 1 alpha ls
| 2 beta w.txt
| 3 gamma
|
@@ -156,7 +156,7 @@
== snap altn grid=100x30 cursor=4,19
|New Newcol Find Grep Help Tutor Dump NextColor Debug Kill
| /tmp/pardes-snap/windownav/cwd/w.txt Save New De /tmp/pardes-snap/windownav/cwd New Del
-| 1 alpha
+| 1 alpha ls
| 2 beta w.txt
| 3 gamma
|
@@ -171,7 +171,7 @@
|
|
| /tmp/pardes-snap/windownav/cwd New Del
-|
+| ls
| w.txt
|
|
@@ -187,7 +187,7 @@
== snap up grid=100x30 cursor=7,2
|New Newcol Find Grep Help Tutor Dump NextColor Debug Kill
| /tmp/pardes-snap/windownav/cwd/w.txt Save New De /tmp/pardes-snap/windownav/cwd New Del
-| 1 alpha
+| 1 alpha ls
| 2 beta w.txt
| 3 gamma
|
@@ -202,7 +202,7 @@
|
|
| /tmp/pardes-snap/windownav/cwd New Del
-|
+| ls
| w.txt
|
|
@@ -218,7 +218,7 @@
== snap right grid=100x30 cursor=54,4
|New Newcol Find Grep Help Tutor Dump NextColor Debug Kill
| /tmp/pardes-snap/windownav/cwd/w.txt Save New De /tmp/pardes-snap/windownav/cwd New Del
-| 1 alpha
+| 1 alpha ls
| 2 beta w.txt
| 3 gamma
|
@@ -233,7 +233,7 @@
|
|
| /tmp/pardes-snap/windownav/cwd New Del
-|
+| ls
| w.txt
|
|
@@ -249,7 +249,7 @@
== snap left grid=100x30 cursor=7,2
|New Newcol Find Grep Help Tutor Dump NextColor Debug Kill
| /tmp/pardes-snap/windownav/cwd/w.txt Save New De /tmp/pardes-snap/windownav/cwd New Del
-| 1 alpha
+| 1 alpha ls
| 2 beta w.txt
| 3 gamma
|
@@ -264,7 +264,7 @@
|
|
| /tmp/pardes-snap/windownav/cwd New Del
-|
+| ls
| w.txt
|
|
@@ -280,7 +280,7 @@
== snap down grid=100x30 cursor=4,19
|New Newcol Find Grep Help Tutor Dump NextColor Debug Kill
| /tmp/pardes-snap/windownav/cwd/w.txt Save New De /tmp/pardes-snap/windownav/cwd New Del
-| 1 alpha
+| 1 alpha ls
| 2 beta w.txt
| 3 gamma
|
@@ -295,7 +295,7 @@
|
|
| /tmp/pardes-snap/windownav/cwd New Del
-|
+| ls
| w.txt
|
|
@@ -311,7 +311,7 @@
== snap toggle-doc grid=100x30 cursor=7,2
|New Newcol Find Grep Help Tutor Dump NextColor Debug Kill
| /tmp/pardes-snap/windownav/cwd/w.txt Save New De /tmp/pardes-snap/windownav/cwd New Del
-| 1 alpha
+| 1 alpha ls
| 2 beta w.txt
| 3 gamma
|
@@ -326,7 +326,7 @@
|
|
| /tmp/pardes-snap/windownav/cwd New Del
-|
+| ls
| w.txt
|
|
@@ -342,7 +342,7 @@
== snap toggle-back grid=100x30 cursor=4,19
|New Newcol Find Grep Help Tutor Dump NextColor Debug Kill
| /tmp/pardes-snap/windownav/cwd/w.txt Save New De /tmp/pardes-snap/windownav/cwd New Del
-| 1 alpha
+| 1 alpha ls
| 2 beta w.txt
| 3 gamma
|
@@ -357,7 +357,7 @@
|
|
| /tmp/pardes-snap/windownav/cwd New Del
-|
+| ls
| w.txt
|
|
diff --git a/test/snapshots/windowops.golden b/test/snapshots/windowops.golden
index 0f7e38f4..4101fa86 100644
--- a/test/snapshots/windowops.golden
+++ b/test/snapshots/windowops.golden
@@ -1,7 +1,7 @@
== snap hover-v grid=100x30 cursor=4,4
|New Newcol Find Grep Help Tutor Dump NextColor Debug Kill
| /tmp/pardes-snap/windowops/cwd New Del ╎ /tmp/pardes-snap/windowops/cwd New Del
-| ╎
+| ls ╎ ls
| w.txt ╎ w.txt
| ╎
| ╎
@@ -16,7 +16,7 @@
| ╎
| ╎
| /tmp/pardes-snap/windowops/cwd New Del ╎
-| ╎
+| ls ╎
| w.txt ╎
| ╎
| ╎
@@ -32,7 +32,7 @@
== snap hover-h grid=100x30 cursor=4,4
|New Newcol Find Grep Help Tutor Dump NextColor Debug Kill
| /tmp/pardes-snap/windowops/cwd New Del /tmp/pardes-snap/windowops/cwd New Del
-|
+| ls ls
| w.txt w.txt
|
|
@@ -47,7 +47,7 @@
|
|╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌
| /tmp/pardes-snap/windowops/cwd New Del
-|
+| ls
| w.txt
|
|
@@ -63,7 +63,7 @@
== snap border-drag grid=100x30 cursor=4,4
|New Newcol Find Grep Help Tutor Dump NextColor Debug Kill
| /tmp/pardes-snap/windowops/cwd New De╎ /tmp/pardes-snap/windowops/cwd New Del
-| ╎
+| ls ╎ ls
| w.txt ╎ w.txt
| ╎
| ╎
@@ -78,7 +78,7 @@
| ╎
| ╎
| /tmp/pardes-snap/windowops/cwd New De╎
-| ╎
+| ls ╎
| w.txt ╎
| ╎
| ╎
@@ -94,7 +94,7 @@
== snap border-done grid=100x30 cursor=4,4
|New Newcol Find Grep Help Tutor Dump NextColor Debug Kill
| /tmp/pardes-snap/windowops/cwd New De╎ /tmp/pardes-snap/windowops/cwd New Del
-| ╎
+| ls ╎ ls
| w.txt ╎ w.txt
| ╎
| ╎
@@ -109,7 +109,7 @@
| ╎
| ╎
| /tmp/pardes-snap/windowops/cwd New De╎
-| ╎
+| ls ╎
| w.txt ╎
| ╎
| ╎
@@ -125,7 +125,7 @@
== snap hborder-done grid=100x30 cursor=4,4
|New Newcol Find Grep Help Tutor Dump NextColor Debug Kill
| /tmp/pardes-snap/windowops/cwd New Del /tmp/pardes-snap/windowops/cwd New Del
-|
+| ls ls
| w.txt w.txt
|
|
@@ -136,7 +136,7 @@
|
|╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌
| /tmp/pardes-snap/windowops/cwd New Del
-|
+| ls
| w.txt
|
|
@@ -156,7 +156,7 @@
== snap move-preview grid=100x30 cursor=4,15
|New Newcol Find Grep Help Tutor Dump NextColor Debug Kill
| /tmp/pardes-snap/windowops/cwd New Del /tmp/pardes-snap/windowops/cwd New Del
-|
+| ls ls
| w.txt w.txt
|
|
@@ -167,7 +167,7 @@
|
|
| /tmp/pardes-snap/windowops/cwd New Del
-|
+| ls
| w.txt
|
|
@@ -187,7 +187,7 @@
== snap moved grid=100x30 cursor=4,15
|New Newcol Find Grep Help Tutor Dump NextColor Debug Kill
| /tmp/pardes-snap/windowops/cwd New Del /tmp/pardes-snap/windowops/cwd New Del
-|
+| ls ls
| w.txt w.txt
|
|
@@ -198,7 +198,7 @@
|
|
| /tmp/pardes-snap/windowops/cwd New Del
-|
+| ls
| w.txt
|
|
@@ -218,7 +218,7 @@
== snap altn grid=100x30 cursor=4,19
|New Newcol Find Grep Help Tutor Dump NextColor Debug Kill
| /tmp/pardes-snap/windowops/cwd New Del /tmp/pardes-snap/windowops/cwd New Del
-|
+| ls ls
| w.txt w.txt
|
|
@@ -229,11 +229,11 @@
|
|
| /tmp/pardes-snap/windowops/cwd New Del
-|
+| ls
| w.txt
|
| /tmp/pardes-snap/windowops/cwd New Del
-|
+| ls
| w.txt
|
|
@@ -249,7 +249,7 @@
== snap focus-right grid=100x30 cursor=44,4
|New Newcol Find Grep Help Tutor Dump NextColor Debug Kill
| /tmp/pardes-snap/windowops/cwd New Del /tmp/pardes-snap/windowops/cwd New Del
-|
+| ls ls
| w.txt w.txt
|
|
@@ -260,11 +260,11 @@
|
|
| /tmp/pardes-snap/windowops/cwd New Del
-|
+| ls
| w.txt
|
| /tmp/pardes-snap/windowops/cwd New Del
-|
+| ls
| w.txt
|
|
@@ -280,7 +280,7 @@
== snap debug-on grid=100x30 cursor=44,4
|New Newcol Find Grep Help Tutor Dump NextColor Debug Kill
| /tmp/pardes-snap/windowops/cwd New Del /tmp/pardes-snap/windowops/c╭────────────────────────────╮
-| │pardes resizes=1 │
+| ls ls │pardes resizes=1 │
| w.txt w.txt │terms 4 cols 2 │
| │active #2 58x28 │
| │scroll 0/28 │
@@ -291,11 +291,11 @@
|
|
| /tmp/pardes-snap/windowops/cwd New Del
-|
+| ls
| w.txt
|
| /tmp/pardes-snap/windowops/cwd New Del
-|
+| ls
| w.txt
|
|
@@ -342,7 +342,7 @@
== snap debug-off grid=100x30 cursor=44,4
|New Newcol Find Grep Help Tutor Dump NextColor Debug Kill
| /tmp/pardes-snap/windowops/cwd New Del /tmp/pardes-snap/windowops/cwd New Del
-|
+| ls ls
| w.txt w.txt
|
|
@@ -353,11 +353,11 @@
|
|
| /tmp/pardes-snap/windowops/cwd New Del
-|
+| ls
| w.txt
|
| /tmp/pardes-snap/windowops/cwd New Del
-|
+| ls
| w.txt
|
|