mirror of
				https://github.com/neovim/neovim.git
				synced 2025-10-26 12:27:24 +00:00 
			
		
		
		
	api/lua: make nvim_execute_lua use native lua floats, not special tables
Rationale: the purpose of nvim_execute_lua is to simply call lua code with lua values. If a lua function expects a floating point value, it should be enough to specify a float as argument to nvim_execute_lua. However, make sure to preserve the existing roundtripping behavior of API values when using `vim.api` functions. This is covered by existing lua/api_spec.lua tests.
This commit is contained in:
		| @@ -441,7 +441,7 @@ local function process_function(fn) | |||||||
|     end |     end | ||||||
|     write_shifted_output(output, string.format([[ |     write_shifted_output(output, string.format([[ | ||||||
|     const %s ret = %s(%s); |     const %s ret = %s(%s); | ||||||
|     nlua_push_%s(lstate, ret); |     nlua_push_%s(lstate, ret, true); | ||||||
|     api_free_%s(ret); |     api_free_%s(ret); | ||||||
|   %s |   %s | ||||||
|   %s |   %s | ||||||
|   | |||||||
| @@ -615,7 +615,7 @@ static inline void nlua_create_typed_table(lua_State *lstate, | |||||||
| /// Convert given String to lua string | /// Convert given String to lua string | ||||||
| /// | /// | ||||||
| /// Leaves converted string on top of the stack. | /// Leaves converted string on top of the stack. | ||||||
| void nlua_push_String(lua_State *lstate, const String s) | void nlua_push_String(lua_State *lstate, const String s, bool special) | ||||||
|   FUNC_ATTR_NONNULL_ALL |   FUNC_ATTR_NONNULL_ALL | ||||||
| { | { | ||||||
|   lua_pushlstring(lstate, s.data, s.size); |   lua_pushlstring(lstate, s.data, s.size); | ||||||
| @@ -624,7 +624,7 @@ void nlua_push_String(lua_State *lstate, const String s) | |||||||
| /// Convert given Integer to lua number | /// Convert given Integer to lua number | ||||||
| /// | /// | ||||||
| /// Leaves converted number on top of the stack. | /// Leaves converted number on top of the stack. | ||||||
| void nlua_push_Integer(lua_State *lstate, const Integer n) | void nlua_push_Integer(lua_State *lstate, const Integer n, bool special) | ||||||
|   FUNC_ATTR_NONNULL_ALL |   FUNC_ATTR_NONNULL_ALL | ||||||
| { | { | ||||||
|   lua_pushnumber(lstate, (lua_Number)n); |   lua_pushnumber(lstate, (lua_Number)n); | ||||||
| @@ -633,19 +633,23 @@ void nlua_push_Integer(lua_State *lstate, const Integer n) | |||||||
| /// Convert given Float to lua table | /// Convert given Float to lua table | ||||||
| /// | /// | ||||||
| /// Leaves converted table on top of the stack. | /// Leaves converted table on top of the stack. | ||||||
| void nlua_push_Float(lua_State *lstate, const Float f) | void nlua_push_Float(lua_State *lstate, const Float f, bool special) | ||||||
|   FUNC_ATTR_NONNULL_ALL |   FUNC_ATTR_NONNULL_ALL | ||||||
| { | { | ||||||
|   nlua_create_typed_table(lstate, 0, 1, kObjectTypeFloat); |   if (special) { | ||||||
|   nlua_push_val_idx(lstate); |     nlua_create_typed_table(lstate, 0, 1, kObjectTypeFloat); | ||||||
|   lua_pushnumber(lstate, (lua_Number)f); |     nlua_push_val_idx(lstate); | ||||||
|   lua_rawset(lstate, -3); |     lua_pushnumber(lstate, (lua_Number)f); | ||||||
|  |     lua_rawset(lstate, -3); | ||||||
|  |   } else { | ||||||
|  |     lua_pushnumber(lstate, (lua_Number)f); | ||||||
|  |   } | ||||||
| } | } | ||||||
|  |  | ||||||
| /// Convert given Float to lua boolean | /// Convert given Float to lua boolean | ||||||
| /// | /// | ||||||
| /// Leaves converted value on top of the stack. | /// Leaves converted value on top of the stack. | ||||||
| void nlua_push_Boolean(lua_State *lstate, const Boolean b) | void nlua_push_Boolean(lua_State *lstate, const Boolean b, bool special) | ||||||
|   FUNC_ATTR_NONNULL_ALL |   FUNC_ATTR_NONNULL_ALL | ||||||
| { | { | ||||||
|   lua_pushboolean(lstate, b); |   lua_pushboolean(lstate, b); | ||||||
| @@ -654,17 +658,18 @@ void nlua_push_Boolean(lua_State *lstate, const Boolean b) | |||||||
| /// Convert given Dictionary to lua table | /// Convert given Dictionary to lua table | ||||||
| /// | /// | ||||||
| /// Leaves converted table on top of the stack. | /// Leaves converted table on top of the stack. | ||||||
| void nlua_push_Dictionary(lua_State *lstate, const Dictionary dict) | void nlua_push_Dictionary(lua_State *lstate, const Dictionary dict, | ||||||
|  |                           bool special) | ||||||
|   FUNC_ATTR_NONNULL_ALL |   FUNC_ATTR_NONNULL_ALL | ||||||
| { | { | ||||||
|   if (dict.size == 0) { |   if (dict.size == 0 && special) { | ||||||
|     nlua_create_typed_table(lstate, 0, 0, kObjectTypeDictionary); |     nlua_create_typed_table(lstate, 0, 0, kObjectTypeDictionary); | ||||||
|   } else { |   } else { | ||||||
|     lua_createtable(lstate, 0, (int)dict.size); |     lua_createtable(lstate, 0, (int)dict.size); | ||||||
|   } |   } | ||||||
|   for (size_t i = 0; i < dict.size; i++) { |   for (size_t i = 0; i < dict.size; i++) { | ||||||
|     nlua_push_String(lstate, dict.items[i].key); |     nlua_push_String(lstate, dict.items[i].key, special); | ||||||
|     nlua_push_Object(lstate, dict.items[i].value); |     nlua_push_Object(lstate, dict.items[i].value, special); | ||||||
|     lua_rawset(lstate, -3); |     lua_rawset(lstate, -3); | ||||||
|   } |   } | ||||||
| } | } | ||||||
| @@ -672,18 +677,18 @@ void nlua_push_Dictionary(lua_State *lstate, const Dictionary dict) | |||||||
| /// Convert given Array to lua table | /// Convert given Array to lua table | ||||||
| /// | /// | ||||||
| /// Leaves converted table on top of the stack. | /// Leaves converted table on top of the stack. | ||||||
| void nlua_push_Array(lua_State *lstate, const Array array) | void nlua_push_Array(lua_State *lstate, const Array array, bool special) | ||||||
|   FUNC_ATTR_NONNULL_ALL |   FUNC_ATTR_NONNULL_ALL | ||||||
| { | { | ||||||
|   lua_createtable(lstate, (int)array.size, 0); |   lua_createtable(lstate, (int)array.size, 0); | ||||||
|   for (size_t i = 0; i < array.size; i++) { |   for (size_t i = 0; i < array.size; i++) { | ||||||
|     nlua_push_Object(lstate, array.items[i]); |     nlua_push_Object(lstate, array.items[i], special); | ||||||
|     lua_rawseti(lstate, -2, (int)i + 1); |     lua_rawseti(lstate, -2, (int)i + 1); | ||||||
|   } |   } | ||||||
| } | } | ||||||
|  |  | ||||||
| #define GENERATE_INDEX_FUNCTION(type) \ | #define GENERATE_INDEX_FUNCTION(type) \ | ||||||
| void nlua_push_##type(lua_State *lstate, const type item) \ | void nlua_push_##type(lua_State *lstate, const type item, bool special) \ | ||||||
|   FUNC_ATTR_NONNULL_ALL \ |   FUNC_ATTR_NONNULL_ALL \ | ||||||
| { \ | { \ | ||||||
|   lua_pushnumber(lstate, (lua_Number)(item)); \ |   lua_pushnumber(lstate, (lua_Number)(item)); \ | ||||||
| @@ -698,7 +703,7 @@ GENERATE_INDEX_FUNCTION(Tabpage) | |||||||
| /// Convert given Object to lua value | /// Convert given Object to lua value | ||||||
| /// | /// | ||||||
| /// Leaves converted value on top of the stack. | /// Leaves converted value on top of the stack. | ||||||
| void nlua_push_Object(lua_State *lstate, const Object obj) | void nlua_push_Object(lua_State *lstate, const Object obj, bool special) | ||||||
|   FUNC_ATTR_NONNULL_ALL |   FUNC_ATTR_NONNULL_ALL | ||||||
| { | { | ||||||
|   switch (obj.type) { |   switch (obj.type) { | ||||||
| @@ -712,7 +717,7 @@ void nlua_push_Object(lua_State *lstate, const Object obj) | |||||||
|     } |     } | ||||||
| #define ADD_TYPE(type, data_key) \ | #define ADD_TYPE(type, data_key) \ | ||||||
|     case kObjectType##type: { \ |     case kObjectType##type: { \ | ||||||
|       nlua_push_##type(lstate, obj.data.data_key); \ |       nlua_push_##type(lstate, obj.data.data_key, special); \ | ||||||
|       break; \ |       break; \ | ||||||
|     } |     } | ||||||
|     ADD_TYPE(Boolean,      boolean) |     ADD_TYPE(Boolean,      boolean) | ||||||
| @@ -724,7 +729,7 @@ void nlua_push_Object(lua_State *lstate, const Object obj) | |||||||
| #undef ADD_TYPE | #undef ADD_TYPE | ||||||
| #define ADD_REMOTE_TYPE(type) \ | #define ADD_REMOTE_TYPE(type) \ | ||||||
|     case kObjectType##type: { \ |     case kObjectType##type: { \ | ||||||
|       nlua_push_##type(lstate, (type)obj.data.integer); \ |       nlua_push_##type(lstate, (type)obj.data.integer, special); \ | ||||||
|       break; \ |       break; \ | ||||||
|     } |     } | ||||||
|     ADD_REMOTE_TYPE(Buffer) |     ADD_REMOTE_TYPE(Buffer) | ||||||
|   | |||||||
| @@ -562,7 +562,7 @@ Object executor_exec_lua_api(const String str, const Array args, Error *err) | |||||||
|   } |   } | ||||||
|  |  | ||||||
|   for (size_t i = 0; i < args.size; i++) { |   for (size_t i = 0; i < args.size; i++) { | ||||||
|     nlua_push_Object(lstate, args.items[i]); |     nlua_push_Object(lstate, args.items[i], false); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   if (lua_pcall(lstate, (int)args.size, 1, 0)) { |   if (lua_pcall(lstate, (int)args.size, 1, 0)) { | ||||||
| @@ -583,7 +583,7 @@ Object executor_exec_lua_cb(LuaRef ref, const char *name, Array args, | |||||||
|   nlua_pushref(lstate, ref); |   nlua_pushref(lstate, ref); | ||||||
|   lua_pushstring(lstate, name); |   lua_pushstring(lstate, name); | ||||||
|   for (size_t i = 0; i < args.size; i++) { |   for (size_t i = 0; i < args.size; i++) { | ||||||
|     nlua_push_Object(lstate, args.items[i]); |     nlua_push_Object(lstate, args.items[i], false); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   if (lua_pcall(lstate, (int)args.size+1, retval ? 1 : 0, 0)) { |   if (lua_pcall(lstate, (int)args.size+1, retval ? 1 : 0, 0)) { | ||||||
|   | |||||||
| @@ -339,6 +339,15 @@ describe('API', function() | |||||||
|                  "did\nthe\nfail"}, |                  "did\nthe\nfail"}, | ||||||
|          meth_pcall(meths.execute_lua, 'error("did\\nthe\\nfail")', {})) |          meth_pcall(meths.execute_lua, 'error("did\\nthe\\nfail")', {})) | ||||||
|     end) |     end) | ||||||
|  |  | ||||||
|  |     it('uses native float values', function() | ||||||
|  |       eq(2.5, meths.execute_lua("return select(1, ...)", {2.5})) | ||||||
|  |       eq("2.5", meths.execute_lua("return vim.inspect(...)", {2.5})) | ||||||
|  |  | ||||||
|  |       -- "special" float values are still accepted as return values. | ||||||
|  |       eq(2.5, meths.execute_lua("return vim.api.nvim_eval('2.5')", {})) | ||||||
|  |       eq("{\n  [false] = 2.5,\n  [true] = 3\n}", meths.execute_lua("return vim.inspect(vim.api.nvim_eval('2.5'))", {})) | ||||||
|  |     end) | ||||||
|   end) |   end) | ||||||
|  |  | ||||||
|   describe('nvim_input', function() |   describe('nvim_input', function() | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 Björn Linse
					Björn Linse