diff options
| author | Gabriel Schneider <[email protected]> | 2026-10-01 05:37:37 -0300 |
|---|---|---|
| committer | Gabriel Schneider <[email protected]> | 2026-10-01 05:37:37 -0300 |
| commit | cda0b279a24e8becc3c2836c42e7321830e2467a (patch) | |
| tree | a934136a45b73bee4837623fdf42e0d9165ba6ab /docs | |
| parent | b666f96e734bb87d6558c76c908314da562122d5 (diff) | |
| download | pardes-cda0b279a24e8becc3c2836c42e7321830e2467a.tar.gz pardes-cda0b279a24e8becc3c2836c42e7321830e2467a.zip | |
Recipes work through a pane of their own, its look and exec, and keep a command pane while their open lasts; the docs give cmd panes, the err grep, alt-screen prompts, /pager's refusals, Tty+ on a ctl, --, and theme failures in words
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Diffstat (limited to 'docs')
| -rw-r--r-- | docs/typ/cheatsheet-a4.pdf | 25 | ||||
| -rw-r--r-- | docs/typ/cheatsheet.typ | 2 | ||||
| -rw-r--r-- | docs/typ/guide.typ | 5 | ||||
| -rw-r--r-- | docs/typ/reference.typ | 34 | ||||
| -rw-r--r-- | docs/typ/scripting.typ | 43 | ||||
| -rw-r--r-- | docs/typ/themes.typ | 10 |
6 files changed, 74 insertions, 45 deletions
diff --git a/docs/typ/cheatsheet-a4.pdf b/docs/typ/cheatsheet-a4.pdf index e3d82657..ce50f595 100644 --- a/docs/typ/cheatsheet-a4.pdf +++ b/docs/typ/cheatsheet-a4.pdf @@ -1623,7 +1623,7 @@ B�=>�������b?��F�碮���;�G{�+-�"��}1��B��ӂft(;-؆�F
�T_��F+�Ђ]h@�Q��R� endstream endobj 476 0 obj -<</Length 23144/Filter/FlateDecode>> +<</Length 23145/Filter/FlateDecode>> stream x���Y�$�m'��O�MR-����~Q�RKڝYQ�1�mgTe��Y���-՚l����p�@x��Y�臮��gF" �Ru�K�v*�F[<�U�aq����)���Fn ��7�tpjx�~�R�i��^*?���@�U���6��
7�3��7 ��N�f|����H(]�s�B���
�{��F��HY�w � @@ -1720,10 +1720,9 @@ e��YQç�t�����Ѱ��.s}���uI�.w�*�.ٷ��b|o�z�2�r1P��N����g�1�RK9
��{�2�� �T��"�U�H%.�.� �UV� ��zk��P�m�,OB��e�s�g q��WlB0��[9��S -W[�e�%@#��bUu3�2aJ�(\�=�g�N;3?��W{���%�6A�̚��(2�rӗ�î����q�S�i��d�}�7k:�E��Q�� �Z3�������?�]m�C��}� - -�6�̰���^���길uy��Q�g-.�,B߁�i�<am����Sk�bU&�_Xu�&��Ū�%\�`��� U�sݪ�*���<K��2s�%Uh����T�\lE���ͽ?���}���6�1S��i��3FX�:�DL -]e0Y�p�s����cd�k����n��AP������ϸc���c�\�bu�m,`�,^�"��)��X;���Eq�-:m��[���n1q�_�Z�DŽ�����_*\bfm�'pfk�q6���:1�QSգ�z���C�65Mc�'`U��9l���LJ:p�(1�
�<�����_9[�+�t��>]q߮0�̬�L�� +W[�e�%@#��bUu3�2aJ�(\�=�g�N;3?��W{���%�6A�̚��(2�rӗ�î����q�S�i��d�}�7k:�E��Q�� �Z3�������?�]m�C��}� +�tOՓo��R��7��x.��+t鈗��Q�c�IJ�t���(�hT((&�H2�^\5\_kΘ[�W@�{����"���ֿl�9�:5�+Ve22�U�o +�P��Z�eA� endstream endobj 477 0 obj @@ -1735,12 +1734,12 @@ x�}��Kq�?�U�X
94%MQKS��N�#Ԧ��Q�v��B�ˡ�h�Fk ������! endstream endobj 478 0 obj -<</Creator(Typst 0.15.1)/ModDate(D:20261001035502-03'00)/CreationDate(D:20261001035502-03'00)>> +<</Creator(Typst 0.15.1)/ModDate(D:20261001053558-03'00)/CreationDate(D:20261001053558-03'00)>> endobj 479 0 obj <</Length 996/Type/Metadata/Subtype/XML>> stream -<?xpacket begin="" id="W5M0MpCehiHzreSzNTczkc9d"?><x:xmpmeta xmlns:x="adobe:ns:meta/" x:xmptk="xmp-writer"><rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"><rdf:Description rdf:about="" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:xmp="http://ns.adobe.com/xap/1.0/" xmlns:xmpMM="http://ns.adobe.com/xap/1.0/mm/" xmlns:xmpTPg="http://ns.adobe.com/xap/1.0/t/pg/" xmlns:pdf="http://ns.adobe.com/pdf/1.3/" ><xmp:CreatorTool>Typst 0.15.1</xmp:CreatorTool><dc:language><rdf:Bag><rdf:li>en</rdf:li></rdf:Bag></dc:language><xmp:ModifyDate>2026-10-01T03:55:02-03:00</xmp:ModifyDate><xmp:CreateDate>2026-10-01T03:55:02-03:00</xmp:CreateDate><xmpTPg:NPages>1</xmpTPg:NPages><dc:format>application/pdf</dc:format><xmpMM:InstanceID>kUzCo47beJvuFcNuIwqgGA==</xmpMM:InstanceID><xmpMM:DocumentID>kUzCo47beJvuFcNuIwqgGA==</xmpMM:DocumentID><xmpMM:RenditionClass>proof</xmpMM:RenditionClass><pdf:PDFVersion>1.7</pdf:PDFVersion></rdf:Description></rdf:RDF></x:xmpmeta><?xpacket end="r"?> +<?xpacket begin="" id="W5M0MpCehiHzreSzNTczkc9d"?><x:xmpmeta xmlns:x="adobe:ns:meta/" x:xmptk="xmp-writer"><rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"><rdf:Description rdf:about="" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:xmp="http://ns.adobe.com/xap/1.0/" xmlns:xmpMM="http://ns.adobe.com/xap/1.0/mm/" xmlns:xmpTPg="http://ns.adobe.com/xap/1.0/t/pg/" xmlns:pdf="http://ns.adobe.com/pdf/1.3/" ><xmp:CreatorTool>Typst 0.15.1</xmp:CreatorTool><dc:language><rdf:Bag><rdf:li>en</rdf:li></rdf:Bag></dc:language><xmp:ModifyDate>2026-10-01T05:35:58-03:00</xmp:ModifyDate><xmp:CreateDate>2026-10-01T05:35:58-03:00</xmp:CreateDate><xmpTPg:NPages>1</xmpTPg:NPages><dc:format>application/pdf</dc:format><xmpMM:InstanceID>zTz/YZTHTW8Jt6lL3JCjNQ==</xmpMM:InstanceID><xmpMM:DocumentID>zTz/YZTHTW8Jt6lL3JCjNQ==</xmpMM:DocumentID><xmpMM:RenditionClass>proof</xmpMM:RenditionClass><pdf:PDFVersion>1.7</pdf:PDFVersion></rdf:Description></rdf:RDF></x:xmpmeta><?xpacket end="r"?> endstream endobj 480 0 obj @@ -2225,12 +2224,12 @@ xref 0000086805 00000 n
0000087248 00000 n
0000091194 00000 n
-0000114410 00000 n
-0000114817 00000 n
-0000114930 00000 n
-0000116003 00000 n
+0000114411 00000 n
+0000114818 00000 n
+0000114931 00000 n
+0000116004 00000 n
trailer -<</Size 481/Root 480 0 R/Info 478 0 R/ID[(kUzCo47beJvuFcNuIwqgGA==)(kUzCo47beJvuFcNuIwqgGA==)]>> +<</Size 481/Root 480 0 R/Info 478 0 R/ID[(zTz/YZTHTW8Jt6lL3JCjNQ==)(zTz/YZTHTW8Jt6lL3JCjNQ==)]>> startxref -116190 +116191 %%EOF
\ No newline at end of file diff --git a/docs/typ/cheatsheet.typ b/docs/typ/cheatsheet.typ index a9152709..cec31428 100644 --- a/docs/typ/cheatsheet.typ +++ b/docs/typ/cheatsheet.typ @@ -160,7 +160,7 @@ Every session serves its panes as files. Pane shells get `$PARDES_9P` (socket), file("pane/N/ctl"), [builtins: `Save`, `Edit ...`], file("pane/N/body tag"), [its text (`>>` appends)], ) -#cmd("echo notes.txt:12 > $m/look") +#cmd("echo notes.txt:12 > $m/pane/$n/look") #cmd("echo /foo/ > $m/pane/$n/addr; printf bar > $m/pane/$n/data") #cmd("echo 'Edit ,x/foo/c/bar/' > $m/pane/$n/ctl") #cmd("exec 3<>$m/log; echo follow >&3; cat <&3") diff --git a/docs/typ/guide.typ b/docs/typ/guide.typ index 484a746e..1079b763 100644 --- a/docs/typ/guide.typ +++ b/docs/typ/guide.typ @@ -235,8 +235,9 @@ git's `a/` and `b/` prefixes are dropped (and `c/ i/ w/ o/` with In a pane's shell, `pardes FILE` opens FILE in this session and returns at once, as acme's `B` does. A FILE not there yet opens an empty pane named for it; #word("Save") creates it, making its directories first. Something -the session refuses (a bad name, or a new name in a directory that is there -but may not be read or written) is printed and the command exits 1. +the session refuses (a bad name; a name under a directory you may not +search or write, `permission denied`) is printed and the command exits 1. +`--` ends the options: `pardes -- -name` opens a file named `-name`. `pardes --wait FILE` (`-w`) returns when the pane showing FILE is closed (exit 0) or the session goes away (exit 1), as acme's `E` does. Set diff --git a/docs/typ/reference.typ b/docs/typ/reference.typ index cf5e66d0..748f6f3c 100644 --- a/docs/typ/reference.typ +++ b/docs/typ/reference.typ @@ -44,7 +44,8 @@ safe), only `rmdir` of #file("/pane/<n>") or an empty #file("/col/<n>") removes. Tcreate is refused everywhere. #file("/index") rows are `serial kind dirty name column`, kind `text`, -`term`, `pdf` or `image`, the name `<dir>/+New` for an unnamed scratch. +`term` (a shell), `cmd` (a command's pane, no shell to type into), `pdf` or +`image`, the name `<dir>/+New` for an unnamed scratch. 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 @@ -55,9 +56,9 @@ is not UTF-8 `\xNN`, so a name decodes to the bytes it is. *Failure.* A write fails whenever what it asked for fails, and logs one `err <serial|-> <file>: <why>` record, with no `msg`; a write that succeeds -logs none. So check a write's status first, and read the log's last `err` -only for a write that failed (`echo x > f || tail -1 log`): after a success -the tail may still hold an older `err`. Only writes log: a +logs none. A refused write says why in the log's last `err` record, found +with `grep '^err' log | tail -1`: after a refused Del, Exit or Restore the +newest line may be `new N .../+Unsaved`. Only writes log: a 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 @@ -96,7 +97,7 @@ write. An open that never wrote reads the session's last answer, from whichever client wrote it, so read on the open you wrote. A read is a stream: once read, the next read on that fid is EOF until the next write (or seek to 0). With other clients about, write and read on one open: -#cmd("exec 3<>$m/look; echo x >&3; cat <&3; exec 3<&-") +#cmd("exec 3<>$m/pane/$n/look; echo x >&3; cat <&3; exec 3<&-") *Snapshots.* #file("/index"), #file("/layout"), #file("/recent"), #file("/commands"), #file("/status"), #file("/listeners"), a read-only @@ -206,7 +207,10 @@ A line written to #file("exec") is a #btn("B2") click: - Anything else is a command line, 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 - the command pane's serial; the log says `run <serial> <line>` and `exit <serial> <N|?>`. A reused pane's #file("body") keeps every earlier run + the command pane's serial, and while that open stays open the pane is its +own: another client's command in the same directory gets a pane of its +own. The log says `run <serial> <line>` and `exit <serial> <N|?>`. A +reused pane's #file("body") keeps every earlier run above a `% <line>` row naming each command, so to take only the last run's output read from after the last `% ` row: #cmd("awk '/^% /{out=\"\"; next} {out = out $0 \"\\n\"} END {printf \"%s\", out}' body") @@ -287,7 +291,9 @@ Writes take settings and session builtins (`scope = .session` in wrote). The Restore write is answered, then *every connection is hung up*: dial again, and restart a 9ns mount. The new log has a `new` per pane, `restore <path>`, then `restored <old> <new>` per pane and - `restoredcol <old> <new>` per column. + `restoredcol <old> <new>` per column. A Restore that fails says why in + words, a dump's ZON error with its line (`line 3: expected ','`); a + ThemeFile the dump names that fails to load changes nothing. - `Kill [word...]` (above), `Mount name dial`, `Unmount name`, `Theme x`. - `size C R` sizes a `--detach` session no frontend is attached to (160x50 until then): from 20x6 to 4096x4096, else `invalid size`; refused while a @@ -295,7 +301,9 @@ Writes take settings and session builtins (`scope = .session` in rows (`size: too small for the panes, each its tag and 2 rows`). A bad `size` is refused quoting the value it got (`"5 2"`). -A write is refused whole, before anything runs, in Plan 9's words: +A word that takes its argument after a `+` (`Tty+bash`) works on a ctl as +in a tag. A write is refused whole, before anything runs, in Plan 9's +words: `unknown control message "X"`, `wrong #args in control message "X"`, `bad value in control message ...`, or a word of the other ctl: `not a session control message "Undo": write it to pane/<n>/ctl`, `... "Delcol": write it to col/<serial>/ctl`, `not a window control message "X": write it to /ctl`. A builtin that would open a prompt (#word("Save") on a scratch) fails `control message needs its argument "Save"`. A line that fails as it runs fails with the editor's words (`Mount: already mounted`, `Save /root/x: access denied`), changing nothing. @@ -677,7 +685,9 @@ Terminal panes also have #file("pty/"): Ctrl-C); read the live output stream (a consuming queue shared by readers, not a replay). - #file("pty/status"): one line, `cols rows busy`; busy is 1 while a - command runs or text is typed at the prompt. + command runs or text is typed at the prompt. A terminal whose program was + killed on the alternate screen is at its prompt once the shell draws one + there: busy is 0, and the next #file("pty/run") reads its output whole. - #file("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). @@ -689,7 +699,7 @@ Terminal panes also have #file("pty/"): goes to a `+Pager` pane through the terminal's `pardes -` pager; the last 64 KiB, `exit N cut M` when M bytes were left out, bare `cut` only when the start of that output scrolled out of the scrollback; after a `clear`, the answer is what the command printed from - the clear onward). Or: `busy: <program> is running` (bare `busy` when text is typed at the prompt), + the clear onward). Or: `busy: <program> is running` (bare `busy` when text is typed at the prompt, `busy alternate screen` on the alternate screen with no prompt drawn), `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 before a fresh terminal's first prompt waits for it. One line per run; a @@ -746,7 +756,9 @@ at 200, ending in `…`. Control characters become spaces. closed one at its last (a PDF's is its page); a look at a row reopens it there. - #file("/status"): `pid`, `version`, `panes`. -- #file("/pager"): write a directory (empty means the session's); a read on +- #file("/pager"): write an absolute directory that exists (an empty line + is the session's; one not there is refused `no such directory`, ENOENT, + a relative one `the directory must be absolute`); a read on the same open answers the serial of that directory's one `+Pager`, made or emptied for it. It takes one directory a write. This is what `pardes -` uses. diff --git a/docs/typ/scripting.typ b/docs/typ/scripting.typ index 555c6b43..7bf04efe 100644 --- a/docs/typ/scripting.typ +++ b/docs/typ/scripting.typ @@ -48,26 +48,34 @@ Both hold only where your environment names no pager. = Recipes -Each recipe starts after these lines, which find the session (with a mount) -and name a text pane by its serial (from #file("index"), or one you made): -#cmd("s=${PARDES_9P##*/pardes-9p-}; m=$NINE_MOUNT/pardes/${s%.sock}\nn=3; p=$m/pane/$n") +Each recipe starts after these lines, which find the session (with a +mount) and make a pane of your own. Work through that pane's #file("look") +and #file("exec"), not the root's (see the traps): +#cmd("s=${PARDES_9P##*/pardes-9p-}; m=$NINE_MOUNT/pardes/${s%.sock}\nn=$(cat $m/pane/new); p=$m/pane/$n # a scratch of your own") #pairs( [look around], [#cmd("cat $m/index\ncat $m/layout\ncat $m/focus\ncat $m/commands")], - [open a file at a place], [#cmd("exec 3<>$m/look; echo \"$PWD/main.zig:120\" >&3; cat <&3; exec 3<&- # where it went\necho 'main.zig:0/fn main/' > $m/look # the first match")], - [make, fill, name, save], [#cmd("n=$(cat $m/pane/new) # one pane per open\nprintf 'hello\\n' > $m/pane/$n/body # > replaces, >> appends\necho \"$PWD/notes.txt\" > $m/pane/$n/name\necho Save > $m/pane/$n/ctl\nrmdir $m/pane/$n # close it")], - [say something], [#cmd("echo 'Msg hello' > $m/exec")], + [open a file at a place], [#cmd("exec 3<>$p/look; echo \"$PWD/main.zig:120\" >&3; f=$(cat <&3); exec 3<&- # its pane\necho \"$PWD/main.zig:0/fn main/\" > $p/look # the first match")], + [fill, name, save, close], [#cmd("printf 'hello\\n' > $p/body # > replaces, >> appends\necho \"$PWD/notes.txt\" > $p/name\necho Save > $p/ctl\nrmdir $p")], + [say something], [#cmd("echo 'Msg hello' > $p/exec")], [replace everywhere], [#cmd("echo 'Edit ,x/foo/c/bar/' > $p/ctl\ngrep -c foo $p/body # 0: none left")], [replace one match], [#cmd("echo /old/ > $p/addr && printf new > $p/data")], [delete line 3], [#cmd("echo 3 > $p/addr; : > $p/data")], [select line 3, read it], [#cmd("echo 3 > $p/addr; cp $p/addr $p/dot; cat $p/sel")], - [run a command], [#cmd("exec 3<>$m/exec; echo 'make test' >&3; c=$(cat <&3); exec 3<&- # its pane\nuntil grep -q ') exit ' $m/pane/$c/tag; do sleep 0.2; done\ngrep -o 'exit [0-9?]*' $m/pane/$c/tag")], + [run a command], [#cmd("exec 3<>$p/exec; echo \"cd '$PWD' && make test\" >&3; c=$(cat <&3) # its pane\nuntil grep -q ') exit ' $m/pane/$c/tag; do sleep 0.2; done\ncat $m/pane/$c/body; exec 3<&- # read it before letting go")], [run at a prompt], [#cmd("t=$(awk '$2==\"term\"{print $1; exit}' $m/index)\nexec 3<>$m/pane/$t/pty/run; echo ls >&3; cat <&3; exec 3<&-")], [type, interrupt], [#cmd("t=$(awk '$2==\"term\"{print $1; exit}' $m/index)\nprintf 'q' > $m/pane/$t/pty/data # \\r Enter, \\x03 Ctrl-C\necho 'sig INT' > $m/pane/$t/pty/ctl")], - [ask the language server], [#cmd("echo /myFunc/ > $p/addr; echo dot=addr > $p/ctl\necho Hover > $p/exec # also Rename new, Symbols")], + [ask the language server], [#cmd("exec 3<>$p/look; echo \"$PWD/main.zig\" >&3; q=$m/pane/$(cat <&3); exec 3<&-\necho /myFunc/ > $q/addr; echo dot=addr > $q/ctl\necho Hover > $q/exec # also Rename new, Symbols")], [follow what happens], [#cmd("exec 3<>$m/log; echo 'follow new' >&3\ntimeout 30 cat <&3; exec 3<&-")], ) +A command pane your #file("exec") open was answered is yours while that +open stays open: another client's command in the same directory gets a +pane of its own. Read its #file("body") and poll its tag before you close +the open; once you have, the directory's next command may reuse the pane. +In #file("index") a `term` is a shell to type at, a `cmd` a +command's pane. + `follow` without `new` replays the ring first. == A script for a tag @@ -140,12 +148,19 @@ pardes the editor of every program run there. = Traps <traps> -- Check the write's own status first: a refused write says only `Invalid - argument` or `Input/output error`, and only then is the log's last `err` - record its reason: `echo Save > $p/ctl || tail -1 $m/log`. A write that - succeeds adds no record, so after a success the log's tail may still show - an older, unrelated `err`. Only writes log: a refused open, truncation or +- A refused write says only `Invalid argument` or `Input/output error`; + its reason is the log's last `err` record: `grep '^err' $m/log | tail -1`. + Not the log's last line: after a refused Del, Exit or Restore that may be + `new N .../+Unsaved`. A write that succeeds adds no record, so check the + write's own status first. Only writes log: a refused open, truncation or `rmdir` has its errno alone. +- The root #file("look") and #file("exec") act at the active pane, which + another client, an idle shell or an event helper may own: a line written + there may be typed into a terminal or taken by an event reader. Use a + pane's own #file("look") and #file("exec"). +- `head` through a 9ns mount says `Illegal seek` on the files that stat 0 + (#file("index"), #file("layout"), #file("log"), #file("recent")): they + are streams. Use `sed -n 1p` or `awk 'NR==1'`; `tail -n` works. - #file("addr") belongs to the pane, not to you, and moves on: each `/re/` searches from the last address, a #file("data") write leaves it just past what it wrote, and a read moves it too. Write #file("addr") @@ -167,7 +182,7 @@ pardes the editor of every program run there. - Read #file("look"), #file("exec") or #file("pager") on the open you wrote: a read answers the panes touched by this open's last write, and a fresh open reads the session's last answer, from whichever client wrote - it (`exec 3<>$m/exec; echo cmd >&3; cat <&3; exec 3<&-`). + it (`exec 3<>$p/exec; echo cmd >&3; cat <&3; exec 3<&-`). - `tail -f log` never sees anything new: write `follow` on the open you read. Through a FUSE mount bash's `read -t` cannot time out: wrap the loop in `timeout`. diff --git a/docs/typ/themes.typ b/docs/typ/themes.typ index 9212a27b..918c2ea5 100644 --- a/docs/typ/themes.typ +++ b/docs/typ/themes.typ @@ -91,10 +91,12 @@ An imported theme whose name a port now holds is kept with `_helix` added change its `.name`, and run `ThemeFile themes/mine.zon` (relative to the config directory). Where the host reloads files, saving it updates the theme at once; a malformed save keeps the last good version, and -`Theme <name>` stops the watch. A `ThemeFile` that fails to load changes -nothing: #file("/ctl") and #word("DumpConfig") still name the file that last -loaded, or none. #word("Restore") and `pardes -l` load a dump's -`ThemeFile` again, as a #file("/ctl") write of it does. The format is `pardes.Theme` as +`Theme <name>` stops the watch. A `ThemeFile` that fails to load says why +in words, a ZON error with its line (`line 3: expected ','`), and changes +nothing: the theme shown stays, and #file("/ctl") and #word("DumpConfig") +still name the file that last loaded, or none. #word("Restore") and +`pardes -l` load a dump's `ThemeFile` again, as a #file("/ctl") write of it +does, and one that fails there changes nothing either. The format is `pardes.Theme` as `std.zon.stringify` writes it, a complete theme with no inheritance. The required roles: nullable `bg` and `fg`, `sel_bg`, `sel_fg`, `tag_bg`, |
