How to swap files between windows in VIM?

33,655

Solution 1

There are a few useful commands built in which give you a certain amount of control, but it's not comprehensive. The main ones are:

  • Ctrl-W, r (i.e. hold CTRL, press W, release CTRL, press r) - which rotates the windows (The first window becomes the second one, the second one becomes the third one, etc.)

  • Ctrl-W, x - swap the current window with the next one

  • Ctrl-W, Shift-H - move this window to the far left

  • Ctrl-W, Shift-K - move this window to the top

(and similarly for Ctrl-W, Shift-J and Ctrl-W, Shift-L). See:

:help window-moving

for more information.

Solution 2

I wrote and have been using the following code snippet in my vimrc for copy-pasting my Vim windows.

This defines for example the following shortcuts:

  • <c-w>y: "Yanks the window", i.e. stores the number of the buffer in the current window in a global variable.
  • <c-w>pp: "Puts the window in Place of the current window", i.e. it reads the buffer number stored previously and opens that buffer in the current window. It also stores the number of the buffer that used to be in the current window.

If by "swapping those windows in places", you mean "opening the buffer in window A in window B, and vice versa, without changing the position of the windows", you can use the following keyboard sequence to swap the windows:

  1. Select window A (either with mouse or with keyboard commands)
  2. Press <c-w>y (yanking the buffer number)
  3. Select window B
  4. Press <c-w>pp (pasting the buffer)
  5. Select window A
  6. Press <c-w>pp (pasting the buffer again)

It works only in Vim >= 7.0.

if version >= 700
function! HOpen(dir,what_to_open)

    let [type,name] = a:what_to_open

    if a:dir=='left' || a:dir=='right'
        vsplit
    elseif a:dir=='up' || a:dir=='down'
        split
    end

    if a:dir=='down' || a:dir=='right'
        exec "normal! \<c-w>\<c-w>"
    end

    if type=='buffer'
        exec 'buffer '.name
    else
        exec 'edit '.name
    end
endfunction

function! HYankWindow()
    let g:window = winnr()
    let g:buffer = bufnr('%')
    let g:bufhidden = &bufhidden
endfunction

function! HDeleteWindow()
    call HYankWindow()
    set bufhidden=hide
    close
endfunction

function! HPasteWindow(direction)
    let old_buffer = bufnr('%')
    call HOpen(a:direction,['buffer',g:buffer])
    let g:buffer = old_buffer
    let &bufhidden = g:bufhidden
endfunction

noremap <c-w>d :call HDeleteWindow()<cr>
noremap <c-w>y :call HYankWindow()<cr>
noremap <c-w>p<up> :call HPasteWindow('up')<cr>
noremap <c-w>p<down> :call HPasteWindow('down')<cr>
noremap <c-w>p<left> :call HPasteWindow('left')<cr>
noremap <c-w>p<right> :call HPasteWindow('right')<cr>
noremap <c-w>pk :call HPasteWindow('up')<cr>
noremap <c-w>pj :call HPasteWindow('down')<cr>
noremap <c-w>ph :call HPasteWindow('left')<cr>
noremap <c-w>pl :call HPasteWindow('right')<cr>
noremap <c-w>pp :call HPasteWindow('here')<cr>
noremap <c-w>P :call HPasteWindow('here')<cr>

endif

Solution 3

In my opinion, http://vimcasts.org/episodes/working-with-windows/ has the perfect answer for this question. In brief:

  • ctrl-w w cycle between the open windows
  • ctrl-w h focus the window to the left
  • ctrl-w j focus the window to the down
  • ctrl-w k focus the window to the up
  • ctrl-w l focus the window to the right
  • ctrl-w r rotate all windows
  • ctrl-w x exchange current window with its neighbour
  • ctrl-w H move current window to far left
  • ctrl-w J move current window to bottom
  • ctrl-w K move current window to top
  • ctrl-w L move current window to far right

Solution 4

I asked a similar question around the same time: I wanted a way to swap windows specifically without altering an arbitrarily complicated layout. I ended up making a vim plugin out of one of the solutions that was suggested. It's called WindowSwap.vim; install it with your preferred vim plugin manager and give it a whirl.

With WindowSwap.vim, you'd simply

  1. <Leader>yw to yank a window.
  2. Move your cursor to another window.
  3. <Leader>pw to paste that window, swapping it with the position of the first one.

The key combinations are of course configurable to your preferences.

Solution 5

As <c-w>r or <c-w>x has a restriction that you can't rotate or exchange windows When vertical and horizontal window splits are mixed. And <c-w>H may make the window layout change beyond your expectation especially when you have many windows.

So you may do some work to satisfy your particular needs of window/buffer switching. Here is am example to switching the current window with the top left window(typically I make it vertically maximized):

function! SwitchMainWindow()
  let l:current_buf = winbufnr(0)
  exe "buffer" . winbufnr(1)
  1wincmd w
  exe "buffer" . l:current_buf
endfunction
nnoremap <c-w><c-e> :call SwitchMainWindow()<cr>
Share:
33,655
mdrozdziel
Author by

mdrozdziel

:D

Updated on July 29, 2022

Comments

  • mdrozdziel
    mdrozdziel almost 2 years

    When I work with VIM, I always have multiple windows visible. Sometimes I would like to have an easy way, to swap those windows in places. Is there any Plugin, Macro, etc to make this more easy? BTW, I use MiniBufExplorer.

  • David Rivers
    David Rivers about 13 years
    This should be the "best answer"--native functionality, not a custom Vimscript.
  • bobpaul
    bobpaul over 12 years
    Not completely, no. There are lots of use cases that can't be done using the built in window management without destroying and recreating windows. The swap buffers script allows these use cases.
  • mdrozdziel
    mdrozdziel over 8 years
    What is the reason for adding an answer which brings no new usefull information to the post? This was perfectly answered 6 years ago. Are you doing ad campaign for vimcasts?
  • datakid
    datakid almost 7 years
    note that ctl-w also works. ctl-W will close windows in some terminal emulators.
  • roro
    roro over 4 years
    @mdrozdziel I appreciate this answer 9 years after the OP. Most concise answer with only the info i wanted.