0

When we have a buffer open, and we open a new one with :split or :vsplit, if in any opened window we execute :bprev or :bnext, we could have the same buffer open at the same time in both windows.

Is there any option (if any I will try with a vimscript) to not have the same same buffer open in multiple windows (e.g. don't show it in the new window if it's already open in another one, all in the same tab) while cycling through buffer list ?

  • 1
    I will try and come up with something. But for you and anyone else who is trying, my primary idea is to use the flag a of vims :ls command. A function which checks if a buffer is already active and acts accordingly is all there is to it. – klaus Jun 1 '18 at 13:19
  • Yes, this is something I thought for a vimscript. – simo-zz Jun 1 '18 at 13:20
  • Dare I say this is a duplicate of vi.stackexchange.com/questions/5643/… ? You'll find there an efficient solution that I've implemented and shared at github.com/LucHermitte/lh-misc/blob/master/plugin/… – Luc Hermitte Jun 1 '18 at 15:28
2

You need these following functions:

function! BetterBufferNext() abort

  for b in range(bufnr('%')+1, bufnr('$'))
    if buflisted(b) && bufwinnr(b)==-1
      exe "normal! :b".b."\<cr>"
      return
    endif
  endfor

  for b in range(1, bufnr('%')-1)
    if buflisted(b) && bufwinnr(b)==-1
      exe "normal! :b".b."\<cr>"
      return
    endif
  endfor

endfunction

function! BetterBufferPrev() abort

  for b in range(bufnr('%')-1, 1, -1)
    if buflisted(b) && bufwinnr(b)==-1
      exe "normal! :b".b."\<cr>"
      return
    endif
  endfor

  for b in range(bufnr('$'), bufnr('%')+1, -1)
    if buflisted(b) && bufwinnr(b)==-1
      exe "normal! :b".b."\<cr>"
      return
    endif
  endfor

endfunction

nnoremap <silent> <F7> :call BetterBufferPrev()<cr>
nnoremap <silent> <F8> :call BetterBufferNext()<cr>

Don't use my horrible provided mappings, use your own. Maybe something like [b and ]b. Or maybe even,

command! Bp call BetterBufferPrev()
command! Bn call BetterBufferNext()
  • 2
    Are you sure this is really what the OP is looking for? bufloaded() is about buffers being in memory, not about them being displayed somewhere. – Luc Hermitte Jun 1 '18 at 17:27
  • @LucHermitte I seem to have misunderstood the use bufloaded(). Thank you for noticing. But I don't have any idea how to check if a buffer is active. Do you? – klaus Jun 1 '18 at 17:40
  • 2
    Let's say I open file foo.txt, and that it's bufnr('%') is 22. If I close the file with :q, the file is still loaded (bufloaded(22) -> 1). You should have used bufwinnr() -- As I understand OP's expressed need, see the other Q/A that this one duplicates – Luc Hermitte Jun 1 '18 at 17:42
  • @LucHermitte After reading :h bufwinnr() I think I need only to replace !bufloaded() with !bufwinnr(). Is that correct? – klaus Jun 1 '18 at 17:45
  • 2
    Almost. 0 is a valid value. The result should be compared to -1 -> let undisplayed_buffers = filter(range(1, bufnr('$')), 'buflisted(v:val) && bufwinnr(v:val) == -1') – Luc Hermitte Jun 1 '18 at 17:47

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.