@@ -3,27 +3,43 @@ local Headline = require('orgmode.treesitter.headline')
3
3
local Listitem = require (' orgmode.treesitter.listitem' )
4
4
local M = {}
5
5
6
- --- @param matcher function
6
+ --- @param matcher function (headline : Headline , index : number ): boolean
7
+ --- @param from_end ? boolean
7
8
--- @return Headline | nil
8
- local function query_headlines (matcher )
9
+ local function query_headlines (matcher , from_end )
9
10
local trees = vim .treesitter .get_parser (0 , ' org' , {}):parse ()
10
11
if # trees == 0 then
11
12
return {}
12
13
end
13
14
local root = trees [1 ]:root ()
14
15
local ts_query = tree_utils .parse_query (' (section (headline) @headline)' )
15
- local index = 1
16
+ local headlines = {}
16
17
for _ , match , _ in ts_query :iter_matches (root ) do
17
- -- local items = {}
18
18
for _ , matched_node in pairs (match ) do
19
19
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 )
21
28
if valid then
22
29
return headline
23
30
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
25
39
end
26
40
end
41
+
42
+ return nil
27
43
end
28
44
29
45
--- @param cursor ? Table Cursor position tuple {row , col }
@@ -53,18 +69,23 @@ M.headline_at = function(index)
53
69
end )
54
70
end
55
71
72
+ --- @class FindHeadlineOpts
73
+ --- @field from_end ? boolean
74
+ --- @field exact ? boolean
75
+
56
76
--- @param title string
57
- --- @param exact ? boolean
77
+ --- @param opts ? FindHeadlineOpts
58
78
--- @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 {}
60
81
return query_headlines (function (headline , _ )
61
82
local pattern = ' ^' .. vim .pesc (title :lower ())
62
- if exact then
83
+ if opts . exact then
63
84
pattern = pattern .. ' $'
64
85
end
65
86
66
87
return headline :title ():lower ():match (pattern )
67
- end )
88
+ end , opts . from_end )
68
89
end
69
90
70
91
return M
0 commit comments