Giter VIP home page Giter VIP logo

vim-tmux-navigator's Introduction

Vim Tmux Navigator

This plugin is a repackaging of Mislav Marohnić's tmux-navigator configuration described in this gist. When combined with a set of tmux key bindings, the plugin will allow you to navigate seamlessly between vim and tmux splits using a consistent set of hotkeys.

NOTE: This requires tmux v1.8 or higher.

Usage

This plugin provides the following mappings which allow you to move between Vim panes and tmux splits seamlessly.

  • <ctrl-h> => Left
  • <ctrl-j> => Down
  • <ctrl-k> => Up
  • <ctrl-l> => Right
  • <ctrl-\> => Previous split

Note - you don't need to use your tmux prefix key sequence before using the mappings.

If you want to use alternate key mappings, see the configuration section below.

Installation

Vim

If you don't have a preferred installation method, I recommend using Vundle. Assuming you have Vundle installed and configured, the following steps will install the plugin:

Add the following line to your ~/.vimrc file

Plugin 'christoomey/vim-tmux-navigator'

Then run

:PluginInstall

If you are using Vim 8+, you don't need any plugin manager. Simply clone this repository inside ~/.vim/pack/plugin/start/ directory and restart Vim.

git clone [email protected]:christoomey/vim-tmux-navigator.git ~/.vim/pack/plugins/start/vim-tmux-navigator

lazy.nvim

If you are using lazy.nvim. Add the following plugin to your configuration.

{
  "christoomey/vim-tmux-navigator",
  cmd = {
    "TmuxNavigateLeft",
    "TmuxNavigateDown",
    "TmuxNavigateUp",
    "TmuxNavigateRight",
    "TmuxNavigatePrevious",
  },
  keys = {
    { "<c-h>", "<cmd><C-U>TmuxNavigateLeft<cr>" },
    { "<c-j>", "<cmd><C-U>TmuxNavigateDown<cr>" },
    { "<c-k>", "<cmd><C-U>TmuxNavigateUp<cr>" },
    { "<c-l>", "<cmd><C-U>TmuxNavigateRight<cr>" },
    { "<c-\\>", "<cmd><C-U>TmuxNavigatePrevious<cr>" },
  },
}

Then, restart Neovim and lazy.nvim will automatically install the plugin and configure the keybindings.

tmux

To configure the tmux side of this customization there are two options:

Add a snippet

Add the following to your ~/.tmux.conf file:

# 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|l?n?vim?x?|fzf)(diff)?$'"
bind-key -n 'C-h' if-shell "$is_vim" 'send-keys C-h'  'select-pane -L'
bind-key -n 'C-j' if-shell "$is_vim" 'send-keys C-j'  'select-pane -D'
bind-key -n 'C-k' if-shell "$is_vim" 'send-keys C-k'  'select-pane -U'
bind-key -n 'C-l' if-shell "$is_vim" 'send-keys C-l'  'select-pane -R'
tmux_version='$(tmux -V | sed -En "s/^tmux ([0-9]+(.[0-9]+)?).*/\1/p")'
if-shell -b '[ "$(echo "$tmux_version < 3.0" | bc)" = 1 ]' \
    "bind-key -n 'C-\\' if-shell \"$is_vim\" 'send-keys C-\\'  'select-pane -l'"
if-shell -b '[ "$(echo "$tmux_version >= 3.0" | bc)" = 1 ]' \
    "bind-key -n 'C-\\' if-shell \"$is_vim\" 'send-keys C-\\\\'  'select-pane -l'"

bind-key -T copy-mode-vi 'C-h' select-pane -L
bind-key -T copy-mode-vi 'C-j' select-pane -D
bind-key -T copy-mode-vi 'C-k' select-pane -U
bind-key -T copy-mode-vi 'C-l' select-pane -R
bind-key -T copy-mode-vi 'C-\' select-pane -l

TPM

If you'd prefer, you can use the Tmux Plugin Manager (TPM) instead of copying the snippet. When using TPM, add the following lines to your ~/.tmux.conf:

set -g @plugin 'christoomey/vim-tmux-navigator'
run '~/.tmux/plugins/tpm/tpm'

Thanks to Christopher Sexton who provided the updated tmux configuration in this blog post.

Configuration

Custom Key Bindings

If you don't want the plugin to create any mappings, you can use the five provided functions to define your own custom maps. You will need to define custom mappings in your ~/.vimrc as well as update the bindings in tmux to match.

Vim

Add the following to your ~/.vimrc to define your custom maps:

let g:tmux_navigator_no_mappings = 1

nnoremap <silent> {Left-Mapping} :<C-U>TmuxNavigateLeft<cr>
nnoremap <silent> {Down-Mapping} :<C-U>TmuxNavigateDown<cr>
nnoremap <silent> {Up-Mapping} :<C-U>TmuxNavigateUp<cr>
nnoremap <silent> {Right-Mapping} :<C-U>TmuxNavigateRight<cr>
nnoremap <silent> {Previous-Mapping} :<C-U>TmuxNavigatePrevious<cr>

Note Each instance of {Left-Mapping} or {Down-Mapping} must be replaced in the above code with the desired mapping. Ie, the mapping for <ctrl-h> => Left would be created with nnoremap <silent> <c-h> :<C-U>TmuxNavigateLeft<cr>.

