Tmux Integration
Neovim inside tmux is one of the most powerful terminal development setups. This lesson covers seamless navigation between tmux panes and Neovim splits, clipboard sharing, and session persistence.
The goal is to make Ctrl+h/j/k/l move your focus transparently between Neovim windows AND tmux panes — without thinking about whether you're in Neovim or tmux.
vim-tmux-navigator
This plugin makes Ctrl+h/j/k/l work across both Neovim splits and tmux panes seamlessly:
{
"christoomey/vim-tmux-navigator",
cmd = {
"TmuxNavigateLeft", "TmuxNavigateDown",
"TmuxNavigateUp", "TmuxNavigateRight",
"TmuxNavigatePrevious",
},
keys = {
{ "<C-h>", "<cmd>TmuxNavigateLeft<cr>" },
{ "<C-j>", "<cmd>TmuxNavigateDown<cr>" },
{ "<C-k>", "<cmd>TmuxNavigateUp<cr>" },
{ "<C-l>", "<cmd>TmuxNavigateRight<cr>" },
{ "<C-\\>", "<cmd>TmuxNavigatePrevious<cr>" },
},
},
Corresponding tmux config:
# Smart pane switching with awareness of Neovim splits
is_vim="ps -o state= -o comm= -t '#{pane_tty}' \
| grep -iqE '^[^TXZ ]+ +(\\S+\\/)?g?(view|l?n?vim?x?|fzf)(diff)?$'"
bind-key -n 'C-h' if-shell "" 'send-keys C-h' 'select-pane -L'
bind-key -n 'C-j' if-shell "" 'send-keys C-j' 'select-pane -D'
bind-key -n 'C-k' if-shell "" 'send-keys C-k' 'select-pane -U'
bind-key -n 'C-l' if-shell "" 'send-keys C-l' 'select-pane -R'
bind-key -T copy-mode-vi 'C-h' select-pane -L
bind-key -T copy-mode-vi 'C-j' select-pane -D
bind-key -T copy-mode-vi 'C-k' select-pane -U
bind-key -T copy-mode-vi 'C-l' select-pane -R
Clipboard Sharing
By default, Neovim's yank and the tmux clipboard are separate. Bridge them:
-- Use system clipboard (shared with tmux via terminal clipboard)
vim.opt.clipboard = "unnamedplus"
On Linux servers, install xclip or use OSC52 for clipboard over SSH:
sudo apt install -y xclip
For SSH clipboard sharing, add to your Neovim config:
-- OSC52 clipboard (works over SSH without X11)
vim.g.clipboard = {
name = "OSC 52",
copy = {
["+"] = require("vim.ui.clipboard.osc52").copy("+"),
["*"] = require("vim.ui.clipboard.osc52").copy("*"),
},
paste = {
["+"] = require("vim.ui.clipboard.osc52").paste("+"),
["*"] = require("vim.ui.clipboard.osc52").paste("*"),
},
}
OSC52 requires your terminal emulator to support it (iTerm2, Kitty, WezTerm, etc.).
Recommended Tmux Session Layout with Neovim
#!/bin/bash
SESSION="dev"
PROJECT="/srv/myproject"
tmux has-session -t "$SESSION" 2>/dev/null && tmux attach -t "$SESSION" && exit
tmux new -s "$SESSION" -n "editor" -d
tmux send-keys -t "$SESSION:editor" "cd $PROJECT && nvim ." Enter
tmux new-window -t "$SESSION" -n "shell"
tmux send-keys -t "$SESSION:shell" "cd $PROJECT" Enter
tmux new-window -t "$SESSION" -n "logs"
tmux send-keys -t "$SESSION:logs" "tail -f /var/log/myapp.log" Enter
tmux select-window -t "$SESSION:editor"
tmux attach -t "$SESSION"
Color and True Color in Tmux + Neovim
# Enable true color
set -g default-terminal "tmux-256color"
set -ga terminal-overrides ",*256col*:Tc"
vim.opt.termguicolors = true
Without Tc override in tmux, colors will look washed out in Neovim. This is one of the most common tmux + Neovim setup issues.
In LazyVim
LazyVim does not include im-tmux-navigator by default to avoid interfering with default window mappings for non-tmux users. However, it can be added trivially by enabling the mux extra. Furthermore, LazyVim configures clipboard support and true color settings out of the box.
| Aspect | Vanilla Neovim | LazyVim |
|---|---|---|
| Tmux Navigation | Manual im-tmux-navigator setup | Enable via :LazyExtras (search for mux) |
| Clipboard | Needs unnamedplus & OSC52 setup | Handled automatically in options.lua |
| True Colors | Requires ermguicolors | Enabled by default in LazyVim |
Adding Tmux Navigation to LazyVim
If you do not want to use :LazyExtras, you can manually add the plugin to LazyVim. Create a new file in your plugins directory:
return {
"christoomey/vim-tmux-navigator",
cmd = {
"TmuxNavigateLeft",
"TmuxNavigateDown",
"TmuxNavigateUp",
"TmuxNavigateRight",
"TmuxNavigatePrevious",
},
keys = {
{ "<c-h>", "<cmd><C-U>TmuxNavigateLeft<cr>" },
{ "<c-j>", "<cmd><C-U>TmuxNavigateDown<cr>" },
{ "<c-k>", "<cmd><C-U>TmuxNavigateUp<cr>" },
{ "<c-l>", "<cmd><C-U>TmuxNavigateRight<cr>" },
{ "<c-\\>", "<cmd><C-U>TmuxNavigatePrevious<cr>" },
},
}
LazyVim will merge this file and automatically override the default Neovim window navigation mappings so that your pane switching works flawlessly.