122 lines
5.3 KiB
Markdown
122 lines
5.3 KiB
Markdown
# How this runs: TUIOS, not tmux
|
|
|
|
Read this before writing any code or starting any session. Everything here was measured on
|
|
this setup; the commands are real.
|
|
|
|
## The environment is TUIOS
|
|
|
|
The terminal multiplexer on these machines is **TUIOS**, not tmux. There is no tmux session
|
|
to attach to, and a design that assumes tmux will not work. TUIOS calls its groupings
|
|
**workspaces**, and each split inside a workspace is a **pane**. A pane is a real terminal
|
|
(its own PTY) running a program.
|
|
|
|
Consequences that have already cost us two days:
|
|
|
|
1. **A workspace with no panes is deleted, and the rest are renumbered.** Never hold a
|
|
workspace number. Always resolve a workspace by name at the moment you use it.
|
|
2. **A page must keep one pane that never exits**, or the page vanishes. This is why every
|
|
screen in this project has a permanent pane.
|
|
3. **TUIOS owns part of the keyboard.** In window-management mode it keeps `h j k l`, `z`
|
|
and `n`. A program only receives keys in terminal mode, entered with `i` or `Enter`, and
|
|
you leave window mode with the prefix key then `Esc` (default prefix `Ctrl+B`).
|
|
4. **A resize reaches the program as a normal terminal resize** (SIGWINCH). Handle it. Do
|
|
not hardcode sizes.
|
|
|
|
## The machines
|
|
|
|
| Name | Address | Reachable how |
|
|
|---|---|---|
|
|
| `.13` `nixos-desktop` | `192.168.20.13` | headless, hosts the work and the Paperclip server; also reachable over the web |
|
|
| `.27` `sam-4screen-desktop` | `192.168.20.27` | local only |
|
|
| `.51` `sam-thinkpad` | `192.168.20.51` | local only |
|
|
|
|
`.13` is the machine that hosts work. `.27` and `.51` are where a person sits. Any machine
|
|
can drive any other over ssh, but ssh needs a key already installed
|
|
(`ssh-copy-id 192.168.20.13` once if it ever asks for a password).
|
|
|
|
## Starting a session
|
|
|
|
Session creation needs a real terminal. Measured: `tuios new` and `tuios attach` both fail
|
|
with "Standard output is not a terminal" when run from a script. So the person creates the
|
|
session, once, in a terminal:
|
|
|
|
```
|
|
# on .27, to create a session that lives on .13
|
|
tuios new --host nixos-desktop cookie
|
|
|
|
# on the machine that owns the folder, plainly
|
|
tuios new cookie
|
|
```
|
|
|
|
Then inside a pane of that session, on the host where the folder lives:
|
|
|
|
```
|
|
cd ~/src/cookie
|
|
```
|
|
|
|
Rules that follow from this:
|
|
|
|
- The session lives on one machine. The folder lives on one machine. Use the same one.
|
|
- Inside the session, on the host that owns the folder, nothing else is needed. No `--host`.
|
|
- `--host` is only for acting on a *different* machine from where you typed the command.
|
|
|
|
## Reading and driving a session from a script
|
|
|
|
```
|
|
tuios list-sessions
|
|
tuios list-workspaces -s cookie --json # number and name of each workspace
|
|
tuios list-windows -s cookie --json # panes, their workspace and their name
|
|
tuios new-window NAME -s cookie --workspace "<number>" --cwd <dir> --no-focus --keep-open -- <command...>
|
|
tuios capture-pane -s cookie -w <window-id> # what the pane shows now
|
|
tuios send-keys -s cookie -w <window-id> <Key> # drive a program in a pane
|
|
tuios close-window <window-id> -s cookie
|
|
```
|
|
|
|
The colour codes in `list-windows` output wrap the name, so match on the stripped text.
|
|
Anything matching a bare name must strip escape sequences first — a plain ` name ` match
|
|
fails and made a live session look absent.
|
|
|
|
## What this means for our four screens
|
|
|
|
Each screen is a pane in its own workspace, named for what it shows. The Go program draws
|
|
inside the pane it is given; it never owns the whole terminal. A screen that needs the
|
|
whole width is a pane that has been zoomed, not a separate mode.
|
|
|
|
When a screen is started, it is started with the project and the session in its
|
|
environment, so it knows what to read. When it is started twice, the second start must
|
|
adopt the existing pane rather than create a duplicate.
|
|
|
|
## Testing an interface change
|
|
|
|
A test in a plain terminal, or in tmux, proves only that the program draws. TUIOS owns part
|
|
of the keyboard and forwards mouse clicks relative to the pane, so the real check is:
|
|
|
|
```
|
|
tuios new-window harness-check -s "$TUIOS_SESSION" --no-focus --keep-open -- /tmp/harness-bin
|
|
tuios capture-pane -s "$TUIOS_SESSION" -w harness-check
|
|
tuios send-keys -s "$TUIOS_SESSION" -w harness-check Down --repeat 2
|
|
```
|
|
|
|
If the pane shows what you expect after the keys, it works where it will be used.
|
|
|
|
## Opening the screens
|
|
|
|
The session for this project is named **`paperclip-harness`**. The scripts take that name
|
|
themselves; they never read `TUIOS_SESSION`, because that is the session of the pane you
|
|
happen to be typing in, and using it once put a screen in the wrong session.
|
|
|
|
```
|
|
bin/layout # every screen, in order, adopting what is already there
|
|
bin/screen tree # one screen
|
|
bin/screen reply AUD-162
|
|
```
|
|
|
|
Both are idempotent: a second run focuses the pane that is already running that screen. The
|
|
pane is a shell that starts the program and returns to the shell when it exits, so a pane
|
|
never closes itself and the workspace keeps the pane that stops it being deleted.
|
|
|
|
Measured: closing the last pane on a workspace leaves the number but **erases the
|
|
workspace's name**. Reopening therefore falls back to the first empty workspace and renames
|
|
it, which is why `bin/screen` prints either `created` or `adopted` and the workspace it
|
|
used. Nothing stores a workspace number.
|