local M = {} function M.find_headline(node) if node:type() == "atx_heading" then return node end if node:type() == "section" then -- The headline is always the first child of a section local child = node:child "atx_heading" if child then return child end end if node:parent() then return M.find_headline(node:parent()) end return nil end function M.headline_level(headline) local heading_content = headline:field "heading_content" if not heading_content or #heading_content == 0 then return 0 end local _, level = heading_content[1]:start() return level - 1 end function M.get_node_at_cursor(cursor) if not cursor then return vim.treesitter.get_node() end return vim.treesitter.get_node { bufnr = 0, pos = { cursor[1] - 1, cursor[2] }, } end function M.closest_headline_node(cursor) local node = M.get_node_at_cursor(cursor) if not node then return nil end return M.find_headline(node) end return M