aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTristan Konolige <tristan.konolige@gmail.com>2020-04-18 17:04:37 -0600
committerGitHub <noreply@github.com>2020-04-19 01:04:37 +0200
commitbf0f74586153dfa8d550e1cfefd83ca9e0354171 (patch)
treeef631999ea9cb6d778bf5035eb4cdabd007d17ce
parentc5466ba6ef8333183e1c43c7e762e44539fb2358 (diff)
downloadrneovim-bf0f74586153dfa8d550e1cfefd83ca9e0354171.tar.gz
rneovim-bf0f74586153dfa8d550e1cfefd83ca9e0354171.tar.bz2
rneovim-bf0f74586153dfa8d550e1cfefd83ca9e0354171.zip
lua: allow deepcopy of functions (#12136)
-rw-r--r--runtime/doc/lua.txt5
-rw-r--r--runtime/lua/vim/shared.lua11
-rw-r--r--test/functional/lua/vim_spec.lua16
3 files changed, 30 insertions, 2 deletions
diff --git a/runtime/doc/lua.txt b/runtime/doc/lua.txt
index 800f24b5c9..7f376cbbf0 100644
--- a/runtime/doc/lua.txt
+++ b/runtime/doc/lua.txt
@@ -908,7 +908,10 @@ deep_equal({a}, {b}) *vim.deep_equal()*
deepcopy({orig}) *vim.deepcopy()*
Returns a deep copy of the given object. Non-table objects are
copied as in a typical Lua assignment, whereas table objects
- are copied recursively.
+ are copied recursively. Functions are naively copied, so
+ functions in the copied table point to the same functions as
+ those in the input table. Userdata and threads are not copied
+ and will throw an error.
Parameters: ~
{orig} Table to copy
diff --git a/runtime/lua/vim/shared.lua b/runtime/lua/vim/shared.lua
index 1bf1c63fd7..d18fcfaf95 100644
--- a/runtime/lua/vim/shared.lua
+++ b/runtime/lua/vim/shared.lua
@@ -8,6 +8,9 @@ local vim = vim or {}
--- Returns a deep copy of the given object. Non-table objects are copied as
--- in a typical Lua assignment, whereas table objects are copied recursively.
+--- Functions are naively copied, so functions in the copied table point to the
+--- same functions as those in the input table. Userdata and threads are not
+--- copied and will throw an error.
---
--@param orig Table to copy
--@returns New table of copied keys and (nested) values.
@@ -34,10 +37,16 @@ vim.deepcopy = (function()
string = _id,
['nil'] = _id,
boolean = _id,
+ ['function'] = _id,
}
return function(orig)
- return deepcopy_funcs[type(orig)](orig)
+ local f = deepcopy_funcs[type(orig)]
+ if f then
+ return f(orig)
+ else
+ error("Cannot deepcopy object of type "..type(orig))
+ end
end
end)()
diff --git a/test/functional/lua/vim_spec.lua b/test/functional/lua/vim_spec.lua
index 5ce4bf2973..ca74d185cd 100644
--- a/test/functional/lua/vim_spec.lua
+++ b/test/functional/lua/vim_spec.lua
@@ -341,6 +341,22 @@ describe('lua stdlib', function()
and vim.tbl_count(b) == 2
and tostring(a) ~= tostring(b)
]]))
+
+ ok(exec_lua([[
+ local f1 = function() return 1 end
+ local f2 = function() return 2 end
+ local t1 = {f = f1}
+ local t2 = vim.deepcopy(t1)
+ t1.f = f2
+ return t1.f() ~= t2.f()
+ ]]))
+
+ eq('Error executing lua: .../shared.lua: Cannot deepcopy object of type thread',
+ pcall_err(exec_lua, [[
+ local thread = coroutine.create(function () return 0 end)
+ local t = {thr = thread}
+ vim.deepcopy(t)
+ ]]))
end)
it('vim.pesc', function()