diff options
| author | user <user@clank> | 2026-08-15 23:53:30 +0200 |
|---|---|---|
| committer | user <user@clank> | 2026-08-15 23:53:30 +0200 |
| commit | 4dc055692c56324a94d1087331da8862ea650d2b (patch) | |
| tree | 5ddec99f7cf6b144ede4138b6e952c84379725aa /docs/scripting.md | |
| parent | sl0ppty: marks a font actually draws at cell size (diff) | |
| download | slosh-4dc055692c56324a94d1087331da8862ea650d2b.tar.gz slosh-4dc055692c56324a94d1087331da8862ea650d2b.tar.xz slosh-4dc055692c56324a94d1087331da8862ea650d2b.zip | |
sl0ppty: a README you can read, and docs/ for the rest
The README was 331 lines and had become a manual with a title. Everything
in it was true and most of it was the wrong thing to hand somebody who
has just arrived: five pages of shader expression semantics before they
have split a pane.
So the front page is 60 lines -- what it is, install, run, where the docs
are, and six bullets on what is actually different about it -- and the
detail moved into docs/, nine pages that each answer one question:
index.md what it is, install, run, where to go
keys.md the leader, every default, rebinding, direct binds
panes.md splitting, resizing, the mouse, dead panes, small terminals
config.md the file, live reload, include, themes, the knobs
shaders.md the passes, the built-ins, the expression language
chrome.md where="chrome", channel, since, the perimeter trick
layouts.md a session as a file, and writing one back out
scripting.md the control socket, OSC 5577, headless
design.md the two decisions, and a map of the source
docs/nav holds the order and the grouping and nothing else -- titles come
from each page's own heading, so a renamed page cannot end up with two
names. It is what the site generator will read.
Reference material that only existed in code comments is written down for
the first time: every action that can be bound (including the two with no
default key, which is what the palette is for), every control verb, the
built-in shaders with what each takes, the pane-state ranking, and the
layout file's shape.
Two things I got wrong on the first pass and fixed before committing: the
docs linked repo files through github.com URLs for a project whose remote
is a private git server, so those are inline paths now; and the README
advertised `make docs`, which does not exist yet. It will in the next
commit, and it can be advertised then.
Diffstat (limited to 'docs/scripting.md')
| -rw-r--r-- | docs/scripting.md | 75 |
1 files changed, 75 insertions, 0 deletions
diff --git a/docs/scripting.md b/docs/scripting.md new file mode 100644 index 0000000..0c27565 --- /dev/null +++ b/docs/scripting.md @@ -0,0 +1,75 @@ +# Scripting + +Three things make sl0ppty easy to drive from other programs: a socket that does +everything the keyboard does, an escape sequence a pane can use to draw its own +chrome, and a headless mode that is the whole program without a terminal. + +## The control socket + +One JSON object per line, over the session's socket. A detached session answers +exactly as an attached one does. + +```bash +$ sl0ppty -s work cmd '{"cmd":"new-tab","name":"api"}' +{"ok":true,"id":2} +$ sl0ppty -s work cmd '{"cmd":"panes"}' +{"ok":true,"panes":[{"id":1,"title":"nvim","alive":true,...}]} +``` + +Panes and tabs are addressed by **id**, so a background tab is scriptable. + +| verb | | +|---|---| +| `panes` `tabs` | what exists, with ids, rects, titles, purposes, state | +| `snapshot` | the composited screen, as JSON or `format:"text"` | +| `deadline` | when the session wants its next frame, in ms, or -1 | +| `send` | bytes as if typed, decoded like input (`"data":"\\x01\\\\"`) | +| `raw` | bytes straight into the focused pane's pty | +| `resize` | `cols` `rows`, and optionally `cell_w` `cell_h` | +| `split` | `dir:"cols"\|"rows"`, `id` for which pane to split | +| `focus` | `id` | +| `close` `rerun` | `id`, or 0 for the focused pane | +| `new-tab` `select-tab` `close-tab` `move-tab` `set-name` | tabs, by `id` or `index` | +| `set-purpose` | `target:"pane"\|"tab"`, `id`, `purpose` | +| `dump-layout` `apply-layout` | see [layouts](layouts.md) | +| `notify` | put a line in the session's status area | +| `graphics` | the kitty placements on screen, or the bytes sent for them | +| `clipboard` | what the session has copied | +| `reload` | re-read the config; answers `{"ok":true,"warning":...}` if it had a complaint | +| `edit-config` | open the config in a pane | +| `alive` | is it running, and how many panes and tabs | +| `quit` | end the session | + +## A pane can draw its own chrome + +By printing an escape sequence — no plugin, no config: + +```bash +printf '\033]5577;1;status;building 3/7\033\\' +printf '\033]5577;1;buttons;approve:Approve;cancel:Cancel\033\\' +# clicking [Approve] arrives on the program's stdin as: +# \033]5577;1;click;approve\033\\ +``` + +The status text appears in the pane's frame; the buttons are real targets in it. +A program that wants to be asked something can ask *in place* rather than +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. + +## Headless + +`sl0ppty --script` is the whole program without a terminal: commands on stdin, +answers on stdout. It is how the test suite works — drive these events, assert +this screen — which is also why the suite is 700-odd real end-to-end checks that +finish in eight seconds. + +```bash +$ printf '%s\n' '{"cmd":"split","dir":"cols"}' '{"cmd":"snapshot","format":"text"}' \ + | sl0ppty --script --cols 80 --rows 24 -- /bin/sh +``` + +The bare-verb form (`snapshot text`, `send \x01\\`, `resize 100 30`) is a +human-friendly alias for the same code, so a script and a test cannot drift from +what the API does. |