Autosave on leave

You can configure the plugin to write the current buffer, or all buffers, when navigating from Vim to tmux. This functionality is exposed via the g:tmux_navigator_save_on_switch variable, which can have either of the following values:

Value Behavior
1 :update (write the current buffer, but only if changed)
2 :wall (write all buffers)

To enable this, add the following (with the desired value) to your ~/.vimrc:

" Write all buffers before navigating from Vim to tmux pane
let g:tmux_navigator_save_on_switch = 2
Disable While Zoomed

By default, if you zoom the tmux pane running Vim and then attempt to navigate "past" the edge of the Vim session, tmux will unzoom the pane. This is the default tmux behavior, but may be confusing if you've become accustomed to navigation "wrapping" around the sides due to this plugin.

We provide an option, g:tmux_navigator_disable_when_zoomed, which can be used to disable this unzooming behavior, keeping all navigation within Vim until the tmux pane is explicitly unzoomed.

To disable navigation when zoomed, add the following to your ~/.vimrc:

" Disable tmux navigator when zooming the Vim pane
let g:tmux_navigator_disable_when_zoomed = 1
Preserve Zoom

As noted above, navigating from a Vim pane to another tmux pane normally causes the window to be unzoomed. Some users may prefer the behavior of tmux's -Z option to select-pane, which keeps the window zoomed if it was zoomed. To enable this behavior, set the g:tmux_navigator_preserve_zoom option to 1:

" If the tmux window is zoomed, keep it zoomed when moving from Vim to another pane
let g:tmux_navigator_preserve_zoom = 1

Naturally, if g:tmux_navigator_disable_when_zoomed is enabled, this option will have no effect.

Tmux

Alter each of the five lines of the tmux configuration listed above to use your custom mappings. Note each line contains two references to the desired mapping.

Additional Customization

Ignoring programs that use Ctrl+hjkl movement

In interactive programs such as FZF, Ctrl+hjkl can be used instead of the arrow keys to move the selection up and down. If vim-tmux-navigator is getting in your way trying to change the active window instead, you can make it be ignored and work as if this plugin were not enabled. Just modify the is_vim variable(that you have either on the snipped you pasted on ~/.tmux.conf or on the vim-tmux-navigator.tmux file). For example, to add the program foobar:

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

Restoring Clear Screen (C-l)

The default key bindings include <Ctrl-l> which is the readline key binding for clearing the screen. The following binding can be added to your ~/.tmux.conf file to provide an alternate mapping to clear-screen.

bind C-l send-keys 'C-l'

With this enabled you can use <prefix> C-l to clear the screen.

Thanks to Brian Hogan for the tip on how to re-map the clear screen binding.

Restoring SIGQUIT (C-\)

The default key bindings also include <Ctrl-\> which is the default method of sending SIGQUIT to a foreground process. Similar to "Clear Screen" above, a key binding can be created to replicate SIGQUIT in the prefix table.

bind C-\\ send-keys 'C-\'

Alternatively, you can exclude the previous pane key binding from your ~/.tmux.conf. If using TPM, the following line can be used to unbind the previous pane binding set by the plugin.

unbind -n C-\\

Disable Wrapping

By default, if you try to move past the edge of the screen, tmux/vim will "wrap" around to the opposite side. To disable this, you'll need to configure both tmux and vim:

For vim, you only need to enable this option:

let  g:tmux_navigator_no_wrap = 1

Tmux doesn't have an option, so whatever key bindings you have need to be set to conditionally wrap based on position on screen:

is_vim="ps -o state= -o comm= -t '#{pane_tty}' \
    | grep -iqE '^[^TXZ ]+ +(\\S+\\/)?g?(view|l?n?vim?x?|fzf)(diff)?$'"
bind-key -n 'C-h' if-shell "$is_vim" { send-keys C-h } { if-shell -F '#{pane_at_left}'   {} { select-pane -L } }
bind-key -n 'C-j' if-shell "$is_vim" { send-keys C-j } { if-shell -F '#{pane_at_bottom}' {} { select-pane -D } }
bind-key -n 'C-k' if-shell "$is_vim" { send-keys C-k } { if-shell -F '#{pane_at_top}'    {} { select-pane -U } }
bind-key -n 'C-l' if-shell "$is_vim" { send-keys C-l } { if-shell -F '#{pane_at_right}'  {} { select-pane -R } }

bind-key -T copy-mode-vi 'C-h' if-shell -F '#{pane_at_left}'   {} { select-pane -L }
bind-key -T copy-mode-vi 'C-j' if-shell -F '#{pane_at_bottom}' {} { select-pane -D }
bind-key -T copy-mode-vi 'C-k' if-shell -F '#{pane_at_top}'    {} { select-pane -U }
bind-key -T copy-mode-vi 'C-l' if-shell -F '#{pane_at_right}'  {} { select-pane -R }

Nesting

If you like to nest your tmux sessions, this plugin is not going to work properly. It probably never will, as it would require detecting when Tmux would wrap from one outermost pane to another and propagating that to the outer session.

