mirror of
				https://github.com/neovim/neovim.git
				synced 2025-11-04 01:34:25 +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
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
					  if (special) {
 | 
				
			||||||
    nlua_create_typed_table(lstate, 0, 1, kObjectTypeFloat);
 | 
					    nlua_create_typed_table(lstate, 0, 1, kObjectTypeFloat);
 | 
				
			||||||
    nlua_push_val_idx(lstate);
 | 
					    nlua_push_val_idx(lstate);
 | 
				
			||||||
    lua_pushnumber(lstate, (lua_Number)f);
 | 
					    lua_pushnumber(lstate, (lua_Number)f);
 | 
				
			||||||
    lua_rawset(lstate, -3);
 | 
					    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