Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 9 additions & 3 deletions lua/luasnip/loaders/from_lua.lua
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ local M = {}
-- It is not exported, because it will (in its current state) only ever be used
-- in one place, and it feels a bit wrong to expose put a function into `M`.
-- Instead, it is inserted into the global environment before a luasnippet-file
-- is loaded, and removed from it immediately when this is done
-- is loaded, and the previous value restored immediately when this is done
local function get_loaded_file_debuginfo()
-- we can skip looking at the first four stackframes, since
-- 1 is this function
Expand Down Expand Up @@ -155,14 +155,20 @@ local function _luasnip_load_file(file)
-- Since this function has to reach the snippet-constructor, and fenvs
-- aren't inherited by called functions, we have to set it in the global
-- environment.
-- Save and restore, don't unconditionally nil: this function is re-entrant.
-- A snippet-file may, while it is executing, cause another file to be
-- loaded (for example by requiring a module from a plugin that registers a
-- collection in its setup), and clearing the global on return from that
-- inner load would silence source-recording for the rest of the outer file.
local prev_get_debuginfo = _G.__luasnip_get_loaded_file_frame_debuginfo
_G.__luasnip_get_loaded_file_frame_debuginfo = util.ternary(
session.config.loaders_store_source,
get_loaded_file_debuginfo,
nil
)
local run_ok, file_snippets_or_err, file_autosnippets = pcall(func)
-- immediately nil it.
_G.__luasnip_get_loaded_file_frame_debuginfo = nil
-- immediately restore it.
_G.__luasnip_get_loaded_file_frame_debuginfo = prev_get_debuginfo

if not run_ok then
local err = file_snippets_or_err
Expand Down
1 change: 1 addition & 0 deletions tests/data/lua-snippets/nested-load/inner/all.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
return { s("nested_inner", t("inner")) }
13 changes: 13 additions & 0 deletions tests/data/lua-snippets/nested-load/outer/all.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
-- Loading this file triggers another load while it is still executing, as
-- happens when a snippet-file requires a module from a plugin that registers
-- its own collection.
local before = s("nested_before", t("before"))

require("luasnip.loaders.from_lua").load({
paths = os.getenv("LUASNIP_SOURCE")
.. "/tests/data/lua-snippets/nested-load/inner",
})

local after = s("nested_after", t("after"))

return { before, after }
32 changes: 32 additions & 0 deletions tests/integration/source_spec.lua
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ local ls_helpers = require("helpers")
local exec_lua, feed, exec =
ls_helpers.exec_lua, ls_helpers.feed, ls_helpers.exec
local Screen = require("test.functional.ui.screen")
local assert = ls_helpers.assert

describe("loaders:", function()
local screen
Expand Down Expand Up @@ -59,6 +60,37 @@ describe("loaders:", function()
})
end)

it("lua: stores source after a nested load.", function()
setup({
no_snip_globals = true,
setup_extend = { loaders_store_source = true },
})
exec_lua(
string.format(
[[require("luasnip.loaders.from_lua").load({paths="%s"})]],
os.getenv("LUASNIP_SOURCE")
.. "/tests/data/lua-snippets/nested-load/outer"
)
)

-- `nested_after` is defined after the outer file triggers a load of
-- the inner collection, and used to end up without a source.
assert.eq(
{
nested_before = true,
nested_inner = true,
nested_after = true,
},
exec_lua([[
local has_source = {}
for _, snip in ipairs(ls.get_snippets("all")) do
has_source[snip.trigger] = ls.snippet_source.get(snip) ~= nil
end
return has_source
]])
)
end)

it("vscode: error-message when parser not installed.", function()
setup({
no_snip_globals = true,
Expand Down
Loading