Created
August 24, 2013 07:04
-
-
Save john2x/6326576 to your computer and use it in GitHub Desktop.
Delete buffer while keeping window layout (don't close buffer's windows) Version 2008-11-18 from http://vim.wikia.com/wiki/VimTip165
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
" Delete buffer while keeping window layout (don't close buffer's windows). | |
" Version 2008-11-18 from http://vim.wikia.com/wiki/VimTip165 | |
if v:version < 700 || exists('loaded_bclose') || &cp | |
finish | |
endif | |
let loaded_bclose = 1 | |
if !exists('bclose_multiple') | |
let bclose_multiple = 1 | |
endif | |
" Display an error message. | |
function! s:Warn(msg) | |
echohl ErrorMsg | |
echomsg a:msg | |
echohl NONE | |
endfunction | |
" Command ':Bclose' executes ':bd' to delete buffer in current window. | |
" The window will show the alternate buffer (Ctrl-^) if it exists, | |
" or the previous buffer (:bp), or a blank buffer if no previous. | |
" Command ':Bclose!' is the same, but executes ':bd!' (discard changes). | |
" An optional argument can specify which buffer to close (name or number). | |
function! s:Bclose(bang, buffer) | |
if empty(a:buffer) | |
let btarget = bufnr('%') | |
elseif a:buffer =~ '^\d\+$' | |
let btarget = bufnr(str2nr(a:buffer)) | |
else | |
let btarget = bufnr(a:buffer) | |
endif | |
if btarget < 0 | |
call s:Warn('No matching buffer for '.a:buffer) | |
return | |
endif | |
if empty(a:bang) && getbufvar(btarget, '&modified') | |
call s:Warn('No write since last change for buffer '.btarget.' (use :Bclose!)') | |
return | |
endif | |
" Numbers of windows that view target buffer which we will delete. | |
let wnums = filter(range(1, winnr('$')), 'winbufnr(v:val) == btarget') | |
if !g:bclose_multiple && len(wnums) > 1 | |
call s:Warn('Buffer is in multiple windows (use ":let bclose_multiple=1")') | |
return | |
endif | |
let wcurrent = winnr() | |
for w in wnums | |
execute w.'wincmd w' | |
let prevbuf = bufnr('#') | |
if prevbuf > 0 && buflisted(prevbuf) && prevbuf != w | |
buffer # | |
else | |
bprevious | |
endif | |
if btarget == bufnr('%') | |
" Numbers of listed buffers which are not the target to be deleted. | |
let blisted = filter(range(1, bufnr('$')), 'buflisted(v:val) && v:val != btarget') | |
" Listed, not target, and not displayed. | |
let bhidden = filter(copy(blisted), 'bufwinnr(v:val) < 0') | |
" Take the first buffer, if any (could be more intelligent). | |
let bjump = (bhidden + blisted + [-1])[0] | |
if bjump > 0 | |
execute 'buffer '.bjump | |
else | |
execute 'enew'.a:bang | |
endif | |
endif | |
endfor | |
execute 'bdelete'.a:bang.' '.btarget | |
execute wcurrent.'wincmd w' | |
endfunction | |
command! -bang -complete=buffer -nargs=? Bclose call <SID>Bclose('<bang>', '<args>') |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment