christoomey / vim-tmux-navigator

Seamless navigation between tmux panes and vim splits
MIT License
5.35k stars 332 forks source link

Custom mappings fail with Tmux, Neovim, Nixos #140

Open Meyermagic opened 8 years ago

Meyermagic commented 8 years ago

I doubt this is actually issue with your plugin, but I'd appreciate any help debugging the issue.

My window navigation bindings work in vim alone, and tmux alone (and behave identically), but vim nested inside tmux does not respond at all. Calling the TmuxNavigate* commands directly works as expected.

tmux 2.2 Neovim 0.1.4, packaged via https://github.com/NixOS/nixpkgs/blob/master/pkgs/applications/editors/neovim/default.nix

~/.tmux.conf

# Smart pane switching with awareness of Vim splits.
# See: https://github.com/christoomey/vim-tmux-navigator
is_vim="ps -o state= -o comm= -t '#{pane_tty}' | grep -iqE '^[^TXZ ]+ +(\\S+\\/)?g?(view|(\.?n?vim?x?(-wrapped)?))(diff)?$'"

# Ctrl-arrow navigation
bind-key -n C-Left if-shell "$is_vim" "send-keys C-Left"  "select-pane -L"
bind-key -n C-Down if-shell "$is_vim" "send-keys C-Down"  "select-pane -D"
bind-key -n C-Up if-shell "$is_vim" "send-keys C-Up"  "select-pane -U"
bind-key -n C-Right if-shell "$is_vim" "send-keys C-Right"  "select-pane -R"

# Ctrl-shift-arrow resizing
bind-key -n C-S-Left if-shell "$is_vim" "send-keys C-S-Left"  "resize-pane -L"
bind-key -n C-S-Down if-shell "$is_vim" "send-keys C-S-Down"  "resize-pane -D"
bind-key -n C-S-Up if-shell "$is_vim" "send-keys C-S-Up"  "resize-pane -U"
bind-key -n C-S-Right if-shell "$is_vim" "send-keys C-S-Right"  "resize-pane -R"

# Alt-arrow splitting (create in direction of arrow)
bind-key -n M-Down if-shell "$is_vim" "send-keys M-Down"  "split-window -v"
bind-key -n M-Up if-shell "$is_vim" "send-keys M-Up"  "split-window -v; select-pane -U"
bind-key -n M-Left if-shell "$is_vim" "send-keys M-Left"  "split-window -h; select-pane -L"
bind-key -n M-Right if-shell "$is_vim" "send-keys M-Right"  "split-window -h"

Note that I've already adjusted the grep pattern to correctly match the process, ".nvim-wrapped".

~/.config/nvim/init.vim

"dein Scripts-----------------------------
if &compatible
  set nocompatible               " Be iMproved
endif

" Required:
set runtimepath^=/home/meyer/.config/nvim/repos/github.com/Shougo/dein.vim,/nix/store/kvzs4b08221l8sqhian7djwbvmwiq0xs-neovim-0.1.4/share/nvim/runtime

" Required:
call dein#begin(expand('/home/meyer/.config/nvim'))

" Let dein manage dein
" Required:
call dein#add('Shougo/dein.vim')

" Add or remove your plugins here:
call dein#add('christoomey/vim-tmux-navigator')

" Required:
call dein#end()

" Required:
filetype plugin indent on

" If you want to install not installed plugins on startup.
if dein#check_install()
  call dein#install()
endif
"End dein Scripts-------------------------

"Configuration ---------------------------

" Split navigation
nnoremap <C-Down> <C-W><C-J>
nnoremap <C-Up> <C-W><C-K>
nnoremap <C-Right> <C-W><C-L>
nnoremap <C-Left> <C-W><C-H>

" Resizing
nnoremap <C-S-Up> <C-W>+
nnoremap <C-S-Down> <C-W>-
nnoremap <C-S-Left> <C-W><
nnoremap <C-S-Right> <C-W>>

" Easier splitting
nnoremap <M-Up> :aboveleft split<CR>
nnoremap <M-Down> :belowright split<CR>
nnoremap <M-Left> :leftabove vsplit<CR>
nnoremap <M-Right> :rightbelow vsplit<CR>