By default this plugin works on the outermost tmux session and the vim sessions it contains, but you can customize the behaviour by adding more commands to the expression used by the grep command.

When nesting tmux sessions via ssh or mosh, you could extend it to look like '(^|\/)g?(view|vim|ssh|mosh?)(diff)?$', which makes this plugin work within the innermost tmux session and the vim sessions within that one. This works better than the default behaviour if you use the outer Tmux sessions as relays to different hosts and have all instances of vim on remote hosts.

Similarly, if you like to nest tmux locally, add |tmux to the expression.

This behaviour means that you can't leave the innermost session with Ctrl-hjkl directly. These following fallback mappings can be targeted to the right Tmux session by escaping the prefix (Tmux' send-prefix command).

bind -r C-h run "tmux select-pane -L"
bind -r C-j run "tmux select-pane -D"
bind -r C-k run "tmux select-pane -U"
bind -r C-l run "tmux select-pane -R"
bind -r C-\ run "tmux select-pane -l"

Another workaround is to configure tmux on the outer machine to send keys to the inner tmux session:

bind-key -n 'M-h' 'send-keys c-h'
bind-key -n 'M-j' 'send-keys c-j'
bind-key -n 'M-k' 'send-keys c-k'
bind-key -n 'M-l' 'send-keys c-l'

Here we bind "meta" key (aka "alt" or "option" key) combinations for each of the four directions and send those along to the innermost session via send-keys. You use the normal C-h,j,k,l while in the outermost session and the alternative bindings to navigate the innermost session. Note that if you use the example above on a Mac, you may need to configure your terminal app to get the option key to work like a normal meta key. Consult your terminal app's manual for details.

A third possible solution is to manually prevent the outermost tmux session from intercepting the navigation keystrokes by disabling the prefix table:

set -g pane-active-border-style 'fg=#000000,bg=#ffff00'
bind -T root F12  \
  set prefix None \;\
  set key-table off \;\
  if -F '#{pane_in_mode}' 'send-keys -X cancel' \;\
  set -g pane-active-border-style 'fg=#000000,bg=#00ff00'
  refresh-client -S \;\

bind -T off F12 \
  set -u prefix \;\
  set -u key-table \;\
  set -g pane-active-border-style 'fg=#000000,bg=#ffff00'
  refresh-client -S

This code, added to the machine running the outermost tmux session, toggles the outermost prefix table on and off with the F12 key. When off, the active pane's border changes to green to indicate that the inner session receives navigation keystrokes. When toggled back on, the border returns to yellow and normal operation resumes and the outermost responds to the nav keystrokes.

The code example above also toggles the prefix key (ctrl-b by default) for the outer session so that same prefix can be temporarily used on the inner session instead of having to use a different prefix (ctrl-a by default) which you may find convenient. If not, simply remove the lines that set/unset the prefix key from the code example above.

netrw

Vim's builtin file explorer, named the netrw plugin, has a default keymapping for <C-l>. When using vim-tmux-navigator with default settings, vim-tmux-navigator will try to override the netrw mapping so that <C-l> will still be mapped to :TmuxNavigateRight as it is for other buffers. If you prefer to keep the netrw mapping, set this variable in your vimrc:

let g:tmux_navigator_disable_netrw_workaround = 1

Alternatively, if you prefer to work around the issue yourself, you can add the following to your vimrc:

let g:tmux_navigator_disable_netrw_workaround = 1
" g:Netrw_UserMaps is a list of lists. If you'd like to add other key mappings,
" just add them like so: [['a', 'command1'], ['b', 'command2'], ...]
let g:Netrw_UserMaps = [['<C-l>', '<C-U>TmuxNavigateRight<cr>']]

Troubleshooting

Vim -> Tmux doesn't work!

This is likely due to conflicting key mappings in your ~/.vimrc. You can check this by running :verbose nmap <C-h> (similar for each of the key bindings). You should see vim-tmux-runner as the source listed for the key binding, but if you see something else, you've got a conflict and will need to remove the other key binding or otherwise restructure your vim config.

Another option is that the pattern matching included in the .tmux.conf is not recognizing that Vim is active. To check that tmux is properly recognizing Vim, use the provided Vim command :TmuxNavigatorProcessList. The output of that command should be a list like:

Ss   -zsh
S+   vim
S+   tmux

If you encounter a different output please open an issue with as much info about your OS, Vim version, and tmux version as possible.

Tmux Can't Tell if Vim Is Active

This functionality requires tmux version 1.8 or higher. You can check your version to confirm with this shell command:

tmux -V # should return 'tmux 1.8'

Switching out of Vim Is Slow

If you find that navigation within Vim (from split to split) is fine, but Vim to a non-Vim tmux pane is delayed, it might be due to a slow shell startup. Consider moving code from your shell's non-interactive rc file (e.g., ~/.zshenv) into the interactive startup file (e.g., ~/.zshrc) as Vim only sources the non-interactive config.

It doesn't work in Vim's terminal mode

Terminal mode is currently unsupported as adding this plugin's mappings there causes conflict with movement mappings for FZF (it also uses terminal mode). There's a conversation about this in #172

It Doesn't Work in tmate

