aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/nvim/lua/converter.c13
-rw-r--r--src/nvim/lua/executor.c13
-rw-r--r--src/nvim/lua/executor.h1
-rw-r--r--src/nvim/lua/vim.lua4
4 files changed, 31 insertions, 0 deletions
diff --git a/src/nvim/lua/converter.c b/src/nvim/lua/converter.c
index 09d1a68898..fca74b5901 100644
--- a/src/nvim/lua/converter.c
+++ b/src/nvim/lua/converter.c
@@ -156,6 +156,13 @@ static LuaTableProps nlua_traverse_table(lua_State *const lstate)
&& other_keys_num == 0
&& ret.string_keys_num == 0)) {
ret.type = kObjectTypeArray;
+ if (tsize == 0 && lua_getmetatable(lstate, -1)) {
+ nlua_pushref(lstate, nlua_empty_dict_ref);
+ if (lua_rawequal(lstate, -2, -1)) {
+ ret.type = kObjectTypeDictionary;
+ }
+ lua_pop(lstate, 2);
+ }
} else if (ret.string_keys_num == tsize) {
ret.type = kObjectTypeDictionary;
} else {
@@ -465,6 +472,8 @@ static bool typval_conv_special = false;
nlua_create_typed_table(lstate, 0, 0, kObjectTypeDictionary); \
} else { \
lua_createtable(lstate, 0, 0); \
+ nlua_pushref(lstate, nlua_empty_dict_ref); \
+ lua_setmetatable(lstate, -2); \
} \
} while (0)
@@ -695,6 +704,10 @@ void nlua_push_Dictionary(lua_State *lstate, const Dictionary dict,
nlua_create_typed_table(lstate, 0, 0, kObjectTypeDictionary);
} else {
lua_createtable(lstate, 0, (int)dict.size);
+ if (dict.size == 0 && !special) {
+ nlua_pushref(lstate, nlua_empty_dict_ref);
+ lua_setmetatable(lstate, -2);
+ }
}
for (size_t i = 0; i < dict.size; i++) {
nlua_push_String(lstate, dict.items[i].key, special);
diff --git a/src/nvim/lua/executor.c b/src/nvim/lua/executor.c
index 2cd6c0db66..242d4e18d1 100644
--- a/src/nvim/lua/executor.c
+++ b/src/nvim/lua/executor.c
@@ -324,6 +324,13 @@ static int nlua_state_init(lua_State *const lstate) FUNC_ATTR_NONNULL_ALL
nlua_nil_ref = nlua_ref(lstate, -1);
lua_setfield(lstate, -2, "NIL");
+ // vim._empty_dict_mt
+ lua_createtable(lstate, 0, 0);
+ lua_pushcfunction(lstate, &nlua_empty_dict_tostring);
+ lua_setfield(lstate, -2, "__tostring");
+ nlua_empty_dict_ref = nlua_ref(lstate, -1);
+ lua_setfield(lstate, -2, "_empty_dict_mt");
+
// internal vim._treesitter... API
nlua_add_treesitter(lstate);
@@ -665,6 +672,12 @@ static int nlua_nil_tostring(lua_State *lstate)
return 1;
}
+static int nlua_empty_dict_tostring(lua_State *lstate)
+{
+ lua_pushstring(lstate, "vim.empty_dict()");
+ return 1;
+}
+
#ifdef WIN32
/// os.getenv: override os.getenv to maintain coherency. #9681
diff --git a/src/nvim/lua/executor.h b/src/nvim/lua/executor.h
index 32f66b629c..3259fc0fa1 100644
--- a/src/nvim/lua/executor.h
+++ b/src/nvim/lua/executor.h
@@ -13,6 +13,7 @@
void nlua_add_api_functions(lua_State *lstate) REAL_FATTR_NONNULL_ALL;
EXTERN LuaRef nlua_nil_ref INIT(= LUA_NOREF);
+EXTERN LuaRef nlua_empty_dict_ref INIT(= LUA_NOREF);
#define set_api_error(s, err) \
do { \
diff --git a/src/nvim/lua/vim.lua b/src/nvim/lua/vim.lua
index e7c5458102..8ba550ea31 100644
--- a/src/nvim/lua/vim.lua
+++ b/src/nvim/lua/vim.lua
@@ -243,6 +243,10 @@ function vim.schedule_wrap(cb)
end)
end
+function vim.empty_dict()
+ return setmetatable({}, vim._empty_dict_mt)
+end
+
-- vim.fn.{func}(...)
vim.fn = setmetatable({}, {
__index = function(t, key)