Create a gist now

Instantly share code, notes, and snippets.

Embed
tmux-vim integration to transparently switch between tmux panes and vim split windows

I use tmux splits (panes). Inside one of these panes there's a Vim process, and it has its own splits (windows).

In Vim I have key bindings C-h/j/k/l set to switch windows in the given direction. (Vim default mappings for windows switching are the same, but prefixed with C-W.) I'd like to use the same keystrokes for switching tmux panes.

An extra goal that I've solved with a dirty hack is to toggle between last active panes with C-\.

Here's how it should work:

  1. If I'm in "vim window 2", going in left (C-h) or down (C-j) direction should switch windows inside vim.
  2. However, if I'm in "vim window 3", going right (C-l) or down (C-j) should select the next tmux pane in that direction.

The solution

The solution has 3 parts:

  1. In ~/.tmux.conf, I bind the keys I want to execute a custom tmux-vim-select-pane command;
  2. tmux-vim-select-pane checks if the foreground process in the current tmux pane is Vim, then forwards the original keystroke to the vim process. Otherwise it simply switches tmux panes.
  3. In Vim, I set bindings for the same keystrokes to a custom function. The function tries to switch windows in the given direction. If the window didn't change, that means there are no more windows in the given direction inside vim, and it forwards the pane switching command to tmux by shelling out to tmux select-pane.

Installation

  • check tmux -V that you have v1.8

  • get the vim-tmux-navigator plugin

  • additional ~/.tmux.conf config & tmux-vim-select-pane script:

    curl -fsSL https://gist.github.com/mislav/5189704/raw/install.sh | bash -e
curl -fsSL https://gist.github.com/mislav/5189704/raw/tmux.conf \
>> ~/.tmux.conf
curl -fsSL https://raw.github.com/mislav/dotfiles/1500cd2/bin/tmux-vim-select-pane \
-o /usr/local/bin/tmux-vim-select-pane
chmod +x /usr/local/bin/tmux-vim-select-pane
# Smart pane switching with awareness of vim splits
bind -n C-k run-shell 'tmux-vim-select-pane -U'
bind -n C-j run-shell 'tmux-vim-select-pane -D'
bind -n C-h run-shell 'tmux-vim-select-pane -L'
bind -n C-l run-shell 'tmux-vim-select-pane -R'
bind -n "C-\\" run-shell 'tmux-vim-select-pane -l'
# Bring back clear screen under tmux prefix
bind C-l send-keys 'C-l'
@jondkinney

This comment has been minimized.

Show comment
Hide comment
@jondkinney

jondkinney Mar 19, 2013

Using the above on OS X I was getting the following error in tmux:

'tmux-vim-select-pane -L' returned 127

The reason is that I named the 'tmux-vim-select-pane.sh' file with the extension and the tmux bindings are trying to execute it without one.

So if anyone else comes across this and can't figure out where to place the shell script... put it in /usr/loca/bin (provided that is in your path, which it should be if you use homebrew) and name it simply 'tmux-vim-select-pane' without the quotes. Notice the lack of .sh on the file name. It'd prob work in your home directory too, but that's messy.

Using the above on OS X I was getting the following error in tmux:

'tmux-vim-select-pane -L' returned 127

The reason is that I named the 'tmux-vim-select-pane.sh' file with the extension and the tmux bindings are trying to execute it without one.

So if anyone else comes across this and can't figure out where to place the shell script... put it in /usr/loca/bin (provided that is in your path, which it should be if you use homebrew) and name it simply 'tmux-vim-select-pane' without the quotes. Notice the lack of .sh on the file name. It'd prob work in your home directory too, but that's messy.

@tarruda

This comment has been minimized.

Show comment
Hide comment
@tarruda

tarruda Mar 20, 2013

Hello friend, I also had posted a similar gist a few days ago, you should check it out, especially the vim script file which uses the system function to avoid redraws

tarruda commented Mar 20, 2013

Hello friend, I also had posted a similar gist a few days ago, you should check it out, especially the vim script file which uses the system function to avoid redraws

@aaronjensen

This comment has been minimized.

Show comment
Hide comment
@aaronjensen

aaronjensen Mar 22, 2013

wow i thought i was the only one crazy enough to do this. My solution is similar but has vim set the tmux pane title so tmux knows if it's in vim or not. Looks like there's some good stuff for me to learn in these two solutions.

