update jsregexp to 0.0.6.

Still continues to work with 0.0.5 too, but also support 0.0.6, which,
despite having the same API, is a bit harder to set up (see `util/jsregexp.lua`)
This commit is contained in:
L3MON4D3 2023-11-29 23:01:28 +01:00 committed by L3MON4D3
parent 1def353778
commit e449e6e325
14 changed files with 161 additions and 80 deletions

View file

@ -15,4 +15,4 @@ jobs:
LUAROCKS_API_KEY: ${{ secrets.LUAROCKS_API_KEY }} LUAROCKS_API_KEY: ${{ secrets.LUAROCKS_API_KEY }}
with: with:
dependencies: | dependencies: |
jsregexp == 0.0.5 jsregexp >= 0.0.5, <= 0.0.6

2
.gitignore vendored
View file

@ -2,3 +2,5 @@
/deps/nvim_multiversion /deps/nvim_multiversion
/doc/tags /doc/tags
/lua/luasnip-jsregexp.so /lua/luasnip-jsregexp.so
/deps/luasnip-jsregexp.so
/lua/luasnip-jsregexp.lua

5
.gitmodules vendored
View file

@ -1,3 +1,6 @@
[submodule "deps/jsregexp"] [submodule "deps/jsregexp"]
path = deps/jsregexp path = deps/jsregexp
url = ../../kmarius/jsregexp/ url = ../../kmarius/jsregexp
[submodule "deps/jsregexp005"]
path = deps/jsregexp005
url = ../../kmarius/jsregexp

View file

@ -40,32 +40,42 @@ ifeq ($(LUASNIP_DETECTED_OS),Darwin)
# remove -bundle, should be equivalent to the -shared hardcoded by jsregexp. # remove -bundle, should be equivalent to the -shared hardcoded by jsregexp.
LUA_LDLIBS=-undefined dynamic_lookup -all_load LUA_LDLIBS=-undefined dynamic_lookup -all_load
endif endif
JSREGEXP_PATH=deps/jsregexp JSREGEXP_PATH=deps/jsregexp
JSREGEXP005_PATH=deps/jsregexp005
jsregexp: jsregexp:
git submodule init git submodule init
git submodule update git submodule update
make "INCLUDE_DIR=-I$(shell pwd)/deps/lua51_include/" LDLIBS="${LUA_LDLIBS}" -C ${JSREGEXP_PATH} make "INCLUDE_DIR=-I$(shell pwd)/deps/lua51_include/" LDLIBS="${LUA_LDLIBS}" -C ${JSREGEXP_PATH}
make "INCLUDE_DIR=-I$(shell pwd)/deps/lua51_include/" LDLIBS="${LUA_LDLIBS}" -C ${JSREGEXP005_PATH}
install_jsregexp: jsregexp install_jsregexp: jsregexp
# access via require("luasnip-jsregexp") # remove old binary.
# The hyphen must be used here, otherwise the luaopen_*-call will fail. rm "$(shell pwd)/lua/luasnip-jsregexp.so" || true
# See the package.loaders-section [here](https://www.lua.org/manual/5.1/manual.html#pdf-require) # there is some additional trickery to make this work with jsregexp-0.0.6 in
cp "$(shell pwd)/${JSREGEXP_PATH}/jsregexp.so" "$(shell pwd)/lua/luasnip-jsregexp.so" # util/jsregexp.lua.
cp "$(shell pwd)/${JSREGEXP_PATH}/jsregexp.lua" "$(shell pwd)/lua/luasnip-jsregexp.lua"
# just move out of jsregexp-directory, so it is not accidentially deleted.
cp "$(shell pwd)/${JSREGEXP_PATH}/jsregexp.so" "$(shell pwd)/deps/luasnip-jsregexp.so"
uninstall_jsregexp: uninstall_jsregexp:
# also remove binaries of older version.
rm "$(shell pwd)/lua/luasnip-jsregexp.so" rm "$(shell pwd)/lua/luasnip-jsregexp.so"
rm "$(shell pwd)/lua/deps/luasnip-jsregexp.so"
rm "$(shell pwd)/lua/luasnip-jsregexp.lua"
TEST_07?=true TEST_07?=true
TEST_09?=true TEST_09?=true
TEST_MASTER?=true TEST_MASTER?=true
# Expects to be run from repo-location (eg. via `make -C path/to/luasnip`). # Expects to be run from repo-location (eg. via `make -C path/to/luasnip`).
test: nvim jsregexp test: nvim install_jsregexp
# unset PATH and CPATH to prevent system-env leaking into the neovim-build, # unset PATH and CPATH to prevent system-env leaking into the neovim-build,
# add our helper-functions to lpath. # add our helper-functions to lpath.
# exit as soon as an error occurs. # exit as soon as an error occurs.
unset LUA_PATH LUA_CPATH; \ unset LUA_PATH LUA_CPATH; \
export LUASNIP_SOURCE=$(shell pwd); \ export LUASNIP_SOURCE=$(shell pwd); \
export JSREGEXP_PATH=$(shell pwd)/${JSREGEXP_PATH}; \ export JSREGEXP_ABS_PATH=$(shell pwd)/${JSREGEXP_PATH}; \
export JSREGEXP005_ABS_PATH=$(shell pwd)/${JSREGEXP005_PATH}; \
export TEST_FILE=$(realpath ${TEST_FILE}); \ export TEST_FILE=$(realpath ${TEST_FILE}); \
export BUSTED_ARGS=--lpath=$(shell pwd)/tests/?.lua; \ export BUSTED_ARGS=--lpath=$(shell pwd)/tests/?.lua; \
set -e; \ set -e; \

