Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Swap both elements of a pair together #81

Merged
merged 1 commit into from
Oct 24, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 39 additions & 5 deletions lua/nvim-paredit/api/dragging.lua
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ local ts_forms = require("nvim-paredit.treesitter.forms")
local ts_pairs = require("nvim-paredit.treesitter.pairs")
local traversal = require("nvim-paredit.utils.traversal")
local common = require("nvim-paredit.utils.common")
local text_api = require("nvim-paredit.api.text")
local ts = require("nvim-treesitter.ts_utils")
local config = require("nvim-paredit.config")

Expand Down Expand Up @@ -76,13 +77,46 @@ local function drag_node_in_pair(current_node, nodes, opts)
return
end

local buf = vim.api.nvim_get_current_buf()
if pair[2] and corresponding_pair[2] then
ts.swap_nodes(pair[2], corresponding_pair[2], buf, true)
local left_pair, right_pair
if direction == 1 then
left_pair = pair
right_pair = corresponding_pair
else
left_pair = corresponding_pair
right_pair = pair
end

if not left_pair[1] or not left_pair[2] then
return
end

if not right_pair[1] or not right_pair[2] then
return
end
if pair[1] and corresponding_pair[1] then
ts.swap_nodes(pair[1], corresponding_pair[1], buf, true)

local left_range_1 = { left_pair[1]:range() }
local left_range_2 = { left_pair[2]:range() }
-- stylua: ignore
local left_range = {
left_range_1[1], left_range_1[2],
left_range_2[3], left_range_2[4]
}

local right_range_1 = { right_pair[1]:range() }
local right_range_2 = { right_pair[2]:range() }
-- stylua: ignore
local right_range = {
right_range_1[1], right_range_1[2],
right_range_2[3], right_range_2[4]
}

local buf = vim.api.nvim_get_current_buf()
local cursor_pos = 1
if opts.reversed then
cursor_pos = 0
end

text_api.swap_ranges(buf, left_range, right_range, cursor_pos)
end

local function drag_pair(opts)
Expand Down
40 changes: 40 additions & 0 deletions lua/nvim-paredit/api/text.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
local M = {}

-- Swap the text in the given buffer represented by left_range and right_range
function M.swap_ranges(buf, left_range, right_range, cursor_pos)
-- stylua: ignore
local left_text = vim.api.nvim_buf_get_text(
buf,
left_range[1], left_range[2],
left_range[3], left_range[4],
{}
)
-- stylua: ignore
local right_text = vim.api.nvim_buf_get_text(buf,
right_range[1], right_range[2],
right_range[3], right_range[4],
{}
)

-- stylua: ignore
vim.api.nvim_buf_set_text(buf,
right_range[1], right_range[2],
right_range[3], right_range[4],
left_text
)
if cursor_pos == 1 then
vim.api.nvim_win_set_cursor(0, { right_range[1] + 1, right_range[2] })
end

-- stylua: ignore
vim.api.nvim_buf_set_text(buf,
left_range[1], left_range[2],
left_range[3], left_range[4],
right_text
)
if cursor_pos == 0 then
vim.api.nvim_win_set_cursor(0, { left_range[1] + 1, left_range[2] })
end
end

return M
2 changes: 1 addition & 1 deletion lua/nvim-paredit/treesitter/pairs.lua
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ local M = {}
-- matched nodes.
function M.find_pairwise_nodes(target_node, opts)
local root_node = ts_utils.find_local_root(target_node)
local enclosing_form = ts_forms.find_nearest_form(target_node, opts)
local enclosing_form = ts_forms.get_node_root(target_node, opts):parent()
if not enclosing_form then
return
end
Expand Down
25 changes: 8 additions & 17 deletions tests/nvim-paredit/motion_spec.lua
Original file line number Diff line number Diff line change
Expand Up @@ -268,52 +268,43 @@ describe("motions :: ", function()
it("should move to parent form start", function()
-- (aa (bb) @(|cc) #{1})
prepare_buffer({
content = "(aa (bb) @(cc) #{1})",
cursor = { 1, 11 },
"(aa (bb) @(|cc) #{1})"
})

-- (aa (bb) @|(cc) #{1})
internal_api.move_to_parent_form_start()
expect({
cursor = { 1, 10 },
"(aa (bb) @|(cc) #{1})"
})

-- |(aa (bb) @(cc) #{1})
internal_api.move_to_parent_form_start()
expect({
cursor = { 1, 0 },
"|(aa (bb) @(cc) #{1})"
})

-- |(aa (bb) @(cc) #{1})
internal_api.move_to_parent_form_start()
expect({
cursor = { 1, 0 },
"|(aa (bb) @(cc) #{1})"
})
end)

it("should move to parent form end", function()
-- (aa (bb) |@(cc) #{1})
prepare_buffer({
content = "(aa (bb) @(cc) #{1})",
cursor = { 1, 9 },
"(aa (bb) |@(cc) #{1})",
})

-- (aa (bb) @(cc|) #{1})
internal_api.move_to_parent_form_end()
expect({
cursor = { 1, 13 },
"(aa (bb) @(cc|) #{1})",
})

-- (aa (bb) @(cc) #{1}|)
internal_api.move_to_parent_form_end()
expect({
cursor = { 1, 19 },
"(aa (bb) @(cc) #{1}|)",
})

-- (aa (bb) @(cc) #{1}|)
internal_api.move_to_parent_form_end()
expect({
cursor = { 1, 19 },
"(aa (bb) @(cc) #{1}|)",
})
end)
end)
38 changes: 38 additions & 0 deletions tests/nvim-paredit/pair_drag_spec.lua
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,44 @@ describe("pair dragging ::", function()
})
end)

it("should drag multiline pairs", function()
prepare_buffer({
"{:a |{:a1 1",
" :a2 2}",
" :b {:b1 1",
" :b2 2}}",
})
paredit.drag_element_forwards({
dragging = {
auto_drag_pairs = true,
},
})
expect({
"{:b {:b1 1",
" :b2 2}",
" |:a {:a1 1",
" :a2 2}}",
})
end)

it("should drag pairs with differing line counts", function()
prepare_buffer({
"{:a |{:a1 1",
" :a2 2}",
" :b {:b1 1 :b2 2}}",
})
paredit.drag_element_forwards({
dragging = {
auto_drag_pairs = true,
},
})
expect({
"{:b {:b1 1 :b2 2}",
" |:a {:a1 1",
" :a2 2}}",
})
end)

it("should drag map pairs backwards", function()
prepare_buffer({
content = "{:a 1 :b 2}",
Expand Down
Loading