summaryrefslogtreecommitdiff
path: root/docs/fs.md
diff options
context:
space:
mode:
Diffstat (limited to 'docs/fs.md')
-rw-r--r--docs/fs.md74
1 files changed, 52 insertions, 22 deletions
diff --git a/docs/fs.md b/docs/fs.md
index 6a82b633..985e36a1 100644
--- a/docs/fs.md
+++ b/docs/fs.md
@@ -20,9 +20,12 @@ and `PARDES_PANE` (their pane's serial).
`PARDES_9P` and `PARDES_PANE`) writes FILE to that pane's `look` and returns
at once, as acme's `B` does. A FILE not there yet (`pardes notes/new.txt`)
opens a new pane named for it, empty, and its Save creates the file, making
-its directories first when they are not there either. A missing
-`PARDES_9P`/`PARDES_PANE` starts a separate editor instead. Bare `pardes` in
-a pane refuses and names `--nested`.
+its directories first when they are not there either. A session that
+answers never gets a nested editor in its pane: what it refuses (a bad
+name, a pane it has not) is printed, `pardes: <file>: <why>`, and the
+launch exits 1, leaving no pane behind. A missing `PARDES_9P`/`PARDES_PANE`,
+or a session that does not answer, starts a separate editor instead. Bare
+`pardes` in a pane refuses and names `--nested`.
`--wait` (`-w`) returns when the pane that shows FILE is deleted (exit 0) or
the session goes away (exit 1), as acme's `E` does. Use
@@ -150,9 +153,13 @@ column's `exec` take one command a line. The whole write is checked first
(a control character other than a tab fails it all, EINVAL); then lines run
in order, and a failing line fails the write after the lines before it took
effect, as acme's ctl does. Blank lines are skipped. A mount cuts a big
-write into pieces of at most one message (msize 8192, less the header), and
+write into pieces of at most one message (msize 64 KiB, 65536 negotiated,
+less the header), and
each line runs once it is whole. A write that does not fill its message is
-whole, so its last line runs even without a newline (`printf Save > exec`). An `Edit` whose `{` or
+whole, so its last line runs even without a newline (`printf Save > exec`),
+unless it is a multiple of 4096 bytes: that is where a writer's buffer (stdio,
+a mount's page cache) filled and cut a line, so its tail waits for the next
+write or the close. An `Edit` whose `{` or
`a`/`c`/`i` text is still open waits for the next write on that open, and
fails at the close if it never ends (``unmatched `{'``). A line held past
1 MiB is refused.
@@ -176,8 +183,11 @@ files`.
**Held reads.** A read with nothing to give yet (a followed `log`, `event`,
`pty/data`, `pty/run` before its answer) waits in the editor and is answered
when news comes. A second read on that open meanwhile fails `file in use`.
-A read the client flushed is dropped. Through a FUSE mount bash's `read -t`
-cannot time out: wrap the loop in `timeout N`.
+A read the client flushed is dropped. One connection holds at most 128
+reads at once; the next is refused `too many reads waiting: 128`. A mount
+(9ns) is one connection, so that is 128 followers through it, and the mount
+keeps answering everything else beside them. Through a FUSE mount bash's
+`read -t` cannot time out: wrap the loop in `timeout N`.
**Stats.** Lengths are real (for `event` and `pty/data` the next record's,
zero when none waits; for `log` what an open would freeze). The qid
@@ -192,11 +202,17 @@ A line written to `look` is a right click on it:
selects line 12, newline included; `file:12:5` puts the caret at line 12,
byte column 5; `file:<addr>` takes any address (below), **evaluated from
the file's dot**: `file:/re/` finds the next match after the selection,
- `file:0/re/` the first. `:addr` addresses the pane itself.
+ `file:0/re/` the first. `:addr` addresses the pane itself. A leading `~`
+ is the home directory ($HOME, else the passwd entry's; `~user` that
+ user's) here and wherever a path is typed (`name`, `Save`, `ThemeFile`,
+ `DumpDir`, `Restore`, `pardes '~/x'`), even beside a file named `~`: write
+ `./~` for that.
- `@p<serial>:<addr>` addresses a pane by serial, a terminal's logical lines
too.
- a directory types `ls` into a terminal idle there, else opens one there.
- a URL opens in the browser.
+- in a diff pane, a whole line of the diff opens the place it names, as a
+ right click on its first column does ([tags.md](tags.md#reviewing-diffs)).
- 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`.
@@ -213,6 +229,8 @@ A line written to `exec` is a middle click:
A builtin that needs its argument (`Msg`, `Mount`, `Find`) written bare is
`wrong #args in control message "Msg"`, and so is one that takes none
written with one (`Config extra`).
+- a line starting with `#` is a comment, as in a shell: it runs as
+ nothing, silently, here and in every ctl.
- the language server's words ask about a file pane's text at its cursor
(set it with `addr` and `dot=addr` first): `Hover` fills `+Hover`,
`Rename new` renames the symbol everywhere and lists the places,
@@ -237,7 +255,9 @@ A line written to `exec` is a middle click:
second pane. From a pane whose directory is gone nothing runs: `exec:
<dir>: no such directory` (ENOENT).
-The root's `look` and `exec` act at the active pane and log as that pane's;
+The root's `look` and `exec` act at the active pane and log as that pane's
+(with no pane at all, in the session's directory: a look opens its file,
+making a column as `New` does, and an exec runs its command there);
`/pane/<n>/look` and `exec` at pane n; `/tagexec` and `/col/<n>/exec`
click in the workspace's or that column's tag, run commands in the session's
directory, and log as `-`. A pane's word (`Undo`, `Msg`, `Save`) is refused
@@ -249,8 +269,10 @@ goes on below `exit N` until it lets go of the pty. `Kill` (root ctl)
stops the commands pardes started: bare, all; `Kill make ls`, those whose
line starts with one of the words. For a command pane it signals the whole
line, `&` jobs included; for a line typed into a shell only the foreground
-job (SIGTERM), and the shell decides the rest. With nothing running it says
-`Kill: nothing running`. Kill does not reach a REPL's code: use `sig INT` on
+job (SIGTERM), and the shell decides the rest. With nothing running, named
+or not, it says `Kill: nothing running` and the write succeeds; words that
+name none of what runs fail it (`Kill: no running command has that first
+word`). Kill does not reach a REPL's code: use `sig INT` on
its `pty/ctl`.
## The root ctl
@@ -312,9 +334,14 @@ none). `current` is the column with the keyboard now, which may differ
from the active one. `/index`'s last field is each pane's column serial.
A session holds 16 columns (`no space for a column: 16 max`, ENOSPC), each at
-least 10 cells wide (`Newcol` from a column under 20 fails `this one is too
-narrow to split`). Since root `Newcol` halves the active column, reach 16 by
-writing `Newcol` to the widest column's `exec`.
+least 10 cells wide, so 16 wants a window 160 cells wide or more. `Newcol`
+halves the column it is run from, and one under 20 cells does not split
+(`this one is too narrow to split`): reach 16 by writing `Newcol` to the
+widest column's `exec` each time, not to the root's, which keeps halving the
+one just made. `Newcol` is refused as well when a narrower column would
+wrap its panes' tags onto more rows and leave one under its tag and two
+rows (`Newcol: no space for a column: the panes' tags would not fit`); a
+refused `Newcol` logs its `err` alone and uses up no column serial.
`/col/<n>/ctl` takes `Delcol`, `Joincol`, `New` and `Tty` for that column;
`/col/<n>/exec` is a click in its tag; `rmdir /col/<n>` closes an empty column
@@ -333,7 +360,7 @@ blank matters; `echo` would start a second line). A pane tag may hold
several lines; a column or workspace tag is one, a newline written into it
becoming a space. Control characters other than tab, DEL, C1 controls and
non-UTF-8 bytes are refused (`invalid tag text`). The editable text is at
-most 4096 bytes (`tag: no space: over 4096 bytes`, ENOSPC). All three kinds
+most 4096 bytes (`no space: over 4096 bytes`, ENOSPC; the log says `err <serial> tag: no space: ...`). All three kinds
take the same checks, whole or not at all, and a `>` whose write is refused
changes nothing: its truncation is done with the write that fits, or at the
close (or a read) when none came. A clear is an ordinary edit
@@ -349,13 +376,15 @@ answer the same serial. It goes where acme's makenewwindow puts a window
if empty, else the bottom half of its last pane. A session holds 64 panes
(`no space for a pane: 64 max`), and every pane keeps its tag and 2 rows
(`no space for a pane in that column: each keeps its tag and 2 rows`); both
-are ENOSPC, for this open and for a look, exec, `New` or `Tty` alike.
+are ENOSPC, for this open and for a look, exec, `New` or `Tty` alike. A
+`pane/new` whose column is full takes its rows from a pane in another column
+that has them, last column first, as acme does, and is refused only when
+no pane anywhere can give them.
`rmdir /pane/<n>` closes the pane, unsaved or not.
**`name`** reads the file name (a terminal's directory); a write renames the
buffer (relative to the pane's directory) and marks nothing dirty; `Save`
-then writes under the new name, making its directories first when the name
-went into one not there. A name is one line; refused (EINVAL) are a
+then writes under the new name. A name is one line; refused (EINVAL) are a
second line, a blank at either end, control bytes and non-UTF-8 (`bad
character in file name: a blank at its start`, ...). Up to 255 bytes a
component.
@@ -381,7 +410,8 @@ redo available, then `current`/`notcurrent` and a REPL's id if bound. It
takes:
- the pane builtins: `Del` (`Del k`/`Del j`, or `DelAbove`/`DelBelow`, give
- its rows to the pane above or below), `Save [path]`, `Collapse` (fold),
+ its rows to the pane above or below), `Save [path]` (making the
+ directories the file goes in first, whichever name it writes), `Collapse` (fold),
`Undo`/`Redo` (256 steps each), `Find pat`, `Edit ...`, `Tty [shell]`
(a new terminal pane in its directory), and the column words acting on
its column: `Delcol`, `Left`/`Right`/`Up`/`Down`.
@@ -533,7 +563,7 @@ text, which may hold newlines.
its text (`FX0 0 1 6 Msg hi`).
Write a record back to have it done as the click would: `<o><a><q0> <q1>\n`
-acts on that range; the whole record as read acts on its text (the only way
+acts on that range (the last record of a write needs no newline); 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 `event` that writes its own pane's `exec` gets its command back as a
@@ -566,7 +596,7 @@ Terminal panes also have `pty/`:
replay).
- `pty/status`: one line, `cols rows busy`; busy is 1 while a command runs or
text is typed at the prompt.
-- `pty/ctl`: `winsize C R` (at least 2 rows), `sig INT|TERM|HUP|QUIT|KILL`,
+- `pty/ctl`: `winsize C R` (at least 2 rows, fewer refused `invalid winsize: at least 2 rows`; at most 4096 a side), `sig INT|TERM|HUP|QUIT|KILL`,
`exec` (restart the shell in its directory: refused on a command pane, `a
command pane does not restart`; `exec: <dir>: no such directory` if it is
gone; a shell that cannot start fails and leaves the old one running).
@@ -654,7 +684,7 @@ become spaces.
| panes | 64 (16 on the board) |
| columns | 16 (6 on the board), each at least 10 cells wide |
| rows a pane keeps | its tag and 2 |
-| msize | 8192 offered |
+| msize | 65536 (64 KiB) offered |
| connections | 16 Unix+TCP, 16 QUIC |
| opens holding state | 64 |
| named mounts | 8 |