8

Let's say I have a vertical split, and four buffers open.

I'd like to be able to have one buffer open on the left, and cycle through just the other three on the right. Something like :bnext but skipping open/visible buffers.

Kites
  • 183
  • 3

2 Answers2

6

This is a good new feature idea

Here is another implementation. This one will ignore unlisted buffers, and also it won't rely on a global to decide which is next. Instead the next definition is relative to the current buffer number.

nnoremap <silent> <Plug>CycleToNextBuffer :call <sid>CycleToNext('after')<cr>
if !hasmapto('<Plug>CycleToNextBuffer', 'n')
  nmap <silent> <unique> <F12> <Plug>CycleToNextBuffer
endif
nnoremap <silent> <Plug>CycleToPreviousBuffer :call <sid>CycleToNext('before')<cr>
if !hasmapto('<Plug>CycleToPreviousBuffer', 'n')
  nmap <silent> <unique> <F11> <Plug>CycleToPreviousBuffer
endif

function! s:CycleToNext(direction) abort
  let undisplayed_buffers = filter(range(1, bufnr('$')), 'buflisted(v:val) && bufwinnr(v:val) == -1')
  if empty(undisplayed_buffers)
    echomsg "No hidden (listed) buffer to jump to"
    return
  endif
  if a:direction == 'next'
    let after = filter(copy(undisplayed_buffers), 'v:val > bufnr("%")')
    let buf = empty(after) ? undisplayed_buffers[0] : after[0]
  else
    let before = filter(copy(undisplayed_buffers), 'v:val < bufnr("%")')
    let buf = empty(before) ? undisplayed_buffers[-1] : before[-1]
  endif
  silent exe 'b '.buf
endfunction
saginaw
  • 6,756
  • 2
  • 26
  • 47
Luc Hermitte
  • 17,351
  • 1
  • 33
  • 49
5

This is barely tested, but should work:

    fu! CycleBuffer()
        let i=get(s:, 'cycle_bufnr', 0)%bufnr('$')+1
        while bufwinnr(i) > 0
            let i+=1
        endw
        if i > bufnr('$')
            echomsg 'There is no buffer to cycle to!'
        else
            exe i.'b'
            let s:cycle_bufnr=i
        endif
    endfu
    com! CycleBuffer :call CycleBuffer()

Call :CycleBuffer to advance to the next buffer, that is not visible.

Christian Brabandt
  • 25,820
  • 1
  • 52
  • 77