Which shells
TTY7_SHELL_INTEGRATION is set once it is active, and guards against a second
injection when shells nest. It does not put the integration into a nested
shell — shells you start yourself have none.
A shell launched with arguments you wrote —
shell.args, or a
custom_shells entry — is left alone, because tty7’s injection would
conflict with the flags you chose. Arguments tty7’s own detection supplied
(Git Bash’s -i -l, a WSL row’s --distribution) do not count, so those
rows are still integrated.What it reports
What turns off without it
Run a shell tty7 does not integrate with, and everything below still works — it just falls back to less precise sources:- Ghost suggestions, the completion menu, and ⌃ R’s fuzzy history
- “Command finished” notifications and the failure marks in history search
- Exact working-directory tracking
tty7-server on that host
does the reading. It is a poll, not a report: it is sampled while the pane is
producing output, at most twice a second, so it can trail a cd until the
pane writes something again. A local pane on Windows and a pane connected
to an SSH host have no fallback at all — on the far end of an ssh there
is no process table to read, so a shell that does not report its directory
leaves the pane showing the last directory that did.
Shells you start yourself
The injection happens when the pane’s shell is launched. Typezsh at a
bash prompt — or bash, or sh, or docker exec … sh — and that second
shell is a new process, launched by your shell rather than by tty7. It emits no
prompt marks and no OSC 7, and the pane keeps showing the directory the
outer shell last reported until you exit back to it.
On your own machine this is usually invisible, because prompt frameworks
report the directory themselves: oh-my-zsh does it from
omz_termsupport_cwd in lib/termsupport.zsh. Over SSH it is not. That
file returns early when SSH_CLIENT or SSH_TTY is set, so on a remote host
a zsh you started by hand reports nothing at all, and neither does tty7.
To get integration into that shell, make it the shell tty7 starts:
- A remote host. tty7 asks the host for
$SHELLwhen it connects and bootstraps that shell, sochsh -s /bin/zsh(then reconnect) is what switches it. A login script under Advanced → Session that runszshdoes not — those lines are typed into the session after the shell is already up, so they nest like anything else. Neither doesexec zshfrom your.bashrc: it replaces the process tty7 set up. - A local pane. Set Settings → Terminal → Shell → Program (or
shellin config), and leave Arguments empty — arguments you write turn the injection off.
Per-pane history
Whenper_pane_history is on, the integration is also what makes it work. It
runs after your own rc file — which is the only reason it can: $HISTFILE is
yours to set, wherever you like, and nothing outside the shell knew where it
pointed until then.
The sequence is: seed the pane’s private file from your real history so it does
not start blank, record how much was seeded, repoint $HISTFILE, and merge
everything past that mark back when the pane closes.
More about history →