Prefix-free pane navigation across nested tmux sessions over SSH. Stop doing mental math calculating the right prefix combination.
Alt + arrow switches focused pane both inside the current tmux and across an SSH boundary
(when the tmux on the other side also has this plugin installed). It respects layout geometry - as if the pane layout was in a single local tmux session.
Demo
The other machine must be accessible by SSH in batch mode (without an
interactive passphrase prompt) for the signaling connection to be established.
An encrypted key works when its passphrase has already been remembered by
ssh-agent.
Install
Install the plugin on both the local and remote hosts.
With TPM
set -g @plugin klntsky/tmux-seamless-remoteThen press prefix + I to install it. TPM normally binds this to:
run-shell ~/.tmux/plugins/tpm/bindings/install_pluginsThe command-line equivalent is:
~/.tmux/plugins/tpm/bin/install_pluginsWithout TPM
Clone the repo and source its entrypoint:
run-shell "bash ~/.tmux/plugins/tmux-seamless-remote/tmux-seamless-remote.tmux"Then reload tmux on both hosts.
Configuration
To override the keys before loading the plugin:
set -g @seamless-remote-left-key M-h set -g @seamless-remote-down-key M-j set -g @seamless-remote-up-key M-k set -g @seamless-remote-right-key M-l
Bindings are local to each tmux server and technically they may not match (although that defeats the purpose of using this software somewhat).
Requirements and limitations
- requirements: tmux with pane geometry formats, Bash, awk, OpenSSH, and Linux
/procfor automatic target discovery. The plugin is tested with tmux 3.4 and 3.6. - The plugin owns tmux's
set-titlesandset-titles-stringoptions because the terminal title is its peer-discovery channel. - The local process must be able to open a separate batch-mode SSH connection
to the same destination. Existing
ssh-agentand~/.ssh/configsettings are honored. Passphrase-protected keys work when already unlocked in the agent; password and passphrase prompts are never opened by a key binding. - The exact server socket and session are addressed for every operation. The plugin intentionally falls back to normal local navigation when it cannot prove that a compatible peer exists. Worst case is that geometry-based navigation stops working.
See also: ARCHITECTURE.md.