Удаление всех пустых буферов в VIM

В Vim сейчас есть что-то вроде 120 буферов. Около 50% этих буферов - это пустые файлы. Я хотел бы как-то использовать bufdo!, чтобы закрыть все пустые буферы. Могу ли я сказать:

bufdo! (something)

Где (something) - условная команда, что bdelete текущий буфер IF длина/размер этого буфера равен нулю

Ответы

Ответ 1

Единственное, что я могу придумать для этого, - создать функцию, сообщающую, если буфер пуст или нет. Что-то вроде этого:

function! BufferIsEmpty()
    if line('$') == 1 && getline(1) == '' 
        return 1
    else
        return 0
    endif
endfunction

" Test it like this:
echo BufferIsEmpty()

Ответ 2

Поскольку нельзя влиять на список буферов с помощью команды :bufdo -argument (см. :help :bufdo), мы должны использовать более многословный, но довольно простой скрипт Vim.

Функция ниже перечисляет все существующие номера буферов и удаляет те, у которых нет имени (отображается как [No Name] в интерфейсе) и нет несохраненных изменений. (Последнее гарантируется командой :bdelete которая без знака ! Не удаляет измененный буфер).

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

Если вы хотите полностью удалить пустые буферы, включая незагруженные, подумайте (осторожно!) О замене bdelete на bwipeout (см :help :bd bwipeout :help :bd bwipeout :help :bw).

Чтобы проверить содержимое буфера для удаления, используйте getbufline(). Например, чтобы быть абсолютно уверенным в том, что буфер не содержит текста в нем, изменить, if выражение внутри в while циклы следующим образом.

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

Обратите внимание, что здесь bufexists() заменен на bufloaded(). Это необходимо, потому что можно получить содержимое только тех буферов, которые загружены (для незагруженных буферов getbufline() возвращает пустой список независимо от их содержимого).

Ответ 3

Я использовал следующую функцию для выполнения задания:

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

Он очень похож на версию ib, за исключением того, что он оставляет буфер quickfix отдельно (до тех пор, пока любой другой пустой буфер, который отображается в окне)