diff options
| author | Gabriel Schneider <[email protected]> | 2026-08-11 18:30:13 -0300 |
|---|---|---|
| committer | Gabriel Schneider <[email protected]> | 2026-08-12 13:04:32 -0300 |
| commit | b424164922842796619cb6894ec46d729a8a6826 (patch) | |
| tree | bd4653accfaeb67012f4e7257c61eaf4fb12c892 /test/snapshots/themesel.snap | |
| parent | 08f32cdde672740b71608f3dfccd629dcbac78f7 (diff) | |
| download | pardes-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.
Diffstat (limited to 'test/snapshots/themesel.snap')
| -rw-r--r-- | test/snapshots/themesel.snap | 51 |
1 files changed, 31 insertions, 20 deletions
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 |
