Tmux Part 4: Vim Integration

Vim Integration Seamless Navigation Vim Tmux Navigator is a combination Vim plugin and tmux configuration that allows for seamless navigation using C-h, C-j, C-k, and C-l. It was originally presented as a gist by Mislav Marohnić and is summarize...
This is a companion discussion topic for the original entry at https://thoughtbot.com/upcase/videos/tmux-vim-integration

Hi!

Great episide, but I was wondering, I’m trying out the vim-tmux-runner plugin, but when I call :VtrSendCommand('echo hi') for example, I get the notice: VTR: No runner pane attached.

Does that mean that if I want to start using this for tests, I need to attach a runner pane every time I open up vim to do programming? Since it looked like you didn’t in the screencast.

I’m running into the same problem. I can’t seem to figure out what’s wrong though. If a call the command VtrSendCommand! (with a bang) it does create a new ‘pane’.
github issue 27 on vim-tmux-runner

I just can’t figure out how to put this in my .vimrc to make this happen automagically :frowning:

@jvanbaarsen Did you fix this? I’m using the tslime integration to run my tests at the moment. But I really want to use the tmux-runner plugin.

[running specs from vim sent to tmyx via tslime] (Running Specs from Vim, Sent to tmux via Tslime)

I managed to sometimes have commands been send to tmux by using the following:

VtrSendCommand! "echo hi" You need to call this without exec or call in your .vimrc.

The problem is that it still sometimes thinks there is no pane to attach to. Also it does not work with variables. For example I currently run test this way: exec g:bjo_test_runner g:bjo_test_file (Some projects use Minitest and some Rspec so I need this flexibility ) But when I parse those into VtrSendCommand it sends the following to the pane: g:bjo_test_runner g:bjo_test_file So it does not actually replace the variables. Still not sure if thats something im doing wrong, or a bug in Tmux Runner.

@christoomey Any ideas?

Hello @Sajoku, @jvanbaarsen, you are correct, most of the commands in VTR have both a normal (expects and existing, attached tmux pane), and a bang (!) version that will create a pane as needed. There is also a bit of confusion as there is a function, VtrSendCommand and commands VtrSendCommandToRunner. I need to update these to simplify, but for now, this should help:

For spec running, you can use the following (with vim-rspec):

Bundle 'thoughtbot/vim-rspec'

let g:rspec_command = "VtrSendCommandToRunner! rspec {spec}"

map <Leader>t :call RunNearestSpec()<CR>
2 Likes

@christoomey Thanks for your reply. How would I fit that in with my test running? (Unfortunatly I cant use vim-rspec because I work on projects in Minitest and Rspec). This is the way I run test: https://github.com/jvanbaarsen/dotfiles/blob/master/vimrc#L348

The general pattern should be the same. Some vimscript (a plugin like vim-rspec or vim-spec-runner or some custom code in your vimrc as you have) determines the proper command string for the current context, e.g. rspec spec/things/foo_spec.rb:8 or ruby spec/thing_spec.rb in the case of minitest.

This string, whatever it is, can then be handed off to VTR for execution. The following is example code as to how this might work:

function! DetermineSpecRunString()
  " code to figure out proper spec run string for minitest, test unit, etc
endfuction

...

function! RunCurrentSpec()
  let spec_run_string = DetermineSpecRunString()
  let create_pane_if_needed = 1 " boolean argument for the function
  call VtrSendCommand(spec_run_string, 1)
endfunction

nnoremap <leader>t :call RunCurrentSpec()<cr>
2 Likes

Thanks! That works great :slight_smile:

Awesome @christoomey works like a charm.

Not sure if it’s expected behaviour but when I run a spec and close the open window with exit I get the message:

VTR: Runner pane setting (1) is invalid. Please reattach.

This is the command I run:
``let g:rspec_command = “VtrSendCommandToRunner! spring rspec {spec}”```

@christoomey could you point me in the right direction on how to fix this? :slight_smile:

Hello @Sajoku, I believe this is the expected behavior, but to confirm, you are doing the following:

  1. Run spec (with the specific rspec_command)
  2. Close the rspec / runner pane manually
  3. Attempt to run a spec from vim again

and you are seeing the error message. This is expected. VTR remembers the pane and expects it to exist. Before sending commands, it checks that the pane exists and things haven’t shifted around to prevent sending to the wrong window.

All that said, you have two options if you want to be able to dismiss the window but still run tests:

  • Manually open and attach to a pane with the :VtrAttachToPane command. If there is only one other (non-vim) pane, it will automatically select, otherwise it will prompt for the pane to attach to. Tests should run fine after that
  • Rather than killing the runner pane, use the :VtrDetachRunner command. This will break the runner pane out into a new window, but on the next spec run it will automatically restore it.

Hope that helps

Yes that is exactly what I was doing.

Works like a charm. I eventually stole the line from your dotfiles :smile:

@christoomey, one more question about this episode:

I’ve noticed that when using vim outside of tmux, my timeout settings work such that when I press escape, vim immediately leaves insert mode. However, when I am in tmux, there’s a delay that seems to last about a full second. I assume this is tmux checking for an escape sequence or something similar, but is this a problem you’ve seen, and is there a good solution for it? I looked at your dotfiles and didn’t see anything that stuck out as a way to address this issue.

In case it’s useful, I’m using iTerm2 with the keys set for xterm, but I see the same issue in Terminal.app.

Hey @geoffharcourt, assuming I understand the issue you’re describing correctly, I do in fact have a setting for this: set -s escape-time 0 here in my tmux.conf.

In reality I only have that there for when I am pairing as I don’t use esc in Vim, opting for C-[ or other home row accessible things.

1 Like

That solved it. Was searching for the word timeout. Thanks for the help!

Great information, I’ve wanted this kind of setup for a long time.

I’m running into a problem when using :VtrDetachRunner. The runner gets hidden (and I see there is a new window listed in the status bar named VTR_Pane).

But I try run a test again if fails with: VTR: Runner pane setting (1) is invalid. (shown twice).

My config is let g:rspec_command = "VtrSendCommandToRunner! rspec {spec}".

Hey @andyw8, sorry to hear you’r running into an issue. The workflow you describe should work (I just confirmed locally), so you are likely hitting an issue. Do you mind posting to Issues · christoomey/vim-tmux-runner · GitHub with a summary?

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