Skip to content

Commit

Permalink
more elegantly implement history=false.
Browse files Browse the repository at this point in the history
  • Loading branch information
L3MON4D3 committed Jul 14, 2023
1 parent 718f792 commit 88043f6
Show file tree
Hide file tree
Showing 3 changed files with 81 additions and 61 deletions.
12 changes: 12 additions & 0 deletions lua/luasnip/init.lua
Original file line number Diff line number Diff line change
Expand Up @@ -245,6 +245,18 @@ local function snip_expand(snippet, opts)
session.current_nodes[vim.api.nvim_get_current_buf()] =
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 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
-- whenever outside of this function, we know that if we're here, it's
-- because this snippet was just inserted into buf_snippet_roots.
-- Armed with this knowledge, we can just check which of the roots is
-- this snippet, and remove the other one.
buf_snippet_roots[buf_snippet_roots[1] == snip and 2 or 1]:remove_from_jumplist()
end

-- stores original snippet, it doesn't contain any data from expansion.
session.last_expand_snip = snippet
session.last_expand_opts = opts
Expand Down
18 changes: 0 additions & 18 deletions lua/luasnip/nodes/insertNode.lua
Original file line number Diff line number Diff line change
Expand Up @@ -95,24 +95,6 @@ function ExitNode:input_leave(no_move, dry_run)
end
end

function ExitNode:jump_into(dir, no_move, dry_run)
if not session.config.history then
self:input_enter(no_move, dry_run)
if (dir == 1 and not self.next) or (dir == -1 and not self.prev) then
if self.pos == 0 then
-- leave instantly, self won't be active snippet.
self:input_leave(no_move, dry_run)
end
return nil
else
return self
end
else
-- if no next node, return self as next current node.
return InsertNode.jump_into(self, dir, no_move, dry_run)
end
end

function ExitNode:_update_dependents() end
function ExitNode:update_dependents() end
function ExitNode:update_all_dependents() end
Expand Down
112 changes: 69 additions & 43 deletions lua/luasnip/nodes/snippet.lua
Original file line number Diff line number Diff line change
Expand Up @@ -535,58 +535,75 @@ local function insert_into_jumplist(snippet, start_node, current_node, parent_no
next = next_snippet
end

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
else
if can_link_parent_node then
-- prev is nil, but we can link up using the parent.
parent_node.inner_first = snippet
start_node.prev = parent_node
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
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
if can_link_parent_node 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
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
else
if can_link_parent_node then
parent_node.inner_last = snippet.insert_nodes[0]
snippet.insert_nodes[0].next = parent_node
-- 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
else
snippet.insert_nodes[0].next = current_node
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]
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]
-- 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)
if can_link_parent_node then
start_node.prev = parent_node
snippet.insert_nodes[0].next = parent_node
end
end
end

table.insert(sibling_snippets, own_indx, snippet)
end

Expand Down Expand Up @@ -1040,6 +1057,15 @@ end
-- used in LSP-Placeholders.

function Snippet:exit()
if self.type == types.snippet then
-- if exit is called, this will not be visited again.
-- Thus, also clean up the child-snippets, which will also not be
-- visited again, since they can only be visited through self.
for _, child in ipairs(self.child_snippets) do
child:exit()
end
end

self.visible = false
for _, node in ipairs(self.nodes) do
node:exit()
Expand Down

0 comments on commit 88043f6

Please sign in to comment.