1

I'm trying to get my tmux and neovim to work together as seamlessly as possible. There's kinda one issue I'm having with it though. Whenever I'm in a neovim pane within tmux, and I want to split neovim into horizontal/vertical windows with the default desired bind...

C-w v for vertical

C-w n or C-w s for horizontal.

It just plain hits or misses. Its not very responsive... EDIT: Now noticing that it is responsive, but I have to press C-w twice before I hit s for it to only activate in neovim. Why? I don't want that behavior

Whenever I do that with the C-w s for instance and only hit C-w once then s , it triggers the tmux command to switch between any available sessions. I only want it to do that when I'm in a tmux pane. When in neovim I want it to split. My tmux prefix is C-w and I want to keep as such, but how can I get tmux to ignore commands when I'm in my neovim pane. I don't want to change anymore default binds.

**UPDATE 4/4 /2020: **

# eliminates delay when switching out of mode in vim/nvim
set -sg escape-time 0

# remap prefix from 'C-b' to 'C-a'
unbind C-b
set-option -g prefix C-w
bind C-w send-prefix

# Easy config reload
bind R source-file ~/.tmux.conf \; display-message "tmux.conf reloaded."

unbind '"'
unbind %

# vim-tmux-navigator
is_vim="ps -o state= -o comm= -t '#{pane_tty}' \
    | grep -iqE '^[^TXZ ]+ +(\\S+\\/)?g?(view|n?vim?x?)(diff)?$'"

bind 'v' if-shell "$is_vim" 'send-keys C-w v'  'split-window -h'
bind 's' if-shell "$is_vim" 'send-keys C-w n'  'split-window -v'
bind 'n' if-shell "$is_vim" 'send-keys C-w n' 'split-window -v'

bind 'h' if-shell "$is_vim" 'send-keys C-w h'  'select-pane -L'
bind 'j' if-shell "$is_vim" 'send-keys C-w j'  'select-pane -D'
bind 'k' if-shell "$is_vim" 'send-keys C-w k'  'select-pane -U'
bind 'l' if-shell "$is_vim" 'send-keys C-w l'  'select-pane -R'
bind '\' if-shell "$is_vim" 'send-keys C-w \'  'select-pane -l'

bind 'S-h' if-shell "$is_vim" 'send-keys C-w S-h'
bind 'S-j' if-shell "$is_vim" 'send-keys C-w S-j'
bind 'S-k' if-shell "$is_vim" 'send-keys C-w S-k'
bind 'S-l' if-shell "$is_vim" 'send-keys C-w S-l'

Decided to go back with the vim-tmux-navigator plugin, but I'm having one last issue...I'm not quite sure how can I script neovim's window shifting bind. The bind goes C-w then Shift-<direction>. The last 4 commands in my .tmux.conf is my attempt at it, but its not working

2 Answers 2

3

It isn't clear if you have already tried to configure tmux to do this and it isn't working or if you are asking how to do it.

Anyway, usually this is done by changing the required key bindings to only execute on some condition, for example you might check for neovim:

bind v if -F '#{!=:#{pane_current_command},neovim}' 'splitw -v' 'send v'

Or for choose-tree:

bind s if -F '#{!=:#{pane_current_command},neovim}' 'choose-tree -Zs' 'send s'

You can use a different condition if you would prefer to check something different than pane_current_command see https://github.com/tmux/tmux/wiki/Formats and the FORMATS section in the man page.

You will need to do this for every key binding you want to be passed to neovim when it is running in the active pane.

You could do it in for them all in one go by using key tables which would be shorter but is more fiddly to configure.

9
  • I update my question and made some edits I changed it to this bind v if -F '#{!=:#{pane_current_command},nvim}' 'splitw -v' 'send' Since nvim is the command to run neovim in the terminal. Using neovim in the .conf still splits tmux even when I am in the neovim pane. When I change that line to nvim however, it doesn't trigger tmux...But it also doesn't trigger the window splitting I want. Idk what I'm doing wrong, I reloaded my .conf
    – PrimRock
    Apr 2, 2020 at 22:32
  • Run neovim in one pane then do tmux lsp -F'#{pane_current_command}' in another pane - whatever this shows for the neovim pane is what you want to have in the comparison. My example is slightly wrong - you should send the key you want to send to neovim, so it should be send v or send s not just send. I'll edit it. Apr 3, 2020 at 5:21
  • The tmux lsp -F'#{pane_current_command}' in a tmux pane returns tmux. How can I do that in a neovim pane ? I tried using the :! but that doesn't seem to work. I get E499: Empty file for '%' or '#', only works with "p:h"
    – PrimRock
    Apr 3, 2020 at 21:58
  • No, run neovim in one pane and run the tmux lsp ... in a different pane in the same window, then it will show a line for each pane - one with tmux and one with nvim or neovim or whatever. Apr 4, 2020 at 7:48
  • I get tmux and nvim as the output, but the commands u posted don't work at all...Even when I change neovim to nvim. It ignores tmux pane splitting which is what I want, but it doesn't split the windows in neovim for whatever reason.
    – PrimRock
    Apr 4, 2020 at 9:41
0

vim/neovim by default uses the prefix C-w for window movement and rotation, and I changed my prefix for tmux to C-w as well. With that in mind in order for me to get tmux to recognize I'm in a neovim pane, I would have to hit C-w twice to just ignore tmux and execute my commands in vim/neovim.

However, this is way too much overhead for my liking...

With the help of vim-tmux-navigator with some slight changes I was able to use the default C-w for window movement. The plugin allows you to move from your vim/neovim windows(panes) to tmux panes seamlessly. The plugin by default maps pane movement without the need of C-w with C-<hjkl>. I'm so use to hitting C-w I changed it back to the default... In my .vimrc or init.vim if you're using neovim, I added this for the plugin...

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>
nnoremap <silent> <c-w>\ :TmuxNavigatePrevious<cr>

In my .tmux.conf I added this

unbind C-b
set-option -g prefix C-w
bind C-w send-prefix

# vim-tmux-navigator
is_vim="ps -o state= -o comm= -t '#{pane_tty}' \
    | grep -iqE '^[^TXZ ]+ +(\\S+\\/)?g?(view|n?vim?x?)(diff)?$'"

bind 'h' if-shell "$is_vim" 'send-keys C-w h'  'select-pane -L'
bind 'j' if-shell "$is_vim" 'send-keys C-w j'  'select-pane -D'
bind 'k' if-shell "$is_vim" 'send-keys C-w k'  'select-pane -U'
bind 'l' if-shell "$is_vim" 'send-keys C-w l'  'select-pane -R'
bind '\' if-shell "$is_vim" 'send-keys C-w \'  'select-pane -l'

To check if you're in a vim/neovim pane to split, else split in tmux. I did this...

bind 'v' if-shell "$is_vim" 'send-keys C-w v'  'split-window -h'
bind 's' if-shell "$is_vim" 'send-keys C-w n'  'split-window -v'
bind 'n' if-shell "$is_vim" 'send-keys C-w n' 'split-window -v'

For shifting panes with the shift key I made the mistake of thinking I should use S-<hjkl>, when in reality all S is doing is capitalizing a letter. With that in mind instead of doing for ex, C-w S-h I did this...

bind 'H' if-shell "$is_vim" 'send-keys C-w H'
bind 'J' if-shell "$is_vim" 'send-keys C-w J' 
bind 'K' if-shell "$is_vim" 'send-keys C-w K' 
bind 'L' if-shell "$is_vim" 'send-keys C-w L' 

If you're wondering why I omitted the C-w in the scripts, its because by default the prefix is needed anyways unless I use bind -n

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .