diff options
| author | Gabriel Schneider <[email protected]> | 2026-09-30 23:53:38 -0300 |
|---|---|---|
| committer | Gabriel Schneider <[email protected]> | 2026-10-01 00:12:18 -0300 |
| commit | be7fb126aefedee221d0d32109acb9fc4b71d474 (patch) | |
| tree | f080f205f1fa47f183d6781a2901dd48e5d4536a /docs/typ/reference.typ | |
| parent | 244704dabbe279d03f1432f8474e985aeb25f2ad (diff) | |
| download | pardes-be7fb126aefedee221d0d32109acb9fc4b71d474.tar.gz pardes-be7fb126aefedee221d0d32109acb9fc4b71d474.zip | |
The docs take the 9P agent's round 30: log stats 0, names escape every control byte, $winid and the pager defaults, the one client rule, and Shift-Esc said one way in the guide and the cheatsheet
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Diffstat (limited to 'docs/typ/reference.typ')
| -rw-r--r-- | docs/typ/reference.typ | 66 |
1 files changed, 53 insertions, 13 deletions
diff --git a/docs/typ/reference.typ b/docs/typ/reference.typ index 37f3acbc..28f0c756 100644 --- a/docs/typ/reference.typ +++ b/docs/typ/reference.typ @@ -47,7 +47,8 @@ removes. Tcreate is refused everywhere. Names may hold blanks, so split `head, col = row.rsplit(maxsplit=1)`, then `serial, kind, dirty, name = head.split(maxsplit=3)`. Names in #file("/index"), the log and a terminal's tag are escaped: a newline `\n`, a -backslash `\\`, a byte that is not UTF-8 `\xNN`. +backslash `\\`, and any other control byte, DEL, a C1 control or a byte that +is not UTF-8 `\xNN`, so a name decodes to the bytes it is. = Rules for every file <rules> @@ -57,7 +58,8 @@ refused open or truncation (an OTRUNC open such as `> data` after a failed `addr`), create or remove answers its error alone, as do a write to #file("pane/new") (`permission denied`) and a write on a read-only fid (`bad use of fid`). Errors are words (Plan 9's where pardes has none of its -own), never a C library string. Through 9ns the kernel sees an errno 9ns +own), never a C library string; a ctl refusal quotes the offending word +alone (`wrong #args in control message "Newcol"`). Through 9ns the kernel sees an errno 9ns reads from those words (cloud9's `9ns/src/nine.zig`, `enameToErrno`): `control message`, `invalid` or `bad ` is EINVAL (malformed input); `no such`, `not found` ENOENT; `in use` EBUSY; `no space` ENOSPC; `denied` EACCES; anything else, such as `no match for regexp`, `address out of range`, `Modified` or an `Edit` command pardes leaves out (`w is a sam command pardes's Edit leaves out`), EIO; no refusal reads as EOPNOTSUPP. @@ -112,9 +114,8 @@ connection, and it keeps answering everything else beside its held reads. the range and flag files, the workspace's #file("tag"), the root #file("ctl"), #file("status"), #file("commands"), #file("README"), the #file("look")/#file("exec") answers, #file("focus"); #file("event") and -#file("pty/data") the next record's, zero when none waits; #file("log") -what an open would freeze. A view generated by each read stats 0, as -acme's do: #file("screen"), #file("data"), #file("xdata"), #file("index"), +#file("pty/data") the next record's, zero when none waits. A stream and a +view generated by each read stat 0, as acme's do: #file("log"), #file("screen"), #file("data"), #file("xdata"), #file("index"), #file("layout"), #file("recent"), #file("listeners"), #file("pane/new"). Read those to the end rather than trust a length (`cat` does). The qid version of #file("body"), #file("data") and #file("xdata") is the pane's @@ -143,8 +144,12 @@ files. `pardes '~/x'`), even beside a file named `~`: write `./~` for that. - A path to no file is a miss, as a search that finds nothing is: said on the message row and logged as an `err`, the write still answered. A file - that is there but will not open (no permission to read it, say) fails the - write, with why. + that is there but will not open fails the write and is named: + `look: <path>: permission denied`. A zero column is refused, `file:0:0` + included: columns count from 1. +- A whole line of a diff pane written to #file("look") is the look a + #btn("B3") click on its first column makes. The line is matched in the + pane from its cursor row on, wrapping, and the first match wins. - A plain word selects its next place after dot, wrapping (`LookWord list` on the root ctl lists every place in a `+Search` pane instead). In a terminal a word is always listed, rows spelled `@p3:12:5-9`. @@ -251,7 +256,8 @@ Writes take settings and session builtins (`scope = .session` in - #word("Exit") quits. While panes hold unsaved text it refuses once (#doc("tags", section: "unsaved-panes")): one `unsaved <serial> <name>` record per pane, then the write fails `<name>: Modified (Exit again to discard)` or `4 unsaved panes: Modified (Exit again to discard)` (EIO), - and the list stays in a `+Unsaved` pane. #word("Restore"), #word("Del"), + and the list stays in a `+Unsaved` pane (in the active pane's directory, + or the session's when that directory is not on disk). #word("Restore"), #word("Del"), #word("Delcol") and a pane's `get` refuse the same way with their own word. - #word("Dump") writes `pardes-<date>-<time>.zon` (UTC) in #word("DumpDir"), @@ -293,7 +299,7 @@ word clicked in a tag does. The same lines go in the startup file [`Placement acme|pardes`], [`acme`: where new panes go (#doc("tags", section: "new-panes"))], [`BootShell keep|replace`], [`keep`; `replace` closes the untouched lone shell a dragged document lands beside], [`LookWord search|list`], [`search`: a looked-at word selects its next place, or lists all in `+Search`], - [`Shell <name or path>`], [`$SHELL` when it is executable, else `/bin/sh`: the shell the next terminal and command pane run; a bare name is looked for in the usual bin directories, not `$PATH`; bare #word("Shell") returns to the default], + [`Shell <name or path>`], [`$SHELL` when it is executable, else `/bin/sh`: the shell the next terminal and command pane run; a bare name is looked for in the usual bin directories, not `$PATH`; bare #word("Shell"): `$SHELL` if it is executable, else `/bin/sh`], [`DumpDir <dir>`], [`$XDG_DATA_HOME/pardes`, else `~/.local/share/pardes`: where #word("Dump") writes; bare returns to the default], [`TreeContext`], [off: sticky declaration headers in a source pane (per pane, dumped)], [`TreeContextTagStyle`], [on: draw those headers in the tagline style], @@ -576,7 +582,7 @@ the pane's own #file("look")/#file("exec") (or the root's while it has the keyboard). A record is acme's `<origin><action><q0> <q1> <flag> <n> <text>\n`; read `n` *bytes* of text, which may hold newlines. One open reads a pane's #file("event") at a time, as acme's is one window's: a second open for reading fails `file in use` (EBUSY) until the first is -closed. +closed. A reader whose pane has closed reads EOF. - origin: `E` a 9P write to body or tag, `F` other files and the editor's own lines, `K` keyboard, `M` mouse. @@ -593,7 +599,9 @@ Write a record back to have it done as the click would: `<o><a><q0> <q1>\n` acts and an empty one (`MX12 12`) on the word or file name a click there expands to; the whole record as read acts on its text (the only way for `0 0`). A chorded record with its two follow-ups, in one write or three, runs once -with its argument. `I`, `D`, `i`, `d` are refused. A helper holding +with its argument. A record written back that runs a builtin which fails +(a refused #word("Del")) fails the write, EIO with its `err`, as an +#file("exec") write would. `I`, `D`, `i`, `d` are refused. A helper holding #file("event") that writes its own pane's #file("exec") gets its command back as a record: run it through #file("ctl") instead. @@ -633,8 +641,8 @@ Terminal panes also have #file("pty/"): - #file("pty/run"): one line at the shell's prompt, answered on the same open: #cmd("exec 3<>$m/pane/$n/pty/run; echo make >&3; cat <&3; exec 3<&-") The answer's first line is the header: `exit N` then the command's output - (as the screen showed it: no colour, `\r` progress collapsed, trailing - blanks dropped; the last 64 KiB, `exit N cut M` when M bytes were left + (as the screen showed it: no colour, tabs expanded to blanks, `\r` + progress collapsed, trailing blanks dropped; the last 64 KiB, `exit N cut M` when M bytes were left out, bare `cut` when the start scrolled away or was cleared). Or: `busy: <program> is running` (bare `busy` when text is typed at the prompt), `exit ?` (no status reported, not a success), `error not run` (the shell refused the line, e.g. a fish syntax error), `error shell gone`, `error no prompt marks`, and on a command pane `error a command runs here, not a shell` (`error command done; not a shell` once it ended). A line written @@ -700,6 +708,38 @@ at 200, ending in `…`. Control characters become spaces. `-Dembed-sources=true`; `EffectCode <effect>` lists an effect's files under `/virtual`. += Other ways in <other-clients> + +The scripting chapter's rule (a mount, else plan9port's `9p`) covers most +uses. Two more: + +- #word("Tty9p") (#key("SPC n 9")) opens a terminal with the session + kernel-mounted (Linux v9fs): it asks for your sudo password in the pane, + mounts the socket in a private mount namespace and starts your shell as + you, with `PARDES_MOUNT` naming the mount. Only that shell sees it, and + each takes one of the session's 16 connections. It needs the `9p` and + `9pnet_fd` kernel modules and the `pardes-v9fs` helper the build installs + beside `pardes`. +- `test/ninep.py` is a Python 9P client that exists only in the source tree + (it is not installed). It is for when nothing is mounted and `9p` is not + there, or when a fid must stay open (#file("event"), #file("pty/data"), a + followed #file("log")). Its paths are the served root: + +```python +import sys +from ninep import Client # PYTHONPATH=test +with Client(sys.argv[1]) as c: # a socket path, or (ip, port) + print(c.read('/index').decode(), end='') + n = int(c.read('/pane/new')) + fid = c.open(f'/pane/{n}/event', 0) # hold event: clicks come here + c.write(f'/pane/{n}/exec', b'Msg hi\n') + print(c.read_fid(fid, 0, 4096)) # b'FX0 0 1 6 Msg hi\n' + c.close(fid) + c.remove(f'/pane/{n}') +``` + +`client.screen()` returns the parsed #file("/screen"). + = Limits <limits> #pairs( |
