diff --git a/lua/luasnip/init.lua b/lua/luasnip/init.lua index c92eff351..30b31a484 100644 --- a/lua/luasnip/init.lua +++ b/lua/luasnip/init.lua @@ -97,7 +97,9 @@ local function unlink_set_adjacent_as_current_no_log(snippet) if next_current then -- if snippet was active before, we need to now set its parent to be no -- longer inner_active. - if snippet.parent_node == next_current and next_current.inner_active then + if + snippet.parent_node == next_current and next_current.inner_active + then snippet.parent_node:input_leave_children() else -- set no_move. @@ -106,7 +108,11 @@ local function unlink_set_adjacent_as_current_no_log(snippet) -- this won't try to set the previously broken snippet as -- current, since that link is removed in -- `remove_from_jumplist`. - unlink_set_adjacent_as_current(next_current, "Error while setting adjacent snippet as current node: %s", err) + unlink_set_adjacent_as_current( + next_current, + "Error while setting adjacent snippet as current node: %s", + err + ) end end end @@ -138,7 +144,12 @@ local function safe_jump_current(dir, no_move, dry_run) else local snip = node.parent.snippet - unlink_set_adjacent_as_current(snip, "Removing snippet `%s` due to error %s", snip.trigger, res) + unlink_set_adjacent_as_current( + snip, + "Removing snippet `%s` due to error %s", + snip.trigger, + res + ) return session.current_nodes[vim.api.nvim_get_current_buf()] end end @@ -185,7 +196,11 @@ local function in_snippet() -- if there was an error getting the position, the snippets text was -- most likely removed, resulting in messed up extmarks -> error. -- remove the snippet. - unlink_set_adjacent_as_current(snippet, "Error while getting extmark-position: %s", snip_begin_pos) + unlink_set_adjacent_as_current( + snippet, + "Error while getting extmark-position: %s", + snip_begin_pos + ) return end local pos = vim.api.nvim_win_get_cursor(0) @@ -259,7 +274,8 @@ 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()] + local buf_snippet_roots = + session.snippet_roots[vim.api.nvim_get_current_buf()] 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. @@ -396,7 +412,12 @@ local function safe_choice_action(snip, ...) -- not very elegant, but this way we don't have a near -- re-implementation of unlink_current. - unlink_set_adjacent_as_current(snip, "Removing snippet `%s` due to error %s", snip.trigger, res) + unlink_set_adjacent_as_current( + snip, + "Removing snippet `%s` due to error %s", + snip.trigger, + res + ) return session.current_nodes[vim.api.nvim_get_current_buf()] end end @@ -465,19 +486,21 @@ local function active_update_dependents() local ok, err = pcall(active.update_dependents, active) if not ok then - log.warn( - ) - unlink_set_adjacent_as_current(active.parent.snippet, + log.warn() + unlink_set_adjacent_as_current( + active.parent.snippet, "Error while updating dependents for snippet %s due to error %s", active.parent.snippet.trigger, - err) + err + ) return end -- 'restore' orientation of extmarks, may have been changed by some set_text or similar. ok, err = pcall(active.focus, active) if not ok then - unlink_set_adjacent_as_current(active.parent.snippet, + unlink_set_adjacent_as_current( + active.parent.snippet, "Error while entering node in snippet %s: %s", active.parent.snippet.trigger, err @@ -579,7 +602,11 @@ local function unlink_current_if_deleted() -- * textnodes that should contain text still do so, and -- * that extmarks still fulfill all expectations (should be successive, no gaps, etc.) if not snippet:extmarks_valid() then - unlink_set_adjacent_as_current(snippet, "Detected deletion of snippet `%s`, removing it", snippet.trigger) + unlink_set_adjacent_as_current( + snippet, + "Detected deletion of snippet `%s`, removing it", + snippet.trigger + ) end end @@ -606,7 +633,11 @@ local function exit_out_of_region(node) pcall(snippet.mark.pos_begin_end, snippet.mark) if not ok then - unlink_set_adjacent_as_current(snippet, "Error while getting extmark-position: %s", snip_begin_pos) + unlink_set_adjacent_as_current( + snippet, + "Error while getting extmark-position: %s", + snip_begin_pos + ) return end @@ -736,7 +767,7 @@ local function activate_node(opts) local _, _, _, node = node_util.snippettree_find_undamaged_node(pos, { tree_respect_rgravs = true, tree_preference = node_util.binarysearch_preference.inside, - snippet_preference = node_util.binarysearch_preference.interactive + snippet_preference = node_util.binarysearch_preference.interactive, }) if not node then @@ -746,7 +777,10 @@ local function activate_node(opts) -- 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 + if + not node_util.interactive_node(node) + and rawget(node, "choice") == nil + then if strict then error("Refusing to activate a non-interactive node.") return @@ -766,7 +800,10 @@ local function activate_node(opts) end end - node_util.refocus(session.current_nodes[vim.api.nvim_get_current_buf()], node) + node_util.refocus( + session.current_nodes[vim.api.nvim_get_current_buf()], + node + ) -- input_enter node again, to get highlight and the like. -- One side-effect of this is that an event will be execute twice, but I -- feel like that is a trade-off worth doing, since it otherwise refocus @@ -846,7 +883,7 @@ ls = util.lazy_table({ setup = require("luasnip.config").setup, extend_decorator = extend_decorator, log = require("luasnip.util.log"), - activate_node = activate_node + activate_node = activate_node, }, ls_lazy) return ls diff --git a/lua/luasnip/nodes/insertNode.lua b/lua/luasnip/nodes/insertNode.lua index bd1cae1f4..4d5d9d94b 100644 --- a/lua/luasnip/nodes/insertNode.lua +++ b/lua/luasnip/nodes/insertNode.lua @@ -187,7 +187,8 @@ function ExitNode:jump_from(dir, no_move, dry_run) self:init_dry_run_inner_active(dry_run) local next_node = util.ternary(dir == 1, self.next, self.prev) - local next_inner_node = util.ternary(dir == 1, self.inner_first, self.inner_last) + local next_inner_node = + util.ternary(dir == 1, self.inner_first, self.inner_last) if next_inner_node then self:input_enter_children(dry_run) @@ -199,7 +200,8 @@ function ExitNode:jump_from(dir, no_move, dry_run) -- not have children active if jump_from is called. -- true: don't move - local target_node = next_node:jump_into(dir, true, next_node_dry_run) + local target_node = + next_node:jump_into(dir, true, next_node_dry_run) -- if there is no node that can serve as jump-target, just remain -- here. -- Regular insertNodes don't have to handle this, since there is @@ -220,7 +222,8 @@ function InsertNode:jump_from(dir, no_move, dry_run) self:init_dry_run_inner_active(dry_run) local next_node = util.ternary(dir == 1, self.next, self.prev) - local next_inner_node = util.ternary(dir == 1, self.inner_first, self.inner_last) + local next_inner_node = + util.ternary(dir == 1, self.inner_first, self.inner_last) if next_inner_node then self:input_enter_children(dry_run) diff --git a/lua/luasnip/nodes/snippet.lua b/lua/luasnip/nodes/snippet.lua index 3c5671947..b85bdf8fd 100644 --- a/lua/luasnip/nodes/snippet.lua +++ b/lua/luasnip/nodes/snippet.lua @@ -346,7 +346,7 @@ local function _S(snip, nodes, opts) -- list of snippets expanded within the region of this snippet. -- sorted by their buffer-position, for quick searching. - child_snippets = {} + child_snippets = {}, }), opts ) @@ -483,7 +483,9 @@ function Snippet:remove_from_jumplist() self:exit() - local sibling_list = self.parent_node ~= nil and self.parent_node.parent.snippet.child_snippets or session.snippet_roots[vim.api.nvim_get_current_buf()] + local sibling_list = self.parent_node ~= nil + and self.parent_node.parent.snippet.child_snippets + or session.snippet_roots[vim.api.nvim_get_current_buf()] local self_indx for i, snip in ipairs(sibling_list) do if snip == self then @@ -519,8 +521,15 @@ function Snippet:remove_from_jumplist() end end -local function insert_into_jumplist(snippet, start_node, current_node, parent_node, sibling_snippets, own_indx) - local prev_snippet = sibling_snippets[own_indx-1] +local function insert_into_jumplist( + snippet, + start_node, + current_node, + parent_node, + sibling_snippets, + own_indx +) + local prev_snippet = sibling_snippets[own_indx - 1] -- have not yet inserted self!! local next_snippet = sibling_snippets[own_indx] @@ -610,11 +619,12 @@ function Snippet:trigger_expand(current_node, pos_id, env) local pos = vim.api.nvim_buf_get_extmark_by_id(0, session.ns_id, pos_id, {}) -- find tree-node the snippet should be inserted at (could be before another node). - local _, sibling_snippets, own_indx, parent_node = node_util.snippettree_find_undamaged_node(pos, { - tree_respect_rgravs = false, - tree_preference = node_util.binarysearch_preference.outside, - snippet_preference = node_util.binarysearch_preference.linkable - }) + local _, sibling_snippets, own_indx, parent_node = + node_util.snippettree_find_undamaged_node(pos, { + tree_respect_rgravs = false, + tree_preference = node_util.binarysearch_preference.outside, + snippet_preference = node_util.binarysearch_preference.linkable, + }) if current_node then node_util.refocus(current_node, parent_node) if parent_node then @@ -695,7 +705,7 @@ function Snippet:trigger_expand(current_node, pos_id, env) -- Marks should stay at the beginning of the snippet, only the first mark is needed. start_node.mark = self.nodes[1].mark start_node.pos = -1 - start_node.absolute_position = {-1} + start_node.absolute_position = { -1 } start_node.parent = self -- hook up i0 and start_node, and then the snippet itself. @@ -711,7 +721,14 @@ function Snippet:trigger_expand(current_node, pos_id, env) -- parent_node is nil if the snippet is toplevel. self.parent_node = parent_node - insert_into_jumplist(self, start_node, current_node, parent_node, sibling_snippets, own_indx) + insert_into_jumplist( + self, + start_node, + current_node, + parent_node, + sibling_snippets, + own_indx + ) return parent_node end @@ -1348,10 +1365,16 @@ end -- pos-column has to be a byte-index, not a display-column. function Snippet:smallest_node_at(pos, mode) local self_from, self_to = self.mark:pos_begin_end_raw() - assert(util.pos_cmp(self_from, pos) <= 0 and util.pos_cmp(pos, self_to) <= 0, "pos is not inside the snippet.") + assert( + util.pos_cmp(self_from, pos) <= 0 and util.pos_cmp(pos, self_to) <= 0, + "pos is not inside the snippet." + ) local smallest_node = self:node_at(pos, mode) - assert(smallest_node ~= nil, "could not find a smallest node (very unexpected)") + assert( + smallest_node ~= nil, + "could not find a smallest node (very unexpected)" + ) return smallest_node end @@ -1384,7 +1407,8 @@ end function Snippet:extmarks_valid() -- assumption: extmarks are contiguous, and all can be queried via pos_begin_end_raw. - local ok, current_from, self_to = pcall(self.mark.pos_begin_end_raw, self.mark) + local ok, current_from, self_to = + pcall(self.mark.pos_begin_end_raw, self.mark) if not ok then return false end @@ -1395,12 +1419,17 @@ function Snippet:extmarks_valid() end for _, node in ipairs(self.nodes) do - local ok_, node_from, node_to = pcall(node.mark.pos_begin_end_raw, node.mark) + local ok_, node_from, node_to = + pcall(node.mark.pos_begin_end_raw, node.mark) -- this snippet is invalid if: -- - we can't get the position of some node -- - the positions aren't contiguous or don't completely fill the parent, or -- - any child of this node violates these rules. - if not ok_ or util.pos_cmp(current_from, node_from) ~= 0 or not node:extmarks_valid() then + if + not ok_ + or util.pos_cmp(current_from, node_from) ~= 0 + or not node:extmarks_valid() + then return false end current_from = node_to diff --git a/lua/luasnip/nodes/textNode.lua b/lua/luasnip/nodes/textNode.lua index 6994f9f7d..88fad040d 100644 --- a/lua/luasnip/nodes/textNode.lua +++ b/lua/luasnip/nodes/textNode.lua @@ -49,7 +49,13 @@ end function TextNode:extmarks_valid() local from, to = self.mark:pos_begin_end_raw() - if util.pos_cmp(from, to) == 0 and not (#self.static_text == 0 or (#self.static_text == 1 and #self.static_text[1] == 0)) then + if + util.pos_cmp(from, to) == 0 + and not ( + #self.static_text == 0 + or (#self.static_text == 1 and #self.static_text[1] == 0) + ) + then -- assume the snippet is invalid if a textNode occupies zero space, -- but has text which would occupy some. -- This should allow some modifications, but as soon as a textNode is diff --git a/lua/luasnip/nodes/util.lua b/lua/luasnip/nodes/util.lua index 5a554137d..ec5fc31aa 100644 --- a/lua/luasnip/nodes/util.lua +++ b/lua/luasnip/nodes/util.lua @@ -103,7 +103,7 @@ local function leave_nodes_between(parent, child, no_move) -- entirely (because we stop at nodes[2], and handle nodes[1] -- separately) nodes[i]:input_leave(no_move) - nodes[i-1]:input_leave_children() + nodes[i - 1]:input_leave_children() end nodes[1]:input_leave(no_move) end @@ -114,7 +114,7 @@ local function enter_nodes_between(parent, child, no_move) return end - for i = 1, #nodes-1 do + for i = 1, #nodes - 1 do -- only enter children for nodes before the last (lowest) one. nodes[i]:input_enter(no_move) nodes[i]:input_enter_children() @@ -179,7 +179,10 @@ end local function linkable_node(node) -- node.type has to be one of insertNode, exitNode. - return vim.tbl_contains({types.insertNode, types.exitNode}, rawget(node, "type")) + return vim.tbl_contains( + { types.insertNode, types.exitNode }, + rawget(node, "type") + ) end -- mainly used internally, by binarysearch_pos. @@ -189,7 +192,10 @@ end -- feel appropriate (higher runtime), most cases should be served well by this -- heuristic. local function non_linkable_node(node) - return vim.tbl_contains({types.textNode, types.functionNode}, rawget(node, "type")) + return vim.tbl_contains( + { types.textNode, types.functionNode }, + rawget(node, "type") + ) end -- return whether a node is certainly (not) interactive. -- Coincindentially, the same nodes as (non-)linkable ones, but since there is a @@ -227,7 +233,7 @@ local binarysearch_preference = { return cmp_mid_to >= 0, cmp_mid_from <= 0 end, linkable = prefer_nodes(linkable_node, non_linkable_node), - interactive = prefer_nodes(interactive_node, non_interactive_node) + interactive = prefer_nodes(interactive_node, non_interactive_node), } -- `nodes` is a list of nodes ordered by their occurrence in the buffer. -- `pos` is a row-column-tuble, byte-columns, and we return the node the LEFT @@ -255,12 +261,12 @@ local binarysearch_preference = { -- This way, we are more likely to return a node that can handle a new -- snippet/is interactive. -- * `"prefer_outside"` makes sense when the nodes are not contiguous, and we'd --- like to find a position between two nodes. +-- like to find a position between two nodes. -- This mode makes sense for finding the snippet a new snippet should be -- inserted in, since we'd like to prefer inserting before/after a snippet, if -- the position is ambiguous. --- --- In general: +-- +-- In general: -- These options are useful for making this function more general: When -- searching in the contiguous nodes of a snippet, we'd like this routine to -- return any of them (obviously the one pos is inside/or on the border of, and @@ -270,7 +276,12 @@ local binarysearch_preference = { -- the snippet/node a new snippet should be expanded inside, it seems better to -- shift an existing snippet to the right/left than expand the new snippet -- inside it (when the expand-point is on the boundary). -local function binarysearch_pos(nodes, pos, respect_rgravs, boundary_resolve_mode) +local function binarysearch_pos( + nodes, + pos, + respect_rgravs, + boundary_resolve_mode +) local left = 1 local right = #nodes @@ -280,7 +291,7 @@ local function binarysearch_pos(nodes, pos, respect_rgravs, boundary_resolve_mod return nil, 1 end while true do - local mid = left + math.floor((right-left)/2) + local mid = left + math.floor((right - left) / 2) local mid_mark = nodes[mid].mark local ok, mid_from, mid_to = pcall(mid_mark.pos_begin_end_raw, mid_mark) @@ -309,7 +320,8 @@ local function binarysearch_pos(nodes, pos, respect_rgravs, boundary_resolve_mod local cmp_mid_to = util.pos_cmp(pos, mid_to) local cmp_mid_from = util.pos_cmp(pos, mid_from) - local cont_behind_mid, cont_before_mid = boundary_resolve_mode(cmp_mid_to, cmp_mid_from, nodes[mid]) + local cont_behind_mid, cont_before_mid = + boundary_resolve_mode(cmp_mid_to, cmp_mid_from, nodes[mid]) if cont_behind_mid then -- make sure right-left becomes smaller. @@ -341,7 +353,7 @@ local function first_common_node(a, b) local i = 0 local last_common = a.parent.snippet -- invariant: last_common is parent of both a and b. - while (a_pos[i+1] ~= nil) and a_pos[i + 1] == b_pos[i + 1] do + while (a_pos[i + 1] ~= nil) and a_pos[i + 1] == b_pos[i + 1] do last_common = last_common:resolve_position(a_pos[i + 1]) i = i + 1 end @@ -454,7 +466,11 @@ local function refocus(from, to) end -- pass nil if from/to is nil. -- if either is nil, first_common_node is nil, and the corresponding list empty. - local first_common_snippet, from_snip_path, to_snip_path = first_common_snippet_ancestor_path(from and from.parent.snippet, to and to.parent.snippet) + local first_common_snippet, from_snip_path, to_snip_path = + first_common_snippet_ancestor_path( + from and from.parent.snippet, + to and to.parent.snippet + ) -- we want leave/enter_path to be s.t. leaving/entering all nodes between -- each entry and its snippet (and the snippet itself) will leave/enter all @@ -497,7 +513,8 @@ local function refocus(from, to) -- here. -- snippet does not have input_leave_children, so only input_leave -- needs to be called. - local ok2 = pcall(from.parent.snippet.input_leave, from.parent.snippet, true) + local ok2 = + pcall(from.parent.snippet.input_leave, from.parent.snippet, true) if not ok1 or not ok2 then from.parent.snippet:remove_from_jumplist() end @@ -506,7 +523,8 @@ local function refocus(from, to) local node = from_snip_path[i] local ok1 = pcall(node.input_leave_children, node) local ok2 = pcall(leave_nodes_between, node.parent.snippet, node, true) - local ok3 = pcall(node.parent.snippet.input_leave, node.parent.snippet, true) + local ok3 = + pcall(node.parent.snippet.input_leave, node.parent.snippet, true) if not ok1 or not ok2 or not ok3 then from.parent.snippet:remove_from_jumplist() end @@ -532,11 +550,17 @@ local function refocus(from, to) -- This means that, if we want to enter a non-exitNode, we have to -- explicitly activate the snippet for all jumps to behave correctly. -- (if we enter a i(0)/i(-1), this is not necessary, of course). - if final_leave_node.type == types.exitNode and first_enter_node.type ~= types.exitNode then + if + final_leave_node.type == types.exitNode + and first_enter_node.type ~= types.exitNode + then common_node:input_enter(true) end -- symmetrically, entering an i(0)/i(-1) requires leaving the snippet. - if final_leave_node.type ~= types.exitNode and first_enter_node.type == types.exitNode then + if + final_leave_node.type ~= types.exitNode + and first_enter_node.type == types.exitNode + then common_node:input_leave(true) end @@ -578,10 +602,17 @@ local function generic_extmarks_valid(node, child) -- valid if -- - extmark-extents match. -- - current choice is valid - local ok1, self_from, self_to = pcall(node.mark.pos_begin_end_raw, node.mark) - local ok2, child_from, child_to = pcall(child.mark.pos_begin_end_raw, child.mark) - - if not ok1 or not ok2 or util.pos_cmp(self_from, child_from) ~= 0 or util.pos_cmp(self_to, child_to) ~= 0 then + local ok1, self_from, self_to = + pcall(node.mark.pos_begin_end_raw, node.mark) + local ok2, child_from, child_to = + pcall(child.mark.pos_begin_end_raw, child.mark) + + if + not ok1 + or not ok2 + or util.pos_cmp(self_from, child_from) ~= 0 + or util.pos_cmp(self_to, child_to) ~= 0 + then return false end return child:extmarks_valid() @@ -594,19 +625,25 @@ end -- * the node of this snippet pos is on. local function snippettree_find_undamaged_node(pos, opts) local prev_parent, child_indx, found_parent - local prev_parent_children = session.snippet_roots[vim.api.nvim_get_current_buf()] + local prev_parent_children = + session.snippet_roots[vim.api.nvim_get_current_buf()] while true do -- false: don't respect rgravs. -- Prefer inserting the snippet outside an existing one. - found_parent, child_indx = binarysearch_pos(prev_parent_children, pos, opts.tree_respect_rgravs, opts.tree_preference) + found_parent, child_indx = binarysearch_pos( + prev_parent_children, + pos, + opts.tree_respect_rgravs, + opts.tree_preference + ) if found_parent == false then -- if the procedure returns false, there was an error getting the -- position of a node (in this case, that node is a snippet). -- The position of the offending snippet is returned in child_indx, -- and we can remove it here. prev_parent_children[child_indx]:remove_from_jumplist() - elseif (found_parent ~= nil and not found_parent:extmarks_valid()) then + elseif found_parent ~= nil and not found_parent:extmarks_valid() then -- found snippet damaged (the idea to sidestep the damaged snippet, -- even if no error occurred _right now_, is to ensure that we can -- input_enter all the nodes along the insertion-path correctly). @@ -651,5 +688,5 @@ return { refocus = refocus, generic_extmarks_valid = generic_extmarks_valid, snippettree_find_undamaged_node = snippettree_find_undamaged_node, - interactive_node = interactive_node + interactive_node = interactive_node, } diff --git a/lua/luasnip/session/init.lua b/lua/luasnip/session/init.lua index 77447c3ce..52b3b2fbf 100644 --- a/lua/luasnip/session/init.lua +++ b/lua/luasnip/session/init.lua @@ -17,11 +17,11 @@ M.current_nodes = {} -- snippet_roots[n] => list of snippet-roots in buffer n. M.snippet_roots = setmetatable({}, { -- create missing lists automatically. - __index = function(t,k) + __index = function(t, k) local new_t = {} rawset(t, k, new_t) return new_t - end + end, }) M.ns_id = vim.api.nvim_create_namespace("Luasnip") M.active_choice_nodes = {} diff --git a/lua/luasnip/util/util.lua b/lua/luasnip/util/util.lua index d308323d6..7a247210d 100644 --- a/lua/luasnip/util/util.lua +++ b/lua/luasnip/util/util.lua @@ -612,7 +612,7 @@ end -- compare two positions, <0 => pos1 pos1=pos2, >0 => pos1 > pos2. local function pos_cmp(pos1, pos2) -- if row is different it determines result, otherwise the column does. - return 2*cmp(pos1[1], pos2[1]) + cmp(pos1[2], pos2[2]) + return 2 * cmp(pos1[1], pos2[1]) + cmp(pos1[2], pos2[2]) end return { diff --git a/tests/helpers.lua b/tests/helpers.lua index 3b89a3d24..bbfd2a86f 100644 --- a/tests/helpers.lua +++ b/tests/helpers.lua @@ -67,7 +67,8 @@ function M.session_setup_luasnip(opts) ]]) end - helpers.exec_lua([[ + helpers.exec_lua( + [[ local hl_choiceNode, setup_extend = ... -- MYVIMRC might not be set when nvim is loaded like this. @@ -89,7 +90,8 @@ function M.session_setup_luasnip(opts) ]], -- passing nil here means the argument-list is terminated, I think. -- Just pass false instead of nil/false. - hl_choiceNode or false, setup_extend + hl_choiceNode or false, + setup_extend ) if not no_snip_globals then diff --git a/tests/integration/session_spec.lua b/tests/integration/session_spec.lua index 339665ec3..d1ad47e62 100644 --- a/tests/integration/session_spec.lua +++ b/tests/integration/session_spec.lua @@ -5,9 +5,15 @@ local exec_lua, feed, exec = helpers.exec_lua, helpers.feed, helpers.exec local ls_helpers = require("helpers") local Screen = require("test.functional.ui.screen") -local function expand() exec_lua("ls.expand()") end -local function jump(dir) exec_lua("ls.jump(...)", dir) end -local function change(dir) exec_lua("ls.change_choice(...)", dir) end +local function expand() + exec_lua("ls.expand()") +end +local function jump(dir) + exec_lua("ls.jump(...)", dir) +end +local function change(dir) + exec_lua("ls.change_choice(...)", dir) +end describe("session", function() local screen @@ -15,7 +21,7 @@ describe("session", function() before_each(function() helpers.clear() ls_helpers.setup_jsregexp() - ls_helpers.session_setup_luasnip({hl_choiceNode = true}) + ls_helpers.session_setup_luasnip({ hl_choiceNode = true }) -- add a rather complicated snippet. -- It may be a bit hard to grasp, but will cover lots and lots of @@ -133,14 +139,18 @@ describe("session", function() [1] = { bold = true, foreground = Screen.colors.Brown }, [2] = { bold = true }, [3] = { background = Screen.colors.LightGray }, - [4] = {background = Screen.colors.Red1, foreground = Screen.colors.White} + [4] = { + background = Screen.colors.Red1, + foreground = Screen.colors.White, + }, }) end) it("Deleted snippet is handled properly in expansion.", function() feed("ofn") exec_lua("ls.expand()") - screen:expect{grid=[[ + screen:expect({ + grid = [[ | | /** | @@ -170,9 +180,13 @@ describe("session", function() {0:~ }| {0:~ }| {0:~ }| - {2:-- INSERT --} |]]} - jump(1) jump(1) jump(1) - screen:expect{grid=[[ + {2:-- INSERT --} |]], + }) + jump(1) + jump(1) + jump(1) + screen:expect({ + grid = [[ | | /** | @@ -202,15 +216,18 @@ describe("session", function() {0:~ }| {0:~ }| {0:~ }| - {2:-- INSERT --} |]]} + {2:-- INSERT --} |]], + }) -- delete whole buffer. feed("ggVGcfn") -- immediately expand at the old position of the snippet. exec_lua("ls.expand()") -- first jump goes to i(-1), second might go back into deleted snippet, -- if we did something wrong. - jump(-1) jump(-1) - screen:expect{grid=[[ + jump(-1) + jump(-1) + screen:expect({ + grid = [[ ^/** | * A short Description | */ | @@ -240,11 +257,18 @@ describe("session", function() {0:~ }| {0:~ }| {0:~ }| - {2:-- INSERT --} |]]} + {2:-- INSERT --} |]], + }) -- seven jumps to go to i(0), 8th, again, should not do anything. - jump(1) jump(1) jump(1) jump(1) - jump(1) jump(1) jump(1) - screen:expect{grid=[[ + jump(1) + jump(1) + jump(1) + jump(1) + jump(1) + jump(1) + jump(1) + screen:expect({ + grid = [[ /** | * A short Description | */ | @@ -274,14 +298,16 @@ describe("session", function() {0:~ }| {0:~ }| {0:~ }| - {2:-- INSERT --} |]]} + {2:-- INSERT --} |]], + }) jump(1) - screen:expect{unchanged = true} + screen:expect({ unchanged = true }) end) it("Deleted snippet is handled properly when jumping.", function() feed("ofn") exec_lua("ls.expand()") - screen:expect{grid=[[ + screen:expect({ + grid = [[ | | /** | @@ -311,9 +337,13 @@ describe("session", function() {0:~ }| {0:~ }| {0:~ }| - {2:-- INSERT --} |]]} - jump(1) jump(1) jump(1) - screen:expect{grid=[[ + {2:-- INSERT --} |]], + }) + jump(1) + jump(1) + jump(1) + screen:expect({ + grid = [[ | | /** | @@ -343,7 +373,8 @@ describe("session", function() {0:~ }| {0:~ }| {0:~ }| - {2:-- INSERT --} |]]} + {2:-- INSERT --} |]], + }) -- delete whole buffer. feed("ggVGd") -- should not cause an error. @@ -352,7 +383,8 @@ describe("session", function() it("Deleting nested snippet only removes it.", function() feed("ofn") exec_lua("ls.expand()") - screen:expect{grid=[[ + screen:expect({ + grid = [[ | | /** | @@ -382,10 +414,12 @@ describe("session", function() {0:~ }| {0:~ }| {0:~ }| - {2:-- INSERT --} |]]} + {2:-- INSERT --} |]], + }) feed("jlafn") expand() - screen:expect{grid=[[ + screen:expect({ + grid = [[ | | /** | @@ -415,14 +449,19 @@ describe("session", function() {0:~ }| {0:~ }| {0:~ }| - {2:-- INSERT --} |]]} - jump(1) jump(1) + {2:-- INSERT --} |]], + }) + jump(1) + jump(1) feed("llllvbbbx") -- first jump goes into function-arguments, second will trigger update, -- which will in turn recognize the broken snippet. -- The third jump will then go into the outer snippet. - jump(1) jump(1) jump(-1) - screen:expect{grid=[[ + jump(1) + jump(1) + jump(-1) + screen:expect({ + grid = [[ | | /** | @@ -452,11 +491,13 @@ describe("session", function() {0:~ }| {0:~ }| {0:~ }| - {2:-- SELECT --} |]]} + {2:-- SELECT --} |]], + }) -- this should jump into the $0 of the outer snippet, highlighting the -- entire nested snippet. jump(1) - screen:expect{grid=[[ + screen:expect({ + grid = [[ | | /** | @@ -486,27 +527,34 @@ describe("session", function() {0:~ }| {0:~ }| {0:~ }| - {2:-- SELECT --} |]]} + {2:-- SELECT --} |]], + }) end) - for _, link_roots_val in ipairs({"true", "false"}) do - it(("Snippets are inserted according to link_roots and keep_roots=%s"):format(link_roots_val), function() - exec_lua(([[ + for _, link_roots_val in ipairs({ "true", "false" }) do + it( + ("Snippets are inserted according to link_roots and keep_roots=%s"):format( + link_roots_val + ), + function() + exec_lua(([[ ls.setup({ keep_roots = %s, link_roots = %s }) ]]):format(link_roots_val, link_roots_val)) - feed("ifn") - expand() - -- "o" does not extend the extmark of the active snippet. - feed("Gofn") - expand() - jump(-1) jump(-1) - -- if linked, should end up back in the original snippet, if not, - -- stay in second. - if link_roots_val == "true" then - screen:expect{grid=[[ + feed("ifn") + expand() + -- "o" does not extend the extmark of the active snippet. + feed("Gofn") + expand() + jump(-1) + jump(-1) + -- if linked, should end up back in the original snippet, if not, + -- stay in second. + if link_roots_val == "true" then + screen:expect({ + grid = [[ /** | * A short Description | */ | @@ -536,9 +584,11 @@ describe("session", function() {0:~ }| {0:~ }| {0:~ }| - {2:-- INSERT --} |]]} - else - screen:expect{grid=[[ + {2:-- INSERT --} |]], + }) + else + screen:expect({ + grid = [[ /** | * A short Description | */ | @@ -568,11 +618,13 @@ describe("session", function() {0:~ }| {0:~ }| {0:~ }| - {2:-- INSERT --} |]]} + {2:-- INSERT --} |]], + }) + end end - end) + ) end - for _, keep_roots_val in ipairs({"true", "false"}) do + for _, keep_roots_val in ipairs({ "true", "false" }) do it("Root-snippets are stored iff keep_roots=true", function() exec_lua(([[ ls.setup({ @@ -594,7 +646,8 @@ describe("session", function() -- if linked, should end up back in the original snippet, if not, -- stay in second. if keep_roots_val == "true" then - screen:expect{grid=[[ + screen:expect({ + grid = [[ /** | * ^A{3: short Description} | */ | @@ -624,17 +677,14 @@ describe("session", function() {0:~ }| {0:~ }| {0:~ }| - {2:-- SELECT --} |]]} + {2:-- SELECT --} |]], + }) else - assert( - err:match( - "No Snippet at that position" - ) - ) + assert(err:match("No Snippet at that position")) end end) end - for _, link_children_val in ipairs({"true", "false"}) do + for _, link_children_val in ipairs({ "true", "false" }) do it("Child-snippets are linked iff link_children=true", function() exec_lua(([[ ls.setup({ @@ -650,7 +700,8 @@ describe("session", function() -- expand another child. feed("jjAfn") expand() - screen:expect{grid=[[ + screen:expect({ + grid = [[ /** | * A short Description | */ | @@ -680,14 +731,17 @@ describe("session", function() {0:~ }| {0:~ }| {0:~ }| - {2:-- INSERT --} |]]} + {2:-- INSERT --} |]], + }) -- if linked, should end up back in the original snippet, if not, -- stay in second. if link_children_val == "true" then -- make sure we can jump into the previous child... - jump(-1) jump(-1) - screen:expect{grid=[[ + jump(-1) + jump(-1) + screen:expect({ + grid = [[ /** | * A short Description | */ | @@ -717,10 +771,19 @@ describe("session", function() {0:~ }| {0:~ }| {0:~ }| - {2:-- INSERT --} |]]} + {2:-- INSERT --} |]], + }) -- ...and from the first child back into the parent... - jump(-1) jump(-1) jump(-1) jump(-1) jump(-1) jump(-1) jump(-1) jump(-1) - screen:expect{grid=[[ + jump(-1) + jump(-1) + jump(-1) + jump(-1) + jump(-1) + jump(-1) + jump(-1) + jump(-1) + screen:expect({ + grid = [[ /** | * ^A{3: short Description} | */ | @@ -750,11 +813,26 @@ describe("session", function() {0:~ }| {0:~ }| {0:~ }| - {2:-- SELECT --} |]]} + {2:-- SELECT --} |]], + }) -- ...and back to the end of the second snippet... -- (first only almost to the end, to make sure we makde the correct number of jumps). - jump(1) jump(1) jump(1) jump(1) jump(1) jump(1) jump(1) jump(1) jump(1) jump(1) jump(1) jump(1) jump(1) jump(1) - screen:expect{grid=[[ + jump(1) + jump(1) + jump(1) + jump(1) + jump(1) + jump(1) + jump(1) + jump(1) + jump(1) + jump(1) + jump(1) + jump(1) + jump(1) + jump(1) + screen:expect({ + grid = [[ /** | * A short Description | */ | @@ -784,9 +862,11 @@ describe("session", function() {0:~ }| {0:~ }| {0:~ }| - {2:-- SELECT --} |]]} + {2:-- SELECT --} |]], + }) jump(1) - screen:expect{grid=[[ + screen:expect({ + grid = [[ /** | * A short Description | */ | @@ -816,19 +896,21 @@ describe("session", function() {0:~ }| {0:~ }| {0:~ }| - {2:-- INSERT --} |]]} + {2:-- INSERT --} |]], + }) -- test inability to jump beyond a few times, I've had bugs -- where after a multiple jumps, a new node became active. jump(1) - screen:expect{unchanged = true} + screen:expect({ unchanged = true }) jump(1) - screen:expect{unchanged = true} + screen:expect({ unchanged = true }) jump(1) - screen:expect{unchanged = true} + screen:expect({ unchanged = true }) -- For good measure, make sure the node is actually still active. jump(-1) - screen:expect{grid=[[ + screen:expect({ + grid = [[ /** | * A short Description | */ | @@ -858,9 +940,9 @@ describe("session", function() {0:~ }| {0:~ }| {0:~ }| - {2:-- SELECT --} |]]} + {2:-- SELECT --} |]], + }) else - end end) end @@ -868,12 +950,13 @@ describe("session", function() feed("ifn") expand() -- delete the entier text of a textNode, which will make - -- extmarks_valid() false. + -- extmarks_valid() false. feed("eevllx") -- insert snippet inside the invalid parent. feed("jAfn") expand() - screen:expect{grid=[[ + screen:expect({ + grid = [[ /** | * A short Description | */ | @@ -903,11 +986,13 @@ describe("session", function() {0:~ }| {0:~ }| {0:~ }| - {2:-- INSERT --} |]]} + {2:-- INSERT --} |]], + }) -- make sure the parent is invalid. jump(-1) - screen:expect{grid=[[ + screen:expect({ + grid = [[ /** | * A short Description | */ | @@ -937,11 +1022,12 @@ describe("session", function() {0:~ }| {0:~ }| {0:~ }| - {2:-- INSERT --} |]]} + {2:-- INSERT --} |]], + }) -- should not move back into the parent. jump(-1) - screen:expect{unchanged = true} + screen:expect({ unchanged = true }) end) it("region_check_events works correctly", function() exec_lua([[ @@ -962,7 +1048,8 @@ describe("session", function() -- expand snippet. feed("ifn") expand() - screen:expect{grid=[[ + screen:expect({ + grid = [[ /** | * A short Description | */ | @@ -992,11 +1079,13 @@ describe("session", function() {0:~ }| {0:~ }| {0:~ }| - {2:-- INSERT --} |]]} + {2:-- INSERT --} |]], + }) -- leave its region. feed("Go") -- check we have left the snippet (choiceNode indicator no longer active). - screen:expect{grid=[[ + screen:expect({ + grid = [[ /** | * A short Description | */ | @@ -1026,17 +1115,20 @@ describe("session", function() {0:~ }| {0:~ }| {0:~ }| - |]]} + |]], + }) -- re-activate $0, expand child. - jump(-1) jump(1) + jump(-1) + jump(1) feed("fn") expand() -- jump behind child, activate region_leave, make sure the child and -- root-snippet are _not_ exited. feed("jjAo") - screen:expect{grid=[[ + screen:expect({ + grid = [[ /** | * A short Description | */ | @@ -1066,10 +1158,12 @@ describe("session", function() {0:~ }| {0:~ }| {0:~ }| - |]]} + |]], + }) -- .. and now both are left upon leaving the region of the root-snippet. feed("jji") - screen:expect{grid=[[ + screen:expect({ + grid = [[ /** | * A short Description | */ | @@ -1099,7 +1193,8 @@ describe("session", function() {0:~ }| {0:~ }| {0:~ }| - |]]} + |]], + }) end) it("delete_check_events works correctly", function() exec_lua([[ @@ -1120,7 +1215,8 @@ describe("session", function() -- expand. feed("ifn") expand() - screen:expect{grid=[[ + screen:expect({ + grid = [[ /** | * A short Description | */ | @@ -1150,11 +1246,13 @@ describe("session", function() {0:~ }| {0:~ }| {0:~ }| - {2:-- INSERT --} |]]} + {2:-- INSERT --} |]], + }) -- delete textNode, to trigger unlink_current_if_deleted via esc. feed("eevllx") - screen:expect{grid=[[ + screen:expect({ + grid = [[ /** | * A short Description | */ | @@ -1184,8 +1282,9 @@ describe("session", function() {0:~ }| {0:~ }| {0:~ }| - |]]} + |]], + }) jump(1) - screen:expect{unchanged=true} + screen:expect({ unchanged = true }) end) end) diff --git a/tests/integration/snippet_basics_spec.lua b/tests/integration/snippet_basics_spec.lua index a93fe45a0..5c655fb65 100644 --- a/tests/integration/snippet_basics_spec.lua +++ b/tests/integration/snippet_basics_spec.lua @@ -250,24 +250,30 @@ describe("snippets_basic", function() }) -- last snippet is not forgotten (yet). exec_lua("ls.jump(1)") - screen:expect{grid=[[ + screen:expect({ + grid = [[ a[^a{3:[]ab}]ab | {0:~ }| - {2:-- SELECT --} |]]} + {2:-- SELECT --} |]], + }) feed("o") exec_lua("ls.snip_expand(" .. snip .. ")") - screen:expect{grid=[[ + screen:expect({ + grid = [[ a[a[]ab]ab | a[^]ab | - {2:-- INSERT --} |]]} + {2:-- INSERT --} |]], + }) exec_lua("ls.jump(-1) ls.jump(-1)") -- first snippet can't be accessed anymore. - screen:expect{grid=[[ + screen:expect({ + grid = [[ a[a[]ab]ab | ^a[]ab | - {2:-- INSERT --} |]]} + {2:-- INSERT --} |]], + }) end) it("history=true allows jumping back into exited snippet.", function() @@ -1156,31 +1162,37 @@ describe("snippets_basic", function() feed("iaa") exec_lua([[ ls.expand() ]]) exec_lua([[ ls.jump(1) ]]) - screen:expect{grid=[[ + screen:expect({ + grid = [[ a:(^) | {0:~ }| - {2:-- INSERT --} |]]} + {2:-- INSERT --} |]], + }) feed("aa") exec_lua([[ ls.expand() ]]) exec_lua([[ ls.jump(1) ]]) - screen:expect{grid=[[ + screen:expect({ + grid = [[ a:(a:(^)) | {0:~ }| - {2:-- INSERT --} |]]} + {2:-- INSERT --} |]], + }) feed("aa") exec_lua([[ ls.expand() ]]) exec_lua([[ ls.jump(1) ]]) - screen:expect{grid=[[ + screen:expect({ + grid = [[ a:(a:(a:(^))) | {0:~ }| - {2:-- INSERT --} |]]} + {2:-- INSERT --} |]], + }) -- jump should not move cursor! -- for some reason need multiple jumps to trigger the mistake. exec_lua([[ ls.jump(1)]]) exec_lua([[ ls.jump(1)]]) - screen:expect{unchanged = true} + screen:expect({ unchanged = true }) end) end)