https://github.com/aaronjensen/dotfiles/blob/ebfacc5fba0eca45c592e465e6ed211350a4bce2/tmux.conf#L103-L109
https://github.com/aaronjensen/vimfiles/blob/66b7da914b403c7885db87123068c1f7dc71c0eb/vimrc#L468-L502

wow i thought i was the only one crazy enough to do this. My solution is similar but has vim set the tmux pane title so tmux knows if it's in vim or not. Looks like there's some good stuff for me to learn in these two solutions.

https://github.com/aaronjensen/dotfiles/blob/ebfacc5fba0eca45c592e465e6ed211350a4bce2/tmux.conf#L103-L109
https://github.com/aaronjensen/vimfiles/blob/66b7da914b403c7885db87123068c1f7dc71c0eb/vimrc#L468-L502

@henrik

This comment has been minimized.

Show comment
Hide comment
@henrik

henrik Mar 23, 2013

Very nice! Adapted for arrows instead of hjkl (because I want ctrl+l to clear/redraw my terminal): henrik/dotfiles@24ddbd9

henrik commented Mar 23, 2013

Very nice! Adapted for arrows instead of hjkl (because I want ctrl+l to clear/redraw my terminal): henrik/dotfiles@24ddbd9

@florian

This comment has been minimized.

Show comment
Hide comment
@florian

florian Mar 24, 2013

This is really awesome, thanks for posting!

I had the same problem as @j2fly first, and later got a 126 exit code. Don't forget to sudo chmod +x /usr/bin/tmux-vim-select-pane.

florian commented Mar 24, 2013

This is really awesome, thanks for posting!

I had the same problem as @j2fly first, and later got a 126 exit code. Don't forget to sudo chmod +x /usr/bin/tmux-vim-select-pane.

@has207

This comment has been minimized.

Show comment
Hide comment
@has207

has207 Mar 25, 2013

Nice one.

I recommend updating the ps command to:

ps c -o 'stat=,command=' -t "${active_tty#1}" 2>/dev/null

Replacing "state" with "stat" makes linux ps output bsd-compatible so state flags will include the "+" on linux as well. And redirecting stderr to /dev/null gets rid of any warnings in case you set any DYLD_ env variables on OSX.

has207 commented Mar 25, 2013

Nice one.

I recommend updating the ps command to:

ps c -o 'stat=,command=' -t "${active_tty#1}" 2>/dev/null

Replacing "state" with "stat" makes linux ps output bsd-compatible so state flags will include the "+" on linux as well. And redirecting stderr to /dev/null gets rid of any warnings in case you set any DYLD_ env variables on OSX.

@nathanaelkane

This comment has been minimized.

Show comment
Hide comment
@nathanaelkane

nathanaelkane Apr 4, 2013

Awesome, been wanting exactly this since I started using tmux, thanks!

Awesome, been wanting exactly this since I started using tmux, thanks!

@mislav

This comment has been minimized.

Show comment
Hide comment
@mislav

mislav Apr 7, 2013

@tarruda: Nice, I picked up a trick or two from your solution. Thanks!

Owner

mislav commented Apr 7, 2013

@tarruda: Nice, I picked up a trick or two from your solution. Thanks!

@jfelchner

This comment has been minimized.

Show comment
Hide comment
@jfelchner

jfelchner Apr 9, 2013

@mislav this is exactly what I have been looking for for a while. Thank you for posting it.

@mislav this is exactly what I have been looking for for a while. Thank you for posting it.

@christoomey

This comment has been minimized.

Show comment
Hide comment
@christoomey

christoomey Apr 12, 2013

@mislav, thanks a ton for this. I just set it up and vastly prefer moving around with it.

I did run into two issues while setting it up that I wanted to document here in case anyone else hits them:

  1. The tmux-vim-select-pane uses a format command added to tmux sometime between 1.7 & 1.8. In order to get this running I had to upgrade my tmux to version 1.8. Very straightforward with brew upgrade tmux.
  2. The pattern match used in the tmux-vim-select-pane script was causing an error. I replaced it with: if [ $cmd = "vim" ]; then and all works as expected.

In addition, I extracted the vim plugin into a standalone repo for use with Vundle, Pathogen, etc. I prefer using Vundle for easy install / uninstall and thought I would share in case anyone else wanted to go that route as well. The standalone plugin repo can be found here.

Thanks again!

@mislav, thanks a ton for this. I just set it up and vastly prefer moving around with it.

