neovim

Neovim text editor
git clone https://git.dasho.dev/neovim.git
Log | Files | Refs | README

commit cd3855fb2be78e2dc2d2ca4b8e950d9d9d9081bb
parent 8c2571991ad748b0ee71529951e1502e553aa8ba
Author: phanium <91544758+phanen@users.noreply.github.com>
Date:   Mon, 10 Feb 2025 00:40:43 +0800

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.
Diffstat:
Mruntime/lua/vim/shared.lua | 10+++++-----
Mtest/functional/lua/vim_spec.lua | 1+
2 files changed, 6 insertions(+), 5 deletions(-)

diff --git a/runtime/lua/vim/shared.lua b/runtime/lua/vim/shared.lua @@ -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 diff --git a/test/functional/lua/vim_spec.lua b/test/functional/lua/vim_spec.lua @@ -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)