Maneira eficiente de limpar a lista de buffer

Sep 02 2020

Muitas vezes, depois de dias e dias de codificação, abrindo vim -S sessiontodas as vezes, acabo com uma longa lista de buffer que desejo limpar.

Portanto, eu costumo :lslistar todos os buffers e, em seguida, :bdeletevárias vezes, com um intervalo de números de buffer e / ou especificando explicitamente os nomes de buffer.

Os pontos fracos desta abordagem são dois:

  1. se eu rodar :bdeleteem um único buffer, as linhas N buffers deletede Press ENTER or type command to continuenão aparecem, e a lista de buffer fecha, então tenho que rodar :lsnovamente, o que é muito chato;
  2. Tenho que correr :bdeletevárias vezes, o que é menos doloroso, mas ainda assim irritante.

Se houver uma maneira mais limpa de listar nomes de buffer não contíguos :bdelete, isso seria ótimo, pois resolveria 1 e 2; caso contrário, uma forma de evitar o fechamento da saída de :lsseria boa o suficiente, pois resolveria 2.

Edição importante

Não quero excluir nenhum buffer aberto em uma janela de qualquer guia.

Respostas

4 Matt Sep 02 2020 at 11:23

Para minha configuração, escrevi isto:

~ / .vim / autoload / misc.vim

" Wipe all deleted (unloaded & unlisted) or all unloaded buffers
function! misc#bwipeout(listed) abort
    let l:buffers = filter(getbufinfo(), {_, v -> !v.loaded && (!v.listed || a:listed)})
    if !empty(l:buffers)
        execute 'bwipeout' join(map(l:buffers, {_, v -> v.bufnr}))
    endif
endfunction

~ / .vim / vimrc

" :Bwipeout[!]
" wipe all deleted/unloaded buffers
command! -bar -bang Bwipeout call misc#bwipeout(<bang>0)

Agora faça :Bwipeout!para limpar toda a bagunça.

Nota: :bwipeoutdifere :bdeleteporque realmente exclui o buffer, enquanto :bdeletemantém o nome / número / marcadores locais para reutilização posterior. Você pode ver todos os buffers "excluídos" pelo comando :ls!.

Se ainda quiser fazer uso, :bdeletevocê pode adaptar o código facilmente:

function s:bdelete() abort
    let l:buffers = filter(getbufinfo(), {_, v -> !v.loaded && v.listed})
    if !empty(l:buffers)
        execute 'bdelete' join(map(l:buffers, {_, v -> v.bufnr}))
    endif
endfunction
command! -bar Bdelete call s:bdelete()
3 MaximKim Sep 02 2020 at 11:42

Para minha configuração, escrevi isto:

" kill-all but visible buffers
nnoremap <silent> <M-BS> :call Delete_buffers()<CR>:echo "Non-windowed buffers are deleted"<CR>

"" Delete all(saved) but visible buffers
func! Delete_buffers()
    " all visible buffers in all tabs
    let buflist = []
    for i in range(tabpagenr('$')) call extend(buflist, tabpagebuflist(i + 1)) endfor " all existing buffers for bnr in range(1, bufnr("$"))
        if index(buflist, bnr) == -1 && buflisted(bnr)
            exe 'bd ' . bnr
        endif
    endfor
endfunc

Então, Alt+Backspacetodos os buffers, exceto os atualmente visíveis nas janelas divididas, são excluídos.

Muito prático para salvar / atualizar a sessão sem um monte de buffers desnecessários.

PS, atualizado para não excluir buffers em outras guias.

PPS, thx @matt, versão melhor:

func! Delete_buffers()
    let l:buffers = filter(getbufinfo(), {_, v -> v.hidden})
    if !empty(l:buffers)
        execute 'bwipeout' join(map(l:buffers, {_, v -> v.bufnr}))
    endif
endfunc