aboutsummaryrefslogtreecommitdiffstats
path: root/docs/scripting.md
diff options
context:
space:
mode:
authoruser <user@clank>2026-08-16 18:57:22 +0200
committeruser <user@clank>2026-08-16 18:57:44 +0200
commitb4b066c8c4e26191132f99014555d0a1d3232340 (patch)
treef8b26e3cc107d85069c043f2ade92baad3e3322b /docs/scripting.md
parentsl0ppty: `:load` a preset, without a second KDL reader (diff)
downloadslosh-b4b066c8c4e26191132f99014555d0a1d3232340.tar.gz
slosh-b4b066c8c4e26191132f99014555d0a1d3232340.tar.xz
slosh-b4b066c8c4e26191132f99014555d0a1d3232340.zip
sl0ppty: the prompt speaks config, not a dialect of it
chrome> include "contrib/chrome/heartbeat.kdl" heartbeat.kdl: 1 chrome, 0 content chrome> shaders { ...> tint where="chrome" color="#ff5fd7" amount="abs(sin(t / 5))" ...> dim where="content" amount=80 ...> } 1 chrome, 1 content Both of those were errors an hour ago, and the second one was my fault twice over: `:paste` printed `include "..."` and printing something you cannot type back is a prompt lying about its own output. Pasting it answered `unexpected argument for include`, and `load "..."` answered the same about `load`. So the grammar is now the config's, all of it: an entry, several with `;`, an entry with its own `where=`, a whole `shaders { }` block over as many lines as it takes, `include "f.kdl"`, `load f`. There is a test that reads `:paste`'s block off the screen, clears the pane, types it back line by line and compares the cells -- round-tripping is the property, not a nice-to-have. **The text is a document.** What it says replaces both chains, exactly as naming `shaders { }` in a config replaces the block rather than adding to it, and an entry's `where=` decides which rect it lands on. That drops a rule I invented last week -- "one chain, one rect", which refused an entry that named the other one -- because it made the prompt's mode a law rather than a default and made a two-rect block, the thing `:paste` prints, impossible to paste back. The prompt now keeps the document and sends all of it, so a line aimed at the frame leaves the contents alone, and the reply says `1 chrome, 1 content` rather than `ok`: with routing visible, the counts are the answer worth reading. `route_entries` is the one place routing is decided now -- config file, preset file, typed line, same function. `config_parse_chain_doc` takes the wrapper or the bare entries, because both are things a config contains and therefore both are things somebody will paste. Still nothing in the prompt parses KDL. A file goes by path; a pasted block goes via a temporary file, since an OSC payload cannot carry a newline -- a control byte ends the sequence, by the spec -- and joining lines with `;` would need exactly the comment-and-quote scanner I refused to write. The only syntax the script looks at is counting braces to know whether you have finished typing, and an empty line gives up on that. One hint, for the mistake that started this: when the session says `unknown shader`, the prompt adds `(a file? :load <path>, or include "<path>")`. After the fact rather than before, so a plugin's shader name is never second-guessed. Verified: `tests/test_shader_repl.py` is 41 checks -- every input shape, the multi-line paste and giving up on one, the round trip, the hint -- and `tests/test_inband_shaders.py` gained the document rule in both directions, including that a document naming only the frame takes the contents pass off. Full clean suite green.
Diffstat (limited to 'docs/scripting.md')
-rw-r--r--docs/scripting.md6
1 files changed, 4 insertions, 2 deletions
diff --git a/docs/scripting.md b/docs/scripting.md
index d07d78f..de7e712 100644
--- a/docs/scripting.md
+++ b/docs/scripting.md
@@ -59,8 +59,10 @@ printing a prompt and hoping.
`purpose` is the other verb: `printf '\033]5577;1;purpose;logs\033\\'`. A purpose
declared by a layout or the control API wins and cannot be overwritten this way.
-`shader` is the third, and the only one the session can refuse: it sets the
-shader chain for the pane that asked, in the config's own syntax, and needs
+`shader` is the third, and the only one the session can refuse: it sets the shader
+passes for the pane that asked -- a document in the config's own syntax, so an
+entry's `where=` decides which rect it lands on and the reply counts what went
+where. It needs
`in_band_shaders true` because a program restyling your session is a hazard
before it is a convenience. `shader;` with no rect named clears both of that
pane's chains, which is never refused -- and `clear-shaders` above is the same