2
deps/jsregexp vendored

@ -1 +1 @@
Subproject commit c3e473240eebb65a8870abebafeff83b6c9e7f16 Subproject commit b5a81e21d0875667ba2458ac8ae903afd5568698

1
deps/jsregexp005 vendored Submodule

@ -0,0 +1 @@
Subproject commit dd65498ae2c29b882d6c02c0a30577b08d660b94

View file

@ -1,4 +1,4 @@
local jsregexp = require("luasnip.util.util").jsregexp local jsregexp_compile_safe = require("luasnip.util.jsregexp")
-- these functions get the line up to the cursor, the trigger, and then -- these functions get the line up to the cursor, the trigger, and then
-- determine whether the trigger matches the current line. -- determine whether the trigger matches the current line.
@ -42,9 +42,9 @@ local function match_pattern(line_to_cursor, trigger)
end end
local ecma_engine local ecma_engine
if jsregexp then if jsregexp_compile_safe then
ecma_engine = function(trig) ecma_engine = function(trig)
local trig_compiled, err_maybe = jsregexp.compile(trig .. "$", "") local trig_compiled, err_maybe = jsregexp_compile_safe(trig .. "$", "")
if not trig_compiled then if not trig_compiled then
error(("Error while compiling regex: %s"):format(err_maybe)) error(("Error while compiling regex: %s"):format(err_maybe))
end end

View file

@ -0,0 +1,40 @@
local Path = require("luasnip.util.path")
-- neovim-loader does not handle module-names with dots correctly, so for
-- jsregexp-0.0.6, the call to require("jsregexp.core") in jsregexp.lua errors
-- even if the library is in rtp.
-- Resolve path to jsregexp.so manually, and loadlib it in preload (and remove
-- preload after requires are done and have failed/worked).
-- omit "@".
local this_file = debug.getinfo(1).source:sub(2)
local repo_dir = vim.fn.fnamemodify(this_file, ":h:h:h:h")
local jsregexp_core_path = Path.join(repo_dir, "deps", "luasnip-jsregexp.so")
-- rather gracefully, if the path does not exist, or loadlib can't do its job
-- for some other reason, the preload will be set to nil, ie not be set.
--
-- This means we don't hinder a regularly installed 0.0.6-jsregexp-library,
-- since its `require("jsregexp.core")` will be unaffected.
package.preload["jsregexp.core"] = package.loadlib(jsregexp_core_path, "luaopen_jsregexp_core")
-- jsregexp: first try loading the version installed by luasnip, then global ones.
local jsregexp_ok, jsregexp = pcall(require, "luasnip-jsregexp")
if not jsregexp_ok then
jsregexp_ok, jsregexp = pcall(require, "jsregexp")
end
-- don't want to affect other requires.
package.preload["jsregexp.core"] = nil
if not jsregexp_ok then
return false
end
-- detect version, and return compile-function.
-- 0.0.6-compile_safe and 0.0.5-compile behave the same, ie. nil, err on error.
if jsregexp.compile_safe then
return jsregexp.compile_safe
else
return jsregexp.compile
end

