Merge pull request #23248 from neovim/backport-23234-to-release-0.9

[Backport release-0.9] fix(lua): vim.split may trim inner empty items
This commit is contained in:
Justin M. Keyes
2023-04-21 10:20:01 -04:00
committed by GitHub
2 changed files with 17 additions and 18 deletions

View File

@@ -100,10 +100,9 @@ function vim.gsplit(s, sep, opts)
local start = 1 local start = 1
local done = false local done = false
-- For `trimempty`: -- For `trimempty`: queue of collected segments, to be emitted at next pass.
local segs = {}
local empty_start = true -- Only empty segments seen so far. local empty_start = true -- Only empty segments seen so far.
local empty_segs = 0 -- Empty segments found between non-empty segments.
local nonemptyseg = nil
local function _pass(i, j, ...) local function _pass(i, j, ...)
if i then if i then
@@ -118,14 +117,9 @@ function vim.gsplit(s, sep, opts)
end end
return function() return function()
if trimempty and empty_segs > 0 then if trimempty and #segs > 0 then
-- trimempty: Pop the collected empty segments. -- trimempty: Pop the collected segments.
empty_segs = empty_segs - 1 return table.remove(segs)
return ''
elseif trimempty and nonemptyseg then
local seg = nonemptyseg
nonemptyseg = nil
return seg
elseif done or (s == '' and sep == '') then elseif done or (s == '' and sep == '') then
return nil return nil
elseif sep == '' then elseif sep == '' then
@@ -138,21 +132,24 @@ function vim.gsplit(s, sep, opts)
local seg = _pass(s:find(sep, start, plain)) local seg = _pass(s:find(sep, start, plain))
-- Trim empty segments from start/end. -- Trim empty segments from start/end.
if trimempty and seg == '' then if trimempty and seg ~= '' then
empty_start = false
elseif trimempty and seg == '' then
while not done and seg == '' do while not done and seg == '' do
empty_segs = empty_segs + 1 table.insert(segs, 1, '')
seg = _pass(s:find(sep, start, plain)) seg = _pass(s:find(sep, start, plain))
end end
if done and seg == '' then if done and seg == '' then
return nil return nil
elseif empty_start then elseif empty_start then
empty_start = false empty_start = false
empty_segs = 0 segs = {}
return seg return seg
end end
nonemptyseg = seg ~= '' and seg or nil if seg ~= '' then
seg = '' table.insert(segs, 1, seg)
empty_segs = empty_segs - 1 end
return table.remove(segs)
end end
return seg return seg

View File

@@ -294,9 +294,11 @@ describe('lua stdlib', function()
it('vim.gsplit, vim.split', function() it('vim.gsplit, vim.split', function()
local tests = { local tests = {
-- plain trimempty
{ 'a,b', ',', false, false, { 'a', 'b' } }, { 'a,b', ',', false, false, { 'a', 'b' } },
{ ':aa::::bb:', ':', false, false, { '', 'aa', '', '', '', 'bb', '' } }, { ':aa::::bb:', ':', false, false, { '', 'aa', '', '', '', 'bb', '' } },
{ ':aa::::bb:', ':', false, true, { 'aa', '', '', '', 'bb' } }, { ':aa::::bb:', ':', false, true, { 'aa', '', '', '', 'bb' } },
{ 'aa::::bb:', ':', false, true, { 'aa', '', '', '', 'bb' } },
{ ':aa::bb:', ':', false, true, { 'aa', '', 'bb' } }, { ':aa::bb:', ':', false, true, { 'aa', '', 'bb' } },
{ '/a/b:/b/\n', '[:\n]', false, true, { '/a/b', '/b/' } }, { '/a/b:/b/\n', '[:\n]', false, true, { '/a/b', '/b/' } },
{ '::ee::ff:', ':', false, false, { '', '', 'ee', '', 'ff', '' } }, { '::ee::ff:', ':', false, false, { '', '', 'ee', '', 'ff', '' } },
@@ -315,7 +317,7 @@ describe('lua stdlib', function()
} }
for _, t in ipairs(tests) do for _, t in ipairs(tests) do
eq(t[5], vim.split(t[1], t[2], {plain=t[3], trimempty=t[4]})) eq(t[5], vim.split(t[1], t[2], {plain=t[3], trimempty=t[4]}), t[1])
end end
-- Test old signature -- Test old signature