如何删除 Vim 中的多个缓冲区?

假设我在 Vim 中打开了多个文件作为缓冲区。文件有 *.cpp*.h和一些是 *.xml。我想用 :bd *.xml关闭所有 XML 文件。但是,Vim 不允许这样做(E93: 不止一个匹配...)。

有什么办法吗?

另外,我知道 :bd file1 file2 file3是有效的,那么我能以某种方式评估 *.xmlfile1.xml file2.xml file3.xml吗?

22491 次浏览

你可以用这个。

:exe 'bd '. join(filter(map(copy(range(1, bufnr('$'))), 'bufname(v:val)'), 'v:val =~ "\.xml$"'), ' ')

将它添加到命令中应该很容易。

function! s:BDExt(ext)
let buffers = filter(range(1, bufnr('$')), 'buflisted(v:val) && bufname(v:val) =~ "\.'.a:ext.'$"')
if empty(buffers) |throw "no *.".a:ext." buffer" | endif
exe 'bd '.join(buffers, ' ')
endfunction


command! -nargs=1 BDExt :call s:BDExt(<f-args>)

尝试下面的脚本,例如“ txt”,根据需要更改它,例如“ xml”。 未删除修改后的缓冲区。按 bd 键删除缓冲区。

map <Leader>bd :bufdo call <SID>DeleteBufferByExtension("txt")


function!  <SID>DeleteBufferByExtension(strExt)
if (matchstr(bufname("%"), ".".a:strExt."$") == ".".a:strExt )
if (! &modified)
bd
endif
endif
endfunction

[编辑] 同样没有: bufdo (根据 Luc Hermitte 的要求,参见下面的评论)

map <Leader>bd :call <SID>DeleteBufferByExtension("txt")


function!  <SID>DeleteBufferByExtension(strExt)
let s:bufNr = bufnr("$")
while s:bufNr > 0
if buflisted(s:bufNr)
if (matchstr(bufname(s:bufNr), ".".a:strExt."$") == ".".a:strExt )
if getbufvar(s:bufNr, '&modified') == 0
execute "bd ".s:bufNr
endif
endif
endif
let s:bufNr = s:bufNr-1
endwhile
endfunction

我也一直需要这个功能。这是我的 Vimrc 里的解决方案。

function! GetBufferList()
return filter(range(1,bufnr('$')), 'buflisted(v:val)')
endfunction


function! GetMatchingBuffers(pattern)
return filter(GetBufferList(), 'bufname(v:val) =~ a:pattern')
endfunction


function! WipeMatchingBuffers(pattern)
let l:matchList = GetMatchingBuffers(a:pattern)


let l:count = len(l:matchList)
if l:count < 1
echo 'No buffers found matching pattern ' . a:pattern
return
endif


if l:count == 1
let l:suffix = ''
else
let l:suffix = 's'
endif


exec 'bw ' . join(l:matchList, ' ')


echo 'Wiped ' . l:count . ' buffer' . l:suffix . '.'
endfunction


command! -nargs=1 BW call WipeMatchingBuffers('<args>')

现在,我只需要执行 :BW regex(例如 :BW \.cpp$)并擦除路径名中与该模式匹配的所有匹配缓冲区。

如果您想删除而不是擦除,当然可以用 exec 'bd ' . join(l:matchList, ' ')替换 exec 'bw ' . join(l:matchList, ' ')

可以使用 <C-a>完成所有匹配。因此,如果您键入 :bd *.xml,然后按 <C-a>,vim 将完成对 :bd file1.xml file2.xml file3.xml的命令。

非常简单: 使用 :bd[elete]命令。例如,:bd[elete] buf#1 buf#5 buf#3将删除缓冲区1、3和5。

你也可以选择使用:

    :.,$-bd[elete]    " to delete buffers from the current one to last but one
:%bd[elete]       " to delete all buffers

从 Vim 7.4.282开始,TAB将只为您自动完成一个文件
使用 <c-a>自动完成所有文件。

你可以用:

bd filetype

然后只需使用 <c-a>便于完成所有打开的指定文件类型的文件。

例如,您有1.xml、2.xml、3.xml 和4.xml, 你可以:

bd xml

然后按 <c-a>

Vim 会自动为您完成以下操作:

bd 1.xml 2.xml 3.xml 4.xml

你可以按回车键完成指令。

如果你已经对上面提到的文件进行了更改,请记住:

bd! xml
:3,5bd[elete]

将删除缓冲区范围从3到5。