fix(iter): make pipeline termination conditions consistent (#24614)

If an iterator pipeline stage returns nil as its first return value, the
other return values are ignored and it is treated as if that stage
returned only nil (the semantics of returning nil are different between
different stages). This is consistent with how for loops work in Lua
more generally, where the for loop breaks when the first return value
from the function iterator is nil (see :h for-in for details).
This commit is contained in:
Gregory Anders
2023-08-09 15:41:45 -05:00
committed by GitHub
parent cc4540ebce
commit 2ee8ace217
3 changed files with 28 additions and 42 deletions

View File

@@ -154,6 +154,9 @@ describe('vim.iter', function()
eq({1, 2}, vim.iter(t):slice(1, 2):totable())
eq({10}, vim.iter(t):slice(10, 10):totable())
eq({8, 9, 10}, vim.iter(t):slice(8, 11):totable())
local it = vim.iter(vim.gsplit('a|b|c|d', '|'))
matches('slice%(%) requires a list%-like table', pcall_err(it.slice, it, 1, 3))
end)
it('nth()', function()
@@ -396,39 +399,4 @@ describe('vim.iter', function()
{ item_3 = 'test' },
}, output)
end)
it('handles nil values', function()
local t = {1, 2, 3, 4, 5}
do
local it = vim.iter(t):enumerate():map(function(i, v)
if i % 2 == 0 then
return nil, v*v
end
return v, nil
end)
eq({
{ [1] = 1 },
{ [2] = 4 },
{ [1] = 3 },
{ [2] = 16 },
{ [1] = 5 },
}, it:totable())
end
do
local it = vim.iter(ipairs(t)):map(function(i, v)
if i % 2 == 0 then
return nil, v*v
end
return v, nil
end)
eq({
{ [1] = 1 },
{ [2] = 4 },
{ [1] = 3 },
{ [2] = 16 },
{ [1] = 5 },
}, it:totable())
end
end)
end)