summaryrefslogtreecommitdiff
Commit message (Collapse)AuthorAge
* Terminal.zig is terminal.zig: a file of functions and no fields takes a ↵Gabriel Schneider44 hours
| | | | | | | | namespace's lowercase name The last of the deferred renames, now that the tty and theme agents have landed: panes.terminal at its importers, the alias lines in Text.zig and File.zig and panes.zig's own uses following. dump.zig's Terminal struct, a dump record, is not this. The served sources list and docs/design.typ name the new file. test/perf.zig's references change, so the three perf baselines take its new harness id with their numbers as recorded. No behaviour changes. Co-Authored-By: Claude Opus 5.5 <[email protected]>
* Merge: renames/folds + tagline accents for every themeGabriel Schneider44 hours
|\
| * acme tints a tag's file name, +Name and Tty word quietly, in its own ↵Gabriel Schneider44 hours
| | | | | | | | | | | | | | | | | | | | DMedblue #000099 acme tints nothing in a tag, but the tint is a pardes indicator the user wants in every theme. #000099 is acme's own (draw.h DMedblue, its dirty button): a navy that reads as ink until you look for it. Co-Authored-By: Claude Opus 5.5 <[email protected]>
| * A theme that names no tint for its tags' names takes one of its own hues, so ↵Gabriel Schneider44 hours
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | every theme draws a file's name, a +Name and the Tty word off the tag's ink The faithful ports (neobones_dark, dracula, tokyonight, the *bones, ...), every helix import and any theme file set no tag_name_fg, and ChromeTheme fell back to the plain ink: their tags lost the accent the pardes themes have. The user's neobones_dark looked tinted before only because the Sep 24 build had no such theme and fell back to orchard. The tint is now derived when unset: the theme's keyword colour, else the first of its ANSI accents, syntax, grip, selection or diagnostic colours with a hue, placed at the lightness nearest the ink where the hue holds, at least 4.5:1 on its ground (half a point under the ink's own where the ink has less to spare) and 0.07 off the ink in OKLab. Each ground, plain and focused, gets its own. A theme that names its tint keeps it exactly. Tests: every theme's chrome keeps both tints off the ink and legible; every theme draws a file's basename, +Errors and Tty+sh in a tint, focused or not. Co-Authored-By: Claude Opus 5.5 <[email protected]>
* | fs.py waits for a new file's pane to be named, not only madeGabriel Schneider44 hours
| | | | | | | | | | | | pardes --wait NEWFILE reads pane/new and then writes the pane's name, two requests; the test checked /index for the name as soon as the pane showed, and a gate run caught it between them. It waits for the name now. Co-Authored-By: Claude Opus 5.5 <[email protected]>
* | locations_config.zig and locations_cache.zig fold into locations.zig, the ↵Gabriel Schneider44 hours
| | | | | | | | | | | | | | | | Locations setting and cache beside what uses them Config (75 lines) was re-exported from locations.zig already, and Cache (213) served only its format; locations.zig is 683 lines with them. The cache's own Result, which would be ambiguous beside locations' Result in one file, is Cache.Hit, what its comment already called it. pardes.zig, dump.zig and main.zig import locations.zig. No behaviour changes. Co-Authored-By: Claude Opus 5.5 <[email protected]>
* | tag_layer.zig folds into Layer.zig, whose TagHit its two functions work onGabriel Schneider44 hours
| | | | | | | | | | | | Two functions (sameCell, columnAt) on Layer.TagHit, 32 lines with their imports, used by edit.zig, mouse.zig and look.zig: they sit with the type now, called Layer.sameCell and Layer.columnAt. docs/design.typ names Layer.zig in its place. No behaviour changes. Co-Authored-By: Claude Opus 5.5 <[email protected]>
* | Mini.zig is mini.zig: a file of functions and no fields takes a namespace's ↵Gabriel Schneider44 hours
| | | | | | | | | | | | | | | | lowercase name The naming the split agreed on, deferred until now; panes.mini is its name at its importers. File.zig keeps its alias line (const Mini = panes.mini) so the file another agent is working in changes by that line alone. The served sources list and docs/design.typ name the new file. No behaviour changes; test/perf.zig's two references change, and since the perf harness is keyed by its own text, its three baselines are recorded again (under other agents' builds, so a little slower). Co-Authored-By: Claude Opus 5.5 <[email protected]>
* | shader_build.zig is ShaderBuild.zig: a file that is a struct (its fields are ↵Gabriel Schneider44 hours
| | | | | | | | | | | | | | | | the post chain's builds) takes a type's name The naming the split agreed on: a file with fields is a type, TitleCase, as Messages.zig and Layer.zig are. Its importers bind it as ShaderBuild; comments and docs/render-pipeline.md name the new file. No behaviour changes. Co-Authored-By: Claude Opus 5.5 <[email protected]>
* | Messages.messageLog is Messages.at: the ring's i-th record, read as ↵Gabriel Schneider44 hours
| | | | | | | | | | | | | | | | p.messages.at(i) The rename deferred from the file split; no behaviour changes. Output.zig's one call follows. Co-Authored-By: Claude Opus 5.5 <[email protected]>
| |
| \
| \
| \
| \
| \
*-----. \ Merge: loose end + msize 64K + docs slimming + docs-audit fixes + monkey-gui ↵Gabriel Schneider44 hours
|\ \ \ \ \ | | | | | | | | | | | | | | | | | | + tty ssh acked frames
| | | | * | Over a slow link the tty keeps one frame in flight: it asks the terminal to ↵Gabriel Schneider44 hours
| | | | | | | | | | | | | | | | | | | | | | | | answer after each, and draws the latest state when it does
| | | | * | vaxis sends a frame with nothing changed as nothing: its secondary-cursor ↵Gabriel Schneider44 hours
| | | | | | | | | | | | | | | | | | | | | | | | test read equal as changed
| | | | * | A blank whose ink alone changed is skipped in vaxis's own frame diff, not ↵Gabriel Schneider44 hours
| | | | | | | | | | | | | | | | | | | | | | | | weighed up per cell in the tty
| | | * | | The 9P monkey allows a look's misses to each Twrite that succeeded, not to ↵Gabriel Schneider44 hours
| | | | |/ | | | |/| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 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]>
| | * / | The GUI monkey lives in test/ and runs as zig build monkey-guiGabriel Schneider44 hours
| | |/ / | | | | | | | | | | | | | | | | | | | | 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]>
| * | | Newcol shares a column's rows out again when its narrower tags would leave a ↵Gabriel Schneider44 hours
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | pane under its tag and two rows, or is refused A seeded sweep of placements (New, pane/new, Edit =, Tty, look, Delcol, deletes, refusals included) over screens 6 to 40 rows high found no refused placement that leaves a pane short since lyltlqnz and lrpzwyom; the pane a row short came from Newcol, which halves a column's width so long tags wrap onto more rows, raising those panes' minimums with no rows moved. Newcol now shares each such column's rows out again, and where a column has not the rows for every minimum there is no new column (Newcol: no space for a column: the panes' tags would not fit), as a size too small is refused. The sweep, 300 seeds, is the test; a user's drag or a tag grown by editing may still take a pane under, as before. Co-Authored-By: Claude Opus 5.5 <[email protected]>
| * | | The 9P server offers 64 KiB frames, not 8 KiBGabriel Schneider44 hours
| |/ / | | | | | | | | | | | | | | | 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]>
* | | A tag write past the limit says tag: no space: over 4096 bytes, which 9ns ↵Gabriel Schneider44 hours
| | | | | | | | | | | | | | | | | | | | | | | | maps to ENOSPC as the docs say The tree answers ENOSPC, but through a mount 9ns maps the words, and tag: over 4096 bytes carried none it knows, so a shell saw EIO. The words now hold no space; docs/fs.md says ENOSPC again. Co-Authored-By: Claude Opus 5.5 <[email protected]>
* | | A 9P error past 128 bytes keeps its reason: the path in it gives up its ↵Gabriel Schneider44 hours
| | | | | | | | | | | | | | | | | | | | | | | | middle to … An Rerror carries 128 bytes (Plan 9's ERRMAX) and the engine cut longer text there, and a builtin's failure was first clipped between words to 256 with ...: either way the end, which says why, was what went. tree.handle now fits a long reason by cutting the middle of its longest path, else of the whole text, on a character boundary, and reportFailure fills its buffer the same way. Co-Authored-By: Claude Opus 5.5 <[email protected]>
* | | A Dump makes every directory missing on the way to its DumpDir, as a fresh ↵Gabriel Schneider44 hours
| | | | | | | | | | | | | | | | | | | | | | | | HOME needs outPath made only the last directory, so on a HOME with no ~/.local/share the default DumpDir failed no such directory. It now makes each missing parent, as mkdir -p; the known-wrong line in docs/divergences.md goes. Co-Authored-By: Claude Opus 5.5 <[email protected]>
* | | pardes NEWFILE in a pane opens a pane named it in the session, as acme's B ↵Gabriel Schneider44 hours
| | | | | | | | | | | | | | | | | | | | | | | | 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]>
* | | A dump holds every column a session may, 16, not 6Gabriel Schneider44 hours
| | | | | | | | | | | | | | | | | | Dump of a session with more than 6 columns failed bad dump columns, since dump.zig's max_cols was 6 while a session holds MAX_COLS. It is MAX_COLS now; the limit's lines in docs/fs.md and docs/divergences.md go. Co-Authored-By: Claude Opus 5.5 <[email protected]>
* | | The docs and the 9P skill say each fact once, in the file that owns it, and ↵Gabriel Schneider44 hours
|/ / | | | | | | | | | | say only what a live session does Co-Authored-By: Claude Opus 5.5 <[email protected]>
* | Release Pardes 0.4Gabriel Schneider44 hours
| | | | | | | | Co-Authored-By: Claude Opus 5.5 <[email protected]>
| |
| \
*-. \ Merge: 9P round 24 + acme compat + fuzzer fixes + --wait + tty perf fixes + ↵Gabriel Schneider44 hours
|\ \ \ | | |/ | |/| | | | 9P monkey
| | * The 9P monkey's one-failure rule is a write's: a refused open, create or ↵Gabriel Schneider44 hours
| | | | | | | | | | | | | | | | | | | | | | | | 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]>
| | * The 9P monkey counts the lines a write runs as the tree does: a short ↵Gabriel Schneider44 hours
| | | | | | | | | | | | | | | | | | | | | | | | 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]>
| | * A 9P monkey drives random requests at a throwaway session and checks the ↵Gabriel Schneider44 hours
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 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]>
| * | Snapshots leave out a blank cell's ink, which shows nowhere and the tty now ↵Gabriel Schneider44 hours
| | | | | | | | | | | | keeps from the frame before
| * | The terminal's capabilities are taken up when its answer comes, not at the ↵Gabriel Schneider44 hours
| | | | | | | | | | | | first key after it
| * | Faded ink on blank cells is not sent to the terminal: a focus change sent ↵Gabriel Schneider44 hours
| | | | | | | | | | | | every blank of the other panes again
| * | A lone ESC read by itself is the Escape key at once, not after a 50 ms waitGabriel Schneider44 hours
| |/
* | pardes --wait (-w) in a pane returns only once the pane its file landed in ↵Gabriel Schneider44 hours
| | | | | | | | | | | | | | | | 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]>
* | Only a write logs an err: a refused open or truncation, create or remove, or ↵Gabriel Schneider44 hours
| | | | | | | | | | | | | | | | a write to pane/new, is its error alone, and every refusal is said in words The one-failure rule is a write's. A refused remove, pane/new's open refused for want of a slot, and an OTRUNC open's refused truncation (data's after a failed addr) also logged an err, and a reply carrying only an errno reached the client as the C library's text (Operation not permitted). tree.handle now gives such a reply Plan 9's words, chosen so 9ns maps each back to its errno (EPERM's to EACCES, as Plan 9's does), and serveFs logs errs for writes only, not a write to pane/new, which is only read. docs/fs.md and the 9P skill say so, and that a look miss quotes what was written. Co-Authored-By: Claude Opus 5.5 <[email protected]>
* | One look logs one err: a file:addr whose file is not there is one miss ↵Gabriel Schneider44 hours
| | | | | | | | | | | | | | | | quoting what was written, and a refused placement is the look's only failure A look at utf8txt:#3 from a terminal searched for utf8txt, missed, then found the terminal no text to address: two errs for one write. It is now looked for whole, as zzq:2 already was, so every form's miss reads no match for "<as written>". A look whose new pane was refused a place went on to settle its line in the pane it stayed on and logged has no line N after the placement failure; it now stops there. Co-Authored-By: Claude Opus 5.5 <[email protected]>
* | A name written whole with no newline is checked with its write, as the docs ↵Gabriel Schneider44 hours
| | | | | | | | | | | | | | | | now say, not at the close Round 24's no-newline rule (uwzuqzxp) already covers name, a lines file; the 9P monkey's close_runs_only_line_files repros were from a binary before it. This pins it with a test and corrects docs/fs.md, which still said such a name waited for the close. Co-Authored-By: Claude Opus 5.5 <[email protected]>
* | Under pardes's placement a pane whose neighbour is in no column goes at a ↵Gabriel Schneider44 hours
| | | | | | | | | | | | | | | | column's foot, not nowhere After Delcol took the last column's panes, pane/new under Placement made a scratch that no column held, since a scratch was placed only under the asking pane, which was gone; a look from it then unwrapped the missing parent in belowParent and panicked (the 9P monkey's crash-e1873f34). Both now fall back to the foot of the active column, else the last. Co-Authored-By: Claude Opus 5.5 <[email protected]>
* | The grapheme width test expects two cells for two invalid bytes, as qsltkuom ↵Gabriel Schneider44 hours
| | | | | | | | | | | | | | | | draws them Its reference list compared \xe4\xb8 with vaxis's own gwidth, which counts the pair one cell; since qsltkuom each invalid byte is a cell, one U+FFFD each, as surface.zig draws it, so the pair is two. The unit suite failed on it. Co-Authored-By: Claude Opus 5.5 <[email protected]>
* | An invalid byte in a grapheme is one cell, and never reaches vaxis's widthGabriel Schneider44 hours
| | | | | | | | | | | | uucode joins a stray lead byte (as U+FFFD) to a following e and combining mark into one grapheme; vaxis's gwidth then counts back the replacement rune's three bytes over the one byte it stood for and overflows (gwidth.zig:62), panicking the next frame after a write of \xee e \xcc\x81 to xdata (the 9P monkey's crash-b2417c49). graphemeDisplayWidth now gives each invalid byte one cell, as surface.zig draws it, and measures the valid runs between alone. Co-Authored-By: Claude Opus 5.5 <[email protected]>
* | Writes held before the shell's clock is first seen no longer overflow its ↵Gabriel Schneider44 hours
| | | | | | | | | | | | | | | | first step A 9P write served before a detached host's first pump holds its batch stamped at time 0, so nextWake said to wake at 20 ms while advance, seeing the clock for the first time, set stepped_ns days later and counted due - stepped_ns back past zero: an integer-overflow panic. It was what the 64 KiB msize trial hit in fs-test (restore detached space, the connection closing at the first write's clunk), a race any msize can lose. A batch's wake is now never before the next frame. Co-Authored-By: Claude Opus 5.5 <[email protected]>
* | A class with non-ASCII runes matches them: [éa-z] is taken as (é|[a-z]), a ↵Gabriel Schneider44 hours
| | | | | | | | | | | | | | | | range up to 256 runes spelled out mvzr's classes hold bytes, and it refused a multibyte member as a bad expression. Rewriting the class before compiling, as ^a|^b already is, needs no mvzr patch; runes that differ only in their last byte go as one alternative (\xc3[\xa0-\xbf] for [à-ÿ]) so a 256-rune range fits the 512-operation limit, which counts the pattern as rewritten. A wider range and [^é] are refused, naming why. Co-Authored-By: Claude Opus 5.5 <[email protected]>
* | The README and the 9P skill warn that plan9port's 9p write always truncates, ↵Gabriel Schneider44 hours
| | | | | | | | | | | | | | | | so it replaces a body acme ignores OTRUNC, pardes honours it, and 9p write sets it on every open: a pipe into body that appended under acme replaces the text here. The fix is >> through a mount. Co-Authored-By: Claude Opus 5.5 <[email protected]>
* | A search whose pattern opens with a literal jumps to where that literal is, ↵Gabriel Schneider44 hours
| | | | | | | | | | | | | | | | not through every line Finding /line 049999/ in 1171 KB took 175.5 ms (Debug), each line run through mvzr's matcher in turn. The literal prefix (none when the pattern has a | anywhere) is found with indexOfPos first and matching starts on its line: 4.44 ms. Co-Authored-By: Claude Opus 5.5 <[email protected]>
* | A write to addr, limit or mark asks for no frame, so its close is not held ↵Gabriel Schneider44 hours
| | | | | | | | | | | | | | | | behind one Every write that changes a pane set needs_frame, an addr write too, so the editor drew a whole frame after each and the clunk that followed waited for the turn while it did: 0.5 ms (Debug) to 1.2 ms a clunk, what made addr and event write-back 4-10x acme's. An address, a limit and the mark flag are nothing drawn; their writes no longer ask for a frame. Clunk after an addr write: 0.518 -> 0.015 ms (Debug tty, fs.py client). Co-Authored-By: Claude Opus 5.5 <[email protected]>
* | A pane's ctl reads acme's fields in acme's order, the undo and redo flags ↵Gabriel Schneider44 hours
| | | | | | | | | | | | | | | | included, then pardes's own Where plan9port's line has whether Undo and Redo have a step, pardes's had current, so a client reading acme's fields by position read a word for a flag. The two flags now follow the tab width, as in plan9port's winctlprint, and current|notcurrent and a REPL's id come after them. Co-Authored-By: Claude Opus 5.5 <[email protected]>
* | A pane's ctl takes acme's ctl words, done by the files that replace themGabriel Schneider44 hours
| | | | | | | | | | | | name, put, clean, dirty, del, delete, dot=addr, addr=dot, limit=addr, mark, nomark, show and cleartag were unknown control messages. Each is now done by the file or builtin that replaces it (name, Save, dirty, Del, a Del that does not ask, dot and addr and limit, mark, the tag), checked with the rest of the write before any runs; dump, dumpdir, font, menu and nomenu are refused, EINVAL, saying where pardes does it or that it has no such thing. Co-Authored-By: Claude Opus 5.5 <[email protected]>
* | acme's words run as pardes's or are refused, never as shell commands: Put savesGabriel Schneider44 hours
| | | | | | | | | | | | Put, Get, Delete, Snarf, Cut, Paste, Zerox, Sort, Putall, Load, ID and Send written to exec or tagexec each ran as a shell command that exited 127, the write answering 0 -- a Put that looked like a save. Put now runs Save and Delete a Del that does not ask; the rest are refused, EINVAL, invalid: acme's X is not a pardes builtin (with where pardes does it, where it does), in exec and ctl alike. Co-Authored-By: Claude Opus 5.5 <[email protected]>
* | A look that misses file:/re/ names the file and is logged as that file's pane'sGabriel Schneider44 hours
| | | | | | | | | | | | A miss said only look: no match for regexp, against the pane the look came from. It now says look: <file>: no match for regexp, on the pane of the file it searched. Co-Authored-By: Claude Opus 5.5 <[email protected]>
* | A refused Delcol changes nothing: no +Unsaved opens, no focus movesGabriel Schneider44 hours
| | | | | | | | | | | | Delcol's refusal opened +Unsaved, placing a pane in the layout it was refusing to change. Its unsaved records and notice say which panes; the list pane is left to the refusals of the other words. Co-Authored-By: Claude Opus 5.5 <[email protected]>