Skip to content

Instantly share code, notes, and snippets.

@droustchev
Last active April 8, 2021 21:55
Show Gist options
  • Save droustchev/9c54e492b2bcf5238e7a556bd14e892a to your computer and use it in GitHub Desktop.
Save droustchev/9c54e492b2bcf5238e7a556bd14e892a to your computer and use it in GitHub Desktop.
tmux vim navigation

I recently tried out the fantastic vim-tmux-navigator tmux plugin. Unfortunately, some the default key bindings conflict with some of the key bindings my fuzzy finder of choice uses. I wanted to remap them to the default vim split navigation commands that are prefixed with C-w, and found the solution of hjdivad in his gist. However, I wanted a simpler solution, so after some more digging I stumbled upon this reddit post and ultimately came up with the following solution, which doesn't rely on key bindings that unbind themselves, but uses tmux's 'key-tables'.

In vim, I still use the vim-tmux-navigator plugin, but I overrode the default mappings and configured my own as seen in the vimrc below.

In tmux, instead of using vim-tmux-navigator, I also defined my own key bindings as seen in the tmux.conf below. I re-used the check to find out if we're in vim from the plugin. The crux is the first bind-key, where we map C-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 via send-keys, if not, we execute the appropriate tmux's select-pane command.

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.

Bonus: Add the following to your tmux status line to display the active key-table unless it's the default root:

#{?#{==:#{client_key_table},root},'',#{client_key_table}}
is_vim="ps -o state= -o comm= -t '#{pane_tty}' | grep -iqE '^[^TXZ ]+ +(\\S+\\/)?g?(view|n?vim?x?)(diff)?$'"
bind-key -n C-w switch-client -Tswitch-pane
bind-key -Tswitch-pane h if-shell "$is_vim" "send-keys C-w h" "select-pane -L"
bind-key -Tswitch-pane j if-shell "$is_vim" "send-keys C-w j" "select-pane -D"
bind-key -Tswitch-pane k if-shell "$is_vim" "send-keys C-w k" "select-pane -U"
bind-key -Tswitch-pane l if-shell "$is_vim" "send-keys C-w l" "select-pane -R"
Plug 'christoomey/vim-tmux-navigator'
let g:tmux_navigator_no_mappings=1
nnoremap <silent> <C-w>h :TmuxNavigateLeft<cr>
nnoremap <silent> <C-w>j :TmuxNavigateDown<cr>
nnoremap <silent> <C-w>k :TmuxNavigateUp<cr>
nnoremap <silent> <C-w>l :TmuxNavigateRight<cr>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment