aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorbfredl <bjorn.linse@gmail.com>2023-04-20 13:19:38 +0200
committerbfredl <bjorn.linse@gmail.com>2023-04-27 11:40:00 +0200
commit45bcf8386918bbb475fbe20c48b508aa89ed0624 (patch)
tree772416435a44717c8e42b3d4f59dd85f6ed47bfa
parent9f0762f1fec2aa23df592dda70124e3cbdb703b7 (diff)
downloadrneovim-45bcf8386918bbb475fbe20c48b508aa89ed0624.tar.gz
rneovim-45bcf8386918bbb475fbe20c48b508aa89ed0624.tar.bz2
rneovim-45bcf8386918bbb475fbe20c48b508aa89ed0624.zip
refactor(build): include lpeg as a library
-rw-r--r--.luacheckrc3
-rw-r--r--.styluaignore1
-rw-r--r--CMakeLists.txt13
-rw-r--r--cmake.deps/CMakeLists.txt9
-rw-r--r--cmake.deps/cmake/BuildLpeg.cmake18
-rw-r--r--cmake.deps/cmake/BuildLuarocks.cmake2
-rw-r--r--cmake.deps/cmake/BuildLuv.cmake6
-rw-r--r--cmake.deps/cmake/LpegCMakeLists.txt11
-rw-r--r--cmake/FindLpeg.cmake14
-rw-r--r--cmake/LuaHelpers.cmake23
-rw-r--r--runtime/doc/lua.txt8
-rw-r--r--runtime/lua/vim/_init_packages.lua1
-rw-r--r--runtime/lua/vim/re.lua269
-rw-r--r--src/nlua0.c5
-rw-r--r--src/nvim/CMakeLists.txt16
-rw-r--r--src/nvim/generators/c_grammar.lua2
-rw-r--r--[-rwxr-xr-x]src/nvim/generators/gen_declarations.lua5
-rw-r--r--src/nvim/lua/stdlib.c13
-rw-r--r--test/functional/lua/vim_spec.lua9
19 files changed, 376 insertions, 52 deletions
diff --git a/.luacheckrc b/.luacheckrc
index e804d1c822..cbec2210d3 100644
--- a/.luacheckrc
+++ b/.luacheckrc
@@ -43,5 +43,6 @@ globals = {
exclude_files = {
'test/functional/fixtures/lua/syntax_error.lua',
- 'runtime/lua/vim/treesitter/_meta.lua'
+ 'runtime/lua/vim/treesitter/_meta.lua',
+ 'runtime/lua/vim/re.lua',
}
diff --git a/.styluaignore b/.styluaignore
index c1871de90a..c8f1f6a98b 100644
--- a/.styluaignore
+++ b/.styluaignore
@@ -1,3 +1,4 @@
/scripts
/src
/test
+/runtime/lua/vim/re.lua
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 371112ad73..dad8f4b745 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -160,27 +160,20 @@ foreach(CFGNAME ${CMAKE_CONFIGURATION_TYPES})
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY_${CFGNAME} ${CMAKE_BINARY_DIR}/lib)
endforeach()
-set(LUA_DEPENDENCIES lpeg)
if(NOT LUA_PRG)
foreach(CURRENT_LUA_PRG luajit lua5.1 lua5.2 lua)
unset(_CHECK_LUA_PRG CACHE)
- unset(LUA_PRG_WORKS)
find_program(_CHECK_LUA_PRG ${CURRENT_LUA_PRG})
if(_CHECK_LUA_PRG)
- check_lua_deps(${_CHECK_LUA_PRG} "${LUA_DEPENDENCIES}" LUA_PRG_WORKS)
- if(LUA_PRG_WORKS)
- set(LUA_PRG "${_CHECK_LUA_PRG}" CACHE FILEPATH "Path to a program.")
- break()
- endif()
+ set(LUA_PRG "${_CHECK_LUA_PRG}" CACHE FILEPATH "Path to a program.")
+ break()
endif()
endforeach()
unset(_CHECK_LUA_PRG CACHE)
-else()
- check_lua_deps(${LUA_PRG} "${LUA_DEPENDENCIES}" LUA_PRG_WORKS)
endif()
-if(NOT LUA_PRG_WORKS)
+if(NOT LUA_PRG)
message(FATAL_ERROR "Failed to find a Lua 5.1-compatible interpreter")
endif()
diff --git a/cmake.deps/CMakeLists.txt b/cmake.deps/CMakeLists.txt
index e6852e6265..f740bebc9b 100644
--- a/cmake.deps/CMakeLists.txt
+++ b/cmake.deps/CMakeLists.txt
@@ -41,6 +41,7 @@ set(DEPS_BIN_DIR "${DEPS_INSTALL_DIR}/bin")
set(DEPS_LIB_DIR "${DEPS_INSTALL_DIR}/lib")
set(DEPS_BUILD_DIR "${CMAKE_BINARY_DIR}/build")
set(DEPS_DOWNLOAD_DIR "${DEPS_BUILD_DIR}/downloads")
+set(DEPS_INCLUDE_FLAGS "-I${DEPS_INSTALL_DIR}/include -I${DEPS_INSTALL_DIR}/include/luajit-2.1")
list(APPEND DEPS_CMAKE_ARGS -D CMAKE_INSTALL_PREFIX=${DEPS_INSTALL_DIR})
@@ -54,6 +55,7 @@ option(USE_BUNDLED_MSGPACK "Use the bundled msgpack." ${USE_BUNDLED})
option(USE_BUNDLED_LUAJIT "Use the bundled version of luajit." ${USE_BUNDLED})
option(USE_BUNDLED_LUAROCKS "Use the bundled version of luarocks." ${USE_BUNDLED})
option(USE_BUNDLED_LUV "Use the bundled version of luv." ${USE_BUNDLED})
+option(USE_BUNDLED_LPEG "Use the bundled lpeg." ${USE_BUNDLED})
#XXX(tarruda): Lua is only used for debugging the functional test client, don't
# build it unless explicitly requested
option(USE_BUNDLED_LUA "Use the bundled version of lua." OFF)
@@ -161,6 +163,9 @@ set(LIBVTERM_SHA256 25a8ad9c15485368dfd0a8a9dca1aec8fea5c27da3fa74ec518d5d3787f0
set(LUV_URL https://github.com/luvit/luv/archive/093a977b82077591baefe1e880d37dfa2730bd54.tar.gz)
set(LUV_SHA256 222b38b6425f0926218e14e7da81481fdde6f9660c1feac25a53e6fb52e886e6)
+set(LPEG_URL http://www.inf.puc-rio.br/~roberto/lpeg/lpeg-1.0.2.tar.gz)
+set(LPEG_SHA256 48d66576051b6c78388faad09b70493093264588fcd0f258ddaab1cdd4a15ffe)
+
set(LUA_COMPAT53_URL https://github.com/keplerproject/lua-compat-5.3/archive/v0.9.tar.gz)
set(LUA_COMPAT53_SHA256 ad05540d2d96a48725bb79a1def35cf6652a4e2ec26376e2617c8ce2baa6f416)
@@ -245,6 +250,10 @@ if(USE_BUNDLED_LUV)
include(BuildLuv)
endif()
+if(USE_BUNDLED_LPEG)
+ include(BuildLpeg)
+endif()
+
if(USE_BUNDLED_GETTEXT)
include(BuildGettext)
endif()
diff --git a/cmake.deps/cmake/BuildLpeg.cmake b/cmake.deps/cmake/BuildLpeg.cmake
new file mode 100644
index 0000000000..81efccf1f4
--- /dev/null
+++ b/cmake.deps/cmake/BuildLpeg.cmake
@@ -0,0 +1,18 @@
+list(APPEND LPEG_CMAKE_ARGS "-DCMAKE_C_FLAGS:STRING=${DEPS_INCLUDE_FLAGS}")
+
+ExternalProject_Add(lpeg
+ URL ${LPEG_URL}
+ URL_HASH SHA256=${LPEG_SHA256}
+ DOWNLOAD_NO_PROGRESS TRUE
+ DOWNLOAD_DIR ${DEPS_DOWNLOAD_DIR}/lpeg
+ PATCH_COMMAND ${CMAKE_COMMAND} -E copy
+ ${CMAKE_CURRENT_SOURCE_DIR}/cmake/LpegCMakeLists.txt
+ ${DEPS_BUILD_DIR}/src/lpeg/CMakeLists.txt
+ CMAKE_ARGS ${DEPS_CMAKE_ARGS} ${LPEG_CMAKE_ARGS}
+ CMAKE_CACHE_ARGS ${DEPS_CMAKE_CACHE_ARGS})
+
+if(USE_BUNDLED_LUAJIT)
+ add_dependencies(lpeg luajit)
+elseif(USE_BUNDLED_LUA)
+ add_dependencies(lpeg lua)
+endif()
diff --git a/cmake.deps/cmake/BuildLuarocks.cmake b/cmake.deps/cmake/BuildLuarocks.cmake
index a69d27f4b4..cb29ed9d95 100644
--- a/cmake.deps/cmake/BuildLuarocks.cmake
+++ b/cmake.deps/cmake/BuildLuarocks.cmake
@@ -119,8 +119,6 @@ function(Download ROCK VER)
set(CURRENT_DEP ${ROCK} PARENT_SCOPE)
endfunction()
-Download(lpeg 1.0.2-1)
-
if(USE_BUNDLED_BUSTED)
if(WIN32)
set(BUSTED_EXE "${DEPS_BIN_DIR}/busted.bat")
diff --git a/cmake.deps/cmake/BuildLuv.cmake b/cmake.deps/cmake/BuildLuv.cmake
index eda3934bee..08168c9804 100644
--- a/cmake.deps/cmake/BuildLuv.cmake
+++ b/cmake.deps/cmake/BuildLuv.cmake
@@ -1,6 +1,3 @@
-set(LUV_INCLUDE_FLAGS
- "-I${DEPS_INSTALL_DIR}/include -I${DEPS_INSTALL_DIR}/include/luajit-2.1")
-
set(LUV_CMAKE_ARGS
-D LUA_BUILD_TYPE=System
-D LUA_COMPAT53_DIR=${DEPS_BUILD_DIR}/src/lua-compat-5.3
@@ -26,8 +23,7 @@ if(USE_BUNDLED_LIBUV)
list(APPEND LUV_CMAKE_ARGS -D CMAKE_PREFIX_PATH=${DEPS_INSTALL_DIR})
endif()
-list(APPEND LUV_CMAKE_ARGS
- "-DCMAKE_C_FLAGS:STRING=${LUV_INCLUDE_FLAGS}")
+list(APPEND LUV_CMAKE_ARGS "-DCMAKE_C_FLAGS:STRING=${DEPS_INCLUDE_FLAGS}")
if(CMAKE_GENERATOR MATCHES "Unix Makefiles" AND
(CMAKE_SYSTEM_NAME MATCHES ".*BSD" OR CMAKE_SYSTEM_NAME MATCHES "DragonFly"))
list(APPEND LUV_CMAKE_ARGS -D CMAKE_MAKE_PROGRAM=gmake)
diff --git a/cmake.deps/cmake/LpegCMakeLists.txt b/cmake.deps/cmake/LpegCMakeLists.txt
new file mode 100644
index 0000000000..54cef7a9e4
--- /dev/null
+++ b/cmake.deps/cmake/LpegCMakeLists.txt
@@ -0,0 +1,11 @@
+cmake_minimum_required(VERSION 3.10)
+project (lpeg C)
+
+include(GNUInstallDirs)
+
+file(GLOB LPEG_SOURCES ${CMAKE_SOURCE_DIR}/*.c)
+add_library(lpeg ${LPEG_SOURCES})
+
+install(TARGETS lpeg ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR})
+
+# vim: set ft=cmake:
diff --git a/cmake/FindLpeg.cmake b/cmake/FindLpeg.cmake
new file mode 100644
index 0000000000..d4fc6dbd97
--- /dev/null
+++ b/cmake/FindLpeg.cmake
@@ -0,0 +1,14 @@
+find_library(LPEG_LIBRARY NAMES lpeg_a lpeg liblpeg_a)
+
+# Ubuntu-specific workaround to find system paths
+function(ubuntu)
+ set(CMAKE_FIND_LIBRARY_PREFIXES "")
+ find_library(LPEG_LIBRARY NAMES lpeg PATH_SUFFIXES lua/5.1)
+endfunction()
+ubuntu()
+
+find_package_handle_standard_args(Lpeg DEFAULT_MSG LPEG_LIBRARY)
+mark_as_advanced(LPEG_LIBRARY)
+
+add_library(lpeg INTERFACE)
+target_link_libraries(lpeg INTERFACE ${LPEG_LIBRARY})
diff --git a/cmake/LuaHelpers.cmake b/cmake/LuaHelpers.cmake
index 0239460f2b..00ecd1357f 100644
--- a/cmake/LuaHelpers.cmake
+++ b/cmake/LuaHelpers.cmake
@@ -12,26 +12,3 @@ function(check_lua_module LUA_PRG_PATH MODULE RESULT_VAR)
set(${RESULT_VAR} True PARENT_SCOPE)
endif()
endfunction()
-
-# Check Lua interpreter for dependencies
-function(check_lua_deps LUA_PRG_PATH MODULES RESULT_VAR)
- # Check if the lua interpreter at the given path
- # satisfies all Neovim dependencies
- message(STATUS "Checking Lua interpreter: ${LUA_PRG_PATH}")
- if(NOT EXISTS ${LUA_PRG_PATH})
- message(STATUS
- "[${LUA_PRG_PATH}] file not found")
- endif()
-
- foreach(module ${MODULES})
- check_lua_module(${LUA_PRG_PATH} ${module} has_module)
- if(NOT has_module)
- message(STATUS
- "[${LUA_PRG_PATH}] The '${module}' lua package is required for building Neovim")
- set(${RESULT_VAR} False PARENT_SCOPE)
- return()
- endif()
- endforeach()
-
- set(${RESULT_VAR} True PARENT_SCOPE)
-endfunction()
diff --git a/runtime/doc/lua.txt b/runtime/doc/lua.txt
index 9d4272c906..b3be11efdb 100644
--- a/runtime/doc/lua.txt
+++ b/runtime/doc/lua.txt
@@ -649,6 +649,14 @@ regex:match_line({bufnr}, {line_idx} [, {start}, {end}]) *regex:match_line()*
will be relative {start}.
------------------------------------------------------------------------------
+VIM.LPEG *lua-lpeg*
+
+ *vim.lpeg* *vim.re*
+The Lpeg library for parsing expression grammars is being included as
+`vim.lpeg` (https://www.inf.puc-rio.br/~roberto/lpeg/). In addition, its regex-like
+interface is available as `vim.re` (https://www.inf.puc-rio.br/~roberto/lpeg/re.html).
+
+------------------------------------------------------------------------------
VIM.DIFF *lua-diff*
vim.diff({a}, {b}, {opts}) *vim.diff()*
diff --git a/runtime/lua/vim/_init_packages.lua b/runtime/lua/vim/_init_packages.lua
index 5db258c011..8750afba34 100644
--- a/runtime/lua/vim/_init_packages.lua
+++ b/runtime/lua/vim/_init_packages.lua
@@ -56,6 +56,7 @@ vim._submodules = {
version = true,
fs = true,
iter = true,
+ re = true,
}
-- These are for loading runtime modules in the vim namespace lazily.
diff --git a/runtime/lua/vim/re.lua b/runtime/lua/vim/re.lua
new file mode 100644
index 0000000000..dffe37186a
--- /dev/null
+++ b/runtime/lua/vim/re.lua
@@ -0,0 +1,269 @@
+-- $Id: re.lua $
+-- vendored from lpeg-1.0.2
+-- Copyright © 2007-2019 Lua.org, PUC-Rio.
+
+-- imported functions and modules
+local tonumber, type, print, error = tonumber, type, print, error
+local setmetatable = setmetatable
+local m = require"lpeg"
+
+-- 'm' will be used to parse expressions, and 'mm' will be used to
+-- create expressions; that is, 're' runs on 'm', creating patterns
+-- on 'mm'
+local mm = m
+
+-- pattern's metatable
+local mt = getmetatable(mm.P(0))
+
+
+
+-- No more global accesses after this point
+local version = _VERSION
+if version == "Lua 5.2" then _ENV = nil end
+
+
+local any = m.P(1)
+
+
+-- Pre-defined names
+local Predef = { nl = m.P"\n" }
+
+
+local mem
+local fmem
+local gmem
+
+
+local function updatelocale ()
+ mm.locale(Predef)
+ Predef.a = Predef.alpha
+ Predef.c = Predef.cntrl
+ Predef.d = Predef.digit
+ Predef.g = Predef.graph
+ Predef.l = Predef.lower
+ Predef.p = Predef.punct
+ Predef.s = Predef.space
+ Predef.u = Predef.upper
+ Predef.w = Predef.alnum
+ Predef.x = Predef.xdigit
+ Predef.A = any - Predef.a
+ Predef.C = any - Predef.c
+ Predef.D = any - Predef.d
+ Predef.G = any - Predef.g
+ Predef.L = any - Predef.l
+ Predef.P = any - Predef.p
+ Predef.S = any - Predef.s
+ Predef.U = any - Predef.u
+ Predef.W = any - Predef.w
+ Predef.X = any - Predef.x
+ mem = {} -- restart memoization
+ fmem = {}
+ gmem = {}
+ local mt = {__mode = "v"}
+ setmetatable(mem, mt)
+ setmetatable(fmem, mt)
+ setmetatable(gmem, mt)
+end
+
+
+updatelocale()
+
+
+
+local I = m.P(function (s,i) print(i, s:sub(1, i-1)); return i end)
+
+
+local function patt_error (s, i)
+ local msg = (#s < i + 20) and s:sub(i)
+ or s:sub(i,i+20) .. "..."
+ msg = ("pattern error near '%s'"):format(msg)
+ error(msg, 2)
+end
+
+local function mult (p, n)
+ local np = mm.P(true)
+ while n >= 1 do
+ if n%2 >= 1 then np = np * p end
+ p = p * p
+ n = n/2
+ end
+ return np
+end
+
+local function equalcap (s, i, c)
+ if type(c) ~= "string" then return nil end
+ local e = #c + i
+ if s:sub(i, e - 1) == c then return e else return nil end
+end
+
+
+local S = (Predef.space + "--" * (any - Predef.nl)^0)^0
+
+local name = m.R("AZ", "az", "__") * m.R("AZ", "az", "__", "09")^0
+
+local arrow = S * "<-"
+
+local seq_follow = m.P"/" + ")" + "}" + ":}" + "~}" + "|}" + (name * arrow) + -1
+
+name = m.C(name)
+
+
+-- a defined name only have meaning in a given environment
+local Def = name * m.Carg(1)
+
+
+local function getdef (id, defs)
+ local c = defs and defs[id]
+ if not c then error("undefined name: " .. id) end
+ return c
+end
+
+-- match a name and return a group of its corresponding definition
+-- and 'f' (to be folded in 'Suffix')
+local function defwithfunc (f)
+ return m.Cg(Def / getdef * m.Cc(f))
+end
+
+
+local num = m.C(m.R"09"^1) * S / tonumber
+
+local String = "'" * m.C((any - "'")^0) * "'" +
+ '"' * m.C((any - '"')^0) * '"'
+
+
+local defined = "%" * Def / function (c,Defs)
+ local cat = Defs and Defs[c] or Predef[c]
+ if not cat then error ("name '" .. c .. "' undefined") end
+ return cat
+end
+
+local Range = m.Cs(any * (m.P"-"/"") * (any - "]")) / mm.R
+
+local item = (defined + Range + m.C(any)) / m.P
+
+local Class =
+ "["
+ * (m.C(m.P"^"^-1)) -- optional complement symbol
+ * m.Cf(item * (item - "]")^0, mt.__add) /
+ function (c, p) return c == "^" and any - p or p end
+ * "]"
+
+local function adddef (t, k, exp)
+ if t[k] then
+ error("'"..k.."' already defined as a rule")
+ else
+ t[k] = exp
+ end
+ return t
+end
+
+local function firstdef (n, r) return adddef({n}, n, r) end
+
+
+local function NT (n, b)
+ if not b then
+ error("rule '"..n.."' used outside a grammar")
+ else return mm.V(n)
+ end
+end
+
+
+local exp = m.P{ "Exp",
+ Exp = S * ( m.V"Grammar"
+ + m.Cf(m.V"Seq" * ("/" * S * m.V"Seq")^0, mt.__add) );
+ Seq = m.Cf(m.Cc(m.P"") * m.V"Prefix"^0 , mt.__mul)
+ * (#seq_follow + patt_error);
+ Prefix = "&" * S * m.V"Prefix" / mt.__len
+ + "!" * S * m.V"Prefix" / mt.__unm
+ + m.V"Suffix";
+ Suffix = m.Cf(m.V"Primary" * S *
+ ( ( m.P"+" * m.Cc(1, mt.__pow)
+ + m.P"*" * m.Cc(0, mt.__pow)
+ + m.P"?" * m.Cc(-1, mt.__pow)
+ + "^" * ( m.Cg(num * m.Cc(mult))
+ + m.Cg(m.C(m.S"+-" * m.R"09"^1) * m.Cc(mt.__pow))
+ )
+ + "->" * S * ( m.Cg((String + num) * m.Cc(mt.__div))
+ + m.P"{}" * m.Cc(nil, m.Ct)
+ + defwithfunc(mt.__div)
+ )
+ + "=>" * S * defwithfunc(m.Cmt)
+ + "~>" * S * defwithfunc(m.Cf)
+ ) * S
+ )^0, function (a,b,f) return f(a,b) end );
+ Primary = "(" * m.V"Exp" * ")"
+ + String / mm.P
+ + Class
+ + defined
+ + "{:" * (name * ":" + m.Cc(nil)) * m.V"Exp" * ":}" /
+ function (n, p) return mm.Cg(p, n) end
+ + "=" * name / function (n) return mm.Cmt(mm.Cb(n), equalcap) end
+ + m.P"{}" / mm.Cp
+ + "{~" * m.V"Exp" * "~}" / mm.Cs
+ + "{|" * m.V"Exp" * "|}" / mm.Ct
+ + "{" * m.V"Exp" * "}" / mm.C
+ + m.P"." * m.Cc(any)
+ + (name * -arrow + "<" * name * ">") * m.Cb("G") / NT;
+ Definition = name * arrow * m.V"Exp";
+ Grammar = m.Cg(m.Cc(true), "G") *
+ m.Cf(m.V"Definition" / firstdef * m.Cg(m.V"Definition")^0,
+ adddef) / mm.P
+}
+
+local pattern = S * m.Cg(m.Cc(false), "G") * exp / mm.P * (-any + patt_error)
+
+
+local function compile (p, defs)
+ if mm.type(p) == "pattern" then return p end -- already compiled
+ local cp = pattern:match(p, 1, defs)
+ if not cp then error("incorrect pattern", 3) end
+ return cp
+end
+
+local function match (s, p, i)
+ local cp = mem[p]
+ if not cp then
+ cp = compile(p)
+ mem[p] = cp
+ end
+ return cp:match(s, i or 1)
+end
+
+local function find (s, p, i)
+ local cp = fmem[p]
+ if not cp then
+ cp = compile(p) / 0
+ cp = mm.P{ mm.Cp() * cp * mm.Cp() + 1 * mm.V(1) }
+ fmem[p] = cp
+ end
+ local i, e = cp:match(s, i or 1)
+ if i then return i, e - 1
+ else return i
+ end
+end
+
+local function gsub (s, p, rep)
+ local g = gmem[p] or {} -- ensure gmem[p] is not collected while here
+ gmem[p] = g
+ local cp = g[rep]
+ if not cp then
+ cp = compile(p)
+ cp = mm.Cs((cp / rep + 1)^0)
+ g[rep] = cp
+ end
+ return cp:match(s)
+end
+
+
+-- exported names
+local re = {
+ compile = compile,
+ match = match,
+ find = find,
+ gsub = gsub,
+ updatelocale = updatelocale,
+}
+
+if version == "Lua 5.1" then _G.re = re end
+
+return re
diff --git a/src/nlua0.c b/src/nlua0.c
index af811df324..2cfa16b804 100644
--- a/src/nlua0.c
+++ b/src/nlua0.c
@@ -9,5 +9,10 @@ LUA_API int luaopen_nlua0(lua_State* L) {
luaopen_mpack(L);
lua_setfield(L, -2, "mpack");
+ int luaopen_lpeg(lua_State *);
+ luaopen_lpeg(L);
+ lua_setfield(L, -3, "lpeg");
+ lua_pop(L, 2);
+
return 1;
}
diff --git a/src/nvim/CMakeLists.txt b/src/nvim/CMakeLists.txt
index 28ba4e2ed3..c9a46ecfa1 100644
--- a/src/nvim/CMakeLists.txt
+++ b/src/nvim/CMakeLists.txt
@@ -26,6 +26,7 @@ target_include_directories(main_lib SYSTEM BEFORE INTERFACE ${LIBLUV_INCLUDE_DIR
target_link_libraries(main_lib INTERFACE ${LIBLUV_LIBRARY})
find_package(Iconv REQUIRED)
+find_package(Lpeg REQUIRED)
find_package(Libtermkey 0.22 REQUIRED)
find_package(Libvterm 0.3 REQUIRED)
find_package(Msgpack 1.0.0 REQUIRED)
@@ -38,7 +39,9 @@ target_link_libraries(main_lib INTERFACE
libvterm
msgpack
treesitter
- unibilium)
+ unibilium
+ lpeg)
+target_link_libraries(nlua0 PUBLIC lpeg)
# Libintl (not Intl) selects our FindLibintl.cmake script. #8464
find_package(Libintl REQUIRED)
@@ -324,6 +327,7 @@ if(PREFER_LUA)
endif()
list(APPEND NLUA0_SOURCES ${PROJECT_SOURCE_DIR}/src/nlua0.c)
+
foreach(subdir
os
api
@@ -443,6 +447,9 @@ add_custom_command(
"${NVIM_VERSION_DEF_H}"
DEPENDS "${PROJECT_BINARY_DIR}/cmake.config/auto/versiondef-$<CONFIG>.h")
+set(LUA_GEN ${LUA_GEN_PRG} ${GENERATOR_PRELOAD} ${PROJECT_SOURCE_DIR} $<TARGET_FILE:nlua0>)
+set(LUA_GEN_DEPS ${GENERATOR_PRELOAD} $<TARGET_FILE:nlua0>)
+
# NVIM_GENERATED_FOR_HEADERS: generated headers to be included in headers
# NVIM_GENERATED_FOR_SOURCES: generated headers to be included in sources
# NVIM_GENERATED_SOURCES: generated source files
@@ -476,7 +483,7 @@ foreach(sfile ${NVIM_SOURCES}
set(PREPROC_OUTPUT -E -o ${gf_i})
endif()
- set(depends "${HEADER_GENERATOR}" "${sfile}")
+ set(depends "${HEADER_GENERATOR}" "${sfile}" "${LUA_GEN_DEPS}")
if("${f}" STREQUAL "version.c")
# Ensure auto/versiondef_git.h exists after "make clean".
list(APPEND depends update_version_stamp "${NVIM_VERSION_GIT_H}" "${NVIM_VERSION_DEF_H}")
@@ -484,7 +491,7 @@ foreach(sfile ${NVIM_SOURCES}
add_custom_command(
OUTPUT "${gf_c_h}" "${gf_h_h}"
COMMAND ${CMAKE_C_COMPILER} ${sfile} ${PREPROC_OUTPUT} ${gen_cflags}
- COMMAND "${LUA_PRG}" "${HEADER_GENERATOR}" "${sfile}" "${gf_c_h}" "${gf_h_h}" "${gf_i}"
+ COMMAND ${LUA_GEN} "${HEADER_GENERATOR}" "${sfile}" "${gf_c_h}" "${gf_h_h}" "${gf_i}"
DEPENDS ${depends})
list(APPEND NVIM_GENERATED_FOR_SOURCES "${gf_c_h}")
list(APPEND NVIM_GENERATED_FOR_HEADERS "${gf_h_h}")
@@ -502,9 +509,6 @@ add_custom_command(OUTPUT ${GENERATED_UNICODE_TABLES}
${UNICODE_FILES}
)
-set(LUA_GEN ${LUA_GEN_PRG} ${GENERATOR_PRELOAD} ${PROJECT_SOURCE_DIR} $<TARGET_FILE:nlua0>)
-set(LUA_GEN_DEPS ${GENERATOR_PRELOAD} $<TARGET_FILE:nlua0>)
-
add_custom_command(
OUTPUT ${GENERATED_API_DISPATCH} ${GENERATED_FUNCS_METADATA}
${API_METADATA} ${LUA_API_C_BINDINGS} ${GENERATED_KEYSETS_DEFS}
diff --git a/src/nvim/generators/c_grammar.lua b/src/nvim/generators/c_grammar.lua
index 17a224fd22..d83658e977 100644
--- a/src/nvim/generators/c_grammar.lua
+++ b/src/nvim/generators/c_grammar.lua
@@ -1,4 +1,4 @@
-local lpeg = require('lpeg')
+local lpeg = vim.lpeg
-- lpeg grammar for building api metadata from a set of header files. It
-- ignores comments and preprocessor commands and parses a very small subset
diff --git a/src/nvim/generators/gen_declarations.lua b/src/nvim/generators/gen_declarations.lua
index 4097ff7dc5..7ed0624b05 100755..100644
--- a/src/nvim/generators/gen_declarations.lua
+++ b/src/nvim/generators/gen_declarations.lua
@@ -1,12 +1,9 @@
-#!/usr/bin/lua
-
local fname = arg[1]
local static_fname = arg[2]
local non_static_fname = arg[3]
local preproc_fname = arg[4]
-
-local lpeg = require('lpeg')
+local lpeg = vim.lpeg
local fold = function (func, ...)
local result = nil
diff --git a/src/nvim/lua/stdlib.c b/src/nvim/lua/stdlib.c
index 20a99b2836..c196a89842 100644
--- a/src/nvim/lua/stdlib.c
+++ b/src/nvim/lua/stdlib.c
@@ -611,6 +611,19 @@ void nlua_state_add_stdlib(lua_State *const lstate, bool is_thread)
lua_setfield(lstate, -2, "mpack");
lua_pop(lstate, 3);
+ // vim.lpeg
+ int luaopen_lpeg(lua_State *);
+ luaopen_lpeg(lstate);
+ lua_pushvalue(lstate, -1);
+ lua_setfield(lstate, -4, "lpeg");
+
+ // package.loaded.lpeg = vim.lpeg
+ lua_getglobal(lstate, "package");
+ lua_getfield(lstate, -1, "loaded");
+ lua_pushvalue(lstate, -3);
+ lua_setfield(lstate, -2, "lpeg");
+ lua_pop(lstate, 4);
+
// vim.diff
lua_pushcfunction(lstate, &nlua_xdl_diff);
lua_setfield(lstate, -2, "diff");
diff --git a/test/functional/lua/vim_spec.lua b/test/functional/lua/vim_spec.lua
index 53c21fd668..86eb600bd9 100644
--- a/test/functional/lua/vim_spec.lua
+++ b/test/functional/lua/vim_spec.lua
@@ -3031,6 +3031,15 @@ describe('lua stdlib', function()
eq(false, if_nil(d, c))
eq(NIL, if_nil(a))
end)
+
+ it('lpeg', function()
+ eq(5, exec_lua [[
+ local m = vim.lpeg
+ return m.match(m.R'09'^1, '4504ab')
+ ]])
+
+ eq(4, exec_lua [[ return vim.re.match("abcde", '[a-c]+') ]])
+ end)
end)
describe('lua: builtin modules', function()