summaryrefslogtreecommitdiff
path: root/docs/fs.md
diff options
context:
space:
mode:
Diffstat (limited to 'docs/fs.md')
-rw-r--r--docs/fs.md112
1 files changed, 73 insertions, 39 deletions
diff --git a/docs/fs.md b/docs/fs.md
index 55ffdc9c..0bcc0313 100644
--- a/docs/fs.md
+++ b/docs/fs.md
@@ -1,14 +1,19 @@
# Filesystem
Every native session serves 9P2000 on a Unix socket. Pane shells receive
-`PARDES_9P` (socket path) and `PARDES_PANE` (pane serial). The socket is
+`PARDES_PID` (the editor's process id), `PARDES_9P` (socket path) and
+`PARDES_PANE` (pane serial). The socket is
`$XDG_RUNTIME_DIR/pardes-9p-<pid>.sock`, or lives under
`~/.local/state/pardes` when XDG_RUNTIME_DIR is unset. Detached sessions use
their session name; `--9p=<name>` overrides it.
A `pardes <file>` launched from a pane forwards Look to that pane over 9P.
-`--nested` opens a separate editor and disables forwarding from its pane shells;
-its 9P service stays available.
+`PARDES_PID` alone says the shell is inside pardes; `PARDES_9P` and
+`PARDES_PANE` say how to reach it, and a launch that has the first without the
+other two refuses rather than opening a second editor. `--nested` opens a
+separate editor and withholds `PARDES_PID` from its pane shells, so a pardes
+started in one of them runs a session of its own; its 9P service stays
+available.
Look resolves the OS filesystem first, then the editor's virtual filesystem.
Explicit paths bypass that search:
@@ -68,53 +73,79 @@ Existing Plan9port/v9fs clients need a userspace bridge for QUIC.
```
/README this guide, also src/fs-help.txt
/index one line per pane: serial, kind (text|term|pdf|image), dirty flag, name
-/ctl write: one command per line; read: the serials the last command made or touched
-/new reading it creates one empty pane and answers "<serial>\n" (the /net/tcp/clone idiom)
+/status pid, version and pane count
+/look write a line: a right click on it at the active pane; read: the serials it touched
+/exec write a line: a middle click; read the same serials
/log one line per editor event: new|del|rename|save <serial> <name>; reads park
/screen rendered screen JSON; frozen per open handle
/listeners the session's dial addresses
-/pane/<n>/ name body tag ctl addr data xdata sel errors event, plus pty/{ctl,status,data}
+/pane/ create a directory here to open a pane; remove one to close it
+/pane/<n>/ name body tag ctl addr dot limit data xdata sel dirty mark scroll
+ errors event look exec, plus pty/{ctl,status,data} on terminals
/os/ the host filesystem
/src/ the editor's embedded sources, only when built with -Dembed-sources=true
```
-Nothing in the tree is created by list, stat, walk or read, except that
-reading `/new` makes a pane; that is its whole purpose, so a recursive read
-of the tree makes one pane per open of it.
+Nothing in the tree is created by list, stat, walk or read. A pane is opened
+by Tcreate in `/pane` (`mkdir`) and closed by Tremove on `/pane/<n>` (`rmdir`),
+which is the only create and the only remove the tree serves. The name a
+create asks for is ignored, since a pane is named by the serial the editor
+gives it: the Rcreate qid names the new directory, and because `/index` is
+ordered by serial its last line is the pane just made.
-`/ctl` and `/pane/<n>/ctl` take the editor's own command language, two verbs:
+`/look` and `/exec` are the editor's two clicks, one per line of a write:
-- `look TEXT` is a right click on `TEXT`: a path opens a file, `file:12` jumps
- to a line, a directory opens a shell there, a URL opens in the browser. From
- `/ctl` the look happens at the active pane; from a pane's `ctl` at that pane.
-- `exec TEXT` is a middle click: a command word from `src/builtins.zig`
- (`Save`, `Del`, `New`, `Newcol`, `Mount NAME DIAL`, `Unmount NAME`, `Dump`,
- `Restore`, `Msg TEXT`, `Find`, `Grep`, `Tty`, ...), or anything else, which
- runs in the pane's terminal.
+- a line written to `look` is a right click on it: a path opens a file,
+ `file:12` jumps to a line, a directory opens a shell there, a URL opens in
+ the browser.
+- a line written to `exec` is a middle click: a command word from
+ `src/builtins.zig` (`Save`, `Del`, `New`, `Newcol`, `Mount NAME DIAL`,
+ `Unmount NAME`, `Dump`, `Restore`, `Msg TEXT`, `Find`, `Grep`, `Tty`, ...),
+ or anything else, which runs in the pane's terminal.
-Both verbs are lowercase; the words after `exec` are the editor's capitalized
-commands. A pane's `ctl` also keeps acme's addr verbs (`addr=dot`, `dot=addr`,
-`limit=addr`, `clean`, `dirty`, `cleartag`, `get`, `mark`, `nomark`,
-`noscroll`, `scroll`, `show`). Every line of a write is checked before any
-line runs; a malformed line fails the write with EINVAL. A command that fails
-inside the editor is reported on the message row, not as a write error.
-
-After a write to either `ctl`, reading `/ctl` answers the serials of the panes
-the command created, or, when it created none, the pane a look focused or the
-pane an exec acted on (even one it closed), one per line. Before any command it answers `pid`, `version` and `panes` lines.
+The root's pair clicks at the active pane and `/pane/<n>/look` and
+`/pane/<n>/exec` at that pane. Blank lines are skipped, and every other line
+is checked before any of them runs, so a control character fails the whole
+write with EINVAL; a command that fails inside the editor is reported on the
+message row, not as a write error. Reading any of these files answers the
+serials of the panes the last command created, or, when it created none, the
+pane a look focused or the pane an exec acted on (even one it closed), one
+per line.
`/pane/<n>/name` reads the pane's file name (a terminal's directory) and
writing it renames the buffer; a relative name resolves against the pane's
-directory. `sel` reads the editor selection and writing it replaces the
-selection. `body` appends on write and replaces on truncating open. `addr`
-selects a range and `data` or `xdata` read or replace it. `errors` appends to
-the directory's `+Errors` pane. Holding `event` open redirects the pane's Look
-and Exec clicks to that client; writing a record back performs the action.
+directory. `body` appends on write and replaces on truncating open. `sel`
+reads the selected text and writing it replaces the selection. `errors`
+appends to the directory's `+Errors` pane. Holding `event` open redirects the
+pane's Look and Exec clicks to that client; writing a record back performs the
+action. `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 — and takes one verb, `get`, which reloads the buffer from the name
+it carries.
+
+The three range files `addr`, `dot` and `limit` each read the pair of offsets
+they also accept, so copying one onto another is all that acme's `addr=dot`,
+`dot=addr` and `limit=addr` ever were. A write is either that pair or an
+address expression (`#0,#5`, `/pattern/`, `2+1`); `addr` selects what `data`
+and `xdata` read or replace, `dot` is the editor's own selection and moving it
+scrolls the pane into view, and `limit` bounds a search and reads empty until
+it is set. Truncating a range file empties it; truncating `limit` lifts it.
+
+The three flag files `dirty`, `mark` and `scroll` read `0` or `1` and take
+`0` or `1`: whether the buffer differs from its file, whether a write pushes
+an undo point (writing `1` pushes one now), and whether a write scrolls the
+pane. Truncating `tag` clears the part of the tag you may edit.
-Stats report real lengths for `index`, `ctl`, `name`, `body`, `tag` and `sel`,
-modes 0644/0666 (0444 for read-only files, 0222 for write-only), the pane's
-last edit time or the process start as mtime, and stable qids. Directory
-entries carry no sizes; stat the entry.
+Stats report real lengths for `index`, `status`, `look`, `exec`, `listeners`,
+`name`, `body`, `tag`, `sel`, `ctl`, the range files and the flag files, and
+for `log`, `event` and `pty/data` the length of the record a read would
+answer, which is zero when nothing is waiting. Modes are 0644/0666 (0444 for
+read-only files, 0222 for write-only); mtime is the pane's last edit or the
+process start. The qid version of `body`, `data` and `xdata` is the pane's
+revision, so a stat sees an edit land without reading the text; every other
+file leaves it zero rather than promise a version it cannot keep. Directory
+entries carry no sizes, and neither does `/screen`, which has no length until
+an open renders its frame; stat the entry.
`/log` records `new`, `del`, `rename` and `save` while at least one client
holds it open; a read parks until a record arrives. `/screen` returns JSON with
@@ -132,8 +163,10 @@ enables the option by default, so the device can serve its own source.
This is a control filesystem, not a complete POSIX export. Native filenames
may contain up to 255 bytes. Existing regular OS files support read, write,
-and truncation to zero; protocol create, remove, rename, and other metadata
-changes are refused. Ownership and permissions under `/os` are synthetic.
+and truncation to zero; under `/os` protocol create, remove, rename and other
+metadata changes are refused, as is every create and remove in the control
+tree but the pane directories. Ownership and permissions under `/os` are
+synthetic.
Zero-length truncation accepts the accompanying `mtime` hint sent by Linux
v9fs; the hint is not stored. Standalone timestamp changes remain refused.
@@ -148,7 +181,8 @@ for Unix and TCP, a poll loop for QUIC, and the 9P client for mounts);
`zig build fs-test` drives real sessions using the independent Python client
in `test/ninep.py`; `zig build fs-discovery-test` checks that browsing creates
-nothing and that `new`, `ctl`, `name`, `sel` and `log` behave. `zig build
+nothing, that a pane create and remove work, and that `look`, `exec`, `name`,
+`sel` and `log` behave. `zig build
9p-test` checks the two engine configurations' budgets (the engine's own
tests are cloud9's `zig build test`); `zig build fs-bench` measures
filesystem transactions in the core.