tmate is a tmux fork that aids in setting up remote pair programming sessions. It is designed to run alongside tmux without issue, but occasionally there are hiccups. Specifically, if the versions of tmux and tmate don't match, you can have issues. See this issue for more detail.

Switching between host panes doesn't work when docker is running

Images built from minimalist OSes may not have the ps command or have a simpler version of the command that is not compatible with this plugin. Try installing the procps package using the appropriate package manager command. For Alpine, you would do apk add procps.

If this doesn't solve your problem, you can also try the following:

Replace the is_vim variable in your ~/.tmux.conf file with:

if-shell '[ -f /.dockerenv ]' \
  "is_vim=\"ps -o state=,comm= -t '#{pane_tty}' \
      | grep -iqE '^[^TXZ ]+ +(\\S+\\/)?g?(view|l?n?vim?x?)(diff)?$'\""
  # Filter out docker instances of nvim from the host system to prevent
  # host from thinking nvim is running in a pseudoterminal when its not.
  "is_vim=\"ps -o state=,comm=,cgroup= -t '#{pane_tty}' \
      | grep -ivE '^.+ +.+ +.+\\/docker\\/.+$' \
      | grep -iqE '^[^TXZ ]+ +(\\S+\\/)?g?(view|l?n?vim?x?)(diff)? +'\""

