Take the 2-minute tour ×
Super User is a question and answer site for computer enthusiasts and power users. It's 100% free, no registration required.

Anyone know how I can use the same keys to move between Vim windows as well as Tmux (or tiling WM) panes?

For example when I use my key combination to move to the right pane within VIM, VIM should first detect if there actually is a VIM pane to the right. If not it should call a Tmux command to move to the tmux pane on the right (if a tmux pane on the right exists).

Something similar would have to happen if you move back while being in a Tmux pane.

I suppose that besides Tmux you could also use this with a tiling window manager.

Update: moving out of VIM into a Tmux pane can be done as follows:

function! WinMove(key) 
    let t:curwin = winnr()
    exec "wincmd ".a:key
    if (t:curwin == winnr()) "we haven't moved
        if (match(a:key,'[h]')) "we're we going left
            silent execute "!tmux select-pane -L &>/dev/null &" | redraw!
        elseif (match(a:key,'[j]')) "we're we going down
            silent execute "!tmux select-pane -D &>/dev/null &" | redraw!
        elseif (match(a:key,'[k]')) "we're we going up
            silent execute "!tmux select-pane -U &>/dev/null &" | redraw!
        elseif (match(a:key,'[l]')) "we're we going right
            silent execute "!tmux select-pane -R &>/dev/null &" | redraw!
        endif
    endif
endfunction

map  <Esc><Up> <A-Up>
nmap <silent> <A-Right> :call WinMove('k')<CR> 

map  <Esc><Down> <A-Down>
nmap <silent> <A-Right> :call WinMove('j')<CR> 

map  <Esc><Left> <A-Left>
nmap <silent> <A-Right> :call WinMove('h')<CR> 

map  <Esc><Right> <A-Right>
nmap <silent> <A-Right> :call WinMove('l')<CR> 

Not sure yet if moving back is even possible, but I'm going to investigate it.

share|improve this question
    
What a weird and interesting idea! –  romainl Aug 24 '12 at 12:15
    
Going from the last vim window to the next tmux pane should be possible; switching to the correct vim window when you return to the vim pane (depending on which "direction" you arrived from) may be nearly impossible. –  chepner Aug 25 '12 at 19:53
    
Just out of curiosity, have you managed to get this to work? –  Justin L. Mar 3 '13 at 20:56
add comment

1 Answer 1

I haven't implemented this, but you should be able to make a Vim function that determines if there is a Vim window to the right, left, etc. The function could furthermore call a shell command like tmux select-pane -R if e.g. there is no Vim window to the right.

However, if you end up in a non-Vim pane, like a shell one, you wouldn't be able to use that same Vim key binding to get back: whatever binding you want to use to get back you wouldn't be able to pass directly through to Vim. I hope that makes sense.

I have a harebrained scheme that just might work, at least in the case of Vim panes on the one hand and shells on the other. The big limitation I see is that moving out of shell panes won't work if there's some other program running in the pane; in fact, the program might end up getting some garbage pasted into it. The shell must also not have anything already filled in on the command line, since we are pasting a command into it. Here goes:

  1. Define some mappings in Vim that work in all modes. They should call the functions mentioned above.
  2. Define the same mappings in ~/.inputrc (or .editrc or whatever your shell uses) and make them send a string like tmux select-pane -R\n.
  3. Use those mappings.

It appears that Bash 4's bind builtin can assign a mapping to execute a shell command, so you could use that instead of actually pasting the code into the command line in step 2. It would be great if this could be made to work across all readline programs, but so far I don't see a way to do that; it appears .inputrc doesn't support setting things that way.

share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.