Consider the following script:


var buffer_info = getbufinfo()

g:buflist = []
for dd in getbufinfo()
    add(g:buflist, dd['bufnr'])

def g:BufListRemove()
  # If the buffer is in the buffer list, then remove it.
  var idx = index(g:buflist, bufnr())
  if idx != -1
    remove(g:buflist, idx)

augroup myaugroup
    autocmd BufDelete,BufWipeout * g:BufListRemove()
augroup END

Say that I have 4 buffers opened, numbered from 1 to 4. Hence, echo g:buflist (after having run the above script) returns [1, 2, 3, 4], which is fine.

Say now that the current buffer is 4 and I run :bw. Then, echo g:buflist correctly returns [1, 2, 3].

The problem arise when the wiped out (or deleted) buffer is not %.

Foe example, If the current buffer is 3 and I run :bw1, then echo g:buflist returns [1, 2].

Inspection of the documentation of BufWipeout (same for BufDelete) say that

NOTE:           When this autocommand is executed, the
                current buffer "%" may be different from the
                buffer being deleted "<afile>".
                Don't change to another buffer, it will cause

But then I have no idea on how to circumnavigate this note.

What I want is that if I run e.g. :bw1 , then the item 1 is removed from g:buflist and not the current buffer.

How to achieve that?

  • 2
    Try using expand('<afile>')
    – D. Ben Knoble
    Commented Apr 10, 2023 at 14:24
  • 1
    … almost. I had to str2nr(expand(‘<abuf>’) instead of bufnr(). That solved.
    – Barzi2001
    Commented Apr 10, 2023 at 15:11
  • 1
    Feel free to post a self-answer.
    – D. Ben Knoble
    Commented Apr 10, 2023 at 17:45

1 Answer 1


I had to replace the line:

var idx = index(g:buflist, bufnr())

with the line:

var idx = index(g:buflist, str2nr(expand('<abuf>'))

See :h <abuf> and :h expand() for more information.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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