···11+" Delete buffer while keeping window layout (don't close buffer's windows).
22+" Version 2008-11-18 from http://vim.wikia.com/wiki/VimTip165
33+if v:version < 700 || exists('loaded_bclose') || &cp
44+ finish
55+endif
66+let loaded_bclose = 1
77+if !exists('bclose_multiple')
88+ let bclose_multiple = 1
99+endif
1010+1111+" Display an error message.
1212+function! s:Warn(msg)
1313+ echohl ErrorMsg
1414+ echomsg a:msg
1515+ echohl NONE
1616+endfunction
1717+1818+" Command ':Bclose' executes ':bd' to delete buffer in current window.
1919+" The window will show the alternate buffer (Ctrl-^) if it exists,
2020+" or the previous buffer (:bp), or a blank buffer if no previous.
2121+" Command ':Bclose!' is the same, but executes ':bd!' (discard changes).
2222+" An optional argument can specify which buffer to close (name or number).
2323+function! s:Bclose(bang, buffer)
2424+ if empty(a:buffer)
2525+ let btarget = bufnr('%')
2626+ elseif a:buffer =~ '^\d\+$'
2727+ let btarget = bufnr(str2nr(a:buffer))
2828+ else
2929+ let btarget = bufnr(a:buffer)
3030+ endif
3131+ if btarget < 0
3232+ call s:Warn('No matching buffer for '.a:buffer)
3333+ return
3434+ endif
3535+ if empty(a:bang) && getbufvar(btarget, '&modified')
3636+ call s:Warn('No write since last change for buffer '.btarget.' (use :Bclose!)')
3737+ return
3838+ endif
3939+ " Numbers of windows that view target buffer which we will delete.
4040+ let wnums = filter(range(1, winnr('$')), 'winbufnr(v:val) == btarget')
4141+ if !g:bclose_multiple && len(wnums) > 1
4242+ call s:Warn('Buffer is in multiple windows (use ":let bclose_multiple=1")')
4343+ return
4444+ endif
4545+ let wcurrent = winnr()
4646+ for w in wnums
4747+ execute w.'wincmd w'
4848+ let prevbuf = bufnr('#')
4949+ if prevbuf > 0 && buflisted(prevbuf) && prevbuf != w
5050+ buffer #
5151+ else
5252+ bprevious
5353+ endif
5454+ if btarget == bufnr('%')
5555+ " Numbers of listed buffers which are not the target to be deleted.
5656+ let blisted = filter(range(1, bufnr('$')), 'buflisted(v:val) && v:val != btarget')
5757+ " Listed, not target, and not displayed.
5858+ let bhidden = filter(copy(blisted), 'bufwinnr(v:val) < 0')
5959+ " Take the first buffer, if any (could be more intelligent).
6060+ let bjump = (bhidden + blisted + [-1])[0]
6161+ if bjump > 0
6262+ execute 'buffer '.bjump
6363+ else
6464+ execute 'enew'.a:bang
6565+ endif
6666+ endif
6767+ endfor
6868+ execute 'bdelete'.a:bang.' '.btarget
6969+ execute wcurrent.'wincmd w'
7070+endfunction
7171+7272+command! -bang -complete=buffer -nargs=? Bclose call s:Bclose('<bang>', '<args>')