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.