fix(lua): vim.tbl_get({}, nil, 1) should return nil #32218

Problem:
`vim.tbl_get(tbl, nil, 1)` returns `tbl` itself. In this case, `keys` is not
empty, but `ipairs` skips the iteration:

    local keys = { nil, 1 }
    assert(#keys == 2)
    for i, k in ipairs(keys) do
      assert(false, 'unreachable')
    end

Solution:
Use `select("#", ...)` and `select(i, ...)` to ensure consistency for count and
iteration.
This commit is contained in:
phanium 2025-02-10 00:40:43 +08:00 committed by GitHub
parent 8c2571991a
commit cd3855fb2b
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 6 additions and 5 deletions

View File

@ -526,15 +526,15 @@ end
---@param ... any Optional keys (0 or more, variadic) via which to index the table
---@return any # Nested value indexed by key (if it exists), else nil
function vim.tbl_get(o, ...)
local keys = { ... }
if #keys == 0 then
local nargs = select('#', ...)
if nargs == 0 then
return nil
end
for i, k in ipairs(keys) do
o = o[k] --- @type any
for i = 1, nargs do
o = o[select(i, ...)] --- @type any
if o == nil then
return nil
elseif type(o) ~= 'table' and next(keys, i) then
elseif type(o) ~= 'table' and i ~= nargs then
return nil
end
end

View File

@ -970,6 +970,7 @@ describe('lua stdlib', function()
)
eq(NIL, exec_lua("return vim.tbl_get({}, 'missing_key')"))
eq(NIL, exec_lua('return vim.tbl_get({})'))
eq(NIL, exec_lua("return vim.tbl_get({}, nil, 'key')"))
eq(1, exec_lua("return select('#', vim.tbl_get({}))"))
eq(1, exec_lua("return select('#', vim.tbl_get({ nested = {} }, 'nested', 'missing_key'))"))
end)