I did run into two issues while setting it up that I wanted to document here in case anyone else hits them:

  1. The tmux-vim-select-pane uses a format command added to tmux sometime between 1.7 & 1.8. In order to get this running I had to upgrade my tmux to version 1.8. Very straightforward with brew upgrade tmux.
  2. The pattern match used in the tmux-vim-select-pane script was causing an error. I replaced it with: if [ $cmd = "vim" ]; then and all works as expected.

In addition, I extracted the vim plugin into a standalone repo for use with Vundle, Pathogen, etc. I prefer using Vundle for easy install / uninstall and thought I would share in case anyone else wanted to go that route as well. The standalone plugin repo can be found here.

Thanks again!

@unphased

This comment has been minimized.

Show comment
Hide comment
@unphased

unphased May 16, 2013

It occurred to me that this could be extended in much the similar way to support the vim-aware creation of windows/panes using a single set of shortcut keys (e.g. Ctrl+\ and Ctrl+- , cf. Ctrl+W,V and Ctrl+A,\ and Ctrl+W,S and Ctrl+A,- for vim window and tmux pane splitting, vertically and horizontally, respectively^2). So that if you are not in vim the shortcuts will make new panes vertically split or horizontally split, and if you are in vim it will make split vim-windows.

I'm not sure if this could ever be worth the trouble as there is the quite conceivable need to make a tmux pane while inside vim. This could obviously be done then with the regular method but then why not just keep using the regular method for all cases? But, for the sake of collapsing shortcuts or creating more overloaded powerful shortcuts, this can be accomplished with the same method.

It occurred to me that this could be extended in much the similar way to support the vim-aware creation of windows/panes using a single set of shortcut keys (e.g. Ctrl+\ and Ctrl+- , cf. Ctrl+W,V and Ctrl+A,\ and Ctrl+W,S and Ctrl+A,- for vim window and tmux pane splitting, vertically and horizontally, respectively^2). So that if you are not in vim the shortcuts will make new panes vertically split or horizontally split, and if you are in vim it will make split vim-windows.

I'm not sure if this could ever be worth the trouble as there is the quite conceivable need to make a tmux pane while inside vim. This could obviously be done then with the regular method but then why not just keep using the regular method for all cases? But, for the sake of collapsing shortcuts or creating more overloaded powerful shortcuts, this can be accomplished with the same method.

@shime

This comment has been minimized.

Show comment
Hide comment
@shime

shime Jun 4, 2013

This is just awesome! Thanks for your work! 🍻

