L3MON4D3/LuaSnip

Breaking Changes

L3MON4D3 opened this issue · 20 comments

Watch this issue to be notified of any breaking changes.

thanks to @clason for recommending this

23.07.2021

09716b1

Changed default for wordTrig to true. If you have any snippets that rely on the default being false, wordTrig must now be explicitly set to false, eg.

s({trig = "trigger anywhere"}, {...})

or

s("trigger anywhere", {...})

to

s({trig = "trigger anywhere", wordTrig=false}, {...})

24.07.2021

e9f4d03

Move pseudo-nodes (rep and partial) from luasnip.util.functions to luasnip.extras.

These functions are probably imported once:

local r = require("luasnip.util.functions").rep
local p = require("luasnip.util.functions").partial

Those lines must be changed to

local r = require("luasnip.extras").rep
local p = require("luasnip.extras").partial

02.08.2021

eb4680f

Pass function/dynamicNodes their arg-text without snippet-indent, prepend snippet-indent to returned text.

Should affect very few setups, if a functionNode relies on the previous behaviour, they can now be simplified.

26.08.2021

f2d90d4

This commit changes the third and subsequent arguments to s(...) from s(context, nodes, condition: function, ...) to s(context, nodes, opts: table), meaning no more user-arguments for the condition-function (via s(...) at least).
The condition-function can now be set via opts.condition. As for passing arguments to condition, that is now only possible using partial functions:

-- Checks whether the same number of c1 and c2 occur on the current line.
-- The implementation is omitted as it is irrelevant in this context.
local function char_count_nequal(c1, c2) ... end

-- only expand if a closing ) is missing:
s("(", {t"(", i(1), t")"}, char_count_nequal, "(", ")")

would now be

-- Checks whether the same number of c1 and c2 occur on the current line.
-- The implementation is omitted as it is irrelevant in this context.
local function char_count_nequal(c1, c2) ... end

local function partial(func, ...)
	local args = {...}
	return function() return func(unpack(args))
end

-- only expand if a closing ) is missing:
s("(", {t"(", i(1), t")"}, { condition = partial(char_count_nequal, "(", ")") })

(The user_args for function/dynamicNodes may also be removed in the future)

## 30.08.2021

d2aa43c

Fixes parsing of {,} in lsp-snippets, only closing brackets have to be escaped, opening ones don't.
In fixing, the parser also got more strict, previously "\\begin{$1}" would've parsed just fine, now the closing } has to be escaped("\begin{$1\}").

Doesn't apply anymore as of 31.08.2021, eg."\begin{}" parses just fine again.

05.09.2021

8361b35

The functions used in matchNode are no longer only passed the '\n'-joined text from the node. Instead, they now get the same object as the function passed to functionNode ie. {{line1, line2}, snip}.

Changing

function(text)
	-- do something with text.
end

to

function(args)
	local text = table.concat(args[1], "\n")
	-- do the same thing with text.
end

should do the trick.

21.09.2021

cb4fe49

Changes the signature of the function passed to function/dynamicNodes from

-- snippet inside the table of argnodes' text.
function({argnode_text, snip}, ...) end

to

function(argnode_text, snip, ...) end

