Skip to content

fix(loaders): keep recording sources across a nested lua-load - #1451

Open
Chiarandini wants to merge 1 commit into
L3MON4D3:masterfrom
Chiarandini:fix/nested-load-source
Open

fix(loaders): keep recording sources across a nested lua-load#1451
Chiarandini wants to merge 1 commit into
L3MON4D3:masterfrom
Chiarandini:fix/nested-load-source

Conversation

@Chiarandini

Copy link
Copy Markdown

Problem

With loaders_store_source = true, snippets defined past a certain point in a lua snippet-file are stored with no source, so ls.snippet_source.get returns nil and extras.snip_location cannot jump to their definition. Which file loses its sources varies between runs, which makes it read like flakiness rather than a rule.

Cause

_luasnip_load_file puts __luasnip_get_loaded_file_frame_debuginfo into the global environment before running a snippet-file, and sets it back to nil afterwards. The function is re-entrant, so an inner load clears the getter for the outer file as well, and every snippet the outer file defines after that point is stored without a source.

Re-entering is ordinary rather than exotic: a snippet-file that requires a module from a plugin loaded on demand runs that plugin's setup mid-file, and a setup that registers its own collection loads a file.

Fix

Save the previous value and restore it, instead of clearing unconditionally. get_loaded_file_debuginfo already resolves the correct frame by walking the stack for the nearest _luasnip_load_file, so nesting needs nothing further.

Test

tests/integration/source_spec.lua gains a case backed by two fixture collections. The outer file defines a snippet, triggers a load of the inner collection while it is still executing, then defines another. Before the change the second snippet has no source; after it, both do.

Fails on master, passes with the fix, and loaders_spec stays at 58/58.

🤖 Generated with Claude Code

`_luasnip_load_file` puts `__luasnip_get_loaded_file_frame_debuginfo`
into the global environment before running a snippet-file and set it
back to nil afterwards. The function is re-entrant, so the inner call
cleared the getter for the outer file as well, and every snippet the
outer file defined after that point was stored without a source.

Re-entering is ordinary: a snippet-file that requires a module from a
plugin loaded on demand runs that plugin's setup mid-file, and a setup
that registers its own collection loads a file. The result is that
`ls.snippet_source.get` returns nil, so `snip_location` cannot jump to
the definition and anything else built on sources sees a gap it cannot
explain.

Save the previous value and restore it instead of clearing. The getter
itself already resolves the right frame by walking the stack for the
nearest `_luasnip_load_file`, so nesting needs nothing further.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant