Skip to content

Commit

Permalink
split history=false/true into more specific options.
Browse files Browse the repository at this point in the history
keep_roots=true stores all snippet-roots, while false will only keep the
most recently expanded root.

link_roots makes it possible to jump between roots, link_children makes
it possible to jump back into, and between, children of one snippet.
  • Loading branch information
L3MON4D3 committed Sep 23, 2023
1 parent 6aa3d81 commit 214d145
Show file tree
Hide file tree
Showing 5 changed files with 81 additions and 65 deletions.
5 changes: 4 additions & 1 deletion Examples/snippets.lua
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,10 @@ local conds_expand = require("luasnip.extras.conditions.expand")

-- Every unspecified option will be set to the default.
ls.setup({
history = true,
keep_roots = true,
link_roots = true,
link_children = true,

-- Update more often, :h events for more info.
update_events = "TextChanged,TextChangedI",
-- Snippets aren't automatically removed if their text is deleted.
Expand Down
16 changes: 15 additions & 1 deletion lua/luasnip/config.lua
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,11 @@ local lazy_snip_env = {
}

local defaults = {
history = false,
-- corresponds to legacy "history=false".
keep_roots = false,
link_roots = false,
link_children = false,

update_events = "InsertLeave",
-- see :h User, event should never be triggered(except if it is `doautocmd`'d)
region_check_events = nil,
Expand Down Expand Up @@ -208,6 +212,16 @@ c = {

set_snip_env(conf, user_config)

-- handle legacy-key history.
if user_config.history ~= nil then
conf.keep_roots = user_config.history
conf.link_roots = user_config.history
conf.link_children = user_config.history

-- unset key to prevent handling twice.
conf.history = nil
end

for k, v in pairs(user_config) do
conf[k] = v
end
Expand Down
9 changes: 7 additions & 2 deletions lua/luasnip/init.lua
Original file line number Diff line number Diff line change
Expand Up @@ -253,7 +253,7 @@ local function snip_expand(snippet, opts)
opts.jump_into_func(snip)

local buf_snippet_roots = session.snippet_roots[vim.api.nvim_get_current_buf()]
if not session.config.history and #buf_snippet_roots > 1 then
if not session.config.keep_roots and #buf_snippet_roots > 1 then
-- if history is not set, and there is more than one snippet-root,
-- remove the other one.
-- The nice thing is: since we maintain that #buf_snippet_roots == 1
Expand Down Expand Up @@ -730,10 +730,15 @@ local function activate_node(pos)
snippet_preference = node_util.binarysearch_preference.interactive
})

if not node then
error("Could not find a node at that position.")
return
end

-- only activate interactive nodes, or nodes that are immediately nested
-- inside a choiceNode.
if not node_util.interactive_node(node) and rawget(node, "choice") == nil then
print("Refusing to activate a non-interactive node.")
error("Refusing to activate a non-interactive node.")
return
end

Expand Down
4 changes: 0 additions & 4 deletions lua/luasnip/nodes/insertNode.lua
Original file line number Diff line number Diff line change
Expand Up @@ -245,10 +245,6 @@ function InsertNode:input_leave_children(dry_run)
dry_run.active[self] = false
else
self.inner_active = false
if not session.config.history then
self.inner_first = nil
self.inner_last = nil
end
end
end

Expand Down
112 changes: 55 additions & 57 deletions lua/luasnip/nodes/snippet.lua
Original file line number Diff line number Diff line change
Expand Up @@ -536,73 +536,71 @@ local function insert_into_jumplist(snippet, start_node, current_node, parent_no
next = next_snippet
end

if session.config.history then
if parent_node then
local can_link_parent_node = node_util.linkable_node(parent_node)
-- snippetNode (which has to be empty to be viable here) and
-- insertNode can both deal with inserting a snippet inside them
-- (ie. hooking it up st. it can be visited after jumping back to
-- the snippet of parent).
-- in all cases
if prev ~= nil then
-- if we have a previous snippet we can link to, just do that.
prev.next.next = snippet
start_node.prev = prev.insert_nodes[0]
else
if can_link_parent_node then
-- whether roots should be linked together.
local link_roots = session.config.link_roots

-- whether children of the same snippet should be linked to their parent
-- and eachother.
local link_children = session.config.link_children

if parent_node then
local can_link_parent_node = node_util.linkable_node(parent_node)
-- snippetNode (which has to be empty to be viable here) and
-- insertNode can both deal with inserting a snippet inside them
-- (ie. hooking it up st. it can be visited after jumping back to
-- the snippet of parent).
-- in all cases
if link_children and prev ~= nil then
-- if we have a previous snippet we can link to, just do that.
prev.next.next = snippet
start_node.prev = prev.insert_nodes[0]
else
if can_link_parent_node then
-- only jump from parent to child if link_children is set.
if link_children then
-- prev is nil, but we can link up using the parent.
parent_node.inner_first = snippet
start_node.prev = parent_node
else
-- no way to link up, just jump back to current_node, but
-- don't jump from current_node to this snippet (I feel
-- like that should be good: one can still get back to ones
-- previous history, and we don't mess up whatever jumps
-- are set up around current_node)
start_node.prev = current_node
end
end

-- exact same reasoning here as in prev-case above, omitting comments.
if next ~= nil then
-- jump from next snippets start_node to $0.
next.prev.prev = snippet.insert_nodes[0]
-- jump from $0 to next snippet (skip its start_node)
snippet.insert_nodes[0].next = next
-- make sure we can jump back to the parent.
start_node.prev = parent_node
else
if can_link_parent_node then
parent_node.inner_last = snippet.insert_nodes[0]
snippet.insert_nodes[0].next = parent_node
else
snippet.insert_nodes[0].next = current_node
end
end
else
-- inserted into top-level snippet-forest, just hook up with prev, next.
-- prev and next have to be snippets or nil, in this case.
if prev ~= nil then
prev.next.next = snippet
start_node.prev = prev.insert_nodes[0]
end
if next ~= nil then
snippet.insert_nodes[0].next = next
next.prev.prev = snippet.insert_nodes[0]
-- no way to link up, just jump back to current_node, but
-- don't jump from current_node to this snippet (I feel
-- like that should be good: one can still get back to ones
-- previous history, and we don't mess up whatever jumps
-- are set up around current_node)
start_node.prev = current_node
end
end
else
-- don't store history!
-- Implement by only linking if this is expanded inside another node, and then only the outgoing jumps.
-- As soon as the i0/start_node is jumped from, this snippet will not be jumped into again.
-- (although, it is possible to enter it again, after leaving, by
-- expanding a snippet inside it. Not sure if this is undesirable, if
-- it is, we'll need to do cleanup, somehow)
if parent_node then
local can_link_parent_node = node_util.linkable_node(parent_node)

-- exact same reasoning here as in prev-case above, omitting comments.
if link_children and next ~= nil then
-- jump from next snippets start_node to $0.
next.prev.prev = snippet.insert_nodes[0]
-- jump from $0 to next snippet (skip its start_node)
snippet.insert_nodes[0].next = next
else
if can_link_parent_node then
start_node.prev = parent_node
if link_children then
parent_node.inner_last = snippet.insert_nodes[0]
end
snippet.insert_nodes[0].next = parent_node
else
snippet.insert_nodes[0].next = current_node
end
end
-- don't link different root-nodes for unlinked_roots.
elseif link_roots then
-- inserted into top-level snippet-forest, just hook up with prev, next.
-- prev and next have to be snippets or nil, in this case.
if prev ~= nil then
prev.next.next = snippet
start_node.prev = prev.insert_nodes[0]
end
if next ~= nil then
snippet.insert_nodes[0].next = next
next.prev.prev = snippet.insert_nodes[0]
end
end

table.insert(sibling_snippets, own_indx, snippet)
Expand Down

0 comments on commit 214d145

Please sign in to comment.