aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGregory Anders <greg@gpanders.com>2023-04-24 19:57:40 -0600
committerGregory Anders <greg@gpanders.com>2023-04-25 08:23:16 -0600
commit1e73891d696a00b046ab19d245001424b174c931 (patch)
tree70f5e63c1764d04749be3a13822b57e9b6c6caac
parent147bb87245cdb348e67c659415d0661d48aa5f1e (diff)
downloadrneovim-1e73891d696a00b046ab19d245001424b174c931.tar.gz
rneovim-1e73891d696a00b046ab19d245001424b174c931.tar.bz2
rneovim-1e73891d696a00b046ab19d245001424b174c931.zip
refactor(iter): move helper functions under vim.iter
vim.iter is now both a function and a module (similar to vim.version).
-rw-r--r--runtime/doc/lua.txt223
-rw-r--r--runtime/lua/vim/_init_packages.lua1
-rw-r--r--runtime/lua/vim/iter.lua112
-rw-r--r--runtime/lua/vim/shared.lua105
-rwxr-xr-xscripts/gen_vimdoc.py3
5 files changed, 214 insertions, 230 deletions
diff --git a/runtime/doc/lua.txt b/runtime/doc/lua.txt
index 8e68e9a792..2d3ea75588 100644
--- a/runtime/doc/lua.txt
+++ b/runtime/doc/lua.txt
@@ -1653,26 +1653,6 @@ endswith({s}, {suffix}) *vim.endswith()*
Return: ~
(boolean) `true` if `suffix` is a suffix of `s`
-filter({f}, {src}, {...}) *vim.filter()*
- Filter a table or iterator.
-
- This is a convenience function that performs: >lua
-
- vim.iter(src):filter(f):totable()
-<
-
- Parameters: ~
- • {f} function(...):bool Filter function. Accepts the current
- iterator or table values as arguments and returns true if those
- values should be kept in the final table
- • {src} table|function Table or iterator function to filter
-
- Return: ~
- (table)
-
- See also: ~
- • |Iter:filter()|
-
gsplit({s}, {sep}, {opts}) *vim.gsplit()*
Splits a string at each instance of a separator.
@@ -1718,64 +1698,6 @@ is_callable({f}) *vim.is_callable()*
Return: ~
(boolean) `true` if `f` is callable, else `false`
-iter({src}, {...}) *vim.iter()*
- Create an Iter |lua-iter| object from a table or iterator.
-
- The input value can be a table or a function iterator (see |luaref-in|).
-
- This function wraps the input value into an interface which allows
- chaining multiple pipeline stages in an efficient manner. Each pipeline
- stage receives as input the output values from the prior stage. The values
- used in the first stage of the pipeline depend on the type passed to this
- function:
-
- • List tables pass only the value of each element
- • Non-list tables pass both the key and value of each element
- • Function iterators pass all of the values returned by their respective
- function
-
- Examples: >lua
-
- local it = vim.iter({ 1, 2, 3, 4, 5 })
- it:map(function(v)
- return v * 3
- end)
- it:rev()
- it:skip(2)
- it:totable()
- -- { 9, 6, 3 }
-
- vim.iter(ipairs({ 1, 2, 3, 4, 5 })):map(function(i, v)
- if i > 2 then return v end
- end):totable()
- -- { 3, 4, 5 }
-
- local it = vim.iter(vim.gsplit('1,2,3,4,5', ','))
- it:map(function(s) return tonumber(s) end)
- for i, d in it:enumerate() do
- print(string.format("Column %d is %d", i, d))
- end
- -- Column 1 is 1
- -- Column 2 is 2
- -- Column 3 is 3
- -- Column 4 is 4
- -- Column 5 is 5
-
- vim.iter({ a = 1, b = 2, c = 3, z = 26 }):any(function(k, v)
- return k == 'z'
- end)
- -- true
-<
-
- Parameters: ~
- • {src} table|function Table or iterator.
-
- Return: ~
- Iter |lua-iter|
-
- See also: ~
- • |lua-iter|
-
list_contains({t}, {value}) *vim.list_contains()*
Checks if a list-like table (integer keys without gaps) contains `value`.
@@ -1818,26 +1740,6 @@ list_slice({list}, {start}, {finish}) *vim.list_slice()*
Return: ~
(list) Copy of table sliced from start to finish (inclusive)
-map({f}, {src}, {...}) *vim.map()*
- Map and filter a table or iterator.
-
- This is a convenience function that performs: >lua
-
- vim.iter(src):map(f):totable()
-<
-
- Parameters: ~
- • {f} function(...):?any Map function. Accepts the current iterator
- or table values as arguments and returns one or more new
- values. Nil values are removed from the final table.
- • {src} table|function Table or iterator function to filter
-
- Return: ~
- (table)
-
- See also: ~
- • |Iter:map()|
-
pesc({s}) *vim.pesc()*
Escapes magic chars in |lua-patterns|.
@@ -2099,20 +2001,6 @@ tbl_values({t}) *vim.tbl_values()*
Return: ~
(list) List of values
-totable({f}, {...}) *vim.totable()*
- Collect an iterator into a table.
-
- This is a convenience function that performs: >lua
-
- vim.iter(f):totable()
-<
-
- Parameters: ~
- • {f} (function) Iterator function
-
- Return: ~
- (table)
-
trim({s}) *vim.trim()*
Trim whitespace (Lua pattern "%s") from both sides of a string.
@@ -2933,6 +2821,79 @@ range({spec}) *vim.version.range()*
==============================================================================
Lua module: iter *lua-iter*
+
+The *vim.iter* module provides a generic "iterator" interface over tables
+and iterator functions.
+
+*vim.iter()* wraps its table or function argument into an *Iter* object
+with methods (such as |Iter:filter()| and |Iter:map()|) that transform the
+underlying source data. These methods can be chained together to create
+iterator "pipelines". Each pipeline stage receives as input the output
+values from the prior stage. The values used in the first stage of the
+pipeline depend on the type passed to this function:
+
+• List tables pass only the value of each element
+• Non-list tables pass both the key and value of each element
+• Function iterators pass all of the values returned by their respective
+ function
+
+Examples: >lua
+
+ local it = vim.iter({ 1, 2, 3, 4, 5 })
+ it:map(function(v)
+ return v * 3
+ end)
+ it:rev()
+ it:skip(2)
+ it:totable()
+ -- { 9, 6, 3 }
+
+ vim.iter(ipairs({ 1, 2, 3, 4, 5 })):map(function(i, v)
+ if i > 2 then return v end
+ end):totable()
+ -- { 3, 4, 5 }
+
+ local it = vim.iter(vim.gsplit('1,2,3,4,5', ','))
+ it:map(function(s) return tonumber(s) end)
+ for i, d in it:enumerate() do
+ print(string.format("Column %d is %d", i, d))
+ end
+ -- Column 1 is 1
+ -- Column 2 is 2
+ -- Column 3 is 3
+ -- Column 4 is 4
+ -- Column 5 is 5
+
+ vim.iter({ a = 1, b = 2, c = 3, z = 26 }):any(function(k, v)
+ return k == 'z'
+ end)
+ -- true
+
+<
+
+In addition to the |vim.iter()| function, the |vim.iter| module provides
+convenience functions like |vim.iter.filter()| and |vim.iter.totable()|.
+
+filter({f}, {src}, {...}) *vim.iter.filter()*
+ Filter a table or iterator.
+
+ This is a convenience function that performs: >lua
+
+ vim.iter(src):filter(f):totable()
+<
+
+ Parameters: ~
+ • {f} function(...):bool Filter function. Accepts the current
+ iterator or table values as arguments and returns true if those
+ values should be kept in the final table
+ • {src} table|function Table or iterator function to filter
+
+ Return: ~
+ (table)
+
+ See also: ~
+ • |Iter:filter()|
+
Iter:all({self}, {pred}) *Iter:all()*
Return true if all of the items in the iterator match the given predicate.
@@ -2971,9 +2932,7 @@ Iter:enumerate({self}) *Iter:enumerate()*
vim.iter(ipairs(t))
<
- over
-
- >lua
+ over >lua
vim.iter(t):enumerate()
<
@@ -3331,16 +3290,38 @@ Iter:totable({self}) *Iter:totable()*
Return: ~
(table)
-new({src}, {...}) *new()*
- Create a new Iter object from a table or iterator.
+map({f}, {src}, {...}) *vim.iter.map()*
+ Map and filter a table or iterator.
+
+ This is a convenience function that performs: >lua
+
+ vim.iter(src):map(f):totable()
+<
Parameters: ~
- • {src} table|function Table or iterator to drain values from
+ • {f} function(...):?any Map function. Accepts the current iterator
+ or table values as arguments and returns one or more new
+ values. Nil values are removed from the final table.
+ • {src} table|function Table or iterator function to filter
Return: ~
- Iter
+ (table)
-next() *next()*
- TODO: Documentation
+ See also: ~
+ • |Iter:map()|
+
+totable({f}, {...}) *vim.iter.totable()*
+ Collect an iterator into a table.
+
+ This is a convenience function that performs: >lua
+
+ vim.iter(f):totable()
+<
+
+ Parameters: ~
+ • {f} (function) Iterator function
+
+ Return: ~
+ (table)
vim:tw=78:ts=8:sw=4:sts=4:et:ft=help:norl:
diff --git a/runtime/lua/vim/_init_packages.lua b/runtime/lua/vim/_init_packages.lua
index 2cf2e91a8c..5db258c011 100644
--- a/runtime/lua/vim/_init_packages.lua
+++ b/runtime/lua/vim/_init_packages.lua
@@ -55,6 +55,7 @@ vim._submodules = {
inspect = true,
version = true,
fs = true,
+ iter = true,
}
-- These are for loading runtime modules in the vim namespace lazily.
diff --git a/runtime/lua/vim/iter.lua b/runtime/lua/vim/iter.lua
index 2545853b41..c2e2c5bd9f 100644
--- a/runtime/lua/vim/iter.lua
+++ b/runtime/lua/vim/iter.lua
@@ -1,4 +1,56 @@
---- Iterator implementation.
+---@defgroup lua-iter
+---
+--- The \*vim.iter\* module provides a generic "iterator" interface over tables and iterator
+--- functions.
+---
+--- \*vim.iter()\* wraps its table or function argument into an \*Iter\* object with methods (such
+--- as |Iter:filter()| and |Iter:map()|) that transform the underlying source data. These methods
+--- can be chained together to create iterator "pipelines". Each pipeline stage receives as input
+--- the output values from the prior stage. The values used in the first stage of the pipeline
+--- depend on the type passed to this function:
+---
+--- - List tables pass only the value of each element
+--- - Non-list tables pass both the key and value of each element
+--- - Function iterators pass all of the values returned by their respective
+--- function
+---
+--- Examples:
+--- <pre>lua
+--- local it = vim.iter({ 1, 2, 3, 4, 5 })
+--- it:map(function(v)
+--- return v * 3
+--- end)
+--- it:rev()
+--- it:skip(2)
+--- it:totable()
+--- -- { 9, 6, 3 }
+---
+--- vim.iter(ipairs({ 1, 2, 3, 4, 5 })):map(function(i, v)
+--- if i > 2 then return v end
+--- end):totable()
+--- -- { 3, 4, 5 }
+---
+--- local it = vim.iter(vim.gsplit('1,2,3,4,5', ','))
+--- it:map(function(s) return tonumber(s) end)
+--- for i, d in it:enumerate() do
+--- print(string.format("Column %d is %d", i, d))
+--- end
+--- -- Column 1 is 1
+--- -- Column 2 is 2
+--- -- Column 3 is 3
+--- -- Column 4 is 4
+--- -- Column 5 is 5
+---
+--- vim.iter({ a = 1, b = 2, c = 3, z = 26 }):any(function(k, v)
+--- return k == 'z'
+--- end)
+--- -- true
+--- </pre>
+---
+--- In addition to the |vim.iter()| function, the |vim.iter| module provides convenience functions
+--- like |vim.iter.filter()| and |vim.iter.totable()|.
+
+local M = {}
---@class Iter
local Iter = {}
@@ -733,7 +785,6 @@ end
--- </pre>
---
--- over
----
--- <pre>lua
--- vim.iter(t):enumerate()
--- </pre>
@@ -776,6 +827,7 @@ end
---
---@param src table|function Table or iterator to drain values from
---@return Iter
+---@private
function Iter.new(src, ...)
local it = {}
if type(src) == 'table' then
@@ -807,6 +859,7 @@ function Iter.new(src, ...)
end
end
+ ---@private
function it.next()
return fn(src(s, var))
end
@@ -832,4 +885,57 @@ function ListIter.new(t)
return it
end
-return Iter
+--- Collect an iterator into a table.
+---
+--- This is a convenience function that performs:
+--- <pre>lua
+--- vim.iter(f):totable()
+--- </pre>
+---
+---@param f function Iterator function
+---@return table
+function M.totable(f, ...)
+ return Iter.new(f, ...):totable()
+end
+
+--- Filter a table or iterator.
+---
+--- This is a convenience function that performs:
+--- <pre>lua
+--- vim.iter(src):filter(f):totable()
+--- </pre>
+---
+---@see |Iter:filter()|
+---
+---@param f function(...):bool Filter function. Accepts the current iterator or table values as
+--- arguments and returns true if those values should be kept in the
+--- final table
+---@param src table|function Table or iterator function to filter
+---@return table
+function M.filter(f, src, ...)
+ return Iter.new(src, ...):filter(f):totable()
+end
+
+--- Map and filter a table or iterator.
+---
+--- This is a convenience function that performs:
+--- <pre>lua
+--- vim.iter(src):map(f):totable()
+--- </pre>
+---
+---@see |Iter:map()|
+---
+---@param f function(...):?any Map function. Accepts the current iterator or table values as
+--- arguments and returns one or more new values. Nil values are removed
+--- from the final table.
+---@param src table|function Table or iterator function to filter
+---@return table
+function M.map(f, src, ...)
+ return Iter.new(src, ...):map(f):totable()
+end
+
+return setmetatable(M, {
+ __call = function(_, ...)
+ return Iter.new(...)
+ end,
+})
diff --git a/runtime/lua/vim/shared.lua b/runtime/lua/vim/shared.lua
index 5f4ea8822b..a55deb1415 100644
--- a/runtime/lua/vim/shared.lua
+++ b/runtime/lua/vim/shared.lua
@@ -881,109 +881,4 @@ function vim.defaulttable(create)
})
end
---- Create an Iter |lua-iter| object from a table or iterator.
----
---- The input value can be a table or a function iterator (see |luaref-in|).
----
---- This function wraps the input value into an interface which allows chaining
---- multiple pipeline stages in an efficient manner. Each pipeline stage
---- receives as input the output values from the prior stage. The values used in
---- the first stage of the pipeline depend on the type passed to this function:
----
---- - List tables pass only the value of each element
---- - Non-list tables pass both the key and value of each element
---- - Function iterators pass all of the values returned by their respective
---- function
----
---- Examples:
---- <pre>lua
---- local it = vim.iter({ 1, 2, 3, 4, 5 })
---- it:map(function(v)
---- return v * 3
---- end)
---- it:rev()
---- it:skip(2)
---- it:totable()
---- -- { 9, 6, 3 }
----
---- vim.iter(ipairs({ 1, 2, 3, 4, 5 })):map(function(i, v)
---- if i > 2 then return v end
---- end):totable()
---- -- { 3, 4, 5 }
----
---- local it = vim.iter(vim.gsplit('1,2,3,4,5', ','))
---- it:map(function(s) return tonumber(s) end)
---- for i, d in it:enumerate() do
---- print(string.format("Column %d is %d", i, d))
---- end
---- -- Column 1 is 1
---- -- Column 2 is 2
---- -- Column 3 is 3
---- -- Column 4 is 4
---- -- Column 5 is 5
----
---- vim.iter({ a = 1, b = 2, c = 3, z = 26 }):any(function(k, v)
---- return k == 'z'
---- end)
---- -- true
---- </pre>
----
----@see |lua-iter|
----
----@param src table|function Table or iterator.
----@return Iter @|lua-iter|
-function vim.iter(src, ...)
- local Iter = require('vim.iter')
- return Iter.new(src, ...)
-end
-
---- Collect an iterator into a table.
----
---- This is a convenience function that performs:
---- <pre>lua
---- vim.iter(f):totable()
---- </pre>
----
----@param f function Iterator function
----@return table
-function vim.totable(f, ...)
- return vim.iter(f, ...):totable()
-end
-
---- Filter a table or iterator.
----
---- This is a convenience function that performs:
---- <pre>lua
---- vim.iter(src):filter(f):totable()
---- </pre>
----
----@see |Iter:filter()|
----
----@param f function(...):bool Filter function. Accepts the current iterator or table values as
---- arguments and returns true if those values should be kept in the
---- final table
----@param src table|function Table or iterator function to filter
----@return table
-function vim.filter(f, src, ...)
- return vim.iter(src, ...):filter(f):totable()
-end
-
---- Map and filter a table or iterator.
----
---- This is a convenience function that performs:
---- <pre>lua
---- vim.iter(src):map(f):totable()
---- </pre>
----
----@see |Iter:map()|
----
----@param f function(...):?any Map function. Accepts the current iterator or table values as
---- arguments and returns one or more new values. Nil values are removed
---- from the final table.
----@param src table|function Table or iterator function to filter
----@return table
-function vim.map(f, src, ...)
- return vim.iter(src, ...):map(f):totable()
-end
-
return vim
diff --git a/scripts/gen_vimdoc.py b/scripts/gen_vimdoc.py
index 52d03d9746..d0686e92bc 100755
--- a/scripts/gen_vimdoc.py
+++ b/scripts/gen_vimdoc.py
@@ -188,7 +188,7 @@ CONFIG = {
f'*vim.{name}()*'
if fstem.lower() == '_editor'
else f'*{name}()*'
- if fstem in ('iter.lua')
+ if name[0].isupper()
else f'*{fstem}.{name}()*'),
'module_override': {
# `shared` functions are exposed on the `vim` module.
@@ -202,6 +202,7 @@ CONFIG = {
'fs': 'vim.fs',
'secure': 'vim.secure',
'version': 'vim.version',
+ 'iter': 'vim.iter',
},
'append_only': [
'shared.lua',