Details: The output of the ps command on the host system includes processes running within containers, but containers have their own instances of /dev/pts/*. vim-tmux-navigator relies on /dev/pts/* to determine if vim is running, so if vim is running in say /dev/pts/ in a container and there is a tmux pane (not running vim) in /dev/pts/ on the host system, then without the patch above vim-tmux-navigator will think vim is running when its not.

It Still Doesn't Work!!!

The tmux configuration uses an inlined grep pattern match to help determine if the current pane is running Vim. If you run into any issues with the navigation not happening as expected, you can try using Mislav's original external script which has a more robust check.

vim-tmux-navigator's People

Contributors

anakimluke avatar b0o avatar blueyed avatar bullno1 avatar christoomey avatar cjavdev avatar dkinzer avatar druckdev avatar ebouchut avatar geoffharcourt avatar geolessel avatar goronfreeman avatar hwine avatar jamesoff avatar jaythomason avatar jnpngshiii avatar joshmedeski avatar jsign avatar keith avatar looneym avatar m42e avatar maximkulkin avatar mfk-smart avatar mischi avatar mmjo avatar promisedlandt avatar sdondley avatar strazto avatar thegcat avatar thejohnfreeman avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

vim-tmux-navigator's Issues

Detecting vim running in tmux pane may yield false positives

Your proposed tmux config currently has:

tmux display-message -p '#{pane_current_command}' | grep -iq vim

I've got reports that "pane_current_command" on some systems may yield the full path to the command, not just the command name. This means that for a command such as /home/mislav/.vim/something, the grep check above would yield a false positive since it would match "vim" anywhere in the path.

My script strips the potential path:

cmd="$(tmux display -p '#{pane_current_command}')"
cmd="$(basename "${cmd,,*}")"

if [ "${cmd%m}" = "vi" ]; then
  # this pane runs Vim!
else
  # normal pane
fi

Doesn't work well with vim-session

If I open vim, it works fine, but if I open using OpenSession sessionname it doesn't work anymore.
The strange thing is that :TmuxNavigateLeft and similar works, but the keybindings doesn't work anymore. Rebinding the key doesn't work either.

Can navigate from vim to tmux but not back from tmux

Hello, I've installed the plugin using tmux 1.9 and Vim 7.4 on Mavericks.

I removed any conflicting key mappings from my .vimrc and added the lines to ~/.tmux.conf:

 is_vim='echo "#{pane_current_command}" | grep -iqE "(^|\/)g?(view|n?vim?)(diff)?$"'
 bind -n C-h if-shell "$is_vim" "send-keys C-h" "select-pane -L"
 bind -n C-j if-shell "$is_vim" "send-keys C-j" "select-pane -D"
 bind -n C-k if-shell "$is_vim" "send-keys C-k" "select-pane -U"
 bind -n C-l if-shell "$is_vim" "send-keys C-l" "select-pane -R"
 bind -n C-\ if-shell "$is_vim" "send-keys C-\\" "select-pane -l"

I can navigate from a vim instance in one tmux pane to another tmux pane but not from a tmux pane at the command line to any other tmux pane, running vim or not. I have tested in OS X Terminal and iTerm. I also tried using the tmux configuration lines from the thoughtbot blog post but that did not help.

Any ideas of what else I should check/change?

Netrw conflict

Is it possible not to map <C-l> and <C-h> in netrw windows?

About Tmux zoom feature

I'd like to put in discussion what would be the best behavior when you zoom a particular pane. For me it's a bit annoying when I'm in a zoomed pane and get out of zoom by accident when moving around buffers/panes.

Would it be possible/desirable to have vim-tmux-navigation disabled (both for tmux as for vim) when zoom is ON in a given pane? Because I find vim-tmux-navigation useful solely when zoom is off.

A 3rd-party integration. e.g. seamless i3/tmux/vim

I've extended this idea and joined the window-manager I use, i3, to this navigation hook. Tmux's devs were nice to include new output messages that enables "edge" detection for tmux's panes.

The only thing is I had to change the cmd to:

    let cmd = 'i3-focus ' . tr(a:direction, 'phjkl', 'lLDUR') . ' vim'

Instead of forking this, could you add the cmd as a global so it could be configured?
e.g.

    let g:tmux_navigator_cmd = 'i3-focus %s vim'
    "let g:tmux_navigator_cmd = 'tmux select-pane -%s'

feature request: embedded tmux support

I don't know how possible this would be, but it'd be very cool to navigate panes that are also inside embedded tmux sessions.
I tried something like the following but of course it gets stuck once inside an ssh session
bind -n C-h run "(tmux display-message -p '#{pane_current_command}' | grep -iqP '(vim|ssh)' && tmux send-keys C-h) || tmux select-pane -L"

renders off by one line when using syntastic?

This is a sane plugin for an insane world! Great stuff!

If vim is in my top pane, I have syntastic active mode enabled, do a quick :w and C-j, then vim starts to render everything off by one line.

before

image

after :w and switching panes immediately.

image

if i keep doing this, then it keeps getting worse.

after after

image

If i resize the pane, then everything goes back to normal. I know that syntastic performs a syntax check when I do a :w, and disabling syntastic fixes the problem. Any ideas? Thanks!

Works between tmux panes but not in vim

I have ubuntu 13.04, TMux 1.8 and vim 7.4.16

I simplified my conf files as much as possible and I have this for vim :

set nocompatible              
filetype off                   

set rtp+=~/.vim/bundle/vundle/
call vundle#rc()

Bundle 'gmarik/vundle'
Bundle 'christoomey/vim-tmux-navigator'

And this for tmux:

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"

I did :source ~/.vimrc and tmux source-file ~/.tmux.conf. Now, when I try to navigate between tmux's panes it works but did not switch between window in vim.

What can I do?

Thanks!

Error 127

After updating to Yosemite, I'm no longer able to navigate across tmux splits.

I get

(tmux display-message -p '#{pane_current_command}' | grep -iq vim && tmux send-keys C-h) || tmux select-pane -L returns 127

in the tmux status bar.

My tmux.conf is here and vimrc is here

EDIT: if I run the command in a tmux shell, I do get appropriate switching of panes.

problems with installing vim-tmux-navigator

I installed Vundle and then added

Bundle 'christoomey/vim-tmux-navigator'
to my ./vimrc file

I added the new bindings to my .tmux.conf file:

# Smart pane switching with awareness of vim splits
is_vim='echo "#{pane_current_command}" | grep -iqE "(^|\/)g?(view|n?vim?)(diff)?$"'
bind -n C-h if-shell "$is_vim" "send-keys C-h" "select-pane -L"
bind -n C-j if-shell "$is_vim" "send-keys C-j" "select-pane -D"
bind -n C-k if-shell "$is_vim" "send-keys C-k" "select-pane -U"
bind -n C-l if-shell "$is_vim" "send-keys C-l" "select-pane -R"
bind -n C-\ if-shell "$is_vim" "send-keys C-\\" "select-pane -l"

but when I source the .tmux.conf file, I get this error:

/Users/acandael/.tmux.conf:8: invalid or unknown command: is_vim='echo "#{pane[0/0]│   1 set    nocompatible              " be iMproved, required
/Users/acandael/.tmux.conf:9: invalid or unknown command: "(^|\/)g?(view|n?vim?)(d'

how can I fix this?

greetings,

Anthony

Keybindings No Longer work - OS X 10.10 Yosemite

Just installed OS X 10.10 Yosemite.

Keybindings no longer work in tmux 1.9a

I checked my mappings, for example:
:map
will tell me that it's mapped to :TmuxNavigateDown

but when I press it, it will do nothing.

However, when I run :TmuxNavigateDown in command mode, it works perfectly fine.
Wondering what happened to the binding that made it break.

Does not work for vimx.

I'm running vimx instead of vim and I had to change grep regex to grep -iqE "(^|\/)g?(view|n?vim?x?)(diff)?$" to make vim->vim working.

Hotkeys not working when vim is started from another process (e.g. git)

Hello there,

fine work here. Only problem I've come across is that the hotkeys don't work if started from a different process. This is often the case in my workflow, for example when doing git commit or git mergetool. A quick & dirty fix would be to just change the line

is_vim='echo "#{pane_current_command}" | grep -iqE "(^|\/)g?(view|n?vim?)(diff)?$"'

to

is_vim='echo "#{pane_current_command}" | grep -iqE "(^|\/)(git|g?(view|n?vim?)(diff))?$"'

in your .tmux.conf which is what I'm using right now, however this results in having the hotkeys active whenever git is the active command, and not just when vim has been started through git. I was wondering if you could come up with a better solution?

tmux nav works with vim, not with view

I haven't found a way to debug this, but everything works as intended, except when
I start 'view' instead of 'vim'. I've mapped -left/right/down/up as keys to move.

ssh & vim break the tmux detection mechanism

Currently if I ssh within tmux and open vim there - tmux-navigator won't realise that I am still running vim.

I'd suggest something along the lines of

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

So that people can simply rename their window to vim to regain the navigator's functionality.

Perhaps grep in this case could end up with some false matches, so perhaps egrep "\bvim\b" would be an improvement.

Less cluttered run-shell bindings

Oy mates,

so I used this for a while and in a recent cleanup I mentioned that the bindings you are using are pretty cluttered.

bind -n C-h run "(tmux display-message -p '#{pane_current_command}' | grep -iqE '(^|\/)g?(view|vim?)(diff)?$' && tmux send-keys C-h) || tmux select-pane -L"

First off: display-message is not needed. #{pane_current_command} is fully sufficient, since it will be replaced with the command by tmux before executing.
Also, we can omit grep since all common shells provide the the [[ command and POSIX ERE (at least bash and zsh do; afaik ksh does too) and for those that do not grep -iqE $regex <<< '#{pane_current_command}' does a better job.
The regex-part can be generalized to g?(view|vim)(diff)? since tmux only gives the name of the current output - never the flags or parameters.

bind -n C-h run "[[ #{pane_current_command} =~ g?(view|vim)(diff)? ]] && tmux send-keys C-h || tmux select-pane -L"
bind -n C-j run "[[ #{pane_current_command} =~ g?(view|vim)(diff)? ]] && tmux send-keys C-j || tmux select-pane -D"
bind -n C-k run "[[ #{pane_current_command} =~ g?(view|vim)(diff)? ]] && tmux send-keys C-k || tmux select-pane -U"
bind -n C-l run "[[ #{pane_current_command} =~ g?(view|vim)(diff)? ]] && tmux send-keys C-l || tmux select-pane -R"

Would be a better approach.

Take it if you want, dismiss if not.

Edit:
Tmux can also eval variables, so to make it even better:

viewvimdiff="[[ #{pane_current_command} =~ g?(view|vim)(diff)? ]]"
bind -n C-h run "$viewvimdiff && tmux send-keys C-h || tmux select-pane -L"
bind -n C-j run "$viewvimdiff && tmux send-keys C-j || tmux select-pane -D"
bind -n C-k run "$viewvimdiff && tmux send-keys C-k || tmux select-pane -U"
bind -n C-l run "$viewvimdiff && tmux send-keys C-l || tmux select-pane -R"

Script malfunctioning

Just updated the script with git pull and now I get the following errors:

Error detected while processing /home/jonathfe/.vim/bundle/vim-tmux-navigator/plugin/tmux_navigator.vim:
line 4:
E492: Not an editor command: ^M
line 5:
E15: Invalid expression: exists("g:loaded_tmux_navigator") || &cp || v:version < 700^M
line 88:
E171: Missing :endif

Awesome plugin BTW

Backspace won't work in tmux

I use this setup extensively, but recently my backspace key stopped working in tmux. Now, backspace jumps between vertically split windows. Here's my .tmux.conf:

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

set -g prefix C-a # this just changes my prefix from ctrl-b to ctrl-a
bind \ split-window -h # Split panes horizontal
bind - split-window -v # Split panes vertically  

If I remove the left and right bindings (C-h and C-l), then backspace starts working again. Any ideas?

Unable to move between splits in Vimdiff

I am having difficulties moving between panes when using Vimdiff.

If I am in a file and diff another file with :vert diffsplit filename you can move between splits as desired. Using the more common method of splitting (at least for me) of opening vim with vimdiff file1 file2 the cursor will not move between splits.

Is vitality workaround still need?

I have just installed vitality and didn't understand why vim was redrawing after switching panes until I found the workaround @Keithbsmiley added for issue #7.

I commented out the redraw line and I couldn't reproduce the issue. Is it still present? The redraws can get somewhat irritating, so avoiding them if they are not necessary would be great.

Seems to break in vim 7.4

Just upgraded to Vim 7.4 and noticed navigation stopped working.

I'm using the Vim from homebrew.

VIM - Vi IMproved 7.4 (2013 Aug 10, compiled Nov 14 2013 11:18:12)
MacOS X (unix) version
Included patches: 1-52
Compiled by Homebrew
Huge version without GUI.  Features included (+) or not (-):
+acl             +farsi           +mouse_netterm   +syntax
+arabic          +file_in_path    +mouse_sgr       +tag_binary
+autocmd         +find_in_path    -mouse_sysmouse  +tag_old_static
-balloon_eval    +float           +mouse_urxvt     -tag_any_white
-browse          +folding         +mouse_xterm     -tcl
++builtin_terms  -footer          +multi_byte      +terminfo
+byte_offset     +fork()          +multi_lang      +termresponse
+cindent         -gettext         -mzscheme        +textobjects
-clientserver    -hangul_input    +netbeans_intg   +title
+clipboard       +iconv           +path_extra      -toolbar
+cmdline_compl   +insert_expand   -perl            +user_commands
+cmdline_hist    +jumplist        +persistent_undo +vertsplit
+cmdline_info    +keymap          +postscript      +virtualedit
+comments        +langmap         +printer         +visual
+conceal         +libcall         +profile         +visualextra
+cryptv          +linebreak       +python          +viminfo
+cscope          +lispindent      -python3         +vreplace
+cursorbind      +listcmds        +quickfix        +wildignore
+cursorshape     +localmap        +reltime         +wildmenu
+dialog_con      -lua             +rightleft       +windows
+diff            +menu            +ruby            +writebackup
+digraphs        +mksession       +scrollbind      -X11
-dnd             +modify_fname    +signs           -xfontset
-ebcdic          +mouse           +smartindent     -xim
+emacs_tags      -mouseshape      -sniff           -xsmp
+eval            +mouse_dec       +startuptime     -xterm_clipboard
+ex_extra        -mouse_gpm       +statusline      -xterm_save
+extra_search    -mouse_jsbterm   -sun_workshop    -xpm
   system vimrc file: "$VIM/vimrc"
     user vimrc file: "$HOME/.vimrc"
 2nd user vimrc file: "~/.vim/vimrc"
      user exrc file: "$HOME/.exrc"
  fall-back for $VIM: "/usr/local/share/vim"
Compilation: /usr/bin/clang -c -I. -Iproto -DHAVE_CONFIG_H   -F/usr/local/Frameworks -DMACOS_X_UNIX  -Os -w -pipe -march=native -mmacosx-version-min=10.9 -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=1      
Linking: /usr/bin/clang   -L. -L/usr/local/lib -F/usr/local/opt/python/Frameworks -L/usr/local/lib -F/usr/local/Frameworks -Wl,-headerpad_max_install_names -o vim        -lm  -lncurses -liconv -framework Cocoa    -framework Python   -lruby.2.0.0 -lobjc   

Feature request: command to generate the .tmux.conf stuff

Since you can customize the keys, could you create a :foobar command in vim to generate the commands that go into ~/.tmux.conf?

The part I'm talking about is:

# Smart pane switching with awareness of vim splits
bind -n C-h run "(tmux display-message -p '#{pane_current_command}' | grep -iqE '(^|\/)vim$' && tmux send-keys C-h) || tmux select-pane -L"
bind -n C-j run "(tmux display-message -p '#{pane_current_command}' | grep -iqE '(^|\/)vim$' && tmux send-keys C-j) || tmux select-pane -D"
bind -n C-k run "(tmux display-message -p '#{pane_current_command}' | grep -iqE '(^|\/)vim$' && tmux send-keys C-k) || tmux select-pane -U"
bind -n C-l run "(tmux display-message -p '#{pane_current_command}' | grep -iqE '(^|\/)vim$' && tmux send-keys C-l) || tmux select-pane -R"
bind -n C-\ run "(tmux display-message -p '#{pane_current_command}' | grep -iqE '(^|\/)vim$' && tmux send-keys 'C-\\') || tmux select-pane -l" 

Or maybe a simple shell script or a vim -c :tmux-navigator-tmux-commands -c :qa! command could print to stdout the tmux commands directly so that the user wouldn't have to worry about updating settings in two places?

It would also let adding additional commands to tmux-navigator easier to keep in sync.

Switching out of Vim slow

It takes roughly 2.5 seconds to switch from vim to another tmux pane. Switching inside vim or between non vim tmux panes is instant. I'm not sure if it was happening when I initially installed this plugin.

Would you happen to know what is causing it? Or maybe what setting I messed with that caused this?

Screencast

Mappings break in command-line window

When in the command-line window (q: for command history or q/ for search history), TmuxWinCmd errors out.

Maybe the mappings should be scoped to only normal vim buffers and fall back otherwise?

Error detected while processing function <SNR>124_TmuxWinCmd..<SNR>124_TmuxAwareNavigate
:
line    5:
E11: Invalid in command-line window; <CR> executes, CTRL-C quits: wincmd k

@derekprior have you seen this?

tmux-navigator breaks after re-sourcing ~/.vimrc

I'm a configuration junkie so I'm always modifying my ~/.vimrc
When I source ~/.vimrc during a session the seamless navigation breaks (I have to use my prefix again)
-Note that navigation works until then.

Has anybody bumped into this?

When I figure out what part of my .vimrc is the cause I will report back!

Moving in vim (cygwin/zsh)

Well, I'd the same experience as decribed in #15, but as the ticket is a bit older I'd like to start a new one.

I'm using tmux/vim in cygwin zsh but it fails in exactly the same way. I've tried the workarrounds with the extra shell script but I didn't get a proper result.

If i call the

display-message -p '#{pane_current_command}'

from the tmux command line it always shows me

zsh

there is no vim showing up. Even if I run the command from vims command line.

Vim does not get detected when run via `make` / use `tmux set-env`?

I have a Makefile task that starts vim, but then :TmuxPaneCurrentCommand is make.

Maybe there's some way to look into the current tmux command's subprocess, which would be vim then, or another method to notify the tmux pane that it should forward the keys?!

Maybe tmux set-environment could be called by the vim part to indicate which pane(s) are meant to receive the keys from tmux?!

Doesn't work when #{pane_current_command} is something unexpected (e.g., git)

Not really an issue, since I already have a solution. Just wanted to share.

Instead of

is_vim='echo "#{pane_current_command}" | grep -iqE "(^|\/)g?(view|n?vim?)(diff)?$"'

we could use

is_vim='tmux show-environment #{pane_id}_is_vim'

then the plugin could do something like

if exists('$TMUX')
    autocmd VimEnter * silent execute '!tmux set-environment ${TMUX_PANE}_is_vim true'
    autocmd VimLeavePre * silent execute '!tmux set-environment -u ${TMUX_PANE}_is_vim'
endif

This wouldn't work if you put vim in the background, but who does that, honestly?

Release version

Would it be possible to have a final release of your plugin with a git tag? I don't always want to grab updates from master.

Thanks for this awesome plugin.

Problems with ctrl-h in neovim

Hi, First of all, this is a great addition to my workfow, thanks!

I know, this is probably a problem with neovim, but control-h does not work there using standard configuration. Is there anything that can be done with any mapping settings?

Thanks
A

Mappings not working with git and vimdiff

It seems like the default regex doesn't work for git using vimdiff as the difftool. For :TmuxPaneCurrentCommand it returns git. I'm using OS X, Tmux 1.8 and Vim 7.4p52 via Homebrew. My current dotfiles are here. Working on a new regex for this to include git

Remote Tmux Sessions

Wondering if there's a good way to pass through navigation commands to vim in a remote tmux session in a local tmux pane.

README references thoughtbot/vim-tmux-navigator

The README references a nonexistent (or private) repository under the Pathogen installation instructions:

git clone https://github.com/thoughtbot/vim-tmux-navigator.git

Should probably be:

git clone https://github.com/christoomey/vim-tmux-navigator.git

Annoying cryptic error message

This message was showing quite frequently for me, I've just muted it. Any reason to leave it as is? The message kept showing and it's quite cryptic and didn't help at solving anything.

diff --git a/plugin/tmux_navigator.vim b/plugin/tmux_navigator.vim
index ef3ae93..c63ed58 100644
--- a/plugin/tmux_navigator.vim
+++ b/plugin/tmux_navigator.vim
@@ -68,7 +68,7 @@ function! s:VimNavigate(direction)
   try
     execute 'wincmd ' . a:direction
   catch
-    echohl ErrorMsg | echo 'E11: Invalid in command-line window; <CR> executes, CTRL-C quits: wincmd k' | echohl None
+    " echohl ErrorMsg | echo 'E11: Invalid in command-line window; <CR> executes, CTRL-C quits: wincmd k' | echohl None
   endtry
 endfunction

difficulty moving between vim windows

Love the idea and the work you put in.

Pressing Control+w and then one of i,j,k,l. This moves the focus between tmux panes as I would expect.

Moving between vim windows seems to sometimes work if I press Control+w and Control+j or Control+k at almost the same time. I have to try multiple times quickly to make it work.

My customisation to my .vimrc did not make any perceptible difference:

let g:tmux_navigator_no_mappings = 1

nnoremap <silent> <h> :TmuxNavigateLeft<cr>
nnoremap <silent> <j> :TmuxNavigateDown<cr>
nnoremap <silent> <k> :TmuxNavigateUp<cr>
nnoremap <silent> <l> :TmuxNavigateRight<cr>
nnoremap <silent> <\> :TmuxNavigatePrevious<cr>

What I was trying to achieve is that I press Control+W and then release and then press one of i,j,k,l to navigate.

Thanks for sharing your work.

Tmux/Tmate/Vim navigation not working

Hello!

Thank you for this great package!

I love this plugin, but have recently noticed an issue when using tmate that my keybindings don't seem to work.

When I run :TmuxPaneCurrentCommand, I get this output:
protocol version mismatch (client 8, server 7)

This is pane-ful (get it?) when using tmate to pair with others remotely, as I've grown accustomed to navigating in vim normally while in tmux. Do you have any suggestions on how I can work around this? I am using Mac OSX Mavericks, homebrew, and iTerm.

Moving between Vim panes, within a Tmux session

When I'm only using Vim, without Tmux, then I can use <C-h>.
When I'm using Vim from withing a Tmux pane, that I can move to another Tmux pane by using <C-h>.

But when I have several Vim panes, within a Tmux pane, then <C-h> will move to the nearest Tmux pane, while I would want it to move to the closest Vim pane. To move between Vim panes, I have to use <C-w>h. Is there any way we could detect whether there is a Vim pane at the left of the current pane, and then do VimNavigate() instead of a TmuxNavigate(), in this case?

Keymappings fail in Neovim

I'm trying out Neovim, and having issues with tmux-navigator in that environment. Calling :TmuxNavigate commands directly works fine, the key mappings seem to fail. My vimrc works fine in the Vanilla OSX vim and mvim, but fails in Neovim.

Remapping to a different combination works, but all fail.

I was worried about conflicts, so I ran this simplified .vimrc and it still fails:

set nocompatible

set shell=bash
set shellpipe=2>/dev/null>
set rtp+=~/.vim/bundle/vundle/
call vundle#begin()
Plugin 'gmarik/vundle'

"Integrate with tmux
Plugin 'christoomey/vim-tmux-navigator'

"End Vundle
call vundle#end()
" "Vundle ended so reenable filetypes
filetype plugin indent on

Any ideas what might be causing this?

This is nvim version: NVIM 0.0.0-alpha+201501221728
Tmux Version: 1.8

Corresponding Neovim issue here: neovim/neovim#1868

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.