" Tmux integration
let g:tmux_navigator_no_mappings = 1
nnoremap <silent> <C-Left> :TmuxNavigateLeft<CR>
nnoremap <silent> <C-Down> :TmuxNavigateDown<CR>
nnoremap <silent> <C-Up> :TmuxNavigateUp<CR>
nnoremap <silent> <C-Right> :TmuxNavigateRight<CR>
christoomey commented 8 years ago

Hey @Meyermagic, based on your statement:

My window navigation bindings work in vim alone, and tmux alone (and behave identically), but vim nested inside tmux does not respond at all. Calling the TmuxNavigate* commands directly works as expected

This leads me to believe that something in the mapping from tmux->vim->tmux is broken. First thing that stands out to me is that it looks like you have duplicate / competing Vim mappings for and the rest. First in the " Split navigation section with <C-w><C-J> and the like, then at the bottom in the " Tmux integration section.

If you're able to find an issue with the core plugin functionality (including using alt mappings as we intend to support that) then I'm happy to investigate and fix, but otherwise I will likely close this issue as we have limited time to support additional use cases.

wilriker commented 7 years ago

My window navigation bindings work in vim alone, and tmux alone (and behave identically), but vim nested inside tmux does not respond at all. Calling the TmuxNavigate* commands directly works as expected

I have exactly the same issue and definitely no competing mappings using tmux 2.3 nvim 0.1.7

is_vim="ps -o state= -o comm= -t '#{pane_tty}' | grep -iqE '^[^TXZ ]+ +(\\S+\\/)?g?(view|n?vim?x?)(diff)?$'"
bind-key -n S-Up      if-shell "$is_vim" "send-keys S-Up"    "display-panes ; select-pane -U"
bind-key -n S-Down    if-shell "$is_vim" "send-keys S-Down"  "display-panes ; select-pane -D"
bind-key -n S-Left    if-shell "$is_vim" "send-keys S-Left"  "display-panes ; select-pane -L"
bind-key -n S-Right   if-shell "$is_vim" "send-keys S-Right" "display-panes ; select-pane -R"
let g:tmux_navigator_no_mappings = 1
nnoremap <S-Up>    :TmuxNavigateUp<CR>
nnoremap <S-Down>  :TmuxNavigateDown<CR>
nnoremap <S-Left>  :TmuxNavigateLeft<CR>
nnoremap <S-Right> :TmuxNavigateRight<CR>

It works flawlessly with the default key mappings (that are partially used for other things, so I cannot use them) but when I change it to Shift+<Arrow> it only works tmux -> (tmux|nvim) or inside nvim if it is not running inside tmux. As soon as the focus is inside nvim the key combinations have no effect anymore at all.

I would be happy to provide any more details.

Best regards Manuel

wilriker commented 7 years ago

I found a workaround (based on #59) but I consider this a rather dirty solution:

is_vim="ps -o state= -o comm= -t '#{pane_tty}' | grep -iqE '^[^TXZ ]+ +(\\S+\\/)?g?(view|n?vim?x?)(diff)?$'"
bind-key -n S-Up      if-shell "$is_vim" "send-keys C-w 'k'" "display-panes ; select-pane -U"
bind-key -n S-Down    if-shell "$is_vim" "send-keys C-w 'j'" "display-panes ; select-pane -D"
bind-key -n S-Left    if-shell "$is_vim" "send-keys C-w 'h'" "display-panes ; select-pane -L"
bind-key -n S-Right   if-shell "$is_vim" "send-keys C-w 'l'" "display-panes ; select-pane -R"
let g:tmux_navigator_no_mappings = 1
" The following mappings work when nvim is NOT inside tmux
nnoremap <S-Up>    :TmuxNavigateUp<CR>
nnoremap <S-Down>  :TmuxNavigateDown<CR>
nnoremap <S-Left>  :TmuxNavigateLeft<CR>
nnoremap <S-Right> :TmuxNavigateRight<CR>
" These mappings are used when nvim IS inside tmux
nnoremap <C-W>k    :TmuxNavigateUp<CR>
nnoremap <C-W>j    :TmuxNavigateDown<CR>
nnoremap <C-W>h    :TmuxNavigateLeft<CR>
nnoremap <C-W>l    :TmuxNavigateRight<CR>

So the tmux commands send <C-W>(h|j|k|l) to nvim where I have a secondary set of key mappings to remap these to TmuxNavigate*. Also I have to maintain the Shift-based keymappings in case I am not inside tmux.

krid78 commented 7 years ago

Well, I face the exact same issue using