Skip to content

Commit fe814c2

Browse files
committed
Add more markdown functionality
1 parent 5375364 commit fe814c2

File tree

2 files changed

+35
-16
lines changed

2 files changed

+35
-16
lines changed

lua/treewalker/markdown/selectors.lua

Lines changed: 30 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ local function find_section_at_row(row)
1212
local node = nodes.get_at_row(row)
1313
if not node then return nil end
1414

15-
local current = node
15+
local current = node --[[@as TSNode?]]
1616
while current do
1717
if current:type() == "section" then
1818
return current
@@ -209,28 +209,42 @@ function M.get_prev_outer_heading(row)
209209
if not util.is_markdown_file() then return nil, nil end
210210
if not heading.is_heading(row) then return nil, nil end
211211

212-
local section = find_section_at_row(row)
213-
if not section then return nil, nil end
214-
215-
local current_level = get_section_level(section)
212+
local current_level = heading.heading_level(row)
216213
if not current_level or current_level <= 1 then return nil, nil end
217214

218-
-- Find parent section with level current_level - 1
219-
local parent = section:parent()
220-
while parent do
221-
if parent:type() == "section" then
222-
local parent_level = get_section_level(parent)
223-
if parent_level == current_level - 1 then
224-
local heading_row = get_section_heading_row(parent)
225-
if heading_row then
226-
return nodes.get_at_row(heading_row), heading_row
215+
-- For out-of-order headings, we need to find the nearest previous heading
216+
-- with a lower level (not necessarily direct AST parent)
217+
local root = vim.treesitter.get_parser():parse()[1]:root()
218+
local target_level = current_level - 1
219+
local best_match = nil
220+
221+
local function find_in_node(node)
222+
if node:type() == "section" then
223+
local section_level = get_section_level(node)
224+
local section_row = get_section_heading_row(node)
225+
226+
if section_row and section_row < row and section_level and section_level <= target_level then
227+
-- Update best match if this is closer or has a higher level (but still <= target_level)
228+
if not best_match or section_row > best_match.row or
229+
(section_row == best_match.row and section_level > best_match.level) then
230+
best_match = { row = section_row, level = section_level }
227231
end
228232
end
229233
end
230-
parent = parent:parent()
234+
235+
-- Recursively search children
236+
for child in node:iter_children() do
237+
find_in_node(child)
238+
end
239+
end
240+
241+
find_in_node(root)
242+
243+
if best_match then
244+
return nodes.get_at_row(best_match.row), best_match.row
231245
end
232246

233247
return nil, nil
234248
end
235249

236-
return M
250+
return M

tests/treewalker/markdown_spec.lua

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -202,6 +202,11 @@ describe("Movement in a markdown file", function()
202202
h.assert_highlighted(110, 1, 132, 0)
203203
end)
204204

205+
it("Move out in out of order headings", function()
206+
vim.fn.cursor(71, 1)
207+
tw.move_out()
208+
h.assert_cursor_at(68, 1)
209+
end)
205210
end)
206211

207212
describe("Swapping in a markdown file:", function()

0 commit comments

Comments
 (0)