I have faced some issues, though, so I thought mentioning them might be helpful for someone:

  • this doesn't work with tmux 1.6 - I'm not sure if it works with 1.7 but it definitely works with 1.8 (there's a script that might help you with installation)
  • curl is not downloading in raw format so it saves HTML response - I've fixed URLs to raw versions in my fork

Thanks once more!

shime commented Jun 4, 2013

This is just awesome! Thanks for your work! 🍻

I have faced some issues, though, so I thought mentioning them might be helpful for someone:

  • this doesn't work with tmux 1.6 - I'm not sure if it works with 1.7 but it definitely works with 1.8 (there's a script that might help you with installation)
  • curl is not downloading in raw format so it saves HTML response - I've fixed URLs to raw versions in my fork

Thanks once more!

@fphilipe

This comment has been minimized.

Show comment
Hide comment
@fphilipe

fphilipe Jun 9, 2013

Might be worth noting that the tmux-vim-select-pane script relies on bash 4. I had version 3.2 on OS X.

fphilipe commented Jun 9, 2013

Might be worth noting that the tmux-vim-select-pane script relies on bash 4. I had version 3.2 on OS X.

@chriseskow

This comment has been minimized.

Show comment
Hide comment
@chriseskow

chriseskow Jun 15, 2013

I was able to get this working without needing the tmux-vim-select-pane script by using the tmux's if-shell command:

bind -n C-k if "[ $(tmux display -p '#{pane_current_command}') = vim ]" "send-keys C-k" "select-pane -U"
bind -n C-j if "[ $(tmux display -p '#{pane_current_command}') = vim ]" "send-keys C-j" "select-pane -D"
bind -n C-h if "[ $(tmux display -p '#{pane_current_command}') = vim ]" "send-keys C-h" "select-pane -L"
bind -n C-l if "[ $(tmux display -p '#{pane_current_command}') = vim ]" "send-keys C-l" "select-pane -R"

Just drop that in your .tmux.rc, add the Vim plugin, and you're all set!

Idea came from this mailing list thread: http://comments.gmane.org/gmane.comp.terminal-emulators.tmux.user/4390

I was able to get this working without needing the tmux-vim-select-pane script by using the tmux's if-shell command:

bind -n C-k if "[ $(tmux display -p '#{pane_current_command}') = vim ]" "send-keys C-k" "select-pane -U"
bind -n C-j if "[ $(tmux display -p '#{pane_current_command}') = vim ]" "send-keys C-j" "select-pane -D"
bind -n C-h if "[ $(tmux display -p '#{pane_current_command}') = vim ]" "send-keys C-h" "select-pane -L"
bind -n C-l if "[ $(tmux display -p '#{pane_current_command}') = vim ]" "send-keys C-l" "select-pane -R"

Just drop that in your .tmux.rc, add the Vim plugin, and you're all set!

Idea came from this mailing list thread: http://comments.gmane.org/gmane.comp.terminal-emulators.tmux.user/4390

@derekprior

This comment has been minimized.

Show comment
Hide comment
@derekprior

derekprior Jun 16, 2013

@eskow, good idea. One less dependency. Here it is with the <C-> command included:

# Smart pane switching with awareness of vim splits
bind -n C-h if "[ $(tmux display -p '#{pane_current_command}') = vim ]" "send-keys C-h" "select-pane -L"
bind -n C-j if "[ $(tmux display -p '#{pane_current_command}') = vim ]" "send-keys C-j" "select-pane -D"
bind -n C-k if "[ $(tmux display -p '#{pane_current_command}') = vim ]" "send-keys C-k" "select-pane -U"
bind -n C-l if "[ $(tmux display -p '#{pane_current_command}') = vim ]" "send-keys C-l" "select-pane -R"
bind -n "C-\\" if "[ $(tmux display -p '#{pane_current_command}') = vim ]" "send-keys C-\\" "select-pane -l"

@eskow, good idea. One less dependency. Here it is with the <C-> command included:

# Smart pane switching with awareness of vim splits
bind -n C-h if "[ $(tmux display -p '#{pane_current_command}') = vim ]" "send-keys C-h" "select-pane -L"
bind -n C-j if "[ $(tmux display -p '#{pane_current_command}') = vim ]" "send-keys C-j" "select-pane -D"
bind -n C-k if "[ $(tmux display -p '#{pane_current_command}') = vim ]" "send-keys C-k" "select-pane -U"
bind -n C-l if "[ $(tmux display -p '#{pane_current_command}') = vim ]" "send-keys C-l" "select-pane -R"
bind -n "C-\\" if "[ $(tmux display -p '#{pane_current_command}') = vim ]" "send-keys C-\\" "select-pane -l"
@erlend

This comment has been minimized.

Show comment
Hide comment
@erlend

erlend Jun 19, 2013

Don't know if it's my build of vim or some other part of my configuration, but #{pane_current_command} returns Vim (with capital V). Fixed the issue by using tr, however it's not as elegant as @eskow's original solution.

bind -n C-h if "[ $(tmux display -p '#{pane_current_command}' | tr '[:upper:]' '[:lower:]') = vim ]" "send-keys C-h" "select-pane -L"
bind -n C-j if "[ $(tmux display -p '#{pane_current_command}' | tr '[:upper:]' '[:lower:]') = vim ]" "send-keys C-j" "select-pane -D"
bind -n C-k if "[ $(tmux display -p '#{pane_current_command}' | tr '[:upper:]' '[:lower:]') = vim ]" "send-keys C-k" "select-pane -U"
bind -n C-l if "[ $(tmux display -p '#{pane_current_command}' | tr '[:upper:]' '[:lower:]') = vim ]" "send-keys C-l" "select-pane -R"
bind -n "C-\\" if "[ $(tmux display -p '#{pane_current_command}' | tr '[:upper:]' '[:lower:]') = vim ]" "send-keys C-\\" "select-pane -l"

erlend commented Jun 19, 2013

Don't know if it's my build of vim or some other part of my configuration, but #{pane_current_command} returns Vim (with capital V). Fixed the issue by using tr, however it's not as elegant as @eskow's original solution.

bind -n C-h if "[ $(tmux display -p '#{pane_current_command}' | tr '[:upper:]' '[:lower:]') = vim ]" "send-keys C-h" "select-pane -L"
bind -n C-j if "[ $(tmux display -p '#{pane_current_command}' | tr '[:upper:]' '[:lower:]') = vim ]" "send-keys C-j" "select-pane -D"
bind -n C-k if "[ $(tmux display -p '#{pane_current_command}' | tr '[:upper:]' '[:lower:]') = vim ]" "send-keys C-k" "select-pane -U"
bind -n C-l if "[ $(tmux display -p '#{pane_current_command}' | tr '[:upper:]' '[:lower:]') = vim ]" "send-keys C-l" "select-pane -R"
bind -n "C-\\" if "[ $(tmux display -p '#{pane_current_command}' | tr '[:upper:]' '[:lower:]') = vim ]" "send-keys C-\\" "select-pane -l"
@niko

This comment has been minimized.

Show comment
Hide comment
@niko

niko Jun 20, 2013

@mislav: Nice idea! @eskow: Even better execution! Thanks.

niko commented Jun 20, 2013

@mislav: Nice idea! @eskow: Even better execution! Thanks.

@mislav

This comment has been minimized.

Show comment
Hide comment
@mislav

mislav Jun 22, 2013

Thanks everyone for comments and help! I've updated the instructions to point to @christoomey's plugin. However, I stick by my tmux-vim-select-pane command to avoid the gnarly inline scripts in tmux config (seen in the last few comments). Detecting vim is tricky enough that it deserves its own script.

Owner

mislav commented Jun 22, 2013

Thanks everyone for comments and help! I've updated the instructions to point to @christoomey's plugin. However, I stick by my tmux-vim-select-pane command to avoid the gnarly inline scripts in tmux config (seen in the last few comments). Detecting vim is tricky enough that it deserves its own script.

@debugloop

This comment has been minimized.

Show comment
Hide comment
@debugloop

debugloop Jun 28, 2013

Any ideas on how to get this to work with (remote) tmux sessions inside the first tmux? I tried something along the lines of:

bind -n C-h run "(tmux display-message -p '#{pane_current_command}' | grep -iq vim && tmux send-keys C-h) || tmux select-pane -L"
bind -n C-j run "(tmux display-message -p '#{pane_current_command}' | grep -iq vim && tmux send-keys C-j) || tmux select-pane -D"
bind -n C-k run "(tmux display-message -p '#{pane_current_command}' | grep -iq vim && tmux send-keys C-k) || tmux select-pane -U"
bind -n C-l run "(tmux display-message -p '#{pane_current_command}' | grep -iq vim && tmux send-keys C-l) || tmux select-pane -R"
bind -n C-\ run "(tmux display-message -p '#{pane_current_command}' | grep -iq vim && tmux send-keys 'C-\\') || tmux select-pane -l"
bind -r C-h run "tmux send-keys C-h"
bind -r C-j run "tmux send-keys C-j"
bind -r C-k run "tmux send-keys C-k"
bind -r C-l run "tmux send-keys C-l"
bind -r C-\ run "tmux send-keys 'C-\\'"

but this won't work for some reason. The idea was to get the outer tmuxes to pass through the C-hjkl to the inner instance...

Any ideas on how to get this to work with (remote) tmux sessions inside the first tmux? I tried something along the lines of:

bind -n C-h run "(tmux display-message -p '#{pane_current_command}' | grep -iq vim && tmux send-keys C-h) || tmux select-pane -L"
bind -n C-j run "(tmux display-message -p '#{pane_current_command}' | grep -iq vim && tmux send-keys C-j) || tmux select-pane -D"
bind -n C-k run "(tmux display-message -p '#{pane_current_command}' | grep -iq vim && tmux send-keys C-k) || tmux select-pane -U"
bind -n C-l run "(tmux display-message -p '#{pane_current_command}' | grep -iq vim && tmux send-keys C-l) || tmux select-pane -R"
bind -n C-\ run "(tmux display-message -p '#{pane_current_command}' | grep -iq vim && tmux send-keys 'C-\\') || tmux select-pane -l"
bind -r C-h run "tmux send-keys C-h"
bind -r C-j run "tmux send-keys C-j"
bind -r C-k run "tmux send-keys C-k"
bind -r C-l run "tmux send-keys C-l"
bind -r C-\ run "tmux send-keys 'C-\\'"

but this won't work for some reason. The idea was to get the outer tmuxes to pass through the C-hjkl to the inner instance...

@nathanlippi

This comment has been minimized.

Show comment
Hide comment
@nathanlippi

nathanlippi Jul 3, 2013

Thank you for sharing!

I've modified this to work with emacs if anyone is interested:
https://gist.github.com/nathanlippi/5923326

Thank you for sharing!

I've modified this to work with emacs if anyone is interested:
https://gist.github.com/nathanlippi/5923326

@mislav

This comment has been minimized.

Show comment
Hide comment
@mislav

mislav Jul 26, 2013

:palmface: My script relied on bash 4 (thanks @fphilipe). Fixed it so it works on bash 3.2 (often system default)

Owner

mislav commented Jul 26, 2013

:palmface: My script relied on bash 4 (thanks @fphilipe). Fixed it so it works on bash 3.2 (often system default)

@svenfuchs

This comment has been minimized.

Show comment
Hide comment
@svenfuchs

svenfuchs Aug 3, 2013

Here's a version that doesn't require a vim plugin, and zooms the left/rightmost tmux pane when trying to navigate "over it". I guess it somewhat screws the "toggle between last active panes" behaviour though, not sure.

https://gist.github.com/svenfuchs/6146321

Here's a version that doesn't require a vim plugin, and zooms the left/rightmost tmux pane when trying to navigate "over it". I guess it somewhat screws the "toggle between last active panes" behaviour though, not sure.

https://gist.github.com/svenfuchs/6146321

@fphilipe

This comment has been minimized.

Show comment
Hide comment
@fphilipe

fphilipe Nov 16, 2013

Whenever I switch from vim to a tmux pane, the weird escape sequence ^[[O gets printed at the last cursor position in vim. See this screenshot.

I tracked it down and found out that this happens when I manually do C-a :send-keys C-h. Does anyone know how to prevent this? One possible fix I guess would be to tell vim to redraw when leaving vim.

Whenever I switch from vim to a tmux pane, the weird escape sequence ^[[O gets printed at the last cursor position in vim. See this screenshot.

I tracked it down and found out that this happens when I manually do C-a :send-keys C-h. Does anyone know how to prevent this? One possible fix I guess would be to tell vim to redraw when leaving vim.

@amiel

This comment has been minimized.

Show comment
Hide comment
@amiel

amiel Apr 25, 2014

Thank you @mislav, @svenfuchs, @christoomey, and everyone else that has contributed to this concept. I like

Here's yet another version: amiel/vim-tmux-navigator

Pros:

  1. Includes @svenfuchs' zoom feature
  2. Works in insert mode (or any mode in vim)

Cons:

  1. Depends on ruby
  2. More complicated setup (vim plugin + external script + tmux.conf)
  3. Drops the toggle between last active panes feature

amiel commented Apr 25, 2014

Thank you @mislav, @svenfuchs, @christoomey, and everyone else that has contributed to this concept. I like

Here's yet another version: amiel/vim-tmux-navigator

Pros:

  1. Includes @svenfuchs' zoom feature
  2. Works in insert mode (or any mode in vim)

Cons:

  1. Depends on ruby
  2. More complicated setup (vim plugin + external script + tmux.conf)
  3. Drops the toggle between last active panes feature
@hjdivad

This comment has been minimized.

Show comment
Hide comment
@hjdivad

hjdivad May 22, 2014

Thanks everyone. This is really helpful. I've added a version that lets you stick to vim's default window keybindings (eg C-w n rather than C-n).

https://gist.github.com/hjdivad/d7f79b45ac2922336fec

hjdivad commented May 22, 2014

Thanks everyone. This is really helpful. I've added a version that lets you stick to vim's default window keybindings (eg C-w n rather than C-n).

https://gist.github.com/hjdivad/d7f79b45ac2922336fec

@blueyed

This comment has been minimized.

Show comment
Hide comment
@blueyed

blueyed Jun 19, 2014

JFI: I've just came up with a pull request for the vim-tmux-navigator plugin, which uses tmux environment instead of detecting vim:
the plugin sets a tmux session environment variable when Vim starts, and unsets it when it exits: christoomey/vim-tmux-navigator#37
(this fixes cases where #{pane_current_command} is e.g. make, when vim got started from a make task).

blueyed commented Jun 19, 2014

JFI: I've just came up with a pull request for the vim-tmux-navigator plugin, which uses tmux environment instead of detecting vim:
the plugin sets a tmux session environment variable when Vim starts, and unsets it when it exits: christoomey/vim-tmux-navigator#37
(this fixes cases where #{pane_current_command} is e.g. make, when vim got started from a make task).

@josuah

This comment has been minimized.

Show comment
Hide comment
@josuah

josuah Mar 28, 2016

Thank you yor this marvellous idea, and for the implementation! Thank to it, I now use these snippets:

In .vimrc:

function! TmuxMove(direction)
        let wnr = winnr()
        silent! execute 'wincmd ' . a:direction
        " If the winnr is still the same after we moved, it is the last pane
        if wnr == winnr()
                call system('tmux select-pane -' . tr(a:direction, 'phjkl', 'lLDUR'))
        end
endfunction

nnoremap <silent> <c-h> :call TmuxMove('h')<cr>
nnoremap <silent> <c-j> :call TmuxMove('j')<cr>
nnoremap <silent> <c-k> :call TmuxMove('k')<cr>
nnoremap <silent> <c-l> :call TmuxMove('l')<cr>

In .tmux.conf:

bind -n C-k if "[ $(tmux display -p '#{pane_current_command}') = vim ]" "send-keys C-k" "select-pane -U"
bind -n C-j if "[ $(tmux display -p '#{pane_current_command}') = vim ]" "send-keys C-j" "select-pane -D"
bind -n C-h if "[ $(tmux display -p '#{pane_current_command}') = vim ]" "send-keys C-h" "select-pane -L"
bind -n C-l if "[ $(tmux display -p '#{pane_current_command}') = vim ]" "send-keys C-l" "select-pane -R"

It may only work for vim in tmux, and do not handle any issue anywhere, but that works for me.

Thank you again to all contributors!

josuah commented Mar 28, 2016

Thank you yor this marvellous idea, and for the implementation! Thank to it, I now use these snippets:

In .vimrc:

function! TmuxMove(direction)
        let wnr = winnr()
        silent! execute 'wincmd ' . a:direction
        " If the winnr is still the same after we moved, it is the last pane
        if wnr == winnr()
                call system('tmux select-pane -' . tr(a:direction, 'phjkl', 'lLDUR'))
        end
endfunction

nnoremap <silent> <c-h> :call TmuxMove('h')<cr>
nnoremap <silent> <c-j> :call TmuxMove('j')<cr>
nnoremap <silent> <c-k> :call TmuxMove('k')<cr>
nnoremap <silent> <c-l> :call TmuxMove('l')<cr>

In .tmux.conf:

bind -n C-k if "[ $(tmux display -p '#{pane_current_command}') = vim ]" "send-keys C-k" "select-pane -U"
bind -n C-j if "[ $(tmux display -p '#{pane_current_command}') = vim ]" "send-keys C-j" "select-pane -D"
bind -n C-h if "[ $(tmux display -p '#{pane_current_command}') = vim ]" "send-keys C-h" "select-pane -L"
bind -n C-l if "[ $(tmux display -p '#{pane_current_command}') = vim ]" "send-keys C-l" "select-pane -R"

It may only work for vim in tmux, and do not handle any issue anywhere, but that works for me.

Thank you again to all contributors!

@KabbAmine

This comment has been minimized.

Show comment
Hide comment
@KabbAmine

KabbAmine Apr 11, 2016

Awesome, thanks @sshbio

Awesome, thanks @sshbio

@zhaohuaxishi

This comment has been minimized.

Show comment
Hide comment
@zhaohuaxishi

zhaohuaxishi Apr 25, 2016

Awesome, thanks @sshbio

Awesome, thanks @sshbio

@touilfarouk

This comment has been minimized.

Show comment
Hide comment
@touilfarouk

touilfarouk Jan 13, 2017

Best tmux config for ubuntu and vim ?

Best tmux config for ubuntu and vim ?

@droustchev

This comment has been minimized.

Show comment
Hide comment
@droustchev

droustchev Feb 7, 2018

I came up with a slightly simpler solution than hjdivad, which allows to use vim's default split navigation bindings C-w {h,j,k,l}, here's the gist.
My solution shows how to easily set up key bindings in tmux that require multiple keys, using key-tables.

I came up with a slightly simpler solution than hjdivad, which allows to use vim's default split navigation bindings C-w {h,j,k,l}, here's the gist.
My solution shows how to easily set up key bindings in tmux that require multiple keys, using key-tables.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment