termdock_

Shell integration

One line in your shell rc. It is the single highest-value thing you can configure, and it unlocks four features nothing else can offer.

The problem it solves

Every terminal has the same blind spot. It receives one long stream of characters and has no idea which of them are your prompt, which are the command you typed, and which are that command's output. It is all just text arriving.

That is why no multiplexer offers "jump back to the previous command" or "copy that command's output" — not because nobody thought of it, but because the information genuinely is not there to act on.

OSC 133 is the fix the terminal world settled on: the shell announces the boundaries as it goes. Four invisible, zero-width markers per command — prompt starts, prompt ends, command started running, command finished with its exit status.

termdock records them in its own VT emulator, which is why this works over SSH, in any terminal, whether or not the terminal you are sitting at has ever heard of OSC 133. tmux cannot do this at any price: it has no emulator of its own to record them in.

Turning it on

Add one line to your shell's startup file:

# ~/.bashrc, ~/.zshrc, or ~/.config/fish/config.fish
eval "$(termdock shell-init)"

termdock shell-init detects your shell from $SHELL; pass bash, zsh or fish to be explicit. It prints the snippet rather than installing it — that file is yours and you should read what goes into it. To just look:

termdock shell-init bash | less

Open a new pane afterwards; shells already running won't pick it up. Nothing about your prompt changes visually.

If your prompt comes from a theme — oh-my-zsh, powerlevel10k, starship — put the eval line after that theme's setup, or the theme will overwrite the marker termdock appends to PS1. termdock doctor will tell you whether it found the line at all.

A worked example

You run a test suite. It fails somewhere in three hundred lines of output. You then run four more commands while poking at it, and now the failure is far up the scrollback:

$ go test ./...          ← 300 lines of output, somewhere up there
$ git status
$ vim internal/core/foo.go
$ git diff
$ go build ./...
$                        ← you are here

Without shell integration, retrieving that failure means entering copy-mode, scrolling up by eye past four commands, finding where the test run started, guessing where it ended, drag-selecting several screens of text, and hoping you didn't clip the first line.

With it:

You pressWhat happens
Ctrl-B [ then {Jumps to the prompt of go build.
{ { { {Four more jumps, one per command, landing on go test ./....
Ctrl-B OThe entire output of that run — all 300 lines — is on your clipboard.

What you get

Move by command, not by line

{ and } in copy-mode jump to the previous and next command. Each jump lands on a prompt with that command's output filling the screen below it — which is the thing you were scrolling to find. Repeated presses walk back through your history one command at a time.

Copy a command's whole output

Ctrl-B O. Not "roughly this screenful", not "what's currently visible" — exactly the lines between where that command started printing and where it stopped, whether that is 2 lines or 3000, with the prompt and the command itself excluded.

Which command follows where you are looking: in copy-mode it is the one your cursor sits in, so walking back with { and then copying does what it plainly looks like it should. At a live prompt it is the most recent. Pressed while a build is still running, you get everything it has printed so far.

A verdict on every pane

A pane whose last command failed says so in its title:

 2:go [✗1 47s]        ← exited 1, took 47 seconds
 3:npm                ← last command succeeded, quickly: nothing added

The exit status appears only on failure, the duration only when the command ran longer than a few seconds. A title is no place for noise, and is the thing worth catching out of the corner of your eye when you glance at a pane you left running.

History and timeline

Both of these become possible, and they get their own section: Ctrl-B H searches every command the session has run, and Ctrl-B T draws them on a timeline.

Without it

Nothing breaks. There are simply no marks, and each feature says so and points at the fix rather than silently doing nothing:

no command marks in this pane — run `termdock shell-init` for the shell snippet