From 35e865eba278a1ef48a6ce160767d652a9c54ae8 Mon Sep 17 00:00:00 2001 From: Gabriel Schneider Date: Tue, 29 Sep 2026 06:22:15 -0300 Subject: The docs: Kill leaves bash and fish to run the rest of a line, index rows split from the right, busy names its program, chord follow-ups, /commands rows, Exit's second refusal Dogfood round 16 took these literally and found them false: bash ran the echo after Kill as fish does; a name with spaces broke split(maxsplit=3) since the row ends with the column serial; pty/run's busy line names the program; /commands rows end in a description; a second Exit refusal names only panes edited since. Co-Authored-By: Claude Opus 5.5 --- .agents/skills/pardes-9p/SKILL.md | 13 ++++++----- docs/fs.md | 45 +++++++++++++++++++++++++++------------ src/fs-help.txt | 6 +++--- 3 files changed, 42 insertions(+), 22 deletions(-) diff --git a/.agents/skills/pardes-9p/SKILL.md b/.agents/skills/pardes-9p/SKILL.md index 9e540de8..f9d9e34d 100644 --- a/.agents/skills/pardes-9p/SKILL.md +++ b/.agents/skills/pardes-9p/SKILL.md @@ -80,11 +80,12 @@ $m/ctl the settings, one a line as a write takes them; write a setting or (Newcol makes an empty column, Dump, Theme x; Exit QUITS the editor, Kill [word...] stops the commands pardes started (command panes, lines it typed into shells), a word matching a command line's first word; Exit and Restore refuse once, - naming every unsaved pane, `, : Modified (Exit again to discard them all)`, and the same - word again DISCARDS that text -- not a retry, unlike lock's `file in use`; + naming every unsaved pane, `, : Modified (Exit again to discard)` (Restore's says + `Restore again`); a second refusal names only the panes edited since the last, + as acme's does, and the same word again with nothing edited since DISCARDS them all -- not a retry, unlike lock's `file in use`; Kill stops a command pane's whole line, `&` jobs included; of a line typed into a shell only the foreground job, and the shell decides the rest (of `sleep 30; echo done` - fish runs the echo, bash abandons the line); Joincol folds the keyboard's column into the one + bash and fish both run the echo); Joincol folds the keyboard's column into the one on its right, its panes going below that column's own, in order, and needs such a column); a pane's builtins (Del, Save f, Collapse, which folds that pane, and the column word Delcol, which closes that pane's column) go to $m/pane//ctl @@ -107,8 +108,10 @@ $m/os/ the host filesystem ``` The first field of an index row is a stable pane serial, not a slot or row -number. A row is `serial kind dirty name`, so `row.split(maxsplit=3)` keeps a -name with spaces intact. Re-read the index after anything that might open, +number. A row is `serial kind dirty name column`, the last word the pane's +column serial, so `head, col = row.rsplit(maxsplit=1)` then +`serial, kind, dirty, name = head.split(maxsplit=3)` keeps a name with spaces +intact. Re-read the index after anything that might open, reuse or close a pane. ```sh diff --git a/docs/fs.md b/docs/fs.md index 0da2ccd0..e7c85681 100644 --- a/docs/fs.md +++ b/docs/fs.md @@ -167,8 +167,10 @@ builtins, one a line, at whichever pane has the keyboard as each runs -- `Newcol`, `Dump`, `Mount name dial`, `Theme ink`, `Verbose off`; `Exit`, which quits the editor as acme's does (it refuses once, naming each pane with unsaved text, a `+New` scratch of 100 bytes or more too, in one line, -`, : Modified (Exit again to discard)`, and a second `Exit` -with nothing edited since quits, throwing that text away; a scratch or a +`, : Modified (Exit again to discard)`, whether it came +through a `ctl` write or a click; an `Exit` after more editing refuses +again naming only the panes edited since the last refusal, as acme's does, +and an `Exit` with nothing edited since quits, throwing all of it away; a scratch or a command's output under 100 bytes is not asked about, as acme's winclean asks about no small unnamed window (so a scratch's `dirty` of 1 in `/index` blocks nothing until it holds 100 bytes: it has no file to be out of step @@ -209,9 +211,10 @@ shell's group, so there is none to signal: Kill says `Kill: no job to signal`, and a write of it to `ctl` fails with that; with nothing running it says `Kill: nothing running`; and, of a typed line, only the foreground job, after which what the rest of the line does is the shell's -affair: of `sleep 30; echo done` typed at a prompt, fish goes on and runs -the `echo`, and bash abandons the line, as each does when a job it waits -on is killed -- +affair: of `sleep 30; echo done` typed at a prompt, bash (saying +`Terminated`) and fish (saying `Job 1, 'sleep 30' terminated by signal +SIGTERM`) both go on and run the `echo`: SIGTERM, unlike an interrupt, +ends only the job, not the line -- and reads every setting there is, one a line, in the words a write of it takes (`Verbose on`, `WindowOpacity 70`, `PanelSlide off`, `DumpDir `, `LocationsConfig ...`), so writing what it reads @@ -256,10 +259,19 @@ performed what it asked for (a save written, a shell started). A click on the same word, or the word written to `exec`, still opens its prompt. `/commands` lists every builtin the registry holds, in registry order, one -a line: its word, `arg` when it takes one, `root` or `pane` for the ctl -that takes it, and for a setting that chooses among words those words, -comma-joined, e.g. `Newcol root`, `Save arg pane`, `Verbose arg root on,off`, -`Placement arg root acme,pardes`. Such a setting written bare steps to its +a line: its word, `arg` when it takes one, `root`, `pane` or `both` for the +ctl that takes it, for a setting that chooses among words those words, +comma-joined, then ` -- ` and one sentence of what it does (a builtin's doc +comment's first sentence, a setting's doc), e.g. + +``` +Newcol root -- An empty column right of the keyboard's, its tag taking the keyboard. +Save arg pane -- Write the pane's text to its file, or to the file its argument names. +Verbose arg root on,off -- A builtin says its own name on the message row as it runs, on or off. +Placement arg root acme,pardes -- Where a new pane goes: acme, as makenewwindow does, or pardes, the older rules. +``` + +Every builtin has its sentence; a test fails the build of one without. Such a setting written bare steps to its next value, so a two-valued one flips (`Crt`, `Placement`, `BootShell`), as its word clicked in a tag does; a value it does not take is refused with `bad value in control message; takes ...` naming those it does. It is @@ -709,10 +721,12 @@ for every line the editor says (with `verbose` on, that includes each builtin announcing itself as it runs, on purpose: the log says which ran -- unless the builtin then says something of its own that starts with its name, `Kill: nothing running`, which takes the announcement's place; a -builtin that fails a ctl write is logged by that write's `err` alone, no -announcement and no `msg`, so the same failure again is the same record +builtin that fails its write (`ctl`, `exec`, `/tagexec` or a column's +`exec`) is logged by that write's `err` alone, no announcement and no `msg`, so the same failure again is the same record again; a line said again word for word is counted, `msg 3 Undo: nothing to -undo (x40)`, as `err` is (below); its serial is the pane it ran at, `-` when the keyboard was on a +undo (x40)`, as `err` is (below); a text past 256 bytes is cut there, +between words, and ends in an ellipsis, `…`, as an `err`'s reason is past +200; its serial is the pane it ran at, `-` when the keyboard was on a column or workspace tag, or the line came to the root's ctl, `/tagexec` or a column's ctl or exec), and `err : ` for every write or truncation the tree refused or that @@ -746,7 +760,9 @@ action's case says where: `x`/`l` a click executed or looked at in the tag of the tag. The flag is acme's: 1 the text is a builtin's word, 2 the range was expanded from a click (a second record gives the original range), 4 (a look) the text is a file name or address, 8 (an exec) chorded: two records -follow, the argument's text and where it came from, `:#q0,#q1`. +follow, the argument's text and where it came from, `:#q0,#q1`, each +with no place of its own: offsets `0 0` and flag 0, `Mx0 0 0 5 hello` (as +acme's exec.c:182 writes them). Written back, an `X`/`x` record executes and an `L`/`l` record looks, as the click would have. A chorded one (flag 8) runs with its argument: the record after it in the same write, else the one kept from the click; its @@ -814,7 +830,8 @@ are read so that the answer costs the editor a bounded amount. `exit ?` is a command whose end mark carried no status, which is not a success; `error out of memory` is an answer that could not be made. The header is always the whole first line. It reads -`busy` at once when a command is running or text is typed at the prompt +`busy: is running` at once when a command is running (bare `busy` +where the host cannot name the program, and when text is typed at the prompt) -- a run is a line typed at the shell's prompt, so a program holding the terminal (a REPL, `less`) takes none: write to `pty/data` for it -- which is also when the third field of `pty/status` reads 1. `pty/status` is diff --git a/src/fs-help.txt b/src/fs-help.txt index dc974683..bd822b60 100644 --- a/src/fs-help.txt +++ b/src/fs-help.txt @@ -1,7 +1,7 @@ Pardes control filesystem ========================= README this guide -index one line per pane: serial, kind (text|term|pdf|image), dirty flag, name (+New if unnamed), column serial +index one line per pane: serial, kind (text|term|pdf|image), dirty flag, name (/+New if unnamed), column serial; rsplit(maxsplit=1) first, names hold spaces status pid, version and pane count look write a line: a right click on it at the active pane; read: the serials it touched (this open's) exec write a line: a middle click, an editor command word or a shell line; read the same (every exec file) @@ -13,7 +13,7 @@ ctl settings a line; or Newcol, Dump, Restore [f], Exit (asks once), Kil commands every builtin: word, arg if it takes one, root|pane|both (the ctl that takes it), -- what it does layout a line per column: serial index x width current|notcurrent empty|full pane-serials; active tag the workspace tag, tagexec a word as a click in it; col// a column's tag, ctl (Delcol Joincol New Tty), exec; rmdir: empty only -pane/new open it to make a pane (named +New) in the active column, filling it if empty; the read answers its serial +pane/new open it to make a pane (/+New) in the active column, filling it if empty; the read answers its serial pane// name body tag ctl addr dot limit data xdata sel dirty mark scroll errors (write-only: appended to its directory's +Errors pane) event look exec tagexec, pty/ on terminals; rmdir closes os/, src/ the host filesystem; the editor's own sources @@ -29,7 +29,7 @@ $m below: $NINE_MOUNT/pardes/; $NINE_MOUNT under 9ns --unix; PARDES_MO echo 'Edit ,x/foo/c/bar/' > $m/pane/$n/ctl rename every foo, one undo step (sam's commands) exec 3<>$m/log; echo follow >&3; cat <&3 what happened lately, then wait for more echo Tty > $m/pane/$n/ctl; cat $m/index a terminal in that pane's directory - exec 3<>$m/pane/$n/pty/run; echo make >&3; cat <&3 exit N then its output; or busy, or error + exec 3<>$m/pane/$n/pty/run; echo make >&3; cat <&3 exit N then its output; or busy: is running, or error printf 'ls\r' > $m/pane/$n/pty/data type into a terminal; pty/status: cols rows busy echo 'sig INT' > $m/pane/$n/pty/ctl interrupt it; also winsize C R, and exec to restart -- cgit v1.3