aboutsummaryrefslogtreecommitdiff
path: root/runtime/lua/vim/shared.lua
diff options
context:
space:
mode:
authorShadman <13149513+shadmansaleh@users.noreply.github.com>2021-11-26 16:06:43 +0600
committerGitHub <noreply@github.com>2021-11-26 11:06:43 +0100
commiteb876a0a6f5efb4706625723a8dd45b0c6c133a4 (patch)
tree97d966ef8e3666593bf496ea9414c5981ba8868f /runtime/lua/vim/shared.lua
parent3451121a4e517b42f1df73caed35c3663f57e5eb (diff)
downloadrneovim-eb876a0a6f5efb4706625723a8dd45b0c6c133a4.tar.gz
rneovim-eb876a0a6f5efb4706625723a8dd45b0c6c133a4.tar.bz2
rneovim-eb876a0a6f5efb4706625723a8dd45b0c6c133a4.zip
fix(lua): fix vim.deepcopy for metatables & cycled tables (#16435)
vim.deepcopy previously didn't retain metatables in copies and caused stackoverflow on recursive tables/cycled tables this fixes these issues
Diffstat (limited to 'runtime/lua/vim/shared.lua')
-rw-r--r--runtime/lua/vim/shared.lua19
1 files changed, 9 insertions, 10 deletions
diff --git a/runtime/lua/vim/shared.lua b/runtime/lua/vim/shared.lua
index 6e40b6ca52..bf77f0c776 100644
--- a/runtime/lua/vim/shared.lua
+++ b/runtime/lua/vim/shared.lua
@@ -12,7 +12,7 @@ local vim = vim or {}
--- same functions as those in the input table. Userdata and threads are not
--- copied and will throw an error.
---
----@param orig Table to copy
+---@param orig table Table to copy
---@returns New table of copied keys and (nested) values.
function vim.deepcopy(orig) end -- luacheck: no unused
vim.deepcopy = (function()
@@ -21,17 +21,16 @@ vim.deepcopy = (function()
end
local deepcopy_funcs = {
- table = function(orig)
+ table = function(orig, cache)
+ if cache[orig] then return cache[orig] end
local copy = {}
- if vim._empty_dict_mt ~= nil and getmetatable(orig) == vim._empty_dict_mt then
- copy = vim.empty_dict()
- end
-
+ cache[orig] = copy
+ local mt = getmetatable(orig)
for k, v in pairs(orig) do
- copy[vim.deepcopy(k)] = vim.deepcopy(v)
+ copy[vim.deepcopy(k, cache)] = vim.deepcopy(v, cache)
end
- return copy
+ return setmetatable(copy, mt)
end,
number = _id,
string = _id,
@@ -40,10 +39,10 @@ vim.deepcopy = (function()
['function'] = _id,
}
- return function(orig)
+ return function(orig, cache)
local f = deepcopy_funcs[type(orig)]
if f then
- return f(orig)
+ return f(orig, cache or {})
else
error("Cannot deepcopy object of type "..type(orig))
end