diff options
Diffstat (limited to 'docs/typ/reference.typ')
| -rw-r--r-- | docs/typ/reference.typ | 279 |
1 files changed, 194 insertions, 85 deletions
diff --git a/docs/typ/reference.typ b/docs/typ/reference.typ index e79f9c4d..148ef30e 100644 --- a/docs/typ/reference.typ +++ b/docs/typ/reference.typ @@ -2,43 +2,71 @@ // does, how it fails, and the limits. How pardes behaves on screen is the // guide's; recipes and traps are scripting's; how a mount cuts writes and // the listeners are building's. -#import "style.typ": key, keys, btn, chord, word, tag, addr, file, cmd, doc, pairs +#import "style.typ": key, keys, btn, chord, word, tag, addr, file, cmd, doc, pairs, fstree Every native session is a virtual filesystem, served as 9P2000 (not .u, -not .L), in acme's manner: panes, columns, tags and the session are -files. Paths here are the served ones (#file("/pane/2/body")); through a +not .L) and modelled on acme's (#doc("reference", section: "from-acme")): +panes, columns, tags and the session are files. Paths here are the served ones (#file("/pane/2/body")); through a mount they sit under the session's directory (`$m`; #doc("scripting", section: "find-the-session") says how to find it). The served #file("/README") is a -one-screen summary of this page. Two builtins carry the core: #word("Look") (right-click): open what the +one-screen summary of this page. Two builtins: #word("Look") (right-click): open what the text names, or else find it; #word("Exec") (middle-click): run the builtin it names, or else run it as a shell line. The files #file("look") and #file("exec") take a line each, as those clicks would. = The tree <tree> -``` -/README the one-screen summary (src/fs-help.txt) -/index a line per pane: serial kind dirty name column -/status pid, version, panes -/look /exec write a line: a right / middle click at the pane with the keyboard; read: the serials touched -/pager write a directory: its one +Pager, made or emptied; read: its serial -/log the event log; write `follow` to wait for more -/screen the rendered screen as JSON -/listeners dial addresses -/focus the serial of the pane with the keyboard; write one to move it -/ctl settings and session builtins -/commands every builtin, one a line -/recent files opened lately: open|closed <path> -/layout a line per column, then `active <serial>` -/tag /tagexec the workspace tag, and a word clicked in it -/col/<n>/ tag ctl exec of column <n>; rmdir closes an empty one -/pane/new open it to make a pane; read answers the serial -/pane/<n>/ name body tag ctl addr dot limit data xdata sel dirty mark scroll - errors event look exec tagexec, and pty/{ctl,status,data,run} on terminals; - rmdir closes the pane -/os/ the host filesystem -/src/ the editor's sources (only with -Dembed-sources=true) -``` +#fstree(``` +README the one-screen summary (src/fs-help.txt) @other-files +index a line per pane: serial kind dirty name column @rules +status pid, version, panes @other-files +look write a line: a #word("Look") at the pane with the keyboard; read: the serials touched @look-and-exec +exec write a line: an #word("Exec") there; read: the serials touched @look-and-exec +pager write a directory: its one +Pager, made or emptied; read: its serial @pardes-stdin +log the event log; write follow to wait for more @log +screen the rendered screen as JSON @on-screen +listeners dial addresses @other-files +focus the serial of the pane with the keyboard; write one to move it @columns-and-tags +ctl settings and session builtins @root-ctl +commands every builtin, one a line @other-files +recent files opened lately: open|closed <path> @other-files +layout a line per column, then active <serial> @columns-and-tags +tag the workspace tag @columns-and-tags +tagexec a word clicked in the workspace tag @columns-and-tags +col/ the columns @columns-and-tags + <n>/ column <n>; rmdir closes it when empty @columns-and-tags + tag its tag + ctl its builtins (Delcol Joincol New Tty) + exec a word clicked in its tag +pane/ the panes @panes + new open it to make a pane; read answers the serial @panes + <n>/ pane <n>; rmdir closes it @panes + name the file name; write to rename @panes + body the text; a write appends, > replaces @panes + tag its path, then its words; a write replaces the words @panes + ctl builtins and ctl words, a line each @panes + addr the address data and xdata work on @addresses + dot the selection, as an address @addresses + limit where a forward search stops @addresses + data the text at addr; a write replaces it @addresses + xdata the text in addr's range only @addresses + sel the selected text; a write replaces it @panes + dirty 1 while the text differs from its file @flags + mark 0 or 1; a write marks an undo point @flags + scroll 0 or 1; a write scrolls the pane @flags + errors write-only: text for the directory's +Errors @panes + event the pane's clicks and keys, as acme's event file @event + look a #word("Look") at this pane @look-and-exec + exec an #word("Exec") at this pane @look-and-exec + tagexec a word clicked in this pane's tag @look-and-exec + pty/ terminals only @pty + ctl winsize, sig, exec @pty + status cols rows busy @pty + data the live stream: bytes in as typed, output out @pty + run write a command line; read: exit N, then its output @pty +os/ the host filesystem @mounts +src/ the editor's sources (only with -Dembed-sources=true) @mounts +```) Panes and columns are named by serials the editor gives: stable while they live, never reused (so they can have gaps). Nothing is created by a listing, stat, walk or read: @@ -70,8 +98,8 @@ own), never a C library string; a bad setting value is quoted, the value itself (`bad value in control message; takes on, off "maybe"`); 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 `fs.enameErrno`): the first of these that the -words hold, case aside, wins, and anything else is EIO (`Modified`, an -#word("Edit") command pardes leaves out): +words hold, case aside, wins, and anything else is EIO (`Modified`, a +sam command pardes's #word("Edit") leaves out, `B <cmd`): #pairs( [`control message`], [EINVAL], @@ -95,6 +123,8 @@ words hold, case aside, wins, and anything else is EIO (`Modified`, an [acme's address and argument words: `no match for regexp`, `no previous regular expression`, `address out of range`, `addresses out of order`, `past end of body`, `written to addr failed`, `not locked by this open`, `too small for the panes`, `owns the size`, `no question asked`, `answer takes`], [EINVAL], ) +A file pardes reads (#word("Get"), #word("Look"), #word("Edit")'s `e` and `r`) that is a directory where a file is wanted says `is a directory` (EISDIR), an unreadable one `permission denied` (EACCES), and a device (`/dev/zero`, a tty) `not a regular file` (EIO), never read to the stream limit; #word("Incl") of a file says `not a directory` (ENOTDIR). + The `err` record has the words; a shell sees only the errno. Not failures: a #word("Look") that finds nothing (it answers nothing and logs one @@ -188,7 +218,7 @@ files. 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 right-click on its first column makes. The line is matched in the +- A whole line of a diff pane written to #file("look") is the #word("Look") on its first column. The line is matched in the pane from its cursor row on, wrapping, and the first match wins. - On a PDF pane `:P:H` is hit H of the pane's search on page P, as `file.pdf:P:H` is; a hit not there, or any H with no search active, is a @@ -238,10 +268,12 @@ A line written to #file("exec") is #word("Exec"): #word("Lspwhy") narrates the last query step by step (in `+Lsp`). The write returns once the answer is in; a pane with no file is refused. - acme's words run as pardes's where it has one (`Put` is #word("Save"), - `Delete` a #word("Del") that does not ask); the rest (`Get`, `Putall`, - `Snarf`, `Cut`, `Paste`, `Zerox`, `Sort`, `Load`, `ID`, `Send`, `Tab`, - `Indent`, `Local`, `Incl`, `Abort`) are refused, `invalid: acme's Get is not a pardes builtin: ...`, never run as commands. So is a GUI-only - builtin (`Fonts`) on another frontend. + `Load` is #word("Restore"), `Delete` a #word("Del") that does not ask); + `Get`, `Putall`, `Zerox`, `Tab` and `Incl` are builtins of their own; the + rest (`Snarf`, `Cut`, `Paste`, `Sort`, `ID`, `Send`, `Indent`, `Local`, + `Abort`) are refused, `invalid: acme's Snarf is not a pardes builtin: ...`, + never run as commands. So is a GUI-only builtin (#word("Fonts")) on + another frontend. - Anything else is a command line (a typo ends `exit 127`), at most 1024 bytes, run as the guide says (#doc("tags", section: "command-panes")): typed into a terminal idle at an empty prompt, else run in a command pane. #file("exec") reads back @@ -307,7 +339,7 @@ Writes take settings and session builtins (`scope = .session` in `src/builtins.zig`), acting at the pane with the keyboard: - A setting written bare steps to its next value (a switch flips; so do - #word("Placement"), #word("BootShell"), `Crt`). A value it does not + #word("Placement"), #word("BootShell"), #word("Crt")). A value it does not take is `bad value in control message; ...` naming what it takes; #file("/commands") lists them. A setting the frontend cannot show is refused (`Lift is GUI-only, invalid here`). @@ -356,9 +388,9 @@ runs fails with the editor's words (`Mount: already mounted`, `Save /root/x: acc == Settings <settings> A setting that chooses among words (`on`/`off` switches, -#word("Placement"), #word("BootShell"), `Crt`, `Bloom`, -`Vignette`, `Grain`, `Lift`, #word("Motion"), -`ShaderAnimation`) steps to its next value when given bare, as its +#word("Placement"), #word("BootShell"), #word("Crt"), #word("Bloom"), +#word("Vignette"), #word("Grain"), #word("Lift"), #word("Motion"), +#word("ShaderAnimation")) steps to its next value when given bare, as its word clicked in a tag does. The same lines go in the startup file (#doc("config")). @@ -375,6 +407,8 @@ word clicked in a tag does. The same lines go in the startup file [#word("Placement") `acme|pardes`], [`acme`: where new panes go (#doc("fs", section: "placement"))], [#word("BootShell") `keep|replace`], [`keep`; `replace` closes the untouched lone shell a dragged document lands beside], [#word("LookWord") `search|list`], [`search`: a word given to #word("Look") selects its next place, or lists all in `+Search`], + [#word("DirLook") `pane|terminal`], [`pane`: #word("Look") on a directory opens a pane listing it, as acme's directory window (#doc("reference", section: "from-acme")); `terminal` types `ls` into a terminal idle there, else opens one], + [#word("JumpScope") `file|all`], [`file`: #word("Back") and #word("Forward") keep to the focused pane's file, that pane's places first, then the file's in another pane, and go to another file only when the file has no place left that way; from a terminal or a pane with no file they step through every place; `all`: every place, in the order it was jumped to], [#word("TermImages") `real|petscii`], [`real`: a new terminal draws its program's kitty graphics (yazi's previews) as pixels where the shell can; #word("Petscii") flips one terminal; a tty under a terminal without kitty graphics draws them as glyph art either way], [#word("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 searched for in the usual bin directories, not `$PATH`; bare #word("Shell"): `$SHELL` if it is executable, else `/bin/sh`], [#word("DumpDir") `<dir>`], [`$XDG_DATA_HOME/pardes`, else `~/.local/share/pardes`: where #word("Dump") writes, an absolute or `~` path to a directory that may be written (made if missing); a relative one, or one under a directory that may not be written, is refused; bare returns to the default], @@ -382,16 +416,16 @@ word clicked in a tag does. The same lines go in the startup file [#word("TreeContextTagStyle")], [on: draw those headers in the tagline style], [#word("LocationsConfig") `...`], [the layout of #word("Grep"), search and language-server results (below)], [#word("Wrap"), #word("Colors"), #word("Tagbottom"), #word("Debug")], [toggles], - [`Font <name>[:<size>]`, `Fonts`], [SDL and macOS only; size 8-72 (pixels in SDL, points on macOS)], - [`TaglineSize <1-100>`], [82: tagline face, percent; SDL and macOS], - [`WindowOpacity <0-100>`], [100; SDL only: everything but text and the cursor], - [`Ligatures`], [on; SDL only, macOS draws CoreText's own], - [`Pet cat|frog|off`], [off; SDL only: a sprite in the workspace tag's blank space], + [#word("Font") `<name>[:<size>]`, #word("Fonts")], [SDL and macOS only; size 8-72 (pixels in SDL, points on macOS)], + [#word("TaglineSize") `<1-100>`], [82: tagline face, percent; SDL and macOS], + [#word("WindowOpacity") `<0-100>`], [100; SDL only: everything but text and the cursor], + [#word("Ligatures")], [on; SDL only, macOS draws CoreText's own], + [#word("Pet") `cat|frog|off`], [off; SDL only: a sprite in the workspace tag's blank space], ) #word("LocationsConfig") with no argument prints the current settings as a line that can be run again; with fields it changes only those: -`LocationsConfig context:5 tscontext:on tslocations:off layout:stacked`. +#word("LocationsConfig") `context:5 tscontext:on tslocations:off layout:stacked`. `context` (0) is the source lines shown above and below each match; `tscontext` (off) includes the enclosing tree-sitter declaration headers; `tslocations` (on) shows a location on each declaration header; `layout` @@ -407,19 +441,19 @@ turning it off: #word("PanelSlide"), #word("PanelZoom"), #word("PanelCurtain"), #word("PanelScramble"), #word("PanelType"); all start off, and the web shell has none. Scene passes (the SDL window, and one attached to a detached session), each at a level 0-3 (`on` is 2), all -off: `Crt`, `Bloom`, `Vignette`, `Grain`. -`Shader <file.glsl>` adds a Shadertoy file written for ghostty to the -chain (`Shader off` removes it; it recompiles when saved); -`ShaderAnimation off|on|always` says when the chain animates by itself. The -focused pane can stand off the page: `Lift shadow|rim|auto|off`, +off: #word("Crt"), #word("Bloom"), #word("Vignette"), #word("Grain"). +#word("Shader") `<file.glsl>` adds a Shadertoy file written for ghostty to the +chain (#word("Shader") `off` removes it; it recompiles when saved); +#word("ShaderAnimation") `off|on|always` says when the chain animates by itself. The +focused pane can stand off the page: #word("Lift") `shadow|rim|auto|off`, #word("InactiveDim") `<percent>`, #word("Motion") `off|crisp|smooth|bouncy|playful` (default -`smooth`), `SelectionGlow`, `HoverGlow`, `Occlusion`, -`Parallax`, #word("JumpTrail"), #word("ChipShadow"), -#word("ThumbFlash"), `CursorBlink`, `GripWidth <50-300>`. Most are +`smooth`), #word("SelectionGlow"), #word("HoverGlow"), #word("Occlusion"), +#word("Parallax"), #word("JumpTrail"), #word("ChipShadow"), +#word("ThumbFlash"), #word("CursorBlink"), #word("GripWidth") `<50-300>`. Most are the GUI's; #word("InactiveDim") works everywhere, and #word("JumpTrail"), #word("ChipShadow") and #word("ThumbFlash") are the terminal's. No effect may lower the contrast of text, the selection or a focus indicator. -`EffectCode <effect>` lists that effect's sources under `/virtual` when the +#word("EffectCode") `<effect>` lists that effect's sources under `/virtual` when the build embeds them. Resting the pointer on text for about 32 ms (`look_preview_delay_frames`, @@ -489,8 +523,8 @@ renames the buffer (relative to the pane's directory) and marks nothing dirty; #word("Save") then writes under the new name. A name takes any byte a file name can hold, blanks, control bytes and bytes not UTF-8 included, so what #file("name") reads writes back as it was; refused (EINVAL) are -an empty name, a second line and a NUL (`bad character in file name: an -empty name`, `...: a NUL`). Up to +an empty name, a NUL (`bad character in file name: an +empty name`, `...: a NUL`) and a second line, by the write that brings it (`invalid file name: one name a write, on one line`). Up to 255 bytes a component. A name that can never be valid (a terminal's, a component over 255 bytes, a path too long) is refused by the write that holds it. The ctl word `name x` takes all after its one @@ -509,8 +543,9 @@ pane's, so #file("addr"), #file("data"), #file("dot") and a `file:<addr>` #word( no write (`this pane has no text`). *Image panes.* An image pane's tag reads `img petscii:on|off -palette:commodore|terminal ascii:on|off <path>`. `petscii` is glyph art -instead of pixels (#word("Petscii") toggles it); `palette` is which 16 +palette:commodore|terminal ascii:on|off <path>`. `petscii` says what is +drawn: glyph art (`on`) or pixels (`off`). With no graphics it is always +`on`; #word("Petscii") `on|off` chooses for when graphics are there. `palette` is which 16 colours the glyph art uses, the C64's (`commodore`) or the terminal theme's own 16 (#word("Palette") toggles it); `ascii` is whether the printable ASCII bitmaps join the glyph set the matcher picks from @@ -520,11 +555,10 @@ printable ASCII bitmaps join the glyph set the matcher picks from a PDF's #word("PdfFit") (`width|height`) and #word("PdfTint") (`disabled|filtered|full`) take the value its ctl read shows; bare, they step to the next. -A terminal pane showing kitty graphics shows `petscii:on` or `petscii:off` -after its directory in its tag; #word("Petscii") toggles it there too: on -draws the program's images as glyph art instead of host pixels, off goes -back to pixels. A terminal with no images shows the word only while it is -on. +A terminal pane showing kitty graphics shows `petscii:on|off` after its +directory in its tag, saying the same, and #word("Petscii") chooses there +too. A terminal with no images shows the word only while #word("Petscii") +is on. *#file("sel")* reads the selected text; a write replaces it and leaves the written text selected, and one open's writes run on from the last. @@ -536,10 +570,11 @@ makes its column the active one (a folded pane stays folded); `no such pane`, or while a column or workspace tag has the keyboard. *Pane ctl.* Reading it gives acme's status line: serial, tag length, body -length, isdir (0), dirty, width in cells, font, tab width, undo available, +length, isdir (1 for a directory pane, else 0), dirty, width in cells, font, tab width, undo available, redo available, then `current`/`notcurrent`, a REPL's id if bound, `collapsed` when it is, and for a PDF `fit:width|height -tint:disabled|filtered|full`. It +tint:disabled|filtered|full`. Each field ends in a blank and the line has +no newline, as acme's has none (`cat ctl; echo`). It takes: - the pane builtins: #word("Del") (from the keyboard between two panes it @@ -561,14 +596,14 @@ takes: - `answer <choice>` to the question the pane asks on its message row, logged `ask <serial> <what> <choices>` (`ask 4 del k j`, `ask 4 repl a b`, `ask 4 save path`); `answer -` takes it back. - acme's lowercase ctl words, done by what replaces each: `name x`, `put` - (Save), `clean`/`dirty`, `del`, `delete` (no asking), `dot=addr`, + (#word("Save")), `clean`/`dirty`, `del`, `delete` (no asking), `dot=addr`, `addr=dot`, `limit=addr`, `mark`/`nomark`, `show`, `cleartag`. `dump`, `dumpdir`, `font`, `menu`, `nomenu` are refused, EINVAL. These lowercase words are ctl-only: written to an #file("exec"), `del` is a command line. A file changed on disk reloads by itself only when the buffer has no unsaved edits; otherwise it stays dirty, says `<name> changed on disk (get reloads it, Save overwrites it)`, logs `changed <serial>`, and its next -#word("Save") warns once. +#word("Save") warns once. A file whose disk text is what the pane was read or saved as is no change: an #word("Undo") back across #word("Get") `file` or `e` to unsaved edits says nothing changed, and #word("Save") writes it. == Addresses and data <addresses> @@ -651,15 +686,60 @@ ceiling: == Edit <edit> #word("Edit") `<sam commands>` on a pane's #file("ctl") or #file("exec") (or the -root's, at the pane with the keyboard) runs acme's Edit on the body: addresses as -above, commands `x y g v c a i d s p = m t u` and `{ }`. All changes are -one undo step, applied only if every command succeeds; a failure changes -nothing and fails the write with acme's words (`Edit: no substitution`). -An `x` that finds nothing succeeds silently. `p` and `=` print to the -directory's `+Errors`. Not there: `b B D e r w f X Y`, `< | >`, -`\1`-`\9`. In `s`, `&` is the match (`\&` a literal); in `c`, `a`, `i` it -is a literal. `y` yields the stretch before the first match too. Braces -take a command a line, so a block goes on one open, in one write or +root's, at the pane with the keyboard) runs acme's #word("Edit") over the open text +panes, from that pane's body. Addresses are as above, and `"re"` is the one +open file whose line matches. Commands: + +- `x y g v c a i d s p = m t u` and `{ }`. +- `X`/`Y` run a command in each open file whose line (` +. /path`, `'` when + edited) matches, or does not, in the order the panes were opened (as + #file("index") lists them): `X/'/w` writes every edited file. +- `b` makes a file current; `B` opens files, every name checked before any + opens; `D` closes panes (an edited one on the second asking, as + #word("Del")). +- `e` loads a file over the whole text as #word("Get") `file` does, once the + rest of the Edit is done: the pane takes its name and is clean, one undo + step puts both back, and unsaved edits are asked about once (a scratch + under 100 bytes is not); the file + takes no other command in that Edit. `r` reads a file over dot. `w` writes + all of it, or the address, to its file or a name; all of it to its own + name leaves it clean. A `w` to its own file changed on disk since it was + read is refused once, as #word("Save") is (`modified on disk since read (w + again to overwrite)`), and the next `w` writes it; in an `X` the other + files are written, and the refusal names those it left. `f` names the pane and prints its line. File names + are relative to the file's directory, and `~` is the home directory. +- `<cmd` replaces dot with what `cmd` writes, `|cmd` pipes dot through it, + `>cmd` sends dot to it and prints what it writes. + +Each command runs in its file's directory through #word("Shell"), off the +loop, so the editor goes on, with what a pane's command is given: +`$PARDES_MOUNT`, `$PARDES_9P`, `$PARDES_PID`, and `$winid` the Edit's pane. The write that ran the Edit is held and +answered when they are done, its connection serving other requests +meanwhile (a command may read the session through its mount). A command +that writes the #file("ctl") its Edit came by needs `<>` on both sides, the +Edit's write (`exec 3<>$p/ctl; echo 'Edit ...' >&3`) and its own (`1<>`): +with `>` or `>>` on either, the kernel holds the second write until the +first is answered, the command is stopped at its 10-second limit, and the +Edit fails (EIO), changing nothing. For the same reason a second Edit written +with `>` to that #file("ctl") waits for the first to finish rather than being +refused; through its own `<>` open, or another pane's #file("ctl"), it is +refused `busy` (EBUSY) at once. A flush of the Edit's write (an interrupted +writer) kills the commands and changes nothing. +Such an Edit is a write of its own: one with other lines is refused before +any runs. One Edit's commands run at a time in a session, at most 1024 of +them. While they run, an Edit with no commands runs as usual unless it +would change, undo, rename, close or write a file the running one changes; +that, and a second Edit with commands, is refused `busy` (EBUSY), as are +#word("Del") (acme's `delete`), `rmdir`, #word("Undo"), #word("Redo"), #word("Get") and #word("Zerox") on a pane +it changes or runs a command on; a session that ends lets the commands go. A command that fails (an exit status, 10 seconds, 1 MiB of output) +fails the Edit, its stderr in `+Errors`. Each file's changes are one undo step, applied only if +every command succeeds; a failure changes nothing and fails the write with +acme's words (`Edit: no substitution`), as does a file edited while the +commands ran. An `x` that finds nothing succeeds silently. `p`, `=` and `>` +print to the directory's `+Errors`. Not there: `B <cmd`, `D <cmd`, the `'` +address, `\1`-`\9`. In `s`, `&` is the match (`\&` a literal); in `c`, `a`, +`i` it is a literal. `y` yields the stretch before the first match too. +Braces take a command a line, so a block goes on one open, in one write or several: #cmd("printf 'Edit ,x/foo/{\\ni/</\\na/>/\\n}\\n' > $p/ctl") @@ -716,7 +796,7 @@ back as a record: run it through #file("ctl") instead. == REPLs <repls> #word("Repl") `python` on a terminal's #file("ctl") (or in its tag) binds it as -that language's REPL: a middle-click or #key("Tab") on a `.py` body +that language's REPL: #word("Exec") (or #key("Tab")) on a `.py` body then types the text into the REPL instead of running it; builtin words, tag words, #word("Exec") `<text>` and #raw("@`cmd`") words still run. #word("Repl") takes the languages a code fence names (ada, bash, c, c_sharp, clojure, @@ -831,7 +911,7 @@ at 200, ending in `…`. Control characters become spaces. permitted (`permission denied`, EACCES through a mount); ownership is synthetic. Linux v9fs's truncation `mtime` hint is accepted and dropped. - #file("/src/") (and #file("/shaders") on GUI builds) with - `-Dembed-sources=true`; `EffectCode <effect>` lists an effect's files + `-Dembed-sources=true`; #word("EffectCode") `<effect>` lists an effect's files under `/virtual`. = The pardes command <command-line> @@ -842,7 +922,7 @@ a FILE not there yet opens an empty pane that #word("Save") creates, making its directories. What the session refuses (a bad name; a name under a directory you may not search or write, `permission denied`) is printed and the exit is 1. `--` ends the options (`pardes -- -name`). -`pardes --wait FILE` (`-w`) returns 0 when the pane showing FILE is +`pardes --wait FILE` (`-w`; bare, it says it needs a FILE) returns 0 when the pane showing FILE is deleted, 1 when the session goes away (against a dead `$PARDES_9P` it says the session is gone); with `PARDES_9P` set but no pane of its own it opens FILE in that session and @@ -871,7 +951,7 @@ A command pane runs in the directory it started in, whatever its command does with `cd`, and a relative #word("Look") in it resolves there. The next command for that directory reuses a finished one (from a column tag, only one in that column); one still running, one a background job still prints to, or -one a #file("exec") open still holds is never reused. +one a #file("exec") open still holds is never reused. In a command pane, #key("n") walks that pane's own `file:line` places first (make's errors), whichever pane was walked last, then on through the others. = Find and Grep <find-grep> @@ -904,7 +984,7 @@ it was. `--no-prefix` diff's paths are kept. - *Sessions.* Bare `--detach` names the session after its pid; bare `--attach` needs exactly one session; a second `--detach=NAME` while NAME - runs says so and exits 1. Frontends share the smallest common size. With + runs (a plain session is named by its pid) says so in words and exits 1. Frontends share the smallest common size. With none attached, `size C R` sets the screen, messages clear by the clock, and a pty reports its size in pixels at the last frontend's cell size (8×16 before any), as CSI 14, 16 and 18 t do. @@ -912,11 +992,12 @@ it was. absolute, else `~/.config/pardes/init` (macOS: `~/Library/Application Support/pardes/init`). A line that fails is a notice and `err - init file line N: why`, and the rest still run; a - setting only the other frontend has (`Font` in a terminal) is skipped; + setting only the other frontend has (#word("Font") in a terminal) is skipped; text that is no builtin is not run; saving the init file in a pane - applies its settings again. A dump keeps panes, columns, tags, + applies its settings again and says a bad line as startup does + (`err - init file line N: why`), its commands not run again. A dump keeps panes, columns, tags, selections, the theme and changed settings, but not a picture or a PDF - that is on disk (Restore reads it from there); a terminal + that is on disk (#word("Restore") reads it from there); a terminal comes back with its last MiB of output and a new shell in its old directory; undo history and REPL bindings are not kept. A crash appends two lines (build, time, platform, pid; the panic message) to `crashes` @@ -955,8 +1036,8 @@ Under `9ns --mntgen` (which sets `NINE_MNTGEN=1`) a session is at `$NINE_MOUNT/<service>/<name>`, pardes's `$NINE_MOUNT/pardes/<name>`, and every pane pardes spawns gets it as `$PARDES_MOUNT`. Under `9ns --unix SOCK -- cmd` the session is `$NINE_MOUNT` itself, and `$PARDES_MOUNT` is unset. -plan9port's `9p write` opens with OTRUNC, so it replaces a whole -#file("body"); append with `>>` through a mount. Through a FUSE mount +plan9port's `9p write` opens with OTRUNC, so on #file("body") it replaces +the whole text. To append, use `>>` through a mount. Through a FUSE mount bash's `read -t` cannot time out: wrap a follow loop in `timeout`. The scripting chapter's rule (a mount, else `9p`) covers most uses. Two more: @@ -987,6 +1068,34 @@ with Client(sys.argv[1]) as c: # a socket path, or (ip, port) `client.screen()` returns the parsed #file("/screen"). += Coming from acme <from-acme> + +#pairs( + [`$NAMESPACE/acme`], [not posted there: a session is `$XDG_RUNTIME_DIR/9p/pardes/<name>`; reach it with `9p -a "unix!$PARDES_9P"` or a `9ns --mntgen` mount (#doc("fs", section: "other-clients"))], + [`N/`], [#file("pane/N/"), N the pane's serial], + [`new/ctl`], [read #file("pane/new"): it makes a pane and answers its serial; `rmdir pane/N` closes it], + [`index`], [#file("index") lines are serial, kind, dirty, name, column (acme: id, tag and body lengths, isdir, dirty, tag)], + [rune offsets], [bytes everywhere, event offsets and counts included; addresses snap to rune boundaries], + [`addr` reset on first open], [#file("addr") is the pane's; no open resets it (write `0`)], + [OTRUNC on `data` ignored], [`: > data` deletes the addressed text; OTRUNC on #file("body") (`9p write`) replaces it all], + [event flags 1, 2, 4, 8], [1, 4 and 8; never 2, so no expansion record follows], + [`Get`], [#word("Get") reads the file again, refusing unsaved edits once (a scratch under 100 bytes unasked, as #word("Del") closes it; a file not there, or a directory, is said first); `Get file` loads that file into the pane, which takes its name, and one that fails changes nothing; #word("Undo") after it, or after #word("Edit")'s `e`, puts the old name back with the old text and its saved state; in a directory pane #word("Get") reads the directory again and `Get file` is refused (#word("Look") opens the file) (also `get` on #file("ctl"))], + [`Put`, `Delete`, `Load`], [#word("Save"); a #word("Del") that does not ask; #word("Restore")], + [`Putall`], [#word("Putall"): every pane with unsaved edits to a file is saved, a #word("Zerox") pair once, a refused one said; with a refusal, its write is answered once the other saves have landed], + [`Zerox`], [#word("Zerox"): a second pane on the buffer, one text, undo and unsaved state, its own scroll and cursor; an event reader on one hears no edit made through the other; the twins are kept across #word("Dump") and #word("Restore")], + [`Tab`], [#word("Tab") `N`, 1-16: for every pane, not per window; bare, it says the width, from the root's #file("ctl") as from a pane's #file("exec")], + [`Incl`], [#word("Incl"): for the session, not per window, seeded with `/usr/include` and `/usr/local/include`; it takes absolute (or `~`) directories that exist, and `Incl -` alone clears the list; a name found nowhere else (`stdio.h`, `<stdio.h>`) is tried there], + [`Indent`], [always on: #key("Enter"), #key("o") and #key("O") keep the line's indent as it is], + [`Snarf`, `Cut`, `Paste`], [refused: the chords, #key("y"), #key("p")], + [`Font`, `Send`, `ID`], [#word("Font"); #word("Repl") and #word("Exec"); `$winid`], + [acme's other builtins], [refused: `Sort`, `Local`, `Abort` (plan9port's debugging word)], + [Edit], [every acme command but `B <cmd`, `D <cmd` and the `'` address; no `\1`-`\9`, and an alternation takes the first branch that matches, not the longest; a failing `< | >` command changes nothing, where acme puts in what it wrote (#doc("fs", section: "edit"))], + [`win`], [#word("Tty") is a VT terminal pane; #file("pty/run") runs a line at its prompt and answers `exit N` and the output; with #word("Repl") bound, #word("Exec") on a source pane types the text into it], + [a directory window], [as acme's: a text pane named `dir/` (#file("index") kind `text`, #file("ctl") isdir 1), its entries in columns sorted bytewise, dotfiles shown, a directory's marked `/`; blanks pad the columns where acme's tabs do; a #word("Look") at an entry is from that directory, `Get` or a look at it again reads it again, and an edit is kept until then rather than lost to a resize; never dirty, #word("Save") refuses it; #word("DirLook") `terminal` types `ls` into a terminal there instead], + [the plumber], [none: #word("Look") on an `http://` or `https://` URL runs `xdg-open` (`open` on macOS); files, addresses and directories follow built-in rules], + [#key("Esc") selects what was typed], [#key("Esc") leaves insert mode, or goes back a pane (#doc("tags", section: "modes"))], +) + = Limits <limits> #pairs( |
