5

Given a buffer number i, I want to check if the buffer has been modified after the last save. How do I do that in vimscript?

I tried to use getbufvar() like the following:

if getbufvar(i, "&modified") echo "Modified" else echo "Not Modified" endif 

but this always seems to echo "Modified". What am I doing wrong?

2
  • 4
    I fail to see why getbufvar(bufnr, '&mod') fails to work in your case. Are you sure you're using the right buffer id? For instance, in some autocommand cases, it's easy to get confused and use '%' instead of <amatch> Commented Jun 5, 2020 at 0:08
  • 1
    Luc is right. Your problem lies somewhere else. The most typical error is getbufvar(expand('<abuf>'), ...). Commented Jun 5, 2020 at 4:10

1 Answer 1

11

You could work with getbufinfo(). Note that this function always returns a list of dictionaries.

if getbufinfo(i)[0].changed echo "Modified" else echo "Not Modified" endif 

Note that this will fail, if the buffer with the number i does not exist.

BTW: If you want to know all changed buffers do:

for buf in getbufinfo({'bufmodified': 1}) echo buf.bufnr endfor 

If you want to know about the current buffer do:

if getbufinfo('%')[0].changed echo "Modified" else echo "Not modified" endif 

See :h getbufinfo for the details.

4
  • 2
    Or :echo getbufinfo({'bufmodified': 1})->map({ _, b -> b.bufnr })->join(',') Commented Jun 4, 2020 at 22:36
  • @D.BenKnoble Is that supposed to work as is? It's getting me an "using List as String" error. Commented Feb 23, 2021 at 16:28
  • @D.BenKnoble I can get echo join(map(getbufinfo({'bufmodified': 1}), { _,b -> b.bufnr }),",") to work, but not with the -> syntax. Commented Feb 23, 2021 at 16:36
  • 2
    @PSkocik it works for me; perhaps your vim is a little older and you don't have method syntax. In either case, it's syntax sugar for what you wrote. Commented Feb 23, 2021 at 17:09

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.