Skip to content

Commit

Permalink
Use lhs sibling as indentation ref point
Browse files Browse the repository at this point in the history
  • Loading branch information
julienvincent committed Sep 10, 2023
1 parent 8f2904d commit 679dd5a
Show file tree
Hide file tree
Showing 3 changed files with 85 additions and 4 deletions.
26 changes: 22 additions & 4 deletions lua/nvim-paredit/indentation/native.lua
Original file line number Diff line number Diff line change
Expand Up @@ -99,8 +99,17 @@ local function indent_barf(event)
if parent:type() == "source" then
delta = node_range[2]
else
local form_edges = lang.get_form_edges(parent)
delta = node_range[2] - form_edges.left.range[2] - 1
local row
local ref_node = utils.get_first_sibling_on_upper_line(node, { lang = lang })
if ref_node then
local range = { ref_node:range() }
row = range[2]
else
local form_edges = lang.get_form_edges(parent)
row = form_edges.left.range[2] - 1
end

delta = node_range[2] - row
end

indent_lines(lines, delta * -1, {
Expand All @@ -127,9 +136,18 @@ local function indent_slurp(event)
end

local lines = utils.find_affected_lines(child, utils.get_node_line_range(child_range))
local form_edges = lang.get_form_edges(parent)

local delta = form_edges.left.range[4] - child_range[2]
local row
local ref_node = utils.get_first_sibling_on_upper_line(child, { lang = lang })
if ref_node then
local range = { ref_node:range() }
row = range[2]
else
local form_edges = lang.get_form_edges(parent)
row = form_edges.left.range[4]
end

local delta = row - child_range[2]
indent_lines(lines, delta, {
buf = event.buf,
})
Expand Down
31 changes: 31 additions & 0 deletions lua/nvim-paredit/indentation/utils.lua
Original file line number Diff line number Diff line change
Expand Up @@ -61,4 +61,35 @@ function M.node_is_first_on_line(node, opts)
return sibling_range[3] ~= node_range[1]
end

-- This functions finds the closest sibling to a given `node` which is:
-- 1) Not on the same line (one line higher)
-- 2) Is the first node on the line
--
-- This node can be used as an indentation reference point.
function M.get_first_sibling_on_upper_line(node, opts)
local node_range = { node:range() }

local reference
local prev = node

while prev do
prev = traversal.get_prev_sibling_ignoring_comments(prev, opts)
if not prev then
return reference
end

local sibling_range = { prev:range() }

if reference and reference:range() ~= sibling_range[1] then
return reference
end

if sibling_range[1] ~= node_range[1] then
reference = prev
end
end

return reference
end

return M
32 changes: 32 additions & 0 deletions tests/nvim-paredit/indentation_spec.lua
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,14 @@ describe("forward slurping indentation", function()
after_content = { "(", ";; comment", " a)" },
after_cursor = { 1, 0 },
},

{
"should indent to the first relevant siblings indentation",
before_content = { "(def a []", " target sibling)", "child" },
before_cursor = { 1, 1 },
after_content = { "(def a []", " target sibling", " child)" },
after_cursor = { 1, 1 },
},
})
end)

Expand All @@ -90,6 +98,14 @@ describe("backward slurping indentation", function()
after_content = { "(a b)" },
after_cursor = { 1, 3 },
},

{
"should indent to the first relevant siblings indentation",
before_content = { "(def a []", " target sibling)", "child" },
before_cursor = { 1, 1 },
after_content = { "(def a []", " target sibling", " child)" },
after_cursor = { 1, 1 },
},
})
end)

Expand Down Expand Up @@ -142,6 +158,14 @@ describe("forward barfing indentation", function()
after_content = { "()", ";; comment", "a" },
after_cursor = { 1, 0 },
},

{
"should indent to the first relevant siblings indentation",
before_content = { "(def a []", " target (sibling", " child))" },
before_cursor = { 2, 10 },
after_content = { "(def a []", " target (sibling)", " child)" },
after_cursor = { 2, 10 },
},
})
end)

Expand All @@ -166,5 +190,13 @@ describe("backward barfing indentation", function()
after_content = { "(a", " (bc", " de))" },
after_cursor = { 2, 3 },
},

{
"should indent to the first relevant siblings indentation",
before_content = { "(def a []", " target (sibling", " child))" },
before_cursor = { 3, 1 },
after_content = { "(def a []", " target sibling", " (child))" },
after_cursor = { 3, 2 },
},
})
end)

0 comments on commit 679dd5a

Please sign in to comment.