View file

@ -3,7 +3,7 @@ local types = Ast.node_type
local util = require("luasnip.util.util") local util = require("luasnip.util.util")
local Str = require("luasnip.util.str") local Str = require("luasnip.util.str")
local log = require("luasnip.util.log").new("parser") local log = require("luasnip.util.log").new("parser")
local jsregexp = require("luasnip.util.util").jsregexp local jsregexp_compile_safe = require("luasnip.util.jsregexp")
local directed_graph = require("luasnip.util.directed_graph") local directed_graph = require("luasnip.util.directed_graph")
@ -303,40 +303,46 @@ local function apply_transform_format(nodes, captures)
end end
function M.apply_transform(transform) function M.apply_transform(transform)
if jsregexp then if jsregexp_compile_safe then
local reg_compiled = local reg_compiled, err =
jsregexp.compile(transform.pattern, transform.option) jsregexp_compile_safe(transform.pattern, transform.option)
-- can be passed to functionNode!
return function(lines)
-- luasnip expects+passes lines as list, but regex needs one string.
lines = table.concat(lines, "\n")
local matches = reg_compiled(lines)
local transformed = "" if reg_compiled then
-- index one past the end of previous match. -- can be passed to functionNode!
-- This is used to append unmatched characters to `transformed`, so return function(lines)
-- it's initialized such that the first append is from 1. -- luasnip expects+passes lines as list, but regex needs one string.
local prev_match_end = 0 lines = table.concat(lines, "\n")
for _, match in ipairs(matches) do local matches = reg_compiled(lines)
-- begin_ind and end_ind are inclusive.
transformed = transformed
.. lines:sub(prev_match_end + 1, match.begin_ind - 1)
.. apply_transform_format(transform.format, match.groups)
-- end-inclusive local transformed = ""
prev_match_end = match.end_ind -- index one past the end of previous match.
-- This is used to append unmatched characters to `transformed`, so
-- it's initialized such that the first append is from 1.
local prev_match_end = 0
for _, match in ipairs(matches) do
-- begin_ind and end_ind are inclusive.
transformed = transformed
.. lines:sub(prev_match_end + 1, match.begin_ind - 1)
.. apply_transform_format(transform.format, match.groups)
-- end-inclusive
prev_match_end = match.end_ind
end
transformed = transformed .. lines:sub(prev_match_end + 1, #lines)
return vim.split(transformed, "\n")
end end
transformed = transformed .. lines:sub(prev_match_end + 1, #lines) else
log.error("Failed parsing regex `%s` with options `%s`: %s", transform.pattern, transform.option, err)
return vim.split(transformed, "\n") -- fall through to returning identity.
end end
else
-- without jsregexp, we cannot properly transform whatever is supposed to
-- be transformed here.
-- Just return a function that returns the to-be-transformed string
-- unmodified.
return util.id
end end
-- without jsregexp, or without a valid regex, we cannot properly transform
-- whatever is supposed to be transformed here.
-- Just return a function that returns the to-be-transformed string
-- unmodified.
return util.id
end end
---Variables need the text which is in front of them to determine whether they ---Variables need the text which is in front of them to determine whether they

View file

@ -1,11 +1,5 @@
local session = require("luasnip.session") local session = require("luasnip.session")
-- jsregexp: first try loading the version installed by luasnip, then global ones.
local jsregexp_ok, jsregexp = pcall(require, "luasnip-jsregexp")
if not jsregexp_ok then
jsregexp_ok, jsregexp = pcall(require, "jsregexp")
end
local function get_cursor_0ind() local function get_cursor_0ind()
local c = vim.api.nvim_win_get_cursor(0) local c = vim.api.nvim_win_get_cursor(0)
c[1] = c[1] - 1 c[1] = c[1] - 1
@ -528,6 +522,5 @@ return {
indx_of = indx_of, indx_of = indx_of,
lazy_table = lazy_table, lazy_table = lazy_table,
ternary = ternary, ternary = ternary,
jsregexp = jsregexp_ok and jsregexp,
pos_cmp = pos_cmp, pos_cmp = pos_cmp,
} }

View file

@ -5,11 +5,53 @@ local assert = require("luassert")
local M = {} local M = {}
function M.setup_jsregexp() function M.jsregexp_it(it, name, fn)
-- append default-path. for _, version in ipairs({"005", "006", "luasnip"}) do
exec_lua( it(name .. " (jsregexp-" .. version .. ")", function()
('package.cpath = "%s"'):format(os.getenv("JSREGEXP_PATH") .. "/?.so;;") exec_lua([[
) local version, jsregexp_005_path, jsregexp_path = ...
if version ~= "luasnip" then
if version == "005" then
package.preload["jsregexp"] = package.loadlib(jsregexp_005_path .. "/jsregexp.so", "luaopen_jsregexp")
if package.preload["jsregexp"]().compile_safe then
error("wrong jsregexp-version loaded")
end
else
package.preload["jsregexp.core"] = package.loadlib(jsregexp_path .. "/jsregexp.so", "luaopen_jsregexp_core")
package.path = jsregexp_path .. "/?.lua;;"
-- populate package now, before jsregexp-core-preload is overwritten in util/jsregexp.lua.
-- also load it to check the version.
local jsregexp = require("jsregexp")
-- is actually 0.0.6.
if not jsregexp.compile_safe then
error("wrong jsregexp-version loaded")
end
end
-- don't accidentially load luasnip-jsregexp with unknown version.
local old_require = require
require = function(modulename)
if modulename == "luasnip-jsregexp" then
error("Disabled by `prevent_jsregexp`")
end
return old_require(modulename)
end
else
-- don't accidentially load regular jsregexp.
local old_require = require
require = function(modulename)
if modulename == "jsregexp" then
error("Disabled by `prevent_jsregexp`")
end
return old_require(modulename)
end
end
]], version, os.getenv("JSREGEXP005_ABS_PATH"), os.getenv("JSREGEXP_ABS_PATH"))
fn()
end)
end
end end
function M.prevent_jsregexp() function M.prevent_jsregexp()

View file

@ -205,8 +205,7 @@ describe("Parser", function()
}) })
end) end)
it("can parse transformed variables.", function() ls_helpers.jsregexp_it(it, "can parse transformed variables", function()
ls_helpers.setup_jsregexp()
ls_helpers.session_setup_luasnip() ls_helpers.session_setup_luasnip()
local snip = '"a${TM_LINE_INDEX/(.*)/asdf $1 asdf/g}a"' local snip = '"a${TM_LINE_INDEX/(.*)/asdf $1 asdf/g}a"'
@ -244,8 +243,7 @@ describe("Parser", function()
}) })
end) end)
it("can parse transformed tabstop.", function() ls_helpers.jsregexp_it(it, "can parse transformed tabstop.", function()
ls_helpers.setup_jsregexp()
ls_helpers.session_setup_luasnip() ls_helpers.session_setup_luasnip()
local snip = '"$1 a ${1/(.*)/asdf $1 asdf/} a"' local snip = '"$1 a ${1/(.*)/asdf $1 asdf/} a"'
@ -297,8 +295,7 @@ describe("Parser", function()
error("unexpected key " .. modifier .. " in expected_map") error("unexpected key " .. modifier .. " in expected_map")
end end
it("applies " .. modifier .. " correctly", function() ls_helpers.jsregexp_it(it, "applies " .. modifier .. " correctly", function()
ls_helpers.setup_jsregexp()
ls_helpers.session_setup_luasnip() ls_helpers.session_setup_luasnip()
local snip = ('"${1:%s} ${1/(.*)/${1:/%s}/}"'):format( local snip = ('"${1:%s} ${1/(.*)/${1:/%s}/}"'):format(
text, text,
@ -406,12 +403,7 @@ describe("Parser", function()
{2:-- SELECT --} |]], {2:-- SELECT --} |]],
}) })
exec_lua("ls.jump(1)") exec_lua("ls.jump(1)")
screen:expect({ screen:expect({ unchanged = true })
grid = [[
^q{3:wer} asdf |
{0:~ }|
{2:-- SELECT --} |]],
})
end) end)
it("turns the correct nodes into insert/functionNode", function() it("turns the correct nodes into insert/functionNode", function()
@ -450,8 +442,7 @@ describe("Parser", function()
}) })
end) end)
it("can modify groups in transform.", function() ls_helpers.jsregexp_it(it, "can modify groups in transform.", function()
ls_helpers.setup_jsregexp()
ls_helpers.session_setup_luasnip() ls_helpers.session_setup_luasnip()
local snip = '"$1 a ${1/(.*)/asdf ${1:/upcase} asdf/} a"' local snip = '"$1 a ${1/(.*)/asdf ${1:/upcase} asdf/} a"'
@ -474,8 +465,7 @@ describe("Parser", function()
}) })
end) end)
it("handle multiple captures in transform.", function() ls_helpers.jsregexp_it(it, "handle multiple captures in transform.", function()
ls_helpers.setup_jsregexp()
ls_helpers.session_setup_luasnip() ls_helpers.session_setup_luasnip()
local snip = '"${1:bbb} a ${1/(.)b(.)/${1:/upcase} $2/g} a"' local snip = '"${1:bbb} a ${1/(.)b(.)/${1:/upcase} $2/g} a"'
@ -703,8 +693,7 @@ describe("Parser", function()
}) })
end) end)
it("Applies transform to empty variable.", function() ls_helpers.jsregexp_it(it, "Applies transform to empty variable.", function()
ls_helpers.setup_jsregexp()
ls_helpers.session_setup_luasnip() ls_helpers.session_setup_luasnip()
local snip = "${TM_SELECTED_TEXT/(.*)/ asd /}" local snip = "${TM_SELECTED_TEXT/(.*)/ asd /}"
@ -718,8 +707,7 @@ describe("Parser", function()
}) })
end) end)
it("correctly transforms multiline-values.", function() ls_helpers.jsregexp_it(it, "correctly transforms multiline-values.", function()
ls_helpers.setup_jsregexp()
ls_helpers.session_setup_luasnip() ls_helpers.session_setup_luasnip()
local snip = "${TM_SELECTED_TEXT/([^]*)/a ${1} a/}" local snip = "${TM_SELECTED_TEXT/([^]*)/a ${1} a/}"
@ -737,10 +725,9 @@ describe("Parser", function()
}) })
end) end)
it( ls_helpers.jsregexp_it(it,
"correctly transforms if the match does not include the first character.", "correctly transforms if the match does not include the first character.",
function() function()
ls_helpers.setup_jsregexp()
ls_helpers.session_setup_luasnip() ls_helpers.session_setup_luasnip()
local snip = "${1:asdf.asdf} ${1/[\\.]/-/g}" local snip = "${1:asdf.asdf} ${1/[\\.]/-/g}"
@ -872,8 +859,7 @@ describe("Parser", function()
}) })
end) end)
it("Correctly parses unescaped characters.", function() ls_helpers.jsregexp_it(it, "Correctly parses unescaped characters.", function()
ls_helpers.setup_jsregexp()
ls_helpers.session_setup_luasnip() ls_helpers.session_setup_luasnip()
local snip = "${} asdf" local snip = "${} asdf"

View file

@ -20,7 +20,6 @@ describe("session", function()
before_each(function() before_each(function()
helpers.clear() helpers.clear()
ls_helpers.setup_jsregexp()
ls_helpers.session_setup_luasnip({ hl_choiceNode = true }) ls_helpers.session_setup_luasnip({ hl_choiceNode = true })
-- add a rather complicated snippet. -- add a rather complicated snippet.

View file

@ -8,7 +8,6 @@ describe("snippets_basic", function()
before_each(function() before_each(function()
helpers.clear() helpers.clear()
ls_helpers.setup_jsregexp()
ls_helpers.session_setup_luasnip() ls_helpers.session_setup_luasnip()
screen = Screen.new(50, 3) screen = Screen.new(50, 3)