(eg. the snippet can no longer be accessed as argnode_text[#argnode_text], but only as a separate argument).

This will likely break many configs, but adjusting the existing functions should be straightforward:

-- also likely: args[#args]
f(function(args) return args[1].env.SELECT_DEDENT end, {})

to

f(function(args, snip) return snip.env.SELECT_DEDENT end, {})

23.09.2021

257f65b

Changes the meaning of passive in ext_opts, it now only applies while the snippet is active.
To get back the old behaviour, the new snippet_passive-key may be used:

vim.api.nvim_command("hi LuasnipInsertNodePassive cterm=italic")
ls.config.setup({
	ext_opts = {
		[types.choiceNode] = {
			passive = {
				virt_text = {{"", "GruvboxOrange"}},
			}
		},
	},
})

to

vim.api.nvim_command("hi LuasnipInsertNodeSnippetPassive cterm=italic")
ls.config.setup({
	ext_opts = {
		[types.choiceNode] = {
			snippet_passive = {
				virt_text = {{"", "GruvboxOrange"}},
			}
		},
	},
})

29.10.2021

b7d520e

The module luasnip.extras.conditions was moved to luasnip.extras.expand_conditions due to their incompatibility with show_condition.
To transition, it's enough to change

local conditions = require("luasnip.extras.conditions")

to

local conditions = require("luasnip.extras.expand_conditions")

14.12.2021

dddd655

env is no longer passed to snippetNodes, only the actual snippet contains it. The commit-message contains a short discussion of the change.

Most dynamic/functionNode-functions should keep working, if not, replacing all occurences of

second_arg.env.SOMETHING

with

second_arg.snippet.env.SOMETHING

should do the trick.

07.03.2022

b8a4480

require("luasnip.loader.from_*").load() will no longer load snippets asynchronously, which means startup might take an additional ~60ms (depending on the number of snippets).

There are two ways to mitigate the effect of this change on your precious startuptime:

  • lazy_load the snippets

     require("luasnip.loaders.from_snipmate").lazy_load()
     -- or
     require("luasnip.loaders.from_vscode").lazy_load()
  • or, if you need to modify the loaded snippets in any way, do

     vim.schedule(function()
     	-- likewise for `from_snipmate`
     	require("luasnip.loaders.from_vscode").load()
     	-- modify snippets here.
     end)

    Note: do not vim.schedule lazy_load, the snippets are loaded on certainevents and (depending on scheduling) the autocommands for actually loading the snippets might only be registered after the event already fired.

11.03.2022

48a79b7

The last argument of all nodes is now a table containing optional arguments, which clashes with the user_args of variable length in dynamic/functionNode.
The user_args are now simply accepted in the previously mentioned table:

d(1, some_function, {argnode1, argnode2}, "user_arg1", "user_arg2")

becomes

d(1, some_function, {argnode1, argnode2}, { user_args = {"user_arg1", "user_arg2"}})

This is not a breaking change, but important nonetheless:
We're planning to move away from exposing the internal structure of snippet-storage (the ls.snippets-table) to setting/getting snippets via functions (details in #338).
If some workflow of yours depends on the current layout/direct access to that table, please leave a comment there so we can find a solution.

20.03.2022

Accessing ls.snippets directly is deprecated as of now and will be removed on 27.03.2022.

If you cannot find the time to adapt your luasnip-config until then, follow the ls_snippets_preserve-branch, it will not receive the breaking changes (Packer: use({"L3MON4D3/Luasnip", branch = "ls_snippets_preserve"}), vim-plug: Plug "L3MON4D3/Luasnip", { "branch": "ls_snippets_preserve" }).

From now on, ls.add_snippets() should be used for adding snippets to luasnip.

ls.snippets = {
	all = {
		...
	},
	lua = {
		...
	},
	...
}

becomes

ls.add_snippets(nil, {
	all = {
		...
	},
	lua = {
		...
	},
})
ls.snippets.c = {
	...
}

becomes

ls.add_snippets("c", {
	...
})

If you want to be able to reload your snippets, you can provide an unique key to each add_snippets-call and just :luafile the file adding these snippets after changing it.

ls.add_snippets("lua", {
	...
}, {
	key = "my_lua_snippets"
})

If you're currently using __index on ls.snippets for loading snippets, there is a drop-in-replacement. Just add either of

-- load all snippets directly, on startup.
require("luasnip.loaders.from_lua").load({paths = "path/to/the/snippet/directory"})
-- emulate previous behaviour, eg. load snippets as late as possible.
require("luasnip.loaders.from_lua").lazy_load({paths = "path/to/the/snippet/directory"})

(you'll probably want the lazy_load) to your config.

You can also move the snippet-files to a directory inside any in runtimepath named luasnippets (eg. ~/.config/nvim/luasnippets), in which case they will be autodetected and paths doesn't have to be specified.
There is some more info on this loader in DOC.md

28.03.2022

aeea587

As announced in the previous comment, ls.snippets may no longer be directly accessed as of now.

17.08.2022

0585c11

(This shouldn't affect any configs during "regular" usage)

Luasnip, in some instances, replaces paths with the parent-directory of $MYVIMRC.
If $MYVIMRC is not set (probably due to calling nvim with -u a_minimum_working_example.lua), a heuristic is used to find the file that was loaded. This used to be quickly done, but is now more complicated.
So, from now on, if $MYVIMRC is not set, the cwd is used as this parent-directory.
(If cwd is not desired, MYVIMRC can just be added to env before nvim -u ... is executed)

02.09.2022

c919d04

(shouldn't affect anyone tbh, but technically...)
From now on, the environment-namespace LS will be used for new (not present in vscode) environment-variables.
This also means it can no longer be used for user-defined namespaces, any using this prefix have to be renamed :/

(Some older luasnip-specific variables, SELECT_DEDENT and SELECT_RAW, were also moved for uniformity, but remain accessible under their old names)

09.10.2022

4435518

Deprecation
This commit moves luasnip.extras.expand_conditions to luasnip.extras.conditions.expand, but expand_conditions will still be accessible for a while.
This change is very easily accomodated, just s/require("luasnip.extras.expand_conditions")/require("luasnip.extras.conditions.expand")/g in all affected files should do it.

18.02.2023

a37a52e

Breaking Change
From this commit on, only neovim 0.7 and higher is supported.
If you don't have access to a new-enough version, pin either v1.2.1 (or the commit just before a37a52e, 2dfb6ad).

04.10.2023

d9cb6ab

Deprecation
This commit replaces history with the more granular keep_roots, link_roots, and link_children.
history = val corresponds to keep_roots = val, link_roots = val, link_children = val, and we will do this conversion automatically if history is still set in setup.
The reason for this change is that the new insertion-model introduced by the commit allows for more granular options for controlling connectivity of snippets.