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

如何在Vim中删除多个缓冲区?,vim,buffer,Vim,Buffer,假设在Vim中有多个文件作为缓冲区打开。这些文件有*.cpp,*.h,还有一些是*.xml。我想用:bd*.XML关闭所有XML文件。但是,Vim不允许这样做(E93:多个匹配…) 有没有办法做到这一点 另外,我知道:bd file1 file2 file3有效。因此,我是否可以通过某种方式将*.xml评估为file1.xml file2.xml file3.xml?您可以使用这个 :exe 'bd '. join(filter(map(copy(range(1, bufnr('$'))), '

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

有没有办法做到这一点

另外,我知道
:bd file1 file2 file3
有效。因此,我是否可以通过某种方式将
*.xml
评估为
file1.xml file2.xml file3.xml

您可以使用这个

: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>)
函数!s:BDExt(ext)
让buffers=filter(范围(1,bufnr(“$”),“buflisted(v:val)”和&bufname(v:val)=~“\.”。a:ext.“$”)
如果为空(缓冲区)|抛出“否”。.a:ext.“buffer”| endif
exe“bd”。连接(缓冲区“”)
端功能
命令-nargs=1 BDExt:调用s:BDExt()

尝试下面的脚本。例如“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
映射bd:bufdo调用DeleteBufferByExtension(“txt”) 功能!DeleteBufferByExtension(strExt) if(matchstr(bufname(“%”),.a:strExt.“$”==”.a:strExt) 如果(!&修改) 屋宇署 恩迪夫 恩迪夫 端功能 [编辑] 相同,无:bufdo(根据Luc Hermitte的要求,见下文评论)

映射bd:调用DeleteBufferByExtension(“txt”)
功能!DeleteBufferByExtension(strExt)
设s:bufNr=bufNr(“$”)
而s:bufNr>0
如果已登记(s:bufNr)
if(matchstr(bufname(s:bufNr),“.a:strExt。”$”=“.a:strExt)
如果getbufvar(s:bufNr,“&modified')==0
执行“bd”。s:bufNr
恩迪夫
恩迪夫
恩迪夫
设s:bufNr=s:bufNr-1
循环结束
端功能

我也一直需要这个功能。这是我的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>')
函数!GetBufferList()
返回筛选器(范围(1,bufnr(“$”),“buflisted(v:val)”)
端功能
功能!GetMatchingBuffers(模式)
返回筛选器(GetBufferList(),'bufname(v:val)=~a:pattern')
端功能
功能!擦除匹配缓冲区(模式)
设l:matchList=GetMatchingBuffers(a:pattern)
设l:count=len(l:matchList)
如果l:计数<1
回显“未找到匹配模式的缓冲区”。a:式样
返回
恩迪夫
如果l:count==1
设l:后缀=“”
其他的
设l:后缀='s'
恩迪夫
执行“bw”。加入(l:匹配列表“”)
回声“抹去”。l:伯爵缓冲区'。l:后缀
端功能
命令-nargs=1 BW调用WipeMatchingBuffers(“”)
现在,我只需执行
:BW regex
(例如
:BW\.cpp$
)并擦除路径名中与该模式匹配的所有匹配缓冲区


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

您可以使用
完成所有匹配。因此,如果您键入
:bd*.xml
,然后点击
,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起,
选项卡将仅自动完成一个文件
使用
自动完成所有文件

您只需使用:

bd filetype
然后只需使用
来帮助完成指定文件类型的所有打开的文件

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

bd xml
然后按

vim将按如下方式为您自动完成:

bd 1.xml 2.xml 3.xml 4.xml
只需按enter键即可完成该命令

如果您对上述其中一个文件进行了更改,请记住执行以下操作:

bd! xml

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

我对Vimscript几乎一无所知,但glob()函数如何?
glob()将只提供现有文件(在硬盘上),而不会提供打开的缓冲区。您忘记了
fnameescape()
缓冲区名称。我刚刚检查了
c:/Program files/foo.bar
,甚至检查了
foo.bar.foo
,它工作得很好。
fnameescape()
如果我使用缓冲区名称,可能是必需的。但我只是检查缓冲区名称是否与给定的表达式匹配:
\.{ext}$
--我给:bd`提供缓冲区编号。我没有任何理由为了正则表达式匹配而转义任何内容。我不喜欢
:bufdo
,因为它会弄乱当前窗口。有时我想知道为什么vim不到处支持正则表达式(
:badd
:bdelete
:bufdo
:bn
)@Florian
只允许您循环匹配,在命令行上放置一个条目,
一次添加所有匹配项。天哪,您是对的!抱歉。选项卡仅在只有一个可能的结果时工作。如何在tmux上使用vim?tmux默认情况下不绑定,但如果您将其配置为例如使用而不是to模拟屏幕,您还应该将其配置为映射,例如,将a传递给在tmux中运行的程序。tmux附带的screen-keys.conf会执行该操作。JFTR,以防您安装了(我认为,对于*nix上的每个人来说,它都是必需的),要使
在命令行中以原始方式工作,您应该改用
。这很好。我使用a:ls查看缓冲区编号和它们:a,bbd删除从编号a到bIf的缓冲区。如果要删除单个缓冲区,如3和5,请使用
:bd 3 5
bd! xml
:3,5bd[elete]