termdock_

Working in it all day

The parts that stop mattering in a demo and start mattering on the third day of the same session.

Search every command you have run

Ctrl-B H fuzzy-searches every command run in any pane of the session, newest first, with how each one exited and how long it took:

go test ./...                            ✗1  2m14s  0:api › 1
kubectl rollout status deploy/web                   1:ops › 2
docker compose up -d                          8s    1:ops › 1

Type to filter. Enter types it into the current pane without running it — the list is full of things that already happened, some of which failed, and firing one straight off a fuzzy match is how the wrong directory gets deleted. Repeats collapse to a single entry.

Your shell's own history cannot be this, for three separate reasons: it is per-shell, so what you ran in the pane next door is invisible; it records what you typed but not what happened, so the command that worked looks identical to the three attempts before it; and it is written when that shell exits, so a pane still open has contributed nothing.

Needs shell integration.

See when everything ran

Ctrl-B T draws every command on one shared time scale, oldest first:

23:46:40  go build ./...   ██████████··················  31ms  0:api › 1
23:46:40  go test ./...    ·········███████████████████  60ms  ✗1  0:api › 1
23:46:40  tail -f app.log  ···························█  running  1:ops › 1

It answers the question you ask after something has gone wrong, when the evidence is spread across four panes' scrollback: was the build still running when I started the migration? Because every bar is drawn on the same scale, overlapping work reads as overlap. Commands still going are included and marked.

Needs shell integration.

Tell me when this finishes

Ctrl-B m marks a pane. The moment whatever it is running exits and falls back to a bare prompt, you get a terminal bell and a message naming the pane. An armed pane wears a [⏳] tag on its title; pressing m again takes it back.

Two things make this better than appending ; notify-send done. It needs no shell configuration — termdock asks the pty which process group holds the foreground, so "busy" is that name not being your shell's. And it can be armed after the command is already running, which a wrapper fundamentally cannot: you almost never know in advance that this is the run that will take twenty minutes.

Name your panes

Six panes all called bash tell you nothing. Ctrl-B . names one. The name wins over the process name, appears in the jump picker so the pane becomes findable by it, and is saved with the session so a crash does not undo it. Confirming an empty prompt clears it.

Log a whole window at once

Ctrl-B A asks for a directory and logs every pane in the window, one file each. Press it again to stop them all.

~/bug-1234/
  deploy-feat_login-api_server.log
  deploy-feat_login-worker.log
  deploy-feat_login-pane3.log      ← unnamed panes fall back to position

Files are named after the things you recognise: the session, the window, and the pane's own name where you gave it one. A directory of api.log, worker.log and db.log is worth something an hour later; one of p3-20260821-154233.log is not.

The prompt is prefilled with the default log directory, so the common case is Enter; ~ is expanded and the directory is created if missing. A pane you had already started logging by hand with Ctrl-B L is left alone rather than restarted, so this never truncates a file you opened deliberately.

Type into several panes at once

Ctrl-B y sends your keystrokes to every pane in the window. Useful for driving a handful of machines together — the same tail, the same deploy.

But the pane running your editor, or the one holding the output you are comparing against, is exactly the one that must not receive them. So open the overview (Ctrl-B g) and press space on each pane you want included. The status bar then reads [SYNC 3/7] — before pressing Enter into several machines at once, the number is the thing you want confirmed.

Picking a pane turns synchronisation on by itself, and deselecting the last one turns it off rather than falling back to "everything".

Reopen a closed pane

Ctrl-B Z brings back the pane you just closed: a fresh shell, in the window it came from, started in the directory it was sitting in. The last 16 closures are kept, so repeated presses walk further back.

It covers every way a pane goes away, including a shell that exited on its own — which is the case it mostly exists for: an exit typed into the wrong pane. What comes back is the place, not the process: retyping the command is easy, remembering which of four windows it was in and cd-ing three levels down again is what actually costs you.

Saved layouts

termdock layout save -t work dev   # capture the current arrangement
termdock layout apply dev          # rebuild it, here or on another machine
termdock layout ls
termdock layout rm dev

A session snapshot is automatic and about surviving a crash. A layout is deliberate and about starting the same working set again tomorrow: windows, splits, ratios, window and pane names, and each pane's working directory.

Applying adds to the session rather than replacing it. A layout is something you reach for to start work, and one that silently closed panes you had running — with no undo for a whole session's worth — would be a thing you approach nervously.

This is the job people currently leave a multiplexer for, using tmuxinator or teamocil: an external tool, a YAML file, a language runtime.