summaryrefslogtreecommitdiff
path: root/src
Commit message (Collapse)AuthorAge
* Every builtin says what it does in /commands, and a test holds each to itGabriel Schneider3 days
| | | | | | | | | 87 of the listed words had no description: settings have no doc comment to read, so each now carries a one-sentence doc, and the builtins without one got theirs. Exit's no longer names an internal function, and Repl's first sentence is short enough to be read whole. Co-Authored-By: Claude Opus 5.5 <[email protected]>
* A clicked Exit's refusal names every unsaved pane in one line, as a ctl ↵Gabriel Schneider3 days
| | | | | | | | | | write's does Under the one rule a click fails its write too, but only a ctl write assembled the `<a>, <b>: Modified (Exit again to discard)` line: a click failed with the first pane's name alone. Co-Authored-By: Claude Opus 5.5 <[email protected]>
* A pane from pane/new is the session's directory's scratch, not the last ↵Gabriel Schneider3 days
| | | | | | | | | | active pane's No pane asked for it, so borrowing the directory of whichever pane last had the keyboard named it after an accident; acme's new window has acme's directory. Co-Authored-By: Claude Opus 5.5 <[email protected]>
* A pty/ctl winsize gives a terminal two rows at least, so it no longer reads ↵Gabriel Schneider3 days
| | | | | | | | | | | | busy for ever A one-row pty loses the prompt's input mark as soon as the prompt wraps, and busy detection never sees the shell idle again. Placement already keeps a new terminal at tag + 2 rows; a winsize write now keeps the pty at two. A pane dragged down to one body row keeps a one-row pty, since a taller pty than the pane shows would put its cursor below the pane. Co-Authored-By: Claude Opus 5.5 <[email protected]>
* A new pane with no room under the last goes last all the sameGabriel Schneider3 days
| | | | | | | | | | | | | A pane from pane/new or New takes the bottom half of its column's last pane, as acme's coladd does (cols.c:62-65); when that pane is too short to give it a tag and 2 rows, the fallback halved the tallest pane and put the new one under it, mid-column (the 7 9 8 found). It now goes last all the same, with half the tallest pane's rows (its tag measured at the column's width). Tty from a pane's ctl already follows acme's makenewwindow (the active column first, util.c:456-467); fs.md now says so rather than beside that pane. Co-Authored-By: Claude Opus 5.5 <[email protected]>
* @p<serial>:<address> takes any sam address, as file:<address> doesGabriel Schneider3 days
| | | | | | | | | | @p<serial> took a line spot but an address after it (/re/, #n, $, 0/re/, a range) was dropped, the name failing the file check, and an unknown serial fell through to a search. The pane is now addressed like a file; a miss and a serial no pane has each log an err, and look reads back empty. Co-Authored-By: Claude Opus 5.5 <[email protected]>
* A word written to a raw terminal's look is listed, as in normal modeGabriel Schneider3 days
| | | | | | | | | A new Tty is in raw mode, where a right click is its program's, and a look written to it over 9P did nothing for that reason. The look file is no keyboard input: over 9P a plain word is listed in a +Search pane and read back whatever the terminal's key mode. Co-Authored-By: Claude Opus 5.5 <[email protected]>
* One rule for failing builtins: the write fails, one err, no msgGabriel Schneider3 days
| | | | | | | | | | | | | | | | A builtin that failed through a ctl failed the write and logged its err, but through look, exec, tagexec or a column's exec it only said so on the message row, logged as a msg, and the write succeeded. Now every click write runs its builtin as a ctl line does (ctl.captured): a failure fails the write, with its words (EINVAL for malformed input, else EIO or what the words name), logs one err and no msg or announcement. get's Modified and a look miss are shown but logged once, as their err. A control character's refusal names its reason, a failed click reads back nothing, and look never reads back a pane closed since. The special case for a cut-short Edit through exec goes (the rule covers it); fs.md's table of exceptions becomes the one rule, as does the skill. Co-Authored-By: Claude Opus 5.5 <[email protected]>
* A watched file's deletion wakes the watch at onceGabriel Schneider3 days
| | | | | | | | | | The directory mark took CLOSE_WRITE, MOVED_TO and CREATE only, so a file deleted or moved away was noticed only when something else in the directory next changed. The mark takes DELETE and MOVED_FROM too, so changed <serial> deleted comes at once; a test deletes a watched file and finds the watch readable within a second and the pane told. Co-Authored-By: Claude Opus 5.5 <[email protected]>
* @p names a pane by its serial, as /index and the log doGabriel Schneider3 days
| | | | | | | | | | | | A +Search row for a pane with no path (a terminal's), a jump list row and a line-number look said @p<slot>, the pane's place in the core's table, which no client can see. They now say @p<serial>, and @p resolves a serial. Re-recorded by name, their diffs checked: jumps, ttylook and psearch (whose waits now say @p1) for @p<serial>, and with them argv, nested, reflow, tinywin, ttyhelp and ttyonly for the boot scratch now named <cwd>/+New (the change before). Co-Authored-By: Claude Opus 5.5 <[email protected]>
* An Edit block cut short through exec is an err, not a msgGabriel Schneider3 days
| | | | | | | | | An exec write does not fail for what its command says, so an a/c/i text or { group cut short by a write that ended early was only a msg, easy to miss. Over 9P, that failure (a truncated write, not a command's) is now logged as an err record naming exec; the pane still says it. Co-Authored-By: Claude Opus 5.5 <[email protected]>
* get and a deleted file say what happened: the path, changed <serial> ↵Gabriel Schneider3 days
| | | | | | | | | | | | | | deleted, reloaded get on a file gone from disk failed with a bare ENOENT; it now says get: <path>: no such file. A watched file deleted on disk was silent; the pane keeps its text and says <file> deleted on disk (Save writes it again) once, logged changed <serial> deleted (only a path the watch has read: a pane renamed to a name never on disk is not deleted). A get that throws a dirty buffer's state away logs changed <serial> reloaded, as the watch's reload does. Co-Authored-By: Claude Opus 5.5 <[email protected]>
* A long err record is cut between words, with an ellipsisGabriel Schneider3 days
| | | | | | | An err record's reason was cut at 200 bytes, mid-word. It is now cut at the last word that fits, and ends with an ellipsis. Co-Authored-By: Claude Opus 5.5 <[email protected]>
* A look that makes a +Search pane reads back that paneGabriel Schneider3 days
| | | | | | | | With LookWord list, or in a terminal, a look lists every place in a +Search pane, yet look read back the source pane, as if the hit were selected there. It now reads back the +Search pane it made. Co-Authored-By: Claude Opus 5.5 <[email protected]>
* The boot scratch is <cwd>/+New, not /+NewGabriel Schneider3 days
| | | | | | | | At boot the scratch under the shell was made before the shell said where it was, so its name was /+New. A scratch made from a pane with no directory yet is now the session's, <cwd>/+New. Co-Authored-By: Claude Opus 5.5 <[email protected]>
* A prompt a 9P request opens is an ask, answered with answer, never stackedGabriel Schneider3 days
| | | | | | | | | | | Save through exec on a terminal (or a scratch) opened its path prompt on screen, where no script could see or answer it, and a second Save stacked another. Opened while a 9P request is served, it now logs ask <serial> save path; answer <path> on the pane's ctl saves there and closes it, answer - closes it; asked again, the open one stands. A pane closed with it open logs answer <serial> -. Co-Authored-By: Claude Opus 5.5 <[email protected]>
* Tty takes a directory as long as a path may beGabriel Schneider3 days
| | | | | | | | | | | A terminal's directory rode inline in the spawn effect, capped at 256 bytes, so Tty in a directory of about 377 bytes said path too long. A directory past the inline buffer now goes out of line (Pardes.spawn_dirs, given to the host when the spawn is performed), up to the host's path limit (4095); past that, Tty says its directory is longer than a path may be. The effect queue stays its size. Co-Authored-By: Claude Opus 5.5 <[email protected]>
* Newcol at the column cap says so, and a desktop session holds 16 columnsGabriel Schneider3 days
| | | | | | | | | | | Newcol with every column slot taken, or a column too narrow to split, did nothing and said nothing. It now fails (a ctl write with it) with no space for a column: 16 max (ENOSPC through 9ns), or that the column is too narrow. MAX_COLS is 16 on a desktop, 6 on the board; each column costs about 8 KB of core state (the Pardes struct grows from 1.47 MB to 1.56 MB), most of it its tag's text. fs.md and the skill give the cap. Co-Authored-By: Claude Opus 5.5 <[email protected]>
* /commands takes each word's own doc comment, whole, without citationsGabriel Schneider3 days
| | | | | | | | | | | Repl showed Joincol's first line and Joincol another's, because a comment had drifted above the wrong declaration in builtins.zig; Kill's was cut mid-sentence and Exit's cited exec.c:892. The drifted line is back on Joincol, a parenthesis citing source (.c, .zig) is dropped, and the first sentence is kept whole up to 240 bytes, then cut between words with an ellipsis. A test checks every description opens its own word's comment. Co-Authored-By: Claude Opus 5.5 <[email protected]>
* A Save that fails logs its err, not a save recordGabriel Schneider3 days
| | | | | | | | | The save record was logged as soon as the host was asked to write, so a Save into a read-only directory logged save and then failed. It is now logged only once the write is done; a failure's err record (the write's, naming the path) stands alone, the msg it was also said as dropped. Co-Authored-By: Claude Opus 5.5 <[email protected]>
* A chorded record written back with its two follow-ups runs once, with its ↵Gabriel Schneider3 days
| | | | | | | | | | | | | argument Writing a chorded exec's three records back as read ran the argument and its location as shell commands. The first record (flag 8) now takes the next record as its argument when it comes in the same write, else the one kept from the click (or, with none kept, waits for it); its two follow-up records, however they are written, are consumed as its, never run. Tested written back together and one per write. Co-Authored-By: Claude Opus 5.5 <[email protected]>
* follow new: a log follower that starts at the endGabriel Schneider3 days
| | | | | | | | | A follower read the ring's whole history before anything new, and there was no way to skip it. Writing follow new instead of follow skips what the open froze and waits for what comes after (tail -n0 -f); fs.md and the skill say that follow replays first. Co-Authored-By: Claude Opus 5.5 <[email protected]>
* /commands says what each word does, and that the root's ctl takes EditGabriel Schneider3 days
| | | | | | | | | | | A /commands line gave a word, its argument and root or pane, but not what it does, and called Edit a pane's word though the root's ctl takes it too. Each line now ends with -- and the first sentence of the word's doc comment (read from builtins.zig itself, so there is one copy), and Edit is both. fs.md says a pane's word such as Undo or Msg is refused at the root. Co-Authored-By: Claude Opus 5.5 <[email protected]>
* An a, c or i text with no . line fails the Edit, as an open { doesGabriel Schneider3 days
| | | | | | | | | | sam takes the end of input as a text block's end, so a block cut short (a write that lost its tail, an open closed early) inserted half of itself. An Edit whose a, c or i text never meets its . line now fails with "a, c or i text not ended by a . line" and changes nothing, as an unclosed { does; at a close, logged as an err. Co-Authored-By: Claude Opus 5.5 <[email protected]>
* A pane has a tagexec: a word run as a click in its tagGabriel Schneider3 days
| | | | | | | | | | The workspace had /tagexec and a column its exec, but a pane's own tag could be clicked only by an event record. pane/<n>/tagexec runs each line as a click in that pane's tag (never redirected to its event reader, as a header's is not) and reads back what it touched. The README, fs.md and the skill list it. Co-Authored-By: Claude Opus 5.5 <[email protected]>
* A look written back from an event sets what look reads backGabriel Schneider3 days
| | | | | | | | A look an event reader wrote back ran, but /look still read the last look made through it. It now answers the pane the written-back look found, as a look written there would. Co-Authored-By: Claude Opus 5.5 <[email protected]>
* Refusals and records say more: get quotes its line, a bare answer lists the ↵Gabriel Schneider3 days
| | | | | | | | | | | | choices, a clean reload is logged get's refusal now quotes the line as a builtin's (Save's) does; a bare answer while a question stands says what it takes (answer takes k j or -); and a clean buffer reloaded from disk logs changed <serial> reloaded, as the kept dirty case logs changed <serial>. (A failed Save already says why: Save <path>: <the error in words>.) Co-Authored-By: Claude Opus 5.5 <[email protected]>
* Every refusal over unsaved text names a scratch by its pane tooGabriel Schneider3 days
| | | | | | | | | | | Exit, Restore, Del and Delcol share one list (warnModifiedIn), but it was built in 256 bytes, so with a few long paths a +New scratch near the end fell off Exit's and Restore's, which list every pane; and several +New panes were indistinguishable. The list is built in 1024 bytes (the write's error is still cut to fit, between words), and a scratch is named with its serial, /dir/+New (pane 12), the same everywhere. Co-Authored-By: Claude Opus 5.5 <[email protected]>
* A chorded exec an event reader holds is told its argument, and runs with itGabriel Schneider3 days
| | | | | | | | | | | | With event open, a 2-1 chord's exec went out as one record with flag 8 and nothing after it: the argument was freed unsaid. As acme does (exec.c:150-190), two records follow it, the argument's text and where it came from (file:#q0,#q1, empty when not known), and the pane keeps the argument, so the record written back runs with it (acme's own write-back, xfid.c:842, passes none; the reader was told, so it runs as the click would have). Co-Authored-By: Claude Opus 5.5 <[email protected]>
* A looked word selects its next place in its own pane, as acme's look3Gabriel Schneider3 days
| | | | | | | | | | | | | | A plain word looked at (a look write, a right click, an ML record written back) opened another identically named +Search pane each time, until the panes ran out, and never wrapped. As acme's look3 searches the text for it (look.c:210), it now selects the word's next place in that pane after the dot, wrapping at the end, and opens nothing. LookWord list, a new root setting, keeps the +Search listing (search is the default); the rsearch snapshot and an output test that walk the listing say LookWord list. (The leader-path check over every builtin gets a comptime branch quota, as one more builtin took the GUI build past the default.) Co-Authored-By: Claude Opus 5.5 <[email protected]>
* The docs: sam gotchas, Restore's log order and paths, stream reads, layout's ↵Gabriel Schneider3 days
| | | | | | | | | | | | | | | | | current and active Round 13's doc findings: a sam gotchas box in the skill ($-1 with and without a final newline, N+1 at the end, ^/$ at the end, 2,1, y's leading empty piece, c's literal &, columns from 1); the skill's Restore log order made the true one (new, restore, restored, restoredcol); a relative Restore path is looked for in DumpDir then the session's directory, and a bare one takes the last dump; a follower sees each (xN) as a new line; reading data or xdata moves addr; a second read of look/exec on one fd is EOF (re-open or seek 0); /layout's current (the keyboard's column) and active (acme's activecol) defined; no room, not no rows left; why a scratch's dirty blocks nothing under 100 bytes; the changed record listed. Co-Authored-By: Claude Opus 5.5 <[email protected]>
* A bare Shell names the shell it goes back to, and 12:0 says columns count from 1Gabriel Schneider3 days
| | | | | | | | | A bare Shell reset to the default without saying which; it now says Shell: the default again, <shell> ($SHELL, else /bin/sh). A line:col of column 0 said only address out of range; it now adds that a column counts from 1. Co-Authored-By: Claude Opus 5.5 <[email protected]>
* A column's ctl refuses as the other ctls do, and a bare answer says what it ↵Gabriel Schneider3 days
| | | | | | | | | | | | takes A column's ctl refused an unknown word in words 9ns maps to EIO, and took New extra as New. It now refuses the word as unknown control message (EINVAL, as the root and pane ctls) and any word but Tty with an argument as wrong #args. A bare answer on a pane's ctl says answer takes a choice or -, not unknown control message. Co-Authored-By: Claude Opus 5.5 <[email protected]>
* winsize of no size says out of range, bounded as size isGabriel Schneider3 days
| | | | | | | | | winsize 0 0 was refused as ill-formed, as if the words were wrong, and any u16 was taken. Numbers that are no size (0, or past 4096 a side, the root ctl size's bound) now say invalid winsize: out of range, 1x1 to 4096x4096 (EINVAL through a mount). Co-Authored-By: Claude Opus 5.5 <[email protected]>
* A file changed on disk never reloads over unsaved editsGabriel Schneider3 days
| | | | | | | | | | | | | | | A watched file rewritten on disk was loaded over a buffer's unsaved edits and its dirty flag cleared, so Exit and Del no longer asked about them. A clean buffer still reloads; one with edits keeps its text and stays dirty, says <file> changed on disk (get reloads it, Save overwrites it), logs changed <serial>, and its Save warns once before overwriting the newer file, as acme's Put refuses a file modified since read (exec.c:577); get asks as ever (winclean, exec.c:513). The restored-watch test's dirty case now keeps the snapshot, and the filewatch snapshot script (re-recorded by name) checks both halves: the edited pane keeps its edit and says so, the clean one reloads. Co-Authored-By: Claude Opus 5.5 <[email protected]>
* A multi-line paste into Python's REPL runs whole, back at its promptGabriel Schneider3 days
| | | | | | | | | | | | The Enter went on Python's first output after the paste, before it had taken in the whole paste, and one Enter leaves a multi-line input at ... anyway. Python's output now only restarts a 100 ms quiet wait (the 250 ms fallback stays), and a paste of more than one line gets the second Enter a block gets. fs.py runs print(11)\nprint(22), the same with a trailing newline, and a for block followed by a statement in a real python3, each back at >>>. Co-Authored-By: Claude Opus 5.5 <[email protected]>
* An Edit text block is found in linear time: only a . line is parsed againGabriel Schneider3 days
| | | | | | | | | | | Finding where an Edit block ends parsed the whole block again for every line, copying it into the scratch arena each time: a 10k-line $a block took minutes and tens of GB. sam_edit.waitsFor says what the block waits for, and while that is a text block's . line, only such a line is parsed again (editEnd, shared by Messages and completeEnd), its copy freed. A 10k-line block now takes well under a second and 50 MB of scratch. Co-Authored-By: Claude Opus 5.5 <[email protected]>
* The docs say what Restore renumbers and re-runs, what Tty takes, and how a ↵Gabriel Schneider3 days
| | | | | | | | | | | | | | | range reaches a REPL Round 12's doc findings: the README's ctl line gains Restore, Placement and size (still 45 lines, detail in fs.md); Tty's argument is a shell and Tty on a pane's ctl opens a new pane; a .py pane's range goes to its REPL as an MX<q0> <q1> event write-back; after a Restore panes are renumbered (columns count from 1 again, so often keep theirs), a command pane shows exit ? and does not re-run, and REPL bindings are gone. acme's p adds no newline to what it prints (ecmd.c:744, pdisplay), so pardes's p does not either. Co-Authored-By: Claude Opus 5.5 <[email protected]>
* A command run from a column's tag gets its pane in that columnGabriel Schneider3 days
| | | | | | | | | A command from a column's tag ran in a command pane at the foot of the last column, however far from the tag, and could reuse a finished one anywhere. It now goes to the tag's column, under both placements, and reuses only a finished command pane in that column. Co-Authored-By: Claude Opus 5.5 <[email protected]>
* pty/run's busy names the program holding the terminalGabriel Schneider3 days
| | | | | | | | | busy said only that something ran. Where the host can tell (Linux, the tty's foreground group's /proc comm, a new fg_name host call), it says busy: <program> is running; elsewhere, busy as before. The GUI's host gains the one small callback (render agent's file: gui.zig, fgName). Co-Authored-By: Claude Opus 5.5 <[email protected]>
* unlock's refusal says pane, not windowGabriel Schneider3 days
| | | | | | | "window not locked by this open" was acme's word; pardes has panes. Its test compares the constant, so it follows. Co-Authored-By: Claude Opus 5.5 <[email protected]>
* Repl's unknown-language refusal names a few whole and points to the restGabriel Schneider3 days
| | | | | | | | | The refusal listed every language and was clipped to fit, ending mid-word. It now names six, those that start as the word did first (pithon: python), says how many more, and points at docs/tags.md, which lists them all. Co-Authored-By: Claude Opus 5.5 <[email protected]>
* An event write-back past the text says range past end of bodyGabriel Schneider3 days
| | | | | | | | | A well-formed record whose range ran past the body (or tag) was refused as "bad event syntax", which sent a client looking for a typo. It now says "range past end of body" (or tag); a malformed one keeps the old words. Co-Authored-By: Claude Opus 5.5 <[email protected]>
* size says its limits, keeps every pane its rows, and ptys follow their panesGabriel Schneider3 days
| | | | | | | | | | | | size refused an out-of-range line without saying the range, took a size too small for the panes (leaving bodies of no rows), and a terminal squeezed to its tag kept a pty of its old size. The refusal now names 20x6 to 4096x4096 (a bare size is EINVAL like any malformed line), a size that would leave any pane less than its tag and 2 rows is refused and undone, and a terminal's pty is resized with its pane down to one row (only a folded or unplaced one keeps its grid). Co-Authored-By: Claude Opus 5.5 <[email protected]>
* Tty and Shell refuse a directory: not a shellGabriel Schneider3 days
| | | | | | | | | | A directory passes access(X_OK), so Tty /etc made a pane whose shell exited 127 and Shell /etc was taken. The shell lookup now refuses a directory, and both say "not a shell: /etc is a directory" (Tty and Shell share one refusal, host_io.Shell.refusal). shellset's golden takes the shared wording (re-recorded by name). Co-Authored-By: Claude Opus 5.5 <[email protected]>
* A REPL paste's Enter waits on the clock, not on stale core timeGabriel Schneider3 days
| | | | | | | | | | | | sendToRepl timed the Enter's fallback from stepped_ns, which in an idle detached session is as old as the last frame: the wait was over before it began and the \r went out with the paste, which 3.13's REPL then reads as part of it (4 of 5 sends lost their Enter). The wait now starts from the host's clock and is checked against now_ns; the REPL's echo of the paste still sends it sooner, and the wake is scheduled for the deadline. fs.py sends five times after two idle seconds each in a real pty. Co-Authored-By: Claude Opus 5.5 <[email protected]>
* A pane restored with unsaved text is asked about before it is thrown awayGabriel Schneider3 days
| | | | | | | | | Exit, Restore, Del and get warn only about a pane edited since it was opened, which its saved hash says (set at its first edit). A pane a Dump kept dirty came back with no hash, so a restored session quit at once over it. Restoring one dirty now gives it a hash its text does not match. Co-Authored-By: Claude Opus 5.5 <[email protected]>
* dump.zig's tests run: nothing had included themGabriel Schneider3 days
| | | | | | | | dump.zig was imported by the code but by no test block, so its tests, the dump settings and restored-dot ones among them, never ran. The pardes test block imports it; they all pass. Co-Authored-By: Claude Opus 5.5 <[email protected]>
* The docs give the full-column refusal, an Edit block left open at close, and ↵Gabriel Schneider3 days
| | | | | | | | | | | | byte columns Round 11's doc findings: the skill names the full-column refusal beside the 64-pane cap; fs.md and the skill say an Edit block still open when its open closes fails with unmatched { and an err; and line:col's byte columns get the tip for character columns from tools (the same on ASCII, else a search or #n). A unit test pins the unmatched { at close. Co-Authored-By: Claude Opus 5.5 <[email protected]>
* A detached session with no frontend takes its size from the root ctlGabriel Schneider3 days
| | | | | | | | | | A --detach session nobody is attached to stayed 80x24, too small for an agent's panes, and nothing could change it. The root ctl takes size <cols> <rows> while no frontend is attached (refused while one owns the size), and a client that attaches later still sets its own (the server compares with the core's size). Documented with the 80x24 default. Co-Authored-By: Claude Opus 5.5 <[email protected]>