From cfcff94ab2b1ff5a0fb61dead60ead09bf892d30 Mon Sep 17 00:00:00 2001 From: Gabriel Schneider Date: Mon, 28 Sep 2026 12:15:03 -0300 Subject: docs: data's truncation is pardes's own, a second write inserts, and a waiting pty/run is cancelled Review asked the docs to say what a script trips on: acme ignores OTRUNC on data (fsys.c:543), so truncating it is an extension; addr sits past each write, so a second echo x > data inserts after the first; and a pty/run line waiting for a fresh terminal's first prompt waits for ever if none is drawn, so the way out is to interrupt the read. The lock's retry advice was already there. Co-Authored-By: Claude Opus 5.5 --- .agents/skills/pardes-9p/SKILL.md | 5 +++++ docs/fs.md | 11 +++++++++-- src/fs-help.txt | 2 +- 3 files changed, 15 insertions(+), 3 deletions(-) diff --git a/.agents/skills/pardes-9p/SKILL.md b/.agents/skills/pardes-9p/SKILL.md index 330f029d..e031f436 100644 --- a/.agents/skills/pardes-9p/SKILL.md +++ b/.agents/skills/pardes-9p/SKILL.md @@ -50,6 +50,7 @@ $m/look write a line = a right click on it at the active pane $m/exec write a line = a middle click: an editor command word, or a shell line $m/pane//pty/run write one line, read `exit N` + its output, or `busy` / `error ...`, on the same open: exec 3<>$m/pane/$n/pty/run; echo make >&3; cat <&3 + (a fresh terminal: waits for its first prompt; if none comes, interrupt the read) $m/log recent events, then EOF: new|del|rename|save , msg (exec 3<>$m/log; echo follow >&3; cat <&3 waits for new ones; tail -f does not) $m/screen the rendered screen as JSON, frozen per open @@ -129,6 +130,10 @@ For a file or scratch pane, with `pane=$m/pane/`: | Address a byte range | `echo '#0,#2' > $pane/addr` | `client.write(pane + '/addr', b'#0,#2')` | | Replace that range | `printf 'pub fn' > $pane/data` (`>>` too) | `client.write(pane + '/data', b'pub fn')` | | Delete that range | `: > $pane/data` | truncate `data` (open with OTRUNC) | + +A write leaves `addr` just past what it wrote, so a second `echo x > data` +inserts after the first: write `addr` again before each replacement. +Truncating `data` is pardes's own (acme ignores OTRUNC and always inserts). | Read the selection | `cat $pane/dot` (offsets), `cat $pane/sel` (text) | the same two reads | | Select the addressed range | `cp $pane/addr $pane/dot` | `client.write(pane + '/dot', client.read(pane + '/addr'))` | | Reload from disk | `echo get > $pane/ctl` | `client.write(pane + '/ctl', b'get\n')` | diff --git a/docs/fs.md b/docs/fs.md index bd8ca055..7d0e797c 100644 --- a/docs/fs.md +++ b/docs/fs.md @@ -265,7 +265,11 @@ it is set. Truncating a range file empties it; truncating `limit` lifts it. Truncating `data` or `xdata` deletes the range `addr` names and nothing else, so a shell's `echo NEW > data` replaces that range, `: > data` deletes it, and `>>` inserts at it; only truncating `body` empties the -whole buffer. +whole buffer. Truncating `data` is pardes's own: acme ignores OTRUNC there +(editors/acme/fsys.c:543) and every write inserts. And as in acme a write +leaves `addr` just past what it wrote, so a second `echo x > data` deletes +the empty range there and inserts after the first rather than replacing it +again; write `addr` before each replacement. `addr` belongs to the pane rather than to a client and keeps what was written until someone writes or truncates it, so writing an address and reading it back evaluates it, which is what acme(4) promises of its own `addr`. @@ -389,7 +393,10 @@ which is also when the third field of `pty/status` reads 1. A line written before a new terminal's shell has drawn its first prompt is not busy: it waits for that prompt (a respawn meanwhile keeps it waiting for the new shell's) and is sent then, so the first command a script gives a fresh -terminal is not lost; `error not run` when the shell refused +terminal is not lost. A shell that never draws a tagged prompt (one pardes +could not instrument, or a startup that hangs) leaves such a line waiting +for ever: cancel the read (interrupt it, or close the open) to give up; +`error not run` when the shell refused the line without running it (a fish syntax error; the line is taken back off the prompt); `error shell gone` when the pane closed or its shell was replaced; `error no prompt marks` for a shell pardes could not instrument. diff --git a/src/fs-help.txt b/src/fs-help.txt index bbff6f13..689d8839 100644 --- a/src/fs-help.txt +++ b/src/fs-help.txt @@ -36,7 +36,7 @@ Below, $m is the mount (/mnt/9p/pardes/ via 9ns --mntgen; PARDES_MOUNT in a Pitfalls, one each: Each open of pane/new makes another pane (ls, stat, find never do); rmdir closes even a dirty one. addr takes #n,#m or sam-style /regexp/ (^ $ per line); a failed one makes data refuse until reset. - data: > replaces just the addr range and : > deletes it; body: > empties the whole buffer. + data: > replaces the addr range, : > deletes it, a 2nd > inserts (addr moved); body: > empties all. tag reads the path, then the tag's own text; writes append to that text; truncating clears it. A terminal's body is a history snapshot frozen per open; pty/data is the live stream. exec: a word no builtin knows is typed into a terminal in the pane's directory, and not an error. -- cgit v1.3