我在vim中打开了大量缓冲区,只有少数缓冲区在分割窗口或其他选项卡上打开。有没有办法关闭除了其中一个分割或标签中当前可见的所有内容?
答案 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)
有一个插件可以做到这一点,还有更多!
答案 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'
\ }))