1
\$\begingroup\$

The function below is written in Lua and returns the list of buffers from the current neovim session, it also allows the option to specify a optional table (object) as a parameter, with a listed property to filter the type of buffer returned by the function (only listed buffers, or every single one).

local function get_buffers(options)
 local buffers = {}
 for buffer = 1, vim.fn.bufnr('$') do
 local is_listed = vim.fn.buflisted(buffer) == 1
 if options.listed and is_listed then
 table.insert(buffers, buffer)
 else
 table.insert(buffers, buffer)
 end
 end
 return buffers
end
return get_buffers

The if..else part seems a little bit off for me, I'm not sure if it can be improved, but something tells me that there's some way to make this less repetitive

mdfst13
22.4k6 gold badges34 silver badges70 bronze badges
asked Sep 19, 2021 at 0:36
\$\endgroup\$

2 Answers 2

3
\$\begingroup\$

The only case when you don't want a buffer included is when

  • options.listed is truthy and
  • is_listed is falsy

In every other case you want it included. If my understanding is correct you can simplify the if to a single branch:

 ...
 local is_listed = vim.fn.buflisted(buffer) == 1
 if not (options.listed and is_listed) then
 table.insert(buffers, buffer)
 end
 ...

That code is still calculating is_listed on every iteration. If you move it inside the conditional and remove the parenthesis, the code will be a bit more efficient (is_listed won't be calculated at all when options.listed is falsy)

 ...
 if not options.listed or vim.fn.buflisted(buffer) ~= 1 then
 table.insert(buffers, buffer)
 end
 ...

I think that is good enough. There's some extra perf changes chat can be done. options.listed and vim.fn could be localized into a local variable to make it slightly faster, too. And using table.insert is slower than direct table insertion. Final result:

local function get_buffers(options)
 local buffers = {}
 local len = 0
 local options_listed = options.listed
 local vim_fn = vim.fn
 local buflisted = vim_fn.buflisted
 for buffer = 1, vim_fn.bufnr('$') do
 if not options_listed or buflisted(buffer) ~= 1 then
 len = len + 1
 buffers[len] = buffer
 end
 end
 return buffers
end

There is an API question that is still worth mentioning. In most cases, I try to avoid boolean parameters completely. Instead, consider using two functions: get_all_buffers() (no params) to get all buffers, and get_listed_buffers() (no params) to get only the listed buffers.

answered Sep 23, 2021 at 11:32
\$\endgroup\$
0
3
\$\begingroup\$

The code in your if and else branches is identical.

table.insert(buffers, buffer)

I prefer to use neovim api functions over similar vim functions (bufnr, buflisted).

nvim_list_bufs() gets the current list of buffer handles, and nvim_buf_is_loaded() checks if a buffer is valid and loaded.

Here's an example that returns the buffers that are loaded.

function get_bufs_loaded()
 local bufs_loaded = {}
 for i, buf_hndl in ipairs(vim.api.nvim_list_bufs()) do
 if vim.api.nvim_buf_is_loaded(buf_hndl) then
 bufs_loaded[i] = buf_hndl
 end
 end
 return bufs_loaded
end
answered Dec 26, 2022 at 21:42
\$\endgroup\$
1
  • 1
    \$\begingroup\$ I'm not saying this is a bad answer, but you might want to read How do I write a good answer. The more insightful observations you make about the code in the question the better your answer will be. \$\endgroup\$ Commented Dec 26, 2022 at 22:29

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

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

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.