diff --git a/lua/nvim-treesitter/node_movement.lua b/lua/nvim-treesitter/node_movement.lua index 961ad1637..091715e97 100644 --- a/lua/nvim-treesitter/node_movement.lua +++ b/lua/nvim-treesitter/node_movement.lua @@ -57,10 +57,10 @@ M.do_node_movement = function(kind, move_node) end -- LEFT elseif kind == M.NodeMovementKind.left then - destination_node = utils.get_previous_node(current_node, true, true) + destination_node = utils.get_previous_node(current_node, not move_node, not move_node) -- RIGHT elseif kind == M.NodeMovementKind.right then - destination_node = utils.get_next_node(current_node, true, true) + destination_node = utils.get_next_node(current_node, not move_node, not move_node) end M.current_node[buf] = destination_node or current_node end @@ -68,6 +68,7 @@ M.do_node_movement = function(kind, move_node) if destination_node then node_start_to_vim(destination_node) if move_node then + node_start_to_vim(destination_node) if kind ~= M.NodeMovementKind.down then local dst_range if kind ~= M.NodeMovementKind.up then @@ -85,7 +86,8 @@ M.do_node_movement = function(kind, move_node) local root = parsers.get_parser():parse():root() if dst_range then local new_destination_node = utils.node_from_lsp_range(root, dst_range) - M.current_node[buf] = new_destination_node or current_node + M.current_node[buf] = new_destination_node + node_start_to_vim(M.current_node[buf]) end end end diff --git a/lua/nvim-treesitter/utils.lua b/lua/nvim-treesitter/utils.lua index eea0da999..2c364164e 100644 --- a/lua/nvim-treesitter/utils.lua +++ b/lua/nvim-treesitter/utils.lua @@ -126,7 +126,8 @@ function M.replace_range_text(buf, lsp_range, replacement_lines) end range['end'] = { line = range.start.line + #replacement_lines - 1, - character = end_char } + character = end_char } + return range end --- Replace node text and return new range (LSP range) @@ -159,12 +160,36 @@ function M.swap_nodes(buf, source, destination) local src_range, dst_range if dst_end <= src_start then - src_range = M.replace_node_text(buf, source, destination_text) + src_range = M.node_to_lsp_range(source) + local new_src_range = M.replace_node_text(buf, source, destination_text) dst_range = M.replace_node_text(buf, destination, source_text) - return + + -- Correct range of first change + src_range.start.line = src_range['end'].line - (#destination_text - 1) -- Total end stays the same + src_range.start.character = new_src_range.start.character + src_range.start.character = new_src_range.start.character + if dst_range['end'].line == src_range.start.line then + src_range.start.character = src_range.start.character + #(source_text[#source_text]) - #(destination_text[#destination_text]) + else + end + if dst_range['end'].line == dst_range['end'].line then + src_range['end'].character = src_range['end'].character + #(source_text[#source_text]) - #(destination_text[#destination_text]) + end elseif src_end <= dst_start then - dst_range = M.replace_node_text(buf, destination, source_text) + dst_range = M.node_to_lsp_range(destination) + local new_dst_range = M.replace_node_text(buf, destination, source_text) src_range = M.replace_node_text(buf, source, destination_text) + + -- Correct range of first change + dst_range.start.line = dst_range['end'].line - (#source_text - 1) -- Total end stays the same + dst_range.start.character = new_dst_range.start.character + dst_range.start.character = new_dst_range.start.character + if src_range['end'].line == dst_range.start.line then + dst_range.start.character = new_dst_range.start.character + #(destination_text[#destination_text]) - #(source_text[#source_text]) + end + if src_range['end'].line == dst_range['end'].line then + dst_range['end'].character = new_dst_range['end'].character + #(destination_text[#destination_text]) - #(source_text[#source_text]) + end end return src_range, dst_range end