How do I close all buffers that aren't shown in a window in vim?

后端 未结 5 1650
野趣味
野趣味 2020-12-23 16:23

I have a horde of buffers open in vim, with only a few of them open in split windows or on other tabs. Is there a way to close all but the ones that are currently visible i

相关标签:
5条回答
  • 2020-12-23 17:02

    Here's an alternative solution you can drop in your .vimrc:

    function! Wipeout()
      " list of *all* buffer numbers
      let l:buffers = range(1, bufnr('$'))
    
      " what tab page are we in?
      let l:currentTab = tabpagenr()
      try
        " go through all tab pages
        let l:tab = 0
        while l:tab < tabpagenr('$')
          let l:tab += 1
    
          " go through all windows
          let l:win = 0
          while l:win < winnr('$')
            let l:win += 1
            " whatever buffer is in this window in this tab, remove it from
            " l:buffers list
            let l:thisbuf = winbufnr(l:win)
            call remove(l:buffers, index(l:buffers, l:thisbuf))
          endwhile
        endwhile
    
        " if there are any buffers left, delete them
        if len(l:buffers)
          execute 'bwipeout' join(l:buffers)
        endif
      finally
        " go back to our original tab page
        execute 'tabnext' l:currentTab
      endtry
    endfunction
    

    Use :call Wipeout().

    0 讨论(0)
  • 2020-12-23 17:07

    Yet another take on this. Using the example given in the Vim help for tabpagebuflist() to get a list of the buffers that appear in a tab or window. I have the below in my .vimrc

    function! DeleteInactiveBufs()
        "From tabpagebuflist() help, get a list of all buffers in all tabs
        let tablist = []
        for i in range(tabpagenr('$'))
            call extend(tablist, tabpagebuflist(i + 1))
        endfor
    
        "Below originally inspired by Hara Krishna Dara and Keith Roberts
        "http://tech.groups.yahoo.com/group/vim/message/56425
        let nWipeouts = 0
        for i in range(1, bufnr('$'))
            if bufexists(i) && !getbufvar(i,"&mod") && index(tablist, i) == -1
            "bufno exists AND isn't modified AND isn't in the list of buffers open in windows and tabs
                silent exec 'bwipeout' i
                let nWipeouts = nWipeouts + 1
            endif
        endfor
        echomsg nWipeouts . ' buffer(s) wiped out'
    endfunction
    command! Bdi :call DeleteInactiveBufs()
    
    0 讨论(0)
  • 2020-12-23 17:15

    There's a plugin that does exactly this and a bit more!

    Check out close-buffers.vim

    0 讨论(0)
  • 2020-12-23 17:22

    I know why the second script doesn't work properly.

    This is due to the bufloaded() function which must be bufexits() !

    Indeed, a buffer to delete is not loaded ! Just remove this condition is okay but it is doing some warning when we are trying to wipe out a buffer not used so we have to use bufexists(b).

    The final solution is the following:

    function! CloseHiddenBuffers()
        " Tableau pour memoriser la visibilite des buffers                                                                                      
        let visible = {}
        " Pour chaque onglet...
        for t in range(1, tabpagenr('$'))
            " Et pour chacune de ses fenetres...
            for b in tabpagebuflist(t)
                " On indique que le buffer est visible.
                let visible[b] = 1
            endfor
        endfor
        " Pour chaque numero de buffer possible...
        for b in range(1, bufnr('$'))
            " Si b est un numero de buffer valide et qu'il n'est pas visible, on le
            " supprime.
            if bufexists(b) && !has_key(visible, b)
                " On ferme donc tous les buffers qui ne valent pas 1 dans le tableau et qui
                " sont pourtant charges en memoire.
                execute 'bwipeout' b
            endif
        endfor
    endfun
    

    Thanks to you.

    0 讨论(0)
  • 2020-12-23 17:28

    Add this to your .vimrc:

    function! CloseHiddenBuffers()
      let i = 0
      let n = bufnr('$')
      while i < n
        let i = i + 1
        if bufloaded(i) && bufwinnr(i) < 0
          exe 'bd ' . i
        endif
      endwhile
    endfun
    

    Then you can do this to close hidden buffers:

    :call CloseHiddenBuffers()
    

    (You'll probably want to bind a key or a command to it.)

    Update:

    Here's a version updated to support tab pages. (I don't use tab pages myself, so I hadn't realized that bufwinnr only works for windows on the current page).

    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's loaded and not visible
      for b in range(1, bufnr('$'))
        if bufloaded(b) && !has_key(visible, b)
          exe 'bd ' . b
        endif
      endfor
    endfun
    
    0 讨论(0)
提交回复
热议问题