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

Assume I've got some arbitrary layout of splits in vim.

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

Is there a way to swap one and two and maintain the same layout? It's simple in this example, but I'm looking for a solution that will help for more complex layouts.

UPDATE:

I guess I should be more clear. My previous example was a simplification of the actual use-case. With an actual instance: alt text

How could I swap any two of those splits, maintaining the same layout?

Update! 3+ years later...

I put sgriffin's solution in a Vim plugin you can install with ease! Install it with your favorite plugin manager and give it a try: WindowSwap.vim

a little demo


Solution 1:

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.

Solution 2:

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!