@@ -3,27 +3,43 @@ local Headline = require('orgmode.treesitter.headline')
33local Listitem = require (' orgmode.treesitter.listitem' )
44local M = {}
55
6- --- @param matcher function
6+ --- @param matcher function (headline : Headline , index : number ): boolean
7+ --- @param from_end ? boolean
78--- @return Headline | nil
8- local function query_headlines (matcher )
9+ local function query_headlines (matcher , from_end )
910 local trees = vim .treesitter .get_parser (0 , ' org' , {}):parse ()
1011 if # trees == 0 then
1112 return {}
1213 end
1314 local root = trees [1 ]:root ()
1415 local ts_query = tree_utils .parse_query (' (section (headline) @headline)' )
15- local index = 1
16+ local headlines = {}
1617 for _ , match , _ in ts_query :iter_matches (root ) do
17- -- local items = {}
1818 for _ , matched_node in pairs (match ) do
1919 local headline = Headline :new (matched_node )
20- local valid = matcher (headline , index )
20+ table.insert (headlines , headline )
21+ end
22+ end
23+
24+ if from_end then
25+ for i = # headlines , 1 , - 1 do
26+ local headline = headlines [i ]
27+ local valid = matcher (headline , i )
2128 if valid then
2229 return headline
2330 end
24- index = index + 1
31+ end
32+ return nil
33+ end
34+
35+ for i , headline in ipairs (headlines ) do
36+ local valid = matcher (headline , i )
37+ if valid then
38+ return headline
2539 end
2640 end
41+
42+ return nil
2743end
2844
2945--- @param cursor ? Table Cursor position tuple {row , col }
@@ -53,18 +69,23 @@ M.headline_at = function(index)
5369 end )
5470end
5571
72+ --- @class FindHeadlineOpts
73+ --- @field from_end ? boolean
74+ --- @field exact ? boolean
75+
5676--- @param title string
57- --- @param exact ? boolean
77+ --- @param opts ? FindHeadlineOpts
5878--- @return Headline | nil
59- M .find_headline_by_title = function (title , exact )
79+ M .find_headline_by_title = function (title , opts )
80+ opts = opts or {}
6081 return query_headlines (function (headline , _ )
6182 local pattern = ' ^' .. vim .pesc (title :lower ())
62- if exact then
83+ if opts . exact then
6384 pattern = pattern .. ' $'
6485 end
6586
6687 return headline :title ():lower ():match (pattern )
67- end )
88+ end , opts . from_end )
6889end
6990
7091return M
0 commit comments