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.
Vi and Vim Stack Exchange is a question and answer site for people using the vi and Vim families of text editors. It only takes a minute to sign up.
Sign up to join this communityLet'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.
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
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.