Skip to content

Commit

Permalink
Improve native indent impl under some edge cases
Browse files Browse the repository at this point in the history
There are a few cases, especially when comments are involved, where the
indent would break or do the wrong thing.

This adds some more tests for edge-cases and fixes the behaviour for
those cases.
  • Loading branch information
julienvincent committed Oct 14, 2024
1 parent 5c226e6 commit 67eee38
Show file tree
Hide file tree
Showing 3 changed files with 57 additions and 10 deletions.
22 changes: 19 additions & 3 deletions lua/nvim-paredit/indentation/native.lua
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,11 @@ local function indent_barf(event)
local lhs_range = { lhs:range() }
local node_range = { node:range() }

if not utils.node_is_first_on_line(node, opts) or lhs_range[1] == node_range[1] then
if lhs_range[3] == node_range[1] then
return
end

if not utils.node_is_first_on_line(node, opts) then
return
end

Expand Down Expand Up @@ -136,13 +140,25 @@ local function indent_slurp(event)
if event.type == "slurp-forwards" then
child = parent:named_child(parent:named_child_count() - 1)
else
child = parent:named_child(1)
local first = parent:named_child(0)
if not first then
return
end
child = traversal.get_next_sibling_ignoring_comments(first, opts)
end

if not child then
return
end

local parent_range = { parent:range() }
local child_range = { child:range() }

if not utils.node_is_first_on_line(child, opts) or parent_range[1] == child_range[1] then
if parent_range[1] == child_range[1] then
return
end

if not utils.node_is_first_on_line(child, opts) then
return
end

Expand Down
16 changes: 13 additions & 3 deletions lua/nvim-paredit/indentation/utils.lua
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,19 @@ local common = require("nvim-paredit.utils.common")

local M = {}

local function get_corrected_line_range(range)
-- if the node is at the zeroth position on the last line, it's not actually
-- part of the line.
if range[4] == 0 then
return range[1], range[3] - 1
end
return range[1], range[3]
end

function M.get_node_line_range(range)
local start, _end = get_corrected_line_range(range)
local lines = {}
for i = range[1], range[3], 1 do
for i = start, _end, 1 do
table.insert(lines, i)
end
return lines
Expand Down Expand Up @@ -57,8 +67,8 @@ function M.node_is_first_on_line(node, opts)
return true
end

local sibling_range = { sibling:range() }
return sibling_range[3] ~= node_range[1]
local _, sibling_end = get_corrected_line_range({ sibling:range() })
return sibling_end ~= node_range[1]
end

-- This functions finds the closest sibling to a given `node` which is:
Expand Down
29 changes: 25 additions & 4 deletions tests/nvim-paredit/indentation_spec.lua
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,13 @@ describe("indentation ::", function()
after_content = "( 1)",
after_cursor = { 1, 1 },
},
{
"should not indent when on same line [multiline]",
before_content = {"(", " a) b"},
before_cursor = { 1, 0 },
after_content = {"(", " a b)"},
after_cursor = { 1, 0 },
},
{
"should dedent when node is too far indented",
before_content = { "()", " a" },
Expand All @@ -78,9 +85,9 @@ describe("indentation ::", function()
},
{
"should indent the correct node ignoring comments",
before_content = { "()", ";; comment", "a" },
before_content = { "()", ";; comment", "a ;; another comment", "b" },
before_cursor = { 1, 1 },
after_content = { "(", ";; comment", " a)" },
after_content = { "(", ";; comment", " a) ;; another comment", "b" },
after_cursor = { 1, 0 },
},

Expand All @@ -107,13 +114,27 @@ describe("indentation ::", function()
after_content = { "(a", " b)" },
after_cursor = { 2, 2 },
},
{
"should indent with a comment in the way",
before_content = { "a ;; comment", "(b)" },
before_cursor = { 2, 1 },
after_content = { "(a ;; comment", " b)" },
after_cursor = { 2, 2 },
},
{
"should not indent when on same line",
before_content = { "a (b)" },
before_cursor = { 1, 3 },
after_content = { "(a b)" },
after_cursor = { 1, 3 },
},
{
"should handle empty children",
before_content = { "a", "()" },
before_cursor = { 2, 1 },
after_content = { "(a", ")" },
after_cursor = { 2, 0 },
},
})
end)

Expand Down Expand Up @@ -146,9 +167,9 @@ describe("indentation ::", function()
},
{
"should not dedent if node is on the same line",
before_content = { "(a", "b c)" },
before_content = { "(a", " b c)" },
before_cursor = { 1, 1 },
after_content = { "(a", "b) c" },
after_content = { "(a", " b) c" },
after_cursor = { 1, 1 },
},
{
Expand Down

0 comments on commit 67eee38

Please sign in to comment.