Vim Tips Wiki
Advertisement

Duplicate tip

This tip is very similar to the following:

These tips need to be merged – see the merge guidelines.

Tip 165 Printable Monobook Previous Next

created November 16, 2001 · complexity intermediate · author Raymond Li · version 6.0


I'm not sure if this functionality is already within Vim, but I sometimes I find it useful to keep a split window from closing when deleting a buffer. This has already been discussed on the vim@vim.org mailing list. However, I feel this solution is a little easier to use.

" Put this into .vimrc or make it a plugin.
" Mapping :Bclose to some keystroke would probably be more useful.
" I like the way buflisted() behaves, but some may like the behavior
" of other buffer testing functions.
command! Bclose call <SID>BufcloseCloseIt()
function! <SID>BufcloseCloseIt()
  let l:currentBufNum = bufnr("%")
  let l:alternateBufNum = bufnr("#")
  if buflisted(l:alternateBufNum)
    buffer #
  else
    bnext
  endif
  if bufnr("%") == l:currentBufNum
    new
  endif
  if buflisted(l:currentBufNum)
    execute("bdelete ".l:currentBufNum)
  endif
endfunction

Comments

The MiniBufExplorer.vim plugin (in the scripts area) provides this capability with a really simple and small user interface...


This tip didn't seem to work in gvim 6, I placed it in my _vimrc file as instructed, but deleting buffers still closes the windows they are in, as before ;-(.


I didn't try the tip, but this is the solution I came up with:

You can use the :BufClose command with or without an argument. The argument can be the filename associated with a buffer, or a buffer number. You don't have to be in the window that has the buffer open if you use an argument.

command! -nargs=? -complete=buffer -bang BufClose
 \ :call BufClose(expand('<args>'), expand('<bang>'))

function! BufClose(buffer, bang)
  if a:buffer == ''
    let buffer = bufnr('%')
  else
    let buffer = bufnr(a:buffer)
  endif
  if buffer == -1
    echohl ErrorMsg
    echomsg "No matching buffer for" a:buffer
    echohl None
    return
  endif
  let current_window = winnr()
  let buffer_window = bufwinnr(buffer)
  if buffer_window == -1
    echohl ErrorMsg
    echomsg "Buffer" buffer "isn't open in any windows."
    echohl None
    return
  endif
  if a:bang == '' && getbufvar(buffer, '&modified')
    echohl ErrorMsg
    echomsg 'No write since last change for buffer'
    \ buffer '(add ! to override)'
    echohl None
    return
  endif
  if buffer_window >= 0
    exe 'norm ' . buffer_window . "\<C-w>w"
    exe 'enew' . a:bang
    exe 'norm ' . current_window . "\<C-w>w"
  endif
  silent exe 'bdel' . a:bang . ' ' . buffer
endfunction

> Using :bd <bufferName> works fine for me.

The key part of this tip is deleting the buffer "without closing the window". Normally when you do a ":bd" it will close the window in the split.


Advertisement