如何关闭vim中窗口中未显示的所有缓冲区?

时间:2009-10-07 23:47:09

标签: vim

我在vim中打开了大量缓冲区,只有少数缓冲区在分割窗口或其他选项卡上打开。有没有办法关闭除了其中一个分割或标签中当前可见的所有内容?

6 个答案:

答案 0 :(得分:26)

还有另一种看法。使用Vim帮助中给出的示例tabpagebuflist()来获取选项卡或窗口中显示的缓冲区列表。我的.vimrc

中有以下内容
function! DeleteInactiveBufs()
    "From tabpagebuflist() help, get a list of all buffers in all tabs
    let tablist = []
    for i in range(tabpagenr('$'))
        call extend(tablist, tabpagebuflist(i + 1))
    endfor

    "Below originally inspired by Hara Krishna Dara and Keith Roberts
    "http://tech.groups.yahoo.com/group/vim/message/56425
    let nWipeouts = 0
    for i in range(1, bufnr('$'))
        if bufexists(i) && !getbufvar(i,"&mod") && index(tablist, i) == -1
        "bufno exists AND isn't modified AND isn't in the list of buffers open in windows and tabs
            silent exec 'bwipeout' i
            let nWipeouts = nWipeouts + 1
        endif
    endfor
    echomsg nWipeouts . ' buffer(s) wiped out'
endfunction
command! Bdi :call DeleteInactiveBufs()

答案 1 :(得分:21)

以下是您可以放入.vimrc

的替代解决方案
function! Wipeout()
  " list of *all* buffer numbers
  let l:buffers = range(1, bufnr('$'))

  " what tab page are we in?
  let l:currentTab = tabpagenr()
  try
    " go through all tab pages
    let l:tab = 0
    while l:tab < tabpagenr('$')
      let l:tab += 1

      " go through all windows
      let l:win = 0
      while l:win < winnr('$')
        let l:win += 1
        " whatever buffer is in this window in this tab, remove it from
        " l:buffers list
        let l:thisbuf = winbufnr(l:win)
        call remove(l:buffers, index(l:buffers, l:thisbuf))
      endwhile
    endwhile

    " if there are any buffers left, delete them
    if len(l:buffers)
      execute 'bwipeout' join(l:buffers)
    endif
  finally
    " go back to our original tab page
    execute 'tabnext' l:currentTab
  endtry
endfunction

使用:call Wipeout()

答案 2 :(得分:8)

将此添加到.vimrc:

function! CloseHiddenBuffers()
  let i = 0
  let n = bufnr('$')
  while i < n
    let i = i + 1
    if bufloaded(i) && bufwinnr(i) < 0
      exe 'bd ' . i
    endif
  endwhile
endfun

然后你可以这样做来关闭隐藏的缓冲区:

:call CloseHiddenBuffers()

(您可能希望将键或命令绑定到它。)

<强>更新

这是更新版本以支持标签页。 (我自己不使用标签页,所以我没有意识到bufwinnr仅适用于当前页面上的窗口。)

function! CloseHiddenBuffers()
  " figure out which buffers are visible in any tab
  let visible = {}
  for t in range(1, tabpagenr('$'))
    for b in tabpagebuflist(t)
      let visible[b] = 1
    endfor
  endfor
  " close any buffer that's loaded and not visible
  for b in range(1, bufnr('$'))
    if bufloaded(b) && !has_key(visible, b)
      exe 'bd ' . b
    endif
  endfor
endfun

答案 3 :(得分:3)

我知道为什么第二个脚本无法正常工作。

这是由于bufloaded()函数必须是bufexits()!

确实,没有加载要删除的缓冲区!只是删除这个条件是可以的,但当我们试图消灭未使用的缓冲区时它会发出警告,所以我们必须使用bufexists(b)。

最终解决方案如下:

function! CloseHiddenBuffers()
    " Tableau pour memoriser la visibilite des buffers                                                                                      
    let visible = {}
    " Pour chaque onglet...
    for t in range(1, tabpagenr('$'))
        " Et pour chacune de ses fenetres...
        for b in tabpagebuflist(t)
            " On indique que le buffer est visible.
            let visible[b] = 1
        endfor
    endfor
    " Pour chaque numero de buffer possible...
    for b in range(1, bufnr('$'))
        " Si b est un numero de buffer valide et qu'il n'est pas visible, on le
        " supprime.
        if bufexists(b) && !has_key(visible, b)
            " On ferme donc tous les buffers qui ne valent pas 1 dans le tableau et qui
            " sont pourtant charges en memoire.
            execute 'bwipeout' b
        endif
    endfor
endfun

谢谢你。

答案 4 :(得分:2)

有一个插件可以做到这一点,还有更多!

查看 close-buffers.vim

答案 5 :(得分:0)

如果您使用 fzf,这里有一种选择要删除的缓冲区的方法:

" fzf delete buffers
function! s:list_buffers()
  redir => list
  silent ls
  redir END
  return split(list, "\n")
endfunction
function! s:delete_buffers(lines)
  execute 'bwipeout' join(map(a:lines, {_, line -> split(line)[0]}))
endfunction
command! BD call fzf#run(fzf#wrap({
  \ 'source': s:list_buffers(),
  \ 'sink*': { lines -> s:delete_buffers(lines) },
  \ 'options': '--multi --reverse --bind ctrl-a:select-all+accept'
  \ }))