How to delete multiple buffers in Vim?

后端 未结 8 1323
北恋
北恋 2021-01-29 18:51

Assuming I have multiple files opened as buffers in Vim. The files have *.cpp, *.h and some are *.xml. I want to close all the XML files w

相关标签:
8条回答
  • 2021-01-29 19:24
    :3,5bd[elete]   
    

    Will delete buffer range from 3 to 5 .

    0 讨论(0)
  • 2021-01-29 19:26

    Try the script below. The example is for "txt", change it as needed, e.g. to "xml". Modified buffers are not deleted. Press \bd to delete the buffers.

    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
    

    [Edit] Same without :bufdo (as requested by Luc Hermitte, see comment below)

    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
    
    0 讨论(0)
  • 2021-01-29 19:27

    I too had a need for this functionality all the time. This is the solution I have in my 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>')
    

    Now, I can just do :BW regex (e.g. :BW \.cpp$ and wipe all matching buffers that have match that pattern in their pathname.

    If you want to delete rather than wipe, you can of course replace exec 'bw ' . join(l:matchList, ' ') with exec 'bd ' . join(l:matchList, ' ')

    0 讨论(0)
  • 2021-01-29 19:35

    You can use <C-a> to complete all matches. So if you type :bd *.xml and then hit <C-a>, vim will complete the command to :bd file1.xml file2.xml file3.xml.

    0 讨论(0)
  • 2021-01-29 19:42

    You also can use alternatively use:

        :.,$-bd[elete]    " to delete buffers from the current one to last but one
        :%bd[elete]       " to delete all buffers
    
    0 讨论(0)
  • 2021-01-29 19:46

    You can use this.

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

    It should be quite easy to add it to a command.

    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>)
    
    0 讨论(0)
提交回复
热议问题