How to delete all empty buffers in Vim?

The only thing that I can think of for this is to make a function that reports if the buffer is empty or not. Something like this:

function! BufferIsEmpty()
    return line('$') == 1 && getline(1) == '' 
endfunction

I've been using the following function to do the job:

function! s:CleanEmptyBuffers()
    let buffers = filter(range(1, bufnr('$')), 'buflisted(v:val) && empty(bufname(v:val)) && bufwinnr(v:val)<0 && !getbufvar(v:val, "&mod")')
    if !empty(buffers)
        exe 'bw ' . join(buffers, ' ')
    endif
endfunction

It's very similar to ib's version except that it leaves the quickfix buffer alone (as long as any other empty buffer that is displayed in a window)


Since it is not allowed to affect the buffer list with a :bufdo-argument command (see :help :bufdo), we have to use a more wordy yet fairly straightforward Vim script.

The function below enumerates all existing buffer numbers and deletes those that do not have a name (displayed as [No Name] in the interface) nor any unsaved changes. The latter condition is guaranteed through the invocation of the :bdelete command without the trailing ! sign, in which case modified buffers are skipped.

function! DeleteEmptyBuffers()
    let [i, n; empty] = [1, bufnr('$')]
    while i <= n
        if bufexists(i) && bufname(i) == ''
            call add(empty, i)
        endif
        let i += 1
    endwhile
    if len(empty) > 0
        exe 'bdelete' join(empty)
    endif
endfunction

If you would like to delete empty buffers completely, including the unloaded ones, consider (with care!) replacing the exe 'bdelete' with exe 'bwipeout' (see :help :bd, :help :bw).

To test the contents of a buffer, use the getbufline() function. For instance, to be absolutely sure that the buffer contains no text in it, modify the if statement inside the while loop as follows:

        if bufloaded(i) && bufname(i) == '' && getbufline(i, 1, 2) == ['']

Note that bufexists() is changed to bufloaded() here. It is necessary because it is possible to get the contents only of those buffers that are loaded; for unloaded buffers getbufline() returns an empty list regardless of their contents.

Tags:

Vim