I like the idea of unifying navigation between tmux panes and vim
windows. @mislav did a great job in this gist but it depends on
using C-{h,j,k,l}
for navigation instead of vim's default C-W {h,j,k,l}
.
Tmux's bind-key
doesn't support multiple keys: just a single key with a
modifier, so if we want to keep using C-w
we have to be a bit tricky.
This approach binds C-w
to set up keybindings that a) navigate and b) unset
themselves. It turns out you can't have a bind-key
statement in your
.tmux.conf
that's too long or tmux
will segfault, which is one of the
reasons a lot of the work is done in bash scripts.
Install vim-tmux-navigator
Here's what you'd put in .tmux.conf
bind -n C-W \
bind -n h run "tmux-vim-select-pane -L; tmux-unbind" \; \
bind -n c-h run "tmux-vim-select-pane -L; tmux-unbind" \; \
bind -n j run "tmux-vim-select-pane -D; tmux-unbind" \; \
bind -n c-j run "tmux-vim-select-pane -D; tmux-unbind" \; \
bind -n k run "tmux-vim-select-pane -U; tmux-unbind" \; \
bind -n c-k run "tmux-vim-select-pane -U; tmux-unbind" \; \
bind -n l run "tmux-vim-select-pane -R; tmux-unbind" \; \
bind -n c-l run "tmux-vim-select-pane -R; tmux-unbind" \; \
bind -n v send-keys c-w v\\; run "tmux-unbind" \; \
bind -n c-v send-keys c-w v\\; run "tmux-unbind" \; \
bind -n o send-keys c-w o\\; run "tmux-unbind" \; \
bind -n c-o send-keys c-w o\\; run "tmux-unbind" \; \
bind -n c send-keys c-w c\\; run "tmux-unbind" \; \
bind -n c-c send-keys c-w c\\; run "tmux-unbind" \; \
bind -n r send-keys c-w r\\; run "tmux-unbind" \; \
bind -n c-r send-keys c-w r\\; run "tmux-unbind" \; \
bind -n n send-keys c-w n\\; run "tmux-unbind" \; \
bind -n c-n send-keys c-w n\\; run "tmux-unbind" \; \
tmux-vim-select-pane
is exactly the same as the one @mislav uses, and
tmux-unbind
is pretty straightforward:
#!/usr/bin/env bash
tmux unbind -n h
tmux unbind -n c-h
tmux unbind -n j
tmux unbind -n c-j
tmux unbind -n k
tmux unbind -n c-k
tmux unbind -n l
tmux unbind -n c-l
tmux unbind -n v
tmux unbind -n c-v
tmux unbind -n o
tmux unbind -n c-o
tmux unbind -n c
tmux unbind -n c-c
tmux unbind -n r
tmux unbind -n c-r
tmux unbind -n n
tmux unbind -n c-n
Note that we want to passthrough some C-w
combinations, like C-w n
(for new
window in vim).
I've included a simple Rakefile
and templates that you can use to generate
.tmux.conf
and tmux-unbind
.
One final note is that this doesn't work in tmate, although I'm not sure why yet.
While trying to achieve something similar, I stumbled upon this gist. Thank you for putting it up here, however I thought there has to be a better way and after some more digging I came up with my solution, which I wanted to share here:
Instead of relying on key bindings that unbind themselves, my solution uses tmux's
key-tables
. I wasn't able to confirm this 100%, but my solution should work with tmux v1.6+. It works for sure in tmux v2.5, which is the version I'm currently running. It was inspired by this reddit post.In vim, we'll use the excellent
vim-tmux-navigator
plugin, but we'll override the default mappings and configure our own:In tmux, we won't use
vim-tmux-navigator
, but instead we'll define our own key bindings as follows:I re-used the check to find out if we're in vim from the
vim-tmux-navigator
plugin. The crux is the firstbind-key
, where we mapC-w
to switch the client key-table to switch-pane. This is an arbitrarily chosen name. Below that, we define new key bindings in that key-table, by adding the-T
flag followed by the name of the key-table, here switch-pane. The rest is similar to how the plugin does it:we check if we're in vim, if yes, we send the mapping we defined in the
.vimrc
viasend-keys
, if not, we execute the appropriate tmux'sselect-pane
command.Bonus:
Add the following to your tmux status line to display the active key-table unless it's the default
root
: