How can I swap positions of two open files (in splits) in vim?

Starting with this:

____________________
| one       | two  |
|           |      |
|           |______|
|           | three|
|           |      |
|___________|______|

Make 'three' the active window, then issue the command ctrl+w J. This moves the current window to fill the bottom of the screen, leaving you with:

____________________
| one       | two  |
|           |      |
|___________|______|
| three            |
|                  |
|__________________|

Now make either 'one' or 'two' the active window, then issue the command ctrl+w r. This 'rotates' the windows in the current row, leaving you with:

____________________
| two       | one  |
|           |      |
|___________|______|
| three            |
|                  |
|__________________|

Now make 'two' the active window, and issue the command ctrl+w H. This moves the current window to fill the left of the screen, leaving you with:

____________________
| two       | one  |
|           |      |
|           |______|
|           | three|
|           |      |
|___________|______|

As you can see, the manouevre is a bit of a shuffle. With 3 windows, it's a bit like one of those 'tile game' puzzles. I don't recommand trying this if you have 4 or more windows - you'd be better off closing them then opening them again in the desired positions.

I made a screencast demonstrating how to work with split windows in Vim.


Take a look at :h ctrl-w_ctrl-x and/or :h ctrl-w_ctrl-r. These commands allow you to exchange or rotate windows in the current layout.

Edit: Actually, this will not work in this situation because it only will swap in the current column or row. You could instead go to each of the windows and select the target buffer, but that's pretty verbose.


A bit late to the post, but came across this searching for something else. I wrote two functions awhile back to mark a window and then swap buffers between windows. This seems to be what you're asking for.

Just slap these in your .vimrc and map the functions how you see fit:

function! MarkWindowSwap()
    let g:markedWinNum = winnr()
endfunction

function! DoWindowSwap()
    "Mark destination
    let curNum = winnr()
    let curBuf = bufnr( "%" )
    exe g:markedWinNum . "wincmd w"
    "Switch to source and shuffle dest->source
    let markedBuf = bufnr( "%" )
    "Hide and open so that we aren't prompted and keep history
    exe 'hide buf' curBuf
    "Switch to dest and shuffle source->dest
    exe curNum . "wincmd w"
    "Hide and open so that we aren't prompted and keep history
    exe 'hide buf' markedBuf 
endfunction

nmap <silent> <leader>mw :call MarkWindowSwap()<CR>
nmap <silent> <leader>pw :call DoWindowSwap()<CR>

To use (assuming your mapleader is set to \) you would:

  1. Move to the window to mark for the swap via ctrl-w movement
  2. Type \mw
  3. Move to the window you want to swap
  4. Type \pw

Voila! Swapped buffers without screwing up your window layout!