diff options
Diffstat (limited to 'docs/fs.md')
| -rw-r--r-- | docs/fs.md | 122 |
1 files changed, 91 insertions, 31 deletions
@@ -92,7 +92,7 @@ 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 +/index one line per pane: serial, kind (text|term|pdf|image), dirty flag, name, column serial /status pid, version and pane count /look write a line: a right click on it at the active pane; read: the serials the last look, exec or ctl write touched (made, else acted at) @@ -102,16 +102,44 @@ Existing Plan9port/v9fs clients need a userspace bridge for QUIC. write follow to that open to wait for more /screen rendered screen JSON; frozen per open handle /listeners the session's dial addresses -/focus the serial of the pane with the keyboard; write a serial to give it the keyboard +/focus the serial of the pane with the keyboard; write a serial to give it the keyboard, + which makes its column the active one as a click there would /ctl the settings, one a line as a write takes them; write a setting or a session builtin -/commands every builtin: word, `arg` if it takes one, and `root` or `pane`, the ctl that takes it -/pane/new open it to make a pane; the read answers that pane's serial +/commands every builtin: word, `arg` if it takes one, `root` or `pane` (the ctl that takes it), a setting's values +/layout one line per column, left to right: serial index x width current|notcurrent + empty|full pane-serials...; then active <serial>: the active column, where + pane/new and a look place a pane next (- when there is none) +/tag the workspace tag; > replaces it, >> appends, one line +/col/<n>/tag the tag of the column with serial n, the same way +/col/<n>/ctl write Delcol, Joincol, New or Tty: each acts on that column, as from its tag +/col/<n>/exec write a word: a middle click on it in that column's tag; rmdir col/<n> closes + an empty column (a column with panes is refused, ENOTEMPTY) +/pane/new open it to make a pane; the read answers that pane's serial. A session holds + 64 panes (16 on the board); at that, every route that would open one -- this + open, look, exec, New, Tty -- fails with `no pane slots: 64 max` and an err + record, and look reads back empty /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 ``` +`/layout`, `/tag` and `/col` go past acme, which serves no column files -- +its columns are only where a window sits. They are here so a script can see +where the panes are (`/index`'s last word is each one's column serial) and +edit the tags a person clicks in: a column tag is one line, a newline +written into it a space, and a truncating write (`echo Make > col/3/tag`) +clears it and drops the newline that ends it, as a pane tag's does. A +column is named by its serial, as a pane is: it stays while the column +lives, whatever opens or closes beside it, and is never reused; /layout +gives each column's serial and its index left to right, and the log says +`newcol <serial>` and `delcol <serial>` as columns come and go, and after a +Restore `restoredcol <old> <new>` for each column as `restored` does for +panes. Joincol folds a column into the one on its right, which keeps its own +serial and tag; the joined one's serial is gone (`delcol`). The root ctl +takes no column word: its `Delcol` is refused, pointing at +`col/<serial>/ctl`. + Control messages are split by what they act on, as acme keeps window verbs on a window's ctl and webfs and upas/fs keep session settings on a root ctl. Each builtin declares its scope in src/builtins.zig (`scope = .session`; @@ -119,9 +147,11 @@ every setting is one, the rest act on a pane). `/ctl` takes the session's 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, `<name>: Modified (Exit again to discard)`, and a second -`Exit` with nothing edited since quits, throwing that text away; a scratch -under 100 bytes is not asked about; `Restore`, which replaces every pane, +unsaved text, a `+New` scratch of 100 bytes or more too, in one line, +`<name>, <name>: Modified (Exit again to discard)`, and a second `Exit` +with nothing edited since quits, throwing that text 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; `Restore`, which replaces every pane, asks the same first -- `Dump` writes `pardes-<date>-<time>.zon` (UTC) in `DumpDir` (default `$XDG_DATA_HOME/pardes`, else `~/.local/share/pardes`) and logs `dump <path>`, and `Restore` with no path takes the last one; a @@ -151,14 +181,18 @@ in a shell running without job control (`set +m`) the job shares the 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, so of `sleep 30; echo done` typed at a prompt the `echo` -still runs once the `sleep` is stopped -- +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 -- and reads every setting there is, one a line, in the words a write of it -takes (`Verbose on`, `WindowOpacity 70`, `PanelSlide off`, `DumpDir` bare -for the default directory, `LocationsConfig ...`), so writing what it reads -back changes nothing; platform and startup facts are `/status`'s and the +takes (`Verbose on`, `WindowOpacity 70`, `PanelSlide off`, `DumpDir +<the directory in effect>`, `LocationsConfig ...`), so writing what it reads +back changes nothing; a setting the frontend cannot show (`Lift`, +`GripWidth` on a terminal) is refused as `Lift is GUI-only`; platform and startup facts are `/status`'s and the Config window's, not settings. A pane's `ctl` takes the builtins that act on -a pane (`Del`, `Save f`, `Collapse`, which folds that pane, `Undo` and +a pane (`Del`, or `Del k`/`Del j` to give its rows to the pane above or +below, `Save f`, `Collapse`, which folds that pane, `Undo` and `Redo`, which step its body through its edits, `Find pat`) beside acme's `get`, `lock` and `unlock`. The column words are pane words too, acting on the column that pane is in: `Delcol`, `DelAbove`, `DelBelow` @@ -193,8 +227,13 @@ 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, and `root` or `pane` for the ctl -that takes it, e.g. `Newcol root`, `Save arg pane`, `Verbose arg root`. It is +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 +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 generated from the registry, so it is always this build's own list. `/focus` reads the serial of the pane with the keyboard, and a serial written @@ -307,13 +346,17 @@ terminal's while a program other than its shell holds the tty -- after Ctrl-D the shell would run the text, so nothing is sent and the pane says so. Still commands, whatever is bound: a word in a tag (so the tag is how to run `make` from that file), `Exec <text>` run by name -(typed, a 2-1 chord onto `Exec`, a `ctl` line) and a command word @`cmd` in +(typed, a 2-1 chord onto `Exec`, a `ctl` line) -- in a `.py` pane bound to +a REPL, `Exec print(1)` runs `print(1)` as a command, never in the REPL -- +and a command word @`cmd` in the text, looked at or clicked (`# @`pytest -x`` in a script). A 9P `exec` is no gesture and is never sent: a script writes to the REPL pane's -`pty/data`, multi-line code as a bracketed paste (`\e[200~<code>\e[201~` -then `\r`, and a second `\r` when its last line is indented: one Enter -leaves a block open, pasted or typed; a middle click sends that second one -itself), since line by line a blank line ends a Python block and Python +`pty/data`, multi-line code as a bracketed paste (`\e[200~<code>\e[201~`, +then `\r` in a write of its own once the REPL has echoed the paste -- +Python 3.13's REPL takes an Enter read with the paste as part of it, even a +one-line one -- and a second `\r` when its last line is indented: one Enter +leaves a block open, pasted or typed; a middle click does all of this +itself, holding the Enter until the REPL answers the paste), since line by line a blank line ends a Python block and Python 3.14's REPL auto-indents each line typed into it. The REPL gets the text wherever it is -- at a `pdb` or `input()` prompt too. Bindings are not dumped, so a Restore leaves none. @@ -344,7 +387,11 @@ selection, and leaves `look` reading back empty. `/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. `body` appends on write and replaces on truncating open. `sel` +directory. `body` appends on write and replaces on truncating open. A +terminal's `body` is its history as plain text, frozen per open, in logical +lines: a row the terminal wrapped is joined back to the row before it (the +wrap is ghostty's, as `pty/run`'s output unwraps), and the last line ends +with a newline. `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, and so does a line written to the @@ -372,7 +419,9 @@ for the question the pane asks on its notice band, which the log names as `ask <serial> <what> <choices>` -- `ask 4 del k j` for Del's side from the keyboard (`k` the pane above takes the rows, `j` the one below), `ask 4 repl a b` for which bound REPL takes an exec (a REPL's letter) -- `answer -` -taking it back as Esc does (with no question standing, `answer` is refused), +taking it back as Esc does (a choice the question does not offer is refused, +naming those it does, and the question stands; with no question standing, +`answer` is refused), and acme's `lock` and `unlock` (editors/acme/xfid.c:603-611), for an edit of several writes to `addr` and `data` that another client must not land in the middle of. As in acme the lock binds only the clients that take @@ -496,9 +545,13 @@ then the text you may edit. A write appends to that text, newlines included, and a tag with more than one line takes a row per line on screen; truncating `tag` clears it, as acme's `cleartag` does -- the default words (`Del`, `Put` and the rest) with it, since they are that text until -you edit it, so `echo Make > tag` leaves only `Make`; append with `>>` to -keep them, with `printf ' Make' >> tag`: `echo` ends its word with a -newline, which starts a new line of the tag. The clearing is an edit of the tag like a typed one and its undo +you edit it, so `echo Make > tag` leaves only `Make` -- a truncating write +drops the one newline that ends what it wrote, which would draw an empty +row, and keeps any other; append with `>>` to +keep them, with `printf ' Make' >> tag`. The leading blank is needed: the +tag reads back with no blank after its last word, so `printf Make >> tag` +glues `Make` onto it; and `echo ' Make' >> tag` ends with a newline, which +starts a new line of the tag. The clearing is an edit of the tag like a typed one and its undo history is kept: `u` in the tag brings back the text it cleared, words included. @@ -515,16 +568,21 @@ entries carry no sizes, and neither does `/screen`, which has no length until an open renders its frame; stat the entry. `/log` is one ring (64 KiB) that records whether or not anyone reads it: -`new`, `del`, `rename` (a terminal's too, as its shell changes directory, +`new`, `del`, `rename` (a terminal's too, as its shell changes directory -- +a new terminal is `new N /` until its shell says where it is, then renamed; +it runs `ls` once at its first prompt, a greeting that shows the directory -- since a terminal is named by its directory), `exit <serial> <N>` before the `del` of a terminal whose shell exited by itself, `ask <serial> <what> <choices>` when a pane asks a question (answered by `answer` on its ctl), and `save <serial> <name>`, `dump <path>` when a Dump is written and `restore <path>` in a Restore's new log after its panes' `new`s, then `restored <old> <new>` for each pane, -mapping the serial it had to the one it has now, and `msg <serial|-> <text>` +mapping the serial it had to the one it has now, and `restoredcol <old> +<new>` for each column, and `msg <serial|-> <text>` for every line the editor says, repeats included (with `verbose` on, that -includes each builtin announcing itself as it runs), and `err <serial|-> +includes each builtin announcing itself as it runs, on purpose: the log says +which ran; its serial is the pane it ran at, `-` when the keyboard was on a +column or workspace tag), and `err <serial|-> <file>: <why>` for every write or truncation the tree refused or that failed -- through a mount a shell sees only the errno its kernel mapped the reply to, usually `Invalid argument`, and this is the reason (`err 3 addr: @@ -547,7 +605,8 @@ Control characters in a record become spaces, so a record is one line. (An `event` record is not: acme's `<origin><action><q0> <q1> <flag> <n> <text>\n`, whose text may hold newlines. The origin is `E` (a 9P write to body or tag), `F` (other files, the editor's own lines), `K` (the keyboard) or `M` (the mouse); the -action's case says where: `x`/`l` a click executed or looked at in the tag, +action's case says where: `x`/`l` a click executed or looked at in the tag +(its offsets count the tag's whole text, path included, as `tag` reads), `X`/`L` in the body, `I`/`D` text put in or taken out of the body, `i`/`d` of the tag. Read `n` bytes of the text, not up to a newline -- bytes here, where acme counts runes. Every offset and count pardes serves is in bytes, `#n` and `q0`/`q1` too; the event count @@ -645,8 +704,9 @@ Fid), released on close or disconnect; past that such an open fails with `-Dembed-sources=true` embeds the editor's sources and serves them under `/src` (and `/shaders` on GUI builds). `EffectCode <effect>` lists the current backend's implementation files under `/virtual`, which Look opens; without the -option the command reports the sources as unavailable. The esp32p4 build -enables the option by default, so the device can serve its own source. +option the command reports the sources as unavailable. It is off by default +everywhere; the esp32p4 image in particular has no room for them (~1.8 MB of +source against a 1.5 MiB app partition). 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, |
