如何减少缓冲区列表以仅包含当前在窗口/选项卡中打开的缓冲区?
当我长时间运行Vim时,该:ls命令显示的缓冲区列表太大而无法使用.理想情况下,我想通过运行自定义命令(例如,删除)在选项卡或窗口中当前不可见的所有缓冲区:Only.任何人都可以建议如何实现这一目标?
看起来该:bdelete命令可以接受缓冲区编号列表,但我不确定如何将输出转换为:ls可由:bdelete命令使用的格式.任何帮助,将不胜感激.
让我们说在我的Vim会话中我打开了4个文件.的:ls命令输出:
:ls
1 a "abc.c"
2 h "123.c"
3 h "xyz.c"
4 a "abc.h"
Run Code Online (Sandbox Code Playgroud)
缓冲区1位于当前选项卡中,缓冲区4位于单独的选项卡中,但缓冲区2和3都是隐藏的.我想运行该命令:Only,它将擦除缓冲区2和3,因此:ls命令将输出:
:ls
1 a "abc.c"
4 a "abc.h"
Run Code Online (Sandbox Code Playgroud)
此示例不会使建议的:Only命令看起来非常有用,但如果您有40个缓冲区的列表,那将非常受欢迎.
nel*_*rom 11
command! -nargs=* Only call CloseHiddenBuffers()
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 are loaded and not visible
let l:tally = 0
for b in range(1, bufnr('$'))
if bufloaded(b) && !has_key(visible, b)
let l:tally += 1
exe 'bw ' . b
endif
endfor
echon "Deleted " . l:tally . " buffers"
endfun
Run Code Online (Sandbox Code Playgroud)
我将其更改为使用bwipeout而不是bdelete,并添加了消息以显示已删除了多少缓冲区.
你在找:
:echo map(filter(range(0, bufnr('$')), 'bufwinnr(v:val)>=0'), 'bufname(v:val)')
Run Code Online (Sandbox Code Playgroud)
或者更准确地说:
exe 'bw '.join(filter(range(0, bufnr('$')), 'bufwinnr(v:val)<0'), ' ')
Run Code Online (Sandbox Code Playgroud)
?
编辑:上一个答案没有考虑多个标签.
我似乎使用了一种复杂的方法.打开和显示的缓冲区列表可以通过以下方式获得tabpagebuflist():
let tabs = range(1, tabpagenr())
echo lh#list#unique_sort(eval(join(map(tabs, 'tabpagebuflist(v:val)'), '+')))
Run Code Online (Sandbox Code Playgroud)
(lh#list#unique_sort()来自lh-vim-lib,它定义了vim不提供的sort + unique函数)
为了拥有非打开的缓冲区,它变得有点棘手.我们使用每个选项卡的循环来获取未显示的缓冲区,或者我们在前一个结果和bufexisting缓冲区之间进行区分:
let tabs = range(1, tabpagenr())
let windowed = lh#list#unique_sort(eval(join(map(tabs, 'tabpagebuflist(v:val)'), '+')))
let existing = filter(range(0,bufnr('$')), 'bufexists(v:val)')
let non_windowed = filter(copy(existing), 'match(windowed, "^".v:val."$")<0')
echo non_windowed
Run Code Online (Sandbox Code Playgroud)