Skip to content

Commit 6a97374

Browse files
committed
Use lhs sibling as indentation ref point
1 parent c04c51f commit 6a97374

File tree

3 files changed

+77
-4
lines changed

3 files changed

+77
-4
lines changed

lua/nvim-paredit/indentation/native.lua

Lines changed: 22 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -99,8 +99,17 @@ local function indent_barf(event)
9999
if parent:type() == "source" then
100100
delta = node_range[2]
101101
else
102-
local form_edges = lang.get_form_edges(parent)
103-
delta = node_range[2] - form_edges.left.range[2] - 1
102+
local row
103+
local ref_node = utils.get_first_sibling_on_upper_line(node, { lang = lang })
104+
if ref_node then
105+
local range = { ref_node:range() }
106+
row = range[2]
107+
else
108+
local form_edges = lang.get_form_edges(parent)
109+
row = form_edges.left.range[2] - 1
110+
end
111+
112+
delta = node_range[2] - row
104113
end
105114

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

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

132-
local delta = form_edges.left.range[4] - child_range[2]
140+
local row
141+
local ref_node = utils.get_first_sibling_on_upper_line(child, { lang = lang })
142+
if ref_node then
143+
local range = { ref_node:range() }
144+
row = range[2]
145+
else
146+
local form_edges = lang.get_form_edges(parent)
147+
row = form_edges.left.range[4]
148+
end
149+
150+
local delta = row - child_range[2]
133151
indent_lines(lines, delta, {
134152
buf = event.buf,
135153
})

lua/nvim-paredit/indentation/utils.lua

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,4 +61,35 @@ function M.node_is_first_on_line(node, opts)
6161
return sibling_range[3] ~= node_range[1]
6262
end
6363

64+
-- This functions finds the closest sibling to a given `node` which is:
65+
-- 1) Not on the same line (one line higher)
66+
-- 2) Is the first node on the line
67+
--
68+
-- This node can be used as an indentation reference point.
69+
function M.get_first_sibling_on_upper_line(node, opts)
70+
local node_range = { node:range() }
71+
72+
local reference
73+
local prev = node
74+
75+
while prev do
76+
prev = traversal.get_prev_sibling_ignoring_comments(prev, opts)
77+
if not prev then
78+
return reference
79+
end
80+
81+
local sibling_range = { prev:range() }
82+
83+
if reference and reference:range() ~= sibling_range[1] then
84+
return reference
85+
end
86+
87+
if sibling_range[1] ~= node_range[1] then
88+
reference = prev
89+
end
90+
end
91+
92+
return reference
93+
end
94+
6495
return M

tests/nvim-paredit/indentation_spec.lua

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,14 @@ describe("forward slurping indentation", function()
6666
after_content = { "(", ";; comment", " a)" },
6767
after_cursor = { 1, 0 },
6868
},
69+
70+
{
71+
"should indent to the first relevant siblings indentation",
72+
before_content = { "(def a []", " target sibling)", "child" },
73+
before_cursor = { 1, 1 },
74+
after_content = { "(def a []", " target sibling", " child)" },
75+
after_cursor = { 1, 1 },
76+
},
6977
})
7078
end)
7179

@@ -142,6 +150,14 @@ describe("forward barfing indentation", function()
142150
after_content = { "()", ";; comment", "a" },
143151
after_cursor = { 1, 0 },
144152
},
153+
154+
{
155+
"should indent to the first relevant siblings indentation",
156+
before_content = { "(def a []", " target (sibling", " child))" },
157+
before_cursor = { 2, 10 },
158+
after_content = { "(def a []", " target (sibling)", " child)" },
159+
after_cursor = { 2, 10 },
160+
},
145161
})
146162
end)
147163

@@ -166,5 +182,13 @@ describe("backward barfing indentation", function()
166182
after_content = { "(a", " (bc", " de))" },
167183
after_cursor = { 2, 3 },
168184
},
185+
186+
{
187+
"should indent to the first relevant siblings indentation",
188+
before_content = { "(def a []", " target (sibling", " child))" },
189+
before_cursor = { 3, 1 },
190+
after_content = { "(def a []", " target sibling", " (child))" },
191+
after_cursor = { 3, 2 },
192+
},
169193
})
170194
end)

0 commit comments

Comments
 (0)