How do I use Neovim's built-in lazy iterator API to chain filter and map operations over a list?
Answer
vim.iter()
Explanation
vim.iter() (Neovim 0.10+) is a built-in Lua API that wraps any table or iterator in a lazy iterator object, letting you chain operations like :filter(), :map(), :take(), :skip(), and :totable() in a readable, functional style — without loading plugins like Plenary or Underscore.
How it works
vim.iter(tbl)wraps a list or iterator:filter(fn)keeps only elements for whichfn(val)returns true:map(fn)transforms each element withfn(val)and returns the new value:each(fn)runsfn(val)for side effects without returning a new iterator:totable()collects the final result into a plain Lua table
Example
:lua =vim.iter({1, 2, 3, 4, 5}):filter(function(x) return x % 2 == 0 end):totable()
" → {2, 4}
" Get names of all listed buffers
:lua =vim.iter(vim.api.nvim_list_bufs()):filter(function(b)
return vim.bo[b].buflisted
end):map(function(b)
return vim.api.nvim_buf_get_name(b)
end):totable()
Tips
- Iterators are lazy — no work is done until
:totable(),:each(), or a consuming method is called - Works with both list-like tables (sequential) and iterator functions (e.g., from
ipairs(),pairs()) - Neovim's own
vim.apifunctions that return lists integrate naturally withvim.iter() - Requires Neovim ≥ 0.10; check with
vim.fn.has('nvim-0.10')