diff --git a/lua/luasnip/init.lua b/lua/luasnip/init.lua index 49fda3c79..65b1ae62f 100644 --- a/lua/luasnip/init.lua +++ b/lua/luasnip/init.lua @@ -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 diff --git a/lua/luasnip/nodes/insertNode.lua b/lua/luasnip/nodes/insertNode.lua index 391e357c1..effeceabf 100644 --- a/lua/luasnip/nodes/insertNode.lua +++ b/lua/luasnip/nodes/insertNode.lua @@ -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 diff --git a/lua/luasnip/nodes/snippet.lua b/lua/luasnip/nodes/snippet.lua index 8e0b624c5..3df3d3ac3 100644 --- a/lua/luasnip/nodes/snippet.lua +++ b/lua/luasnip/nodes/snippet.lua @@ -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 @@ -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()