【问题标题】:How to delete multiple buffers in Vim?如何在 Vim 中删除多个缓冲区?
【发布时间】:2010-07-01 06:16:06
【问题描述】:

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

有什么办法吗?

附:我知道:bd file1 file2 file3 有效。那么我可以以某种方式将*.xml 评估为file1.xml file2.xml file3.xml 吗?

【问题讨论】:

    标签: vim buffer


    【解决方案1】:

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

    【讨论】:

    • @Florian <tab> 只允许您在匹配项中循环,在命令行上放置一个条目,<C-a> 一次添加所有匹配项。
    • 天哪,你是对的!对不起。只有一个可能的结果时,选项卡才会起作用。
    • 如何在 tmux 上使用 和 vim?
    • tmux 默认情况下不绑定 ,但如果您将其配置为例如使用 而不是 来模拟屏幕,您还应该将其配置为映射,例如,a 将 传递给在 tmux 内部运行的程序。 tmux 自带的 screen-keys.conf 就是这样做的。
    • JFTR,如果您安装了vim-rsi(我认为,*nix 上的每个人都必须拥有它),要让<C-a> 在命令行中以原始方式工作,您应该请改用<C-x> <C-a>
    【解决方案2】:
    :3,5bd[elete]   
    

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

    【讨论】:

    • 如果要删除3、5等单个缓冲区,请使用:bd 3 5
    【解决方案3】:

    你也可以选择使用:

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

    【讨论】:

    • 这很好用。我做了一个 :ls 来查看缓冲区编号,他们 :a,bbd 来删除从编号 a 到 b 的缓冲区
    【解决方案4】:

    你可以使用它。

    :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>)
    

    【讨论】:

    • 我对 Vimscript 几乎一无所知,但是 glob() 函数呢?
    • glob() 只会给你现有的文件(在你的硬盘上),而不是打开的缓冲区。
    • 您忘记了fnameescape() 缓冲区名称。
    • 我刚刚检查了c:/Program files/foo.bar,甚至foo.bar.foo,它运行良好。如果我使用缓冲区名称,可能需要fnameescape()。但我只检查缓冲区名称是否与给定表达式匹配:\.{ext}$——我将缓冲区编号分配给 :bd`。我没有任何理由逃避任何正则表达式匹配。
    【解决方案5】:

    试试下面的脚本。示例是“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
    

    【讨论】:

    • 我不喜欢:bufdo,因为它弄乱了当前窗口。
    【解决方案6】:

    TAB 从 Vim 7.4.282 开始只会为你自动完成一个文件
    使用&lt;c-a&gt; 自动完成所有文件。

    你可以使用:

    bd filetype
    

    那么就用&lt;c-a&gt;方便完成所有打开的指定文件类型的文件。

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

    bd xml
    

    然后按&lt;c-a&gt;

    vim 会自动完成如下:

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

    您只需按 Enter 键即可完成命令。

    如果您对上述文件之一进行了更改,请记住:

    bd! xml
    

    【讨论】:

      【解决方案7】:

      我也一直需要这个功能。这是我在 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 'bw ' . join(l:matchList, ' ')替换为exec 'bd ' . join(l:matchList, ' ')

      【讨论】:

      • 我有时想知道为什么 vim 不支持所有地方的正则表达式(:badd:bdelete:bufdo:bn...)
      【解决方案8】:

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

      【讨论】:

        猜你喜欢
        • 2010-11-19
        • 2011-09-26
        • 1970-01-01
        • 1970-01-01
        • 2021-09-03
        • 2012-09-19
        • 1970-01-01
        • 1970-01-01
        • 2011-05-23
        相关资源
        最近更新 更多