aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGeorge Zhao <zhaozg@gmail.com>2019-06-10 20:13:18 +0800
committerJustin M. Keyes <justinkz@gmail.com>2019-06-10 14:13:18 +0200
commitc83926cd0aa5720e88e84fa3fae3c0e689cca3ef (patch)
treeb0511481bce7d76b4dfe91b1bdc6d626eeeb5f40
parent3e58e60568c2acc765f3ee72295e2f15baa3cf52 (diff)
downloadrneovim-c83926cd0aa5720e88e84fa3fae3c0e689cca3ef.tar.gz
rneovim-c83926cd0aa5720e88e84fa3fae3c0e689cca3ef.tar.bz2
rneovim-c83926cd0aa5720e88e84fa3fae3c0e689cca3ef.zip
lua: introduce vim.loop (expose libuv event-loop) #10123
Co-authored-by: Andrey Popp <8mayday@gmail.com> closes #9546 closes #10084
-rw-r--r--CMakeLists.txt3
-rw-r--r--cmake/FindLibLUV.cmake32
-rw-r--r--src/nvim/CMakeLists.txt1
-rw-r--r--src/nvim/lua/executor.c7
-rw-r--r--test/functional/lua/loop_spec.lua55
-rw-r--r--third-party/CMakeLists.txt7
-rw-r--r--third-party/cmake/BuildLuarocks.cmake5
-rw-r--r--third-party/cmake/BuildLuv.cmake25
8 files changed, 129 insertions, 6 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 43281dee2c..7d2314a418 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -385,6 +385,9 @@ include_directories(SYSTEM ${LIBUV_INCLUDE_DIRS})
find_package(Msgpack 1.0.0 REQUIRED)
include_directories(SYSTEM ${MSGPACK_INCLUDE_DIRS})
+find_package(LibLUV 1.29.1 REQUIRED)
+include_directories(SYSTEM ${LIBLUV_INCLUDE_DIRS})
+
# Note: The test lib requires LuaJIT; it will be skipped if LuaJIT is missing.
option(PREFER_LUA "Prefer Lua over LuaJIT in the nvim executable." OFF)
diff --git a/cmake/FindLibLUV.cmake b/cmake/FindLibLUV.cmake
new file mode 100644
index 0000000000..d8ce9264c3
--- /dev/null
+++ b/cmake/FindLibLUV.cmake
@@ -0,0 +1,32 @@
+# - Try to find luv
+# Once done this will define
+# LIBLUV_FOUND - System has libluv
+# LIBLUV_INCLUDE_DIRS - The libluv include directories
+# LIBLUV_LIBRARIES - The libraries needed to use libluv
+
+find_path(LIBLUV_INCLUDE_DIR luv/luv.h
+ PATHS ${PC_LIBLUV_INCLUDEDIR} ${PC_LIBLUV_INCLUDE_DIRS}
+ ${LIMIT_SEARCH})
+
+# If we're asked to use static linkage, add libluv.a as a preferred library name.
+if(LIBLUV_USE_STATIC)
+ list(APPEND LIBLUV_NAMES
+ "${CMAKE_STATIC_LIBRARY_PREFIX}luv${CMAKE_STATIC_LIBRARY_SUFFIX}")
+endif()
+
+list(APPEND LIBLUV_NAMES luv)
+
+find_library(LIBLUV_LIBRARY NAMES ${LIBLUV_NAMES}
+ HINTS ${PC_LIBLUV_LIBDIR} ${PC_LIBLUV_LIBRARY_DIRS}
+ ${LIMIT_SEARCH})
+
+set(LIBLUV_LIBRARIES ${LIBLUV_LIBRARY})
+set(LIBLUV_INCLUDE_DIRS ${LIBLUV_INCLUDE_DIR})
+
+include(FindPackageHandleStandardArgs)
+# handle the QUIETLY and REQUIRED arguments and set LIBLUV_FOUND to TRUE
+# if all listed variables are TRUE
+find_package_handle_standard_args(libluv DEFAULT_MSG
+ LIBLUV_LIBRARY LIBLUV_INCLUDE_DIR)
+
+mark_as_advanced(LIBLUV_INCLUDE_DIR LIBLUV_LIBRARY)
diff --git a/src/nvim/CMakeLists.txt b/src/nvim/CMakeLists.txt
index 8abc43c2aa..77c5bf59e4 100644
--- a/src/nvim/CMakeLists.txt
+++ b/src/nvim/CMakeLists.txt
@@ -383,6 +383,7 @@ endif()
# Put these last on the link line, since multiple things may depend on them.
list(APPEND NVIM_LINK_LIBRARIES
+ ${LIBLUV_LIBRARIES}
${LIBUV_LIBRARIES}
${MSGPACK_LIBRARIES}
${LIBVTERM_LIBRARIES}
diff --git a/src/nvim/lua/executor.c b/src/nvim/lua/executor.c
index df08a9dd87..8cb282356a 100644
--- a/src/nvim/lua/executor.c
+++ b/src/nvim/lua/executor.c
@@ -31,6 +31,8 @@
#include "nvim/lua/executor.h"
#include "nvim/lua/converter.h"
+#include "luv/luv.h"
+
typedef struct {
Error err;
String lua_err_str;
@@ -176,6 +178,11 @@ static int nlua_state_init(lua_State *const lstate) FUNC_ATTR_NONNULL_ALL
lua_pushcfunction(lstate, &nlua_schedule);
lua_setfield(lstate, -2, "schedule");
+ // vim.loop
+ luv_set_loop(lstate, &main_loop.uv);
+ luaopen_luv(lstate);
+ lua_setfield(lstate, -2, "loop");
+
lua_setglobal(lstate, "vim");
return 0;
}
diff --git a/test/functional/lua/loop_spec.lua b/test/functional/lua/loop_spec.lua
new file mode 100644
index 0000000000..8cc54e8c13
--- /dev/null
+++ b/test/functional/lua/loop_spec.lua
@@ -0,0 +1,55 @@
+-- Test suite for testing interactions with API bindings
+local helpers = require('test.functional.helpers')(after_each)
+local funcs = helpers.funcs
+local meths = helpers.meths
+local clear = helpers.clear
+local sleep = helpers.sleep
+local eq = helpers.eq
+local matches = helpers.matches
+
+before_each(clear)
+
+describe('vim.loop', function()
+
+ it('version', function()
+ assert(funcs.luaeval('vim.loop.version()')>=72961, "libuv version too old")
+ matches("(%d+)%.(%d+)%.(%d+)", funcs.luaeval('vim.loop.version_string()'))
+ end)
+
+ it('timer', function()
+ meths.execute_lua('vim.api.nvim_set_var("coroutine_cnt", 0)', {})
+
+ local code=[[
+ local loop = vim.loop
+
+ local touch = 0
+ local function wait(ms)
+ local this = coroutine.running()
+ assert(this)
+ local timer = loop.new_timer()
+ timer:start(ms, 0, function ()
+ timer:close()
+ touch = touch + 1
+ coroutine.resume(this)
+ touch = touch + 1
+ assert(touch==3)
+ vim.api.nvim_set_var("coroutine_cnt_1", touch)
+ end)
+ coroutine.yield()
+ touch = touch + 1
+ return touch
+ end
+ coroutine.wrap(function()
+ local touched = wait(10)
+ assert(touched==touch)
+ vim.api.nvim_set_var("coroutine_cnt", touched)
+ end)()
+ ]]
+
+ eq(0, meths.get_var('coroutine_cnt'))
+ meths.execute_lua(code, {})
+ sleep(20)
+ eq(2, meths.get_var('coroutine_cnt'))
+ eq(3, meths.get_var('coroutine_cnt_1'))
+ end)
+end)
diff --git a/third-party/CMakeLists.txt b/third-party/CMakeLists.txt
index db4dae4b39..21a1752054 100644
--- a/third-party/CMakeLists.txt
+++ b/third-party/CMakeLists.txt
@@ -154,8 +154,11 @@ set(LIBTERMKEY_SHA256 cecbf737f35d18f433c8d7864f63c0f878af41f8bd0255a3ebb16010dc
set(LIBVTERM_URL https://github.com/neovim/libvterm/archive/b45b648cab73f9667bde7c0c6045b285e22b3ecd.tar.gz)
set(LIBVTERM_SHA256 37cc123deff29327efa654358c2ebaaf8589da03754ca5adb8ec47be386a0433)
-set(LUV_URL https://github.com/luvit/luv/archive/1.9.1-1.tar.gz)
-set(LUV_SHA256 562b9efaad30aa051a40eac9ade0c3df48bb8186763769abe47ec3fb3edb1268)
+set(LUV_URL https://github.com/luvit/luv/archive/1.29.1-2.tar.gz)
+set(LUV_SHA256 e75d8fd2a14433bb798900a71e45318b3c0b8c2ef2c1c43593482ce95b4999e2)
+
+set(LUA_COMPAT53_URL https://github.com/keplerproject/lua-compat-5.3/archive/v0.7.tar.gz)
+set(LUA_COMPAT53_SHA256 bec3a23114a3d9b3218038309657f0f506ad10dfbc03bb54e91da7e5ffdba0a2)
set(GPERF_URL https://github.com/neovim/deps/raw/ff5b4b18a87397a8564016071ae64f64bcd8c635/opt/gperf-3.1.tar.gz)
set(GPERF_SHA256 588546b945bba4b70b6a3a616e80b4ab466e3f33024a352fc2198112cdbb3ae2)
diff --git a/third-party/cmake/BuildLuarocks.cmake b/third-party/cmake/BuildLuarocks.cmake
index de4db35bfd..3ef7c6300e 100644
--- a/third-party/cmake/BuildLuarocks.cmake
+++ b/third-party/cmake/BuildLuarocks.cmake
@@ -182,7 +182,7 @@ if(USE_BUNDLED_BUSTED)
add_custom_target(luacheck
DEPENDS ${LUACHECK_EXE})
- set(LUV_DEPS luacheck luv-static)
+ set(LUV_DEPS luacheck luv-static lua-compat-5.3)
if(MINGW AND CMAKE_CROSSCOMPILING)
set(LUV_DEPS ${LUV_DEPS} libuv_host)
endif()
@@ -191,9 +191,10 @@ if(USE_BUNDLED_BUSTED)
list(APPEND LUV_ARGS LIBUV_DIR=${HOSTDEPS_INSTALL_DIR})
endif()
# DEPENDS on the previous module, because Luarocks breaks if parallel.
+ SET(LUV_PRIVATE_ARGS LUA_COMPAT53_INCDIR=${DEPS_BUILD_DIR}/src/lua-compat-5.3)
add_custom_command(OUTPUT ${HOSTDEPS_LIB_DIR}/luarocks/rocks/luv
COMMAND ${LUAROCKS_BINARY}
- ARGS make ${LUAROCKS_BUILDARGS} ${LUV_ARGS}
+ ARGS make ${LUAROCKS_BUILDARGS} ${LUV_ARGS} ${LUV_PRIVATE_ARGS}
WORKING_DIRECTORY ${DEPS_BUILD_DIR}/src/luv
DEPENDS ${LUV_DEPS})
add_custom_target(luv
diff --git a/third-party/cmake/BuildLuv.cmake b/third-party/cmake/BuildLuv.cmake
index a62ee72f91..5de5ddbf9c 100644
--- a/third-party/cmake/BuildLuv.cmake
+++ b/third-party/cmake/BuildLuv.cmake
@@ -15,8 +15,26 @@ function(BuildLuv)
message(FATAL_ERROR "Must pass at least one of CONFIGURE_COMMAND, BUILD_COMMAND, INSTALL_COMMAND")
endif()
+ ExternalProject_Add(lua-compat-5.3
+ PREFIX ${DEPS_BUILD_DIR}
+ URL ${LUA_COMPAT53_URL}
+ DOWNLOAD_DIR ${DEPS_DOWNLOAD_DIR}/lua-compat-5.3
+ DOWNLOAD_COMMAND ${CMAKE_COMMAND}
+ -DPREFIX=${DEPS_BUILD_DIR}
+ -DDOWNLOAD_DIR=${DEPS_DOWNLOAD_DIR}/lua-compat-5.3
+ -DURL=${LUA_COMPAT53_URL}
+ -DEXPECTED_SHA256=${LUA_COMPAT53_SHA256}
+ -DTARGET=lua-compat-5.3
+ -DUSE_EXISTING_SRC_DIR=${USE_EXISTING_SRC_DIR}
+ -P ${CMAKE_CURRENT_SOURCE_DIR}/cmake/DownloadAndExtractFile.cmake
+ PATCH_COMMAND ""
+ CONFIGURE_COMMAND ""
+ BUILD_COMMAND ""
+ INSTALL_COMMAND "")
+
ExternalProject_Add(luv-static
PREFIX ${DEPS_BUILD_DIR}
+ DEPENDS lua-compat-5.3
URL ${LUV_URL}
DOWNLOAD_DIR ${DEPS_DOWNLOAD_DIR}/luv
DOWNLOAD_COMMAND ${CMAKE_COMMAND}
@@ -94,9 +112,12 @@ endif()
if(CMAKE_GENERATOR MATCHES "Unix Makefiles" AND
(CMAKE_SYSTEM_NAME MATCHES ".*BSD" OR CMAKE_SYSTEM_NAME MATCHES "DragonFly"))
- set(LUV_BUILD_COMMAND ${CMAKE_COMMAND} "-DCMAKE_MAKE_PROGRAM=gmake" --build .)
+ set(LUV_BUILD_COMMAND ${CMAKE_COMMAND}
+ "-DLUA_COMPAT53_DIR=${DEPS_BUILD_DIR}/src/lua-compat-5.3"
+ "-DCMAKE_MAKE_PROGRAM=gmake" --build .)
else()
- set(LUV_BUILD_COMMAND ${CMAKE_COMMAND} --build .)
+ set(LUV_BUILD_COMMAND ${CMAKE_COMMAND}
+ "-DLUA_COMPAT53_DIR=${DEPS_BUILD_DIR}/src/lua-compat-5.3" --build .)
endif()
set(LUV_INSTALL_COMMAND ${CMAKE_COMMAND} --build . --target install)