mirror of
https://github.com/neovim/neovim.git
synced 2024-12-19 18:55:14 -07:00
feat(lua)!: add stricter vim.tbl_islist() and rename old one to vim.tbl_isarray() (#16440)
feat(lua)!: add stricter vim.tbl_islist(), rename vim.tbl_isarray() Problem: `vim.tbl_islist` allows gaps in tables with integer keys ("arrays"). Solution: Rename `vim.tbl_islist` to `vim.tbl_isarray`, add new `vim.tbl.islist` that checks for consecutive integer keys that start from 1.
This commit is contained in:
parent
33e90f5138
commit
7caf0eafd8
@ -1928,6 +1928,20 @@ tbl_get({o}, {...}) *vim.tbl_get()*
|
||||
Return: ~
|
||||
any Nested value indexed by key (if it exists), else nil
|
||||
|
||||
tbl_isarray({t}) *vim.tbl_isarray()*
|
||||
Tests if a Lua table can be treated as an array (a table indexed by
|
||||
integers).
|
||||
|
||||
Empty table `{}` is assumed to be an array, unless it was created by
|
||||
|vim.empty_dict()| or returned as a dict-like |API| or Vimscript result,
|
||||
for example from |rpcrequest()| or |vim.fn|.
|
||||
|
||||
Parameters: ~
|
||||
• {t} (table)
|
||||
|
||||
Return: ~
|
||||
(boolean) `true` if array-like table, else `false`.
|
||||
|
||||
tbl_isempty({t}) *vim.tbl_isempty()*
|
||||
Checks if a table is empty.
|
||||
|
||||
@ -1941,17 +1955,18 @@ tbl_isempty({t}) *vim.tbl_isempty()*
|
||||
• https://github.com/premake/premake-core/blob/master/src/base/table.lua
|
||||
|
||||
tbl_islist({t}) *vim.tbl_islist()*
|
||||
Tests if a Lua table can be treated as an array.
|
||||
Tests if a Lua table can be treated as a list (a table indexed by
|
||||
consecutive integers starting from 1).
|
||||
|
||||
Empty table `{}` is assumed to be an array, unless it was created by
|
||||
Empty table `{}` is assumed to be an list, unless it was created by
|
||||
|vim.empty_dict()| or returned as a dict-like |API| or Vimscript result,
|
||||
for example from |rpcrequest()| or |vim.fn|.
|
||||
|
||||
Parameters: ~
|
||||
• {t} (table) Table
|
||||
• {t} (table)
|
||||
|
||||
Return: ~
|
||||
(boolean) `true` if array-like table, else `false`
|
||||
(boolean) `true` if list-like table, else `false`.
|
||||
|
||||
tbl_keys({t}) *vim.tbl_keys()*
|
||||
Return a list of all keys used in a table. However, the order of the
|
||||
|
@ -15,6 +15,11 @@ BREAKING CHANGES *news-breaking*
|
||||
|
||||
The following changes may require adaptations in user config or plugins.
|
||||
|
||||
• |vim.tbl_islist()| now checks whether a table is actually list-like (i.e.,
|
||||
has integer keys without gaps and starting from 1). For the previous
|
||||
behavior (only check for integer keys, allow gaps or not starting with 1),
|
||||
use |vim.tbl_isarray()|.
|
||||
|
||||
• "#" followed by a digit no longer stands for a function key at the start of
|
||||
the lhs of a mapping.
|
||||
|
||||
|
@ -320,10 +320,10 @@ function vim.tbl_isempty(t)
|
||||
return next(t) == nil
|
||||
end
|
||||
|
||||
--- We only merge empty tables or tables that are not a list
|
||||
--- We only merge empty tables or tables that are not an array (indexed by integers)
|
||||
---@private
|
||||
local function can_merge(v)
|
||||
return type(v) == 'table' and (vim.tbl_isempty(v) or not vim.tbl_islist(v))
|
||||
return type(v) == 'table' and (vim.tbl_isempty(v) or not vim.tbl_isarray(v))
|
||||
end
|
||||
|
||||
local function tbl_extend(behavior, deep_extend, ...)
|
||||
@ -554,15 +554,15 @@ function vim.spairs(t)
|
||||
end
|
||||
end
|
||||
|
||||
--- Tests if a Lua table can be treated as an array.
|
||||
--- Tests if a Lua table can be treated as an array (a table indexed by integers).
|
||||
---
|
||||
--- Empty table `{}` is assumed to be an array, unless it was created by
|
||||
--- |vim.empty_dict()| or returned as a dict-like |API| or Vimscript result,
|
||||
--- for example from |rpcrequest()| or |vim.fn|.
|
||||
---
|
||||
---@param t table Table
|
||||
---@return boolean `true` if array-like table, else `false`
|
||||
function vim.tbl_islist(t)
|
||||
---@param t table
|
||||
---@return boolean `true` if array-like table, else `false`.
|
||||
function vim.tbl_isarray(t)
|
||||
if type(t) ~= 'table' then
|
||||
return false
|
||||
end
|
||||
@ -570,7 +570,8 @@ function vim.tbl_islist(t)
|
||||
local count = 0
|
||||
|
||||
for k, _ in pairs(t) do
|
||||
if type(k) == 'number' then
|
||||
--- Check if the number k is an integer
|
||||
if type(k) == 'number' and k == math.floor(k) then
|
||||
count = count + 1
|
||||
else
|
||||
return false
|
||||
@ -589,6 +590,38 @@ function vim.tbl_islist(t)
|
||||
end
|
||||
end
|
||||
|
||||
--- Tests if a Lua table can be treated as a list (a table indexed by consecutive integers starting from 1).
|
||||
---
|
||||
--- Empty table `{}` is assumed to be an list, unless it was created by
|
||||
--- |vim.empty_dict()| or returned as a dict-like |API| or Vimscript result,
|
||||
--- for example from |rpcrequest()| or |vim.fn|.
|
||||
---
|
||||
---@param t table
|
||||
---@return boolean `true` if list-like table, else `false`.
|
||||
function vim.tbl_islist(t)
|
||||
if type(t) ~= 'table' then
|
||||
return false
|
||||
end
|
||||
|
||||
local num_elem = vim.tbl_count(t)
|
||||
|
||||
if num_elem == 0 then
|
||||
-- TODO(bfredl): in the future, we will always be inside nvim
|
||||
-- then this check can be deleted.
|
||||
if vim._empty_dict_mt == nil then
|
||||
return nil
|
||||
end
|
||||
return getmetatable(t) ~= vim._empty_dict_mt
|
||||
else
|
||||
for i = 1, num_elem do
|
||||
if t[i] == nil then
|
||||
return false
|
||||
end
|
||||
end
|
||||
return true
|
||||
end
|
||||
end
|
||||
|
||||
--- Counts the number of non-nil values in table `t`.
|
||||
---
|
||||
--- <pre>lua
|
||||
|
@ -521,6 +521,19 @@ describe('lua stdlib', function()
|
||||
]]))
|
||||
end)
|
||||
|
||||
it('vim.tbl_isarray', function()
|
||||
eq(true, exec_lua("return vim.tbl_isarray({})"))
|
||||
eq(false, exec_lua("return vim.tbl_isarray(vim.empty_dict())"))
|
||||
eq(true, exec_lua("return vim.tbl_isarray({'a', 'b', 'c'})"))
|
||||
eq(false, exec_lua("return vim.tbl_isarray({'a', '32', a='hello', b='baz'})"))
|
||||
eq(false, exec_lua("return vim.tbl_isarray({1, a='hello', b='baz'})"))
|
||||
eq(false, exec_lua("return vim.tbl_isarray({a='hello', b='baz', 1})"))
|
||||
eq(false, exec_lua("return vim.tbl_isarray({1, 2, nil, a='hello'})"))
|
||||
eq(true, exec_lua("return vim.tbl_isarray({1, 2, nil, 4})"))
|
||||
eq(true, exec_lua("return vim.tbl_isarray({nil, 2, 3, 4})"))
|
||||
eq(false, exec_lua("return vim.tbl_isarray({1, [1.5]=2, [3]=3})"))
|
||||
end)
|
||||
|
||||
it('vim.tbl_islist', function()
|
||||
eq(true, exec_lua("return vim.tbl_islist({})"))
|
||||
eq(false, exec_lua("return vim.tbl_islist(vim.empty_dict())"))
|
||||
@ -529,6 +542,9 @@ describe('lua stdlib', function()
|
||||
eq(false, exec_lua("return vim.tbl_islist({1, a='hello', b='baz'})"))
|
||||
eq(false, exec_lua("return vim.tbl_islist({a='hello', b='baz', 1})"))
|
||||
eq(false, exec_lua("return vim.tbl_islist({1, 2, nil, a='hello'})"))
|
||||
eq(false, exec_lua("return vim.tbl_islist({1, 2, nil, 4})"))
|
||||
eq(false, exec_lua("return vim.tbl_islist({nil, 2, 3, 4})"))
|
||||
eq(false, exec_lua("return vim.tbl_islist({1, [1.5]=2, [3]=3})"))
|
||||
end)
|
||||
|
||||
it('vim.tbl_isempty', function()
|
||||
|
Loading…
Reference in New Issue
Block a user