diff options
Diffstat (limited to '.agents')
| -rw-r--r-- | .agents/skills/pardes-9p/SKILL.md | 34 |
1 files changed, 24 insertions, 10 deletions
diff --git a/.agents/skills/pardes-9p/SKILL.md b/.agents/skills/pardes-9p/SKILL.md index 16e90dc9..1d32ce7a 100644 --- a/.agents/skills/pardes-9p/SKILL.md +++ b/.agents/skills/pardes-9p/SKILL.md @@ -34,6 +34,10 @@ cat "$m/pane/$PARDES_PANE/body" From there the editor is files: `cat`, `echo >`, `ls` and shell scripts are the whole interface, and nothing below needs more than they do. +`pardes FILE` run in a pane opens FILE in that session and returns at once; +`pardes --wait FILE` returns when that pane is deleted (1 if the session goes +away), which is what `EDITOR='pardes --wait'` needs (`GIT_EDITOR` follows it). + Entries for dead sessions stay listed and answer `Input/output error` on any access, so name the session you mean rather than globbing or taking the newest. `cat "$m/index"` is the cheapest liveness check, and `cat "$m/status"` reports @@ -164,9 +168,10 @@ an open that never wrote, the session's last. With other clients about, write and read one open (`exec 3<>$m/look; echo x >&3; cat <&3; exec 3<&-`). A read is a stream: once read, a second read on the same fd gives EOF (on an open that wrote, until its next write); open again, or seek to 0, to read -it again. Each command line runs once whole, however a mount cuts a big write; a last -line with no newline runs when the open closes, and an Edit block still open -then fails there (an `err`: ``unmatched `{'``, or an a/c/i text with no `.` +it again. Each command line runs once whole, however a mount cuts a big write; a +write's last line with no newline runs with it (and fails it), unless the +write filled its 9P message and may go on; an Edit block still open when the +file closes fails there (an `err`: ``unmatched `{'``, or an a/c/i text with no `.` line), changing nothing. One rule: a builtin that fails, whether through a ctl (a pane's pty/ctl `exec` too), look, exec, tagexec or a column's exec, fails the write (EINVAL for a malformed line, ENOENT for what is not there -- @@ -209,7 +214,11 @@ leaves a multi-line input at `...`). A middle click, or an event write-back, sends what it needs by itself. Sent line by line, a blank line ends a Python block, and Python 3.14's REPL auto-indents each line it is typed. Every refused 9P write adds an `err <serial|-> <file>: <why>` record to `$m/log`; through a mount the write itself only says -`Invalid argument`. +`Invalid argument`. Only writes log one: a refused open or truncation +(an OTRUNC open, as `data`'s after a failed `addr`), create or remove is +its error alone, as are a write to `pane/new` (`permission denied`) and a +write on a fid opened read-only (`bad use of fid`). Errors are words, never +a C errno string. A look miss quotes what was written: `no match for "zzq:#3"`. ## Edit through addresses, dot and the flag files @@ -274,6 +283,8 @@ A `+New` scratch counts as unsaved (and holds up Exit, Restore, Del) only once it holds 100 bytes or more. A read of `data` or `xdata` moves `addr` past what it read, as in acme. Truncating `data` is pardes's own (acme ignores OTRUNC and always inserts). +plan9port's `9p write` always opens with OTRUNC, so `… | 9p write pane/body` +replaces the whole body: append with `>>` through a mount instead. | 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` (refused once while there are unsaved edits; again discards) | `client.write(pane + '/ctl', b'get\n')` | @@ -290,13 +301,15 @@ newline, the leftmost match wins (the first alternative there, not the longest). In a pattern with `\n`, `^` works only first (`^def .*\n` finds every def line) and `$` only just before a `\n`; anywhere else the pattern is refused, not silently unmatched. `^def|^ ` finds lines starting either way -(every branch anchored; a mix like `^def|x` is refused). An expression is evaluated from the current address (the last one +(every branch anchored; a mix like `^def|x` is refused). `[éa-z]` and +`[à-ÿ]` match those runes (a range up to 256 runes); `[^é]` and a wider +range are refused. An expression is evaluated from the current address (the last one written, or just past the last `data` write): `.` is that address, not the selection, `/re/` searches on from its end and wraps unless `limit` is set, `?re?` or `-/re/` searches back, `#100,#50` fails `addresses out of order`, -and a search that backtracks -past a step budget (about 300 ms) fails with `regular expression search -gave up, ...`. A failed address says +and one search that runs past its step budget (about 300 ms; each search of +an Edit `x` has its own) fails with `regular expression search took too +much time, gave up`. A failed address says why (`no match for regexp`, `address out of range`) and leaves no address: `addr` reads empty and `data` refuses until the next good one, so a missed target is never written at the old one. Moving `dot` scrolls the pane to it. `limit` bounds @@ -318,8 +331,9 @@ an open nor a `>` resets it (acme resets it on the first open): each `echo /re/ Write `0` to start from the top. The search wraps, so stop a find-all loop when the address comes back to where it began, or set `limit`. `$pane/ctl` reads acme's window status line — serial, tag length, body length, -a reserved zero, the dirty flag, the width in cells, the font and the tab -width, then `current` or `notcurrent` — and takes `get` (reload from disk), +isdir (0), the dirty flag, the width in cells, the font, the tab width, the +undo flag and the redo flag, as acme's fields — then `current` or +`notcurrent` — and takes `get` (reload from disk), `lock`/`unlock`, and any builtin that acts on a pane (`Del`, `Save f`, `Collapse`, `Undo`/`Redo`: 256 steps; with none left they say so, and the write succeeds). A `lock` another open holds fails at once with `file in use` |
