| Commit message (Collapse) | Author | Age |
| |\ \ \ \
| | | | |
| | | | |
| | | | | |
+ tty ssh acked frames
|
| | | | | |
| | | | |
| | | | |
| | | | | |
answer after each, and draws the latest state when it does
|
| | | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | | |
none when one failed
A look line written a byte a Twrite is a look a byte, each its own write logging its own miss; when its last byte was a control character that one write failed, and the oracle dropped every miss allowance on the path, so seed 51 failed with 21 errs for 1 refused write. Allowances are now counted over the Twrites that succeeded (and an hwrite's only once it has).
Co-Authored-By: Claude Opus 5.5 <[email protected]>
|
| | | |/ /
| | | |
| | | |
| | | |
| | | |
| | | | |
It was a scratch tool (.scratch/render/tools/gui_monkey.py) that the gates rely on and that imported fs.py from a workspace since removed. It is test/gui_monkey.py now, importing from its own directory, and zig build monkey-gui -Dplatform=gui runs it on the built window, the same hidden test windows; it exits 1 when a combination fails, and its outdir is optional.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
|
| | |/ /
| | |
| | |
| | |
| | |
| | | |
8192 was kept for round 24 because 64 KiB seemed to hang fs-test's restore detached space; that was the batch-wake overflow fixed in kmqtwqsm, which any msize could hit, and fs.py passes at 64 KiB with it. A client asking for more now gets it, so a write up to 64 KiB less 24 is one Twrite, and round 24's no-newline cutoff (write_room, the negotiated msize less 24) follows: fs.py checks a 20000-byte ctl line from a 64 KiB client is taken whole. Each of the 16 connection slots holds its buffers at the larger size.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
|
| |/ /
| |
| |
| |
| |
| |
| |
| | |
does, and a start with no terminal says so
A name that did not exist yet failed resolveOs, so the launch fell through to starting an editor of its own, which on a pty with no controlling terminal (a detached session's) ended in a NoDevice error trace. A new name's directory is now resolved and the name kept: the launch reads pane/new and writes that path to the pane's name, so Save creates the file, and --wait waits on that pane (the git commit case). A standalone start whose /dev/tty will not open prints why and exits 1. fs.py covers both; the known-wrong line in docs/divergences.md goes.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
|
| | | | |
| | \ | |
| |\ \ \
| | |/
| |/|
| | | |
9P monkey
|
| | | |
| | |
| | |
| | |
| | |
| | |
| | |
| | | |
remove, or a write to pane/new, must log no err
The coordinator's reading of fs.md, now documented (slnyzzps): only a write or truncation logs its reason; a refused open (pane/new's and an OTRUNC one included), create or remove is its Rerror alone, and so is a write to pane/new. The oracle allowed an err or none for those, and required one for a refused pane/new open.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
|
| | | |
| | |
| | |
| | |
| | |
| | |
| | |
| | | |
write's unended tail is a line of its own
Since round 24 (uwzuqzxp), a write to a lines file shorter than a Twrite holds is whole, as acme takes each write, so a look line written a byte a Twrite is as many looks as bytes, each missing with its own err. one_failure_rule still split the data on newlines whole, allowed one err, and failed the fixed smoke seed (20260929 step 607, size 20 6 written in bytes to look: 7 errs). served_lines models the tree's write (tree.zig) and has a self-check run at start.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
|
| | | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | | |
documented rules
test/monkey9p.py starts pardes --detach with its own HOME, XDG dirs and
runtime dir, speaks raw 9P (test/ninep.py) with a timeout on every reply
and Tflush for held reads, and after each seeded operation checks that
pardes is alive, the one-failure rule over a marker-delimited log window
(with and without a follower), /index against /pane, and chunked against
whole reads. Every run writes a replayable ops log; a failure is saved
with its seed and step, shrunk by delta debugging over replays, and the
run goes on in a fresh session. Teardown makes the fuzzer a subreaper and
kills every process carrying the session's token.
zig build monkey-9p -- --seed N --steps M | --replay F | --shrink F;
a 150-step fixed-seed smoke run is part of fs-test.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
|
| | |/
| |
| |
| | |
keeps from the frame before
|
| | |
| |
| |
| |
| |
| |
| |
| | |
is deleted, so it can be $EDITOR
A launch inside a pane forwards its file to the session's look and returned at once, so fish's Ctrl-O (edit_command_buffer), git commit and crontab -e read their still-unedited file back and went on. With --wait, as acme's E against B and read the way plan9port's E reads acme's log, it finds the pane /index names the file by (the one already showing it, if open), follows /log on one connection with 'follow new', reads /index once more to catch a Del that came first, and then blocks with no deadline until that pane's del record: exit 0, or 1 when the connection ends with the session. The 9P client's one-shot requests keep their 2 s deadline; its new follow takes it for the setup only. Outside pardes nothing changes. --help, docs/fs.md, the README and the 9P skill say to set EDITOR='pardes --wait', which GIT_EDITOR follows. Tested in fs.py (it returns within 50 ms of the Del, a second -w waits on the same pane, one whose session is killed exits 1) and end to end: fish 4.8 in a detached session, echo hi, Ctrl-O, the waiting launch idle in poll, the line edited over 9P, Save, Del, and fish ran echo edited.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
|
| | |
| |
| |
| |
| |
| |
| |
| | |
names capitalised
Mini needs a file but did not say so, so a bare Mini ran and failed EIO. It now requires its argument, refused wrong #args (EINVAL) as every such word is. Its failures, Find's and Grep's start with the builtin's own name (Mini:, Find:, Grep:), as the others' do.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
|
| |/
|
|
|
|
|
|
| |
is linear
Each body or data write copied and hashed the whole buffer, so a write the mount cut in 8 KB pieces was quadratic: 10 MB took 50 s and a 1 MB insert into 10 MB 11 s, holding the editor's turn. An open's appends to body, or inserts going on at data's address, are now held and put in as one splice (one copy, one undo step, one line-starts pass) before any other request, the close, or the editor's step once the writes pause 20 ms. fs.py-driven: 2 MB 2.19 -> 0.16 s, 10 MB 50.17 -> 0.78 s, 1 MB data into 10 MB 11.49 -> 0.26 s. A body-2m case (2 MB in 256 KB writes on one open) joins the perf gate: 84023 -> 15785 us; baselines re-recorded.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
|
| |
|
|
|
|
|
|
| |
tag, as acme's does
The last column's Delcol ended the session. The window now stays, with only the workspace tag; Newcol, and New (which makes the column it goes in), start it again. A word run with no pane at all runs with a stand-in that is no pane, the root ctl takes session words, and pane/new makes its scratch in the session's directory.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
|
| |
|
|
|
|
|
|
| |
callers not found
The ENOENT that 9ns reads from a failure's words came from a tacked-on suffix, grep: no match, not found, definition: nothing found, not found, no shell "x", not found. They now say it once: grep: pattern not found, find: name not found, Callers: callers not found, definition: not found, shell "x" not found (...).
Co-Authored-By: Claude Opus 5.5 <[email protected]>
|
| |
|
|
|
|
|
|
| |
path says why
The theme is read when the host performs the request, after the write had been answered, so a missing file or a bad theme only showed a message; and a path not ending .zon said only invalid theme path. Load failures are now the waiting write's (late, as a Save's), and the path refusal says a theme file is a .zon.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
|
| |
|
|
|
|
| |
A file deleted under an open buffer left dirty 0 and let Del, Exit and the rest throw the only copy of its text away unasked. It now counts as dirty, as acme's does, and the refusals ask about it.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
|
| |
|
|
|
|
| |
std's statFile takes the kernel's ENAMETOOLONG for a bug (errnoBug), so a name, look, DumpDir or Save path with a part over 255 bytes panicked the editor (exec.kindOf via writeName, recentKeeps, dumpFailed). Every non-test statFile now goes through fs.statPath, which refuses such a name as NameTooLong first; fs.py drives long, looping, not-a-directory and not-ours paths through name, look, DumpDir, Dump and Save.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
|
| |
|
|
|
|
|
|
| |
to find it
setEditText found the last edit's end by comparing the old and new texts from both ends and counting rows to it, twice over the file on every keystroke: edit-char grew with the file (+135% at 300k lines). Typing, deleting, Enter and Tab now pass the end they know (setEditTextEnd); the comparison stays for the edits that do not say (paste, pipes, s). perf edit-char: 50k lines 16661 -> 15286 us, 300k lines 30507 -> 22291 us (render alone ~13.6 ms of each, the render agent's).
Co-Authored-By: Claude Opus 5.5 <[email protected]>
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
let the GUI rest; a perf gate
somtrmsz's contrast floors made ChromeTheme.fromTheme run its focus-tint
and separator searches (pow calls each), and Output's RowDecoration.styleAt
called it for every grapheme of every highlighted row: the 50k-line file's
render went from 0.11 ms to 13 ms. Pardes.bodyChrome now keeps the theme's
chrome, worked out again only when the theme differs; recolorSyntax asks
for it once a decorated row, and a plain row (nearly every row of a file)
never asks. ReleaseFast, medium fixture, median us, before -> after (main):
render 13150 -> 76 (111), key-down 14658 -> 79 (110), wheel 13589 -> 76
(109), open 14891 -> 2095 (2055), edit-char 16703 -> 3006 (1251; the rest of
that gap is editing and tree-sitter, not this).
Post.animating asked for frames whenever the window had focus and any pass
was ready, so a still pass kept the GUI drawing at the display's rate
(Bloom: 49% of a core idle, in a hidden test window). A pass now says
whether it moves on its own: the CRT (its hum and dither) and a Shadertoy
file whose source reads iTime, iFrame or iDate (shader_build.readsTime; the
flag rides the wire's post message); Bloom, Vignette and Grain are still.
Bloom idle: 49% -> 1.2%, as with no pass.
zig build perf-gate: the 50k-line file's gestures, each's fastest sample
within 3x of the recorded baseline's (test/perf-baseline-<platform>-
<optimize>.json, recorded from this build), run with every unit-test. On
the regressed code it fails at 180x for render.
|
| |
|
|
|
|
|
|
| |
came from
Once the workspace tag was edited, its own text kept the Restore <path> of the dump at that time, stale after the next Dump; and a Restore dropped the path altogether (the new session had no last dump). A new dump now swaps the old path in the tag's own text, and a Restore points the word at the dump it read.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
|
| |
|
|
|
|
|
|
| |
room fails, and so does a write to an image's or PDF's body
Callers or Callees with nothing found, Hover or Lspwhy with no room for its pane, and a question asked of no file's pane said nothing, the 9P write succeeding; a body write to an image or PDF pane went nowhere. A write that asks a language server now waits for its answer (turn.lsp_answers), and what fails there -- nothing found, no answer, a backend's @none why, a placement with no room (ENOSPC) -- fails the write and logs its err. No diagnostics is said, not failed.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
|
| |
|
|
|
|
| |
A Restore makes a new session, which never loaded the kept list, and saveRecent gives up until it has: Recent was empty after a Restore and nothing opened afterwards was kept. The new session now takes the old one's list (a boot from a dump reads the kept file).
Co-Authored-By: Claude Opus 5.5 <[email protected]>
|
| |
|
|
|
|
| |
Each host closed the running shell before it forked the new one, so an exec whose shell failed left the pane with none and later runs answered error shell gone. A shell not there is now refused up front, and every host starts the new shell first, replacing the old only once the close-on-exec pipe says it ran; a failure there is only said (restartFailed).
Co-Authored-By: Claude Opus 5.5 <[email protected]>
|
| |
|
|
|
|
|
| |
The rename turned `MissingThemeSelection` into `MissingThemesection`; the
theme section is what the test misses.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
|
| |\ \
| | |
| | |
| | | |
cursor + faithful themes
|
| | | |
| | |
| | |
| | |
| | |
| | | |
theme.snap and themesel.snap step past orchard_black into acme and lapis
(now with the current themes) and across the first ported sections; their
step names say where each lands, and only these two goldens are re-recorded.
|
| | | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | | |
as legacy, a section per ported family
The picker's headings come from colors.theme_groups instead of one split at
native_theme_count, so acme (current, matched to plan9port acme's source)
no longer sits under a legacy heading. Ring order follows the sections:
the fifteen pardes palettes, acme, lapis, the faithful ports a family at a
time, then helix and dark, then the imports. An imported theme whose name a
port takes gets _helix, as zed's carry _zed.
|
| | |/
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| | |
the new one
G3's springs now keep the cursor's place in its pane: a pane that moves in
the layout carries them, and the quad is drawn through the pane's presented
box (its transition track), so through a slide, zoom or drag the cursor
rides with the text, and with no transition it lands with it. A focus change,
to another pane or into a column's or the workspace's tag, glides from where
the cursor was drawn to the new place instead of snapping, unclamped while it
crosses. While panes move the cursor is drawn as the overlay quad instead of
vanishing (golden 18-mid-transition re-recorded for that: the only change is
the quad, gliding into the new column's tag).
Lapis: a tag plaque starts flush against its grip's button, the scroll gap
between them part of the plaque, so grip and plaque read as one piece, on
pane and column rows alike; below the button's row the grip keeps its band.
Themes without plaques are unchanged (their grip band and tag band are one
colour, no sliver).
|
| | |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| | |
test/gui_golden.py hashed a scene once two captures 400 ms apart agreed;
on a loaded machine a slow frame agreed with itself before the scene's
change landed and every later hash moved up a scene. A test window now
writes a status file into its capture directory each loop step (gui.zig
writeTestStatus: step, frames captured, idle — nothing owes a frame,
nothing moves, nothing waits on the core's clock), and the harness waits
for an idle step two past the one current when it asks: a 9P write has
been served by then, so the frame is the scene's. Two things kept a
window from ever going idle, both fixed:
- Look-hover re-armed forever: resting on a word with nothing to open, the
hover wait ran its two frames, found nothing, cancelled, and the next
present's pointer refresh started it again: a frame every other frame
for as long as the pointer rested there, live too (CPU). The place last
refused is remembered (Pardes.look_hover_refused) until the pointer
moves off it.
- The virtual clock moved only on a wait that timed out, so a steady
trickle of events held it still; it now moves to the core's wake too
when an event cut the wait short and nothing owes a frame.
Captures go to a directory of their own, outside the session's (a file
written there every frame is a change in the directory its panes look
at). All 17 goldens match the file as recorded at oooopqyv; eight runs,
five alongside a ReleaseFast build and three with all 16 cores saturated
(load 13-19), were byte-identical, 14 s a run unloaded (was ~30).
Tests: the resting pointer lets the core go idle.
|
| | |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| | |
files and dumps
The user asked for the plainer words. Every use is renamed: the
builtins, leader paths, /commands, the docs and tutor, tests, and the
themesel golden, re-recorded. An init file's ThemeSel or FontSel runs
the new word and says `ThemeSel: renamed to Themes`, as ColumnTags is
said; a dump naming an output pane by the old word restores it.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
|
| | |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| | |
closed file reopens it
A file closed by accident, its path forgotten, could not be found again:
the jumplist dropped closed panes. Every file opened (a look, a Save of a
scratch, a Restore, a rename) goes first in a list of 200, kept once, its
dot noted when it closes, kept across sessions in $XDG_STATE_HOME/pardes/
recent. `Recent` (SPC f r) shows it in a reused +Recent, each row
`path:line:col open|closed` a look reopens; /recent reads `open|closed
<path>`. The jumplist keeps a closed file's entries, +Jumps marks them
`(closed)`, and Back to one opens the file at its place. acme has no
such thing; its dump and Load are the nearest.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
|
| | |
| |
| |
| |
| |
| |
| |
| |
| | |
Each Grep with a new pattern opened another +Search, until the column
refused panes. Find and Grep now reuse their directory's one, as acme
reuses +Errors, and the exec reads back the pane it filled; a plain
word's LookWord list search keeps a pane a pattern as before.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
|
| | |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| | |
are ENOENT, a GUI-only setting EINVAL
A Dump into a DumpDir not there failed EIO `file not found`; `no shell
"x"` read as EIO through a mount; and a GUI-only setting on a terminal,
EINVAL in the reply, had no word 9ns reads as EINVAL. Each says so in the
words that give its errno: `no such directory`, `not found`, `invalid
here`.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
|
| | |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| | |
answers
A shell whose exec failed (a script's missing interpreter) was reported
started: Tty and pty/ctl exec succeeded, then the pane died. The child now
reports a failed chdir or exec through a close-on-exec pipe the parent
reads before acknowledging the shell; the host's spawn fails with the
reason (`shell not found`, ENOENT), which fails the waiting write. A Tty
whose first shell never ran leaves no pane; a terminal restarted by
pty/ctl exec keeps its pane.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
|
| | |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| | |
a new one is
The guard that keeps a shell from taking this process's directory before
its chdir lasted only until the first shell spoke; a shell started again
in the same pane (pty/ctl exec) was asked with the old shell's word still
standing. A spawn resets it. fs.py's naming test restarts one too.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
|
| | |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| | |
The round-18 Grep that found nothing slipped past every narrower test.
One broad run now looks files, runs Grep and Find hits and misses, looks
a plain word, Edits two files and Saves them, gets one back from disk,
runs pty/run failing then passing, Kills a command pane, sends to a REPL,
makes and removes a column, answers an ask, and Dumps and Restores,
checking the log and the read-backs at each step, in under 30 s.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
|
| | |
| |
| |
| |
| |
| |
| |
| | |
It failed EIO with `file not found`, which named no file that was
missing. It says `Save <path>: no such directory`, and a late failure
saying `no such` answers ENOENT, as a builtin's does.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
|
| | |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| | |
spoken, so it logs no rename to the session's and back
Each host read /proc/<pid>/cwd right after forking the shell and at every
frame after; before the shell's chdir that says this process's directory,
a rename to it, then the real one a frame later, a rename back. A shell
given a directory is named by it already (newShell) and is no longer
asked at fork; and until it has printed anything, an answer naming this
process's directory is not taken.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
|
| | |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| | |
The greeting waited for any moment the cursor sat at a prompt's input, so
where the first prompt was missed (a resize still pending, a line written
before it), `ls` was typed later into whatever ran then. It is now sent
only while nothing has run (pardes's marks saw no command start) and
nothing is typed at the prompt; past that it is dropped, never typed late.
A prompt drawn again for a resize is still the first.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
|
| | |
| |
| |
| |
| |
| |
| |
| |
| | |
Any rename marked the pane dirty (saved revision one back), while the
guards ask only whether its text was ever edited: /index said dirty for a
pane Exit let go without asking. The name is no edit now, so /index, the
guards and Restore agree; Save writes under the new name all the same.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
|
| |/
|
|
|
|
|
|
|
| |
A scratch took its new name before the host wrote it, so `Save /root/x.txt`
failing with EACCES renamed it anyway; a failed write to another name
marked a clean file dirty. A scratch is now named once its write is done
(promoteSaved), and a failed write puts the saved revision back.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
|
| |\ |
|
| | |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| | |
A native theme `lapis` (src/themes/lapis.zig) from web/theme/lapis.css:
a lapis-deep page, lapis tags with gold names, vellum text, vermilion
rubrics, gold rules and a vermilion tag rule, gold selection in lapis ink.
Its ornament is the theme's new `decor` (colors.Decor), drawn by a pixel
shell inside the chrome it already has (decision 1), all of it off every
focus indicator:
- page_dots: the site's gold dot grid (#e8c46a22, 22 px), drawn by the
cell shader on page-coloured cells alone (flag 0x10000000), so it lies
under the text and never under a selection, a tag or the cursor; fixed
to the window, a page the panes lie on.
- rail_checker: the dither frame's gold and lapis checker in the scroll
track (a decor kind, flag 0x08000000), anchored to its rail; the thumb
stays solid gold.
- tag plaques (tag_border, tag_shadow, tag_stripe): every tag a raised
plaque inside its own band, the site's trail: a 2px gold frame and a
hard 5px vermilion shadow down and right, both within the band's rows
and columns (down, what the slack under the text leaves), so no shadow
reaches a body, a grip or the next pane. The focused pane's plaque is
the code window's title bar, gold and lapis stripes of 2px, its words
on plates of the focused ground; unfocused ones are plain; column and
workspace tags take the object-label language (1px frame, 2px shadow
toward the page). Drawn as decor under the cells (a group's under
range), with blank tag cells see-through and the cells blended
premultiplied (pipeline_over) on such frames; opaque windows only.
- title_shadow: the titles' vermilion offset shadow under a file name's
letters, sampled in the cell shader inside the letters' own cells (flag
0x08000000), none on a cursor.
Chrome carries the decor (decor_*, name_ink, active_name_ink); a theme
file folds a nested decor literal field by field. Left out, with why, in
docs/effects.md: the fonts, the ornaments, a decor crossfade, and in the
tty anything but the colours (a tag row has no spare cell for a shadow).
An empty column is the page. The effect id is masked to 27 bits (ui.vert/ui.frag) for the
fifth flag.
Tests: the cell flags land only on page ground and file-name cells, never
a cursor, nothing without decor; lapis's plaques stay inside their tag's
band, clear of every grip, only the focused one striped; its checker is in
the track; no other theme draws any; the separator and focus
tests cover lapis. Goldens: theme and themesel (the ring gains lapis after
acme). Gates as G4. Feel review: .scratch/render/lapis/ (lapis.png, lapis-2x.png,
tags-focused-vs-unfocused-2x.png, a PanelSlide at 60 fps and a quarter).
|
| | |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| | |
separators and focus tints
Density: dp() in gui.zig draws every size given in pixels in logical
pixels (SDL's window display scale, rounded, at least one), as acme scales
Border, ButtonBorder and Scrollgap: the rules (rule_px), the tag rule, the
grip's ring, its dirty gap and mode bars, the rail's gap to the text and
its minimum, the thumb's inset, the rim, a bar cursor's minimum width,
underline and strikethrough thickness (the atlas is dropped on a scale
change), the rule-grab margin, and the Crt's scanline and mask periods
(pardesScale in the post prefix). Cell- and tagline-measured sizes stay:
the rail's width, Lift's blur and offsets, every motion; iResolution,
fragCoord and iMouse stay in the display's pixels, as ghostty's.
PARDES_TEST_SCALE forces a density in a harness (a test window is 1x
otherwise, whatever display it lands on) and sizes the test font with it.
Colours: a separator that stands off its page by less than 1.5:1 is lifted
toward the text to 1.6:1 (helix, atelier, paper; a theme with no page,
dark, is judged against #121212), and empty_col follows it. forge's own
rule already stands at 3.83:1; what hid it was density: 2 device pixels
on a 3x screen, now 6 (dp). A focused tag's tint closer than 1.5:1 to the
plain tag on a dark page (1.25:1 on a light one) is pushed further the way
it leans, as far as its text keeps its own contrast or 4.5: forge
1.23 -> 1.51 (#2d3440 -> #374253), and likewise dusk, orchard, ink,
lagoon, clay, harvest, spectrum, solarium, forge_soft; daybreak, atelier,
paper to 1.25. dark and helix gain a tint of their own (dark: #484566
under #c8c8c8, 1.54:1; helix: ramp 237 under 250, 1.65:1).
Tag caret: past a full row's end, the G3 glide box sits on the tag's right
edge, where the layer's caret and the pixel shell's are.
Tests: every native theme's separator >= 1.5 and every dark one has a
tint >= 1.25 with readable text; forge keeps its own border; the tag caret
glide box at a full row; at 2x the spine, tag rule, ring, rail start and
gap, and bar cursor double. Legacy-ThemeFile test strips helix's new pair.
Goldens: snapshot goldens change in colour rows only, the tints (orchard
#283a2f -> #314738 at boot, forge, helix and dark in theme/themesel).
GUI goldens: the harness's single Del of the renamed wide pane is refused
since ysqnkyoy (a rename counted as unsaved; fixed on the 9P line in
wkzlsqvy), so scenes 09-17 were recorded with that pane open and the file
was stale since the merge (08 and 18 also moved with ykvnltvs's full-row
tag wrap). The goldens here were recorded with that pane closed (as
wkzlsqvy will close it); against the parent's binary under the same
conditions they differ only in the tints: 01-13 forge's (#2d3440 ->
#374253, and the glyph edges on it), 14 ink's; 15-18 are byte-identical.
Until wkzlsqvy is merged, a run here fails 09-17. Each commit reproduces its own
recorded goldens on this machine (checked at kvtmqkyn). A test window is
1x unless PARDES_TEST_SCALE says otherwise, whatever display it opens on.
Prebuilt shaders refreshed from their sources.
Captures: .scratch/render/dark-borders/{before,after,compare,scale2,scale3}.
|
| | |
| |
| |
| |
| |
| |
| | |
At 80x24 a script's third or fourth pane/new was refused for want of
rows. `size` still sets any other size, and a frontend attaching its own.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
|
| | |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| | |
is said as `dial failed: <reason>`
Mount took any well-formed dial and nothing was found out until the
first look through it, which then said `look: look: dial`. Mount now
probes the peer (version, attach, its root) with the turn out, and fails
its write, mounting nothing, when none answers; the dial errors read as
words, `no answer`, `timed out`, `hung up`, and a look through a peer
gone since names its path: `look: /n/peer/f: dial failed: no answer`.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
|
| | |
| |
| |
| |
| |
| |
| |
| |
| |
| | |
Every look that found something cleared the looker's selection first, so
`@p5:2` or `f.txt:2` written to a pane's look collapsed its dot to
q1-1. Only a look that stays in the pane starts from a clean selection
now; one that goes elsewhere takes away just the click's highlight, and a
miss changes nothing, as acme's look does.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
|
| | |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| | |
smaller window
A terminal of one body row loses its prompt's mark and reads busy for
ever. Placement already refused to make one that short; now layout never
leaves one there either: a grip drag stops at the floor, and a column
squeezed by weights or by the window takes the rows from its other panes.
Text panes keep acme's way and can still be dragged to their tag, since
acme has no terminals to follow. The shrinktag, splitparent and cornerdrag
goldens are re-recorded for it, shrinktag's re-grab moved to where the
grip now is.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
|