When you type ahead during a local command, the keys wait in the terminal for
the shell's next prompt. During an ssh -t command they don't: ssh sends every
key to the far terminal, and the ones the command didn't read are lost when it
exits. ssh-typeahead brings those keys back to zsh's next prompt.
Wrap the ssh, and the command on the far host:
ssh-typeahead relay NONCE "$SSH_TYPEAHEAD_FILE" ssh -t HOST ssh-typeahead run NONCE COMMAND...
where COMMAND is quoted for the far host's shell, as with any ssh. NONCE must
be new for each command, and 1 to 64 letters, digits, dots, dashes and
underscores. Once the command has exited, run reads
the keys left on the far terminal, and relay stops sending keys and tells
run when all the ones it sent have arrived. relay appends them to
$SSH_TYPEAHEAD_FILE, and ssh-typeahead.zsh gives them to zle at the next
prompt, ahead of the keys typed since. The comment at the top of
src/main.rs has the details.
The far terminal's line editing has already been applied to the keys it queued, so a backspace typed during the command is applied, like a local terminal would; and as on a local terminal, typing ^C, ^\ or ^Z drops what was typed before it.
- Install
ssh-typeaheadon both hosts. - In zsh on the near host,
source ssh-typeahead.zsh. It exportsSSH_TYPEAHEAD_FILEonly if$XDG_RUNTIME_DIR(or$TMPDIR) is a directory that you own and that the group and others can't write to, whichrelaychecks too, along with the file being named for its terminal and for its parent process. So runrelayfrom that shell, or exec it from a script that the shell runs: when something else runs it, e.g. vim's:!, the keys belong to that program, not to the shell, and are lost as before. - Use it only with a far host you trust as much as the near one: whatever
runhands back gets typed into your shell.
- Keys that the command read into a buffer but didn't use are gone, as are
keys that it threw away (e.g. a pager quitting with
tcflush). - zle gets the keys, not a command started at the next prompt.
- A process left running on the far terminal can read the keys, and END with
them;
runthen gives up after 2 seconds. - At most 64 KiB of keys come back, and keys that send a NUL (e.g. ^@) don't, since zle can't take them.
- ssh's escape for suspending it (
~^Z) leaves it stopped for good: nothing in its session can continue it. End it with~.instead.
cargo test