Seamless hjkl navigation between Neovim splits and tmux panes. No
wrap-around: stops at the edge instead of jumping across the screen.
Zoom-agnostic adjacency check (parses saved #{window_layout}) — no
unzoom/rezoom flicker. Routes around floating windows (e.g. snacks
lazygit popup) straight to tmux.
Lazy.nvim:
{
dir = "/path/to/tmux.nvim",
keys = {
{ "<C-h>", function() require("tmux").move_left() end, mode = { "n", "t" } },
{ "<C-j>", function() require("tmux").move_down() end, mode = { "n", "t" } },
{ "<C-k>", function() require("tmux").move_up() end, mode = { "n", "t" } },
{ "<C-l>", function() require("tmux").move_right() end, mode = { "n", "t" } },
},
}Bind the same keys in ~/.tmux.conf so they work from non-vim panes:
bind -n C-h if -F '#{@pane-in-direction-L}' 'selectp -L'
bind -n C-j if -F '#{@pane-in-direction-D}' 'selectp -D'
bind -n C-k if -F '#{@pane-in-direction-U}' 'selectp -U'
bind -n C-l if -F '#{@pane-in-direction-R}' 'selectp -R'Or call scripts/pane-in-direction.sh L|D|U|R directly to gate the
selectp so no wrap-around happens at the edge.
local t = require("tmux")
t.move_left()
t.move_down()
t.move_up()
t.move_right()