@@ -17,11 +17,31 @@ function Headline:new(headline_node)
1717 return data
1818end
1919
20+ --- @param cursor ? Table Cursor position tuple {row , col }
21+ --- @return Headline | nil
22+ function Headline .from_cursor (cursor )
23+ local ts_headline = tree_utils .closest_headline (cursor )
24+ if not ts_headline then
25+ return nil
26+ end
27+ return Headline :new (ts_headline )
28+ end
29+
2030--- @return userdata stars node
2131function Headline :stars ()
2232 return self .headline :field (' stars' )[1 ]
2333end
2434
35+ function Headline :refresh ()
36+ tree_utils .parse ()
37+ local start_row , start_col = self .headline :start ()
38+ local updated_headline = Headline .from_cursor ({ start_row + 1 , start_col })
39+ if updated_headline then
40+ self .headline = updated_headline .headline
41+ end
42+ return self
43+ end
44+
2545--- @return number
2646function Headline :level ()
2747 local stars = self :stars ()
@@ -150,6 +170,15 @@ function Headline:todo()
150170 end
151171end
152172
173+ function Headline :title ()
174+ local title = query .get_node_text (self :item (), 0 ) or ' '
175+ local todo , word = self :todo ()
176+ if todo then
177+ title = title :gsub (' ^' .. vim .pesc (word ) .. ' %s*' , ' ' )
178+ end
179+ return title
180+ end
181+
153182--- @return userdata
154183function Headline :plan ()
155184 local section = self .headline :parent ()
@@ -160,6 +189,75 @@ function Headline:plan()
160189 end
161190end
162191
192+ --- @return userdata
193+ function Headline :properties ()
194+ local section = self .headline :parent ()
195+ for _ , node in ipairs (ts_utils .get_named_children (section )) do
196+ if node :type () == ' property_drawer' then
197+ return node
198+ end
199+ end
200+ end
201+
202+ --- @param name string
203+ --- @param value string
204+ function Headline :set_property (name , value )
205+ local properties = self :properties ()
206+ if not properties then
207+ local append_line = self :get_append_line ()
208+ local property_drawer = self :_apply_indent ({ ' :PROPERTIES:' , ' :END:' })
209+ vim .api .nvim_buf_set_lines (0 , append_line , append_line , false , property_drawer )
210+ tree_utils .parse ()
211+ properties = self :refresh ():properties ()
212+ end
213+
214+ local property = (' :%s: %s' ):format (name , value )
215+ local existing_property = self :get_property (name )
216+ if existing_property then
217+ tree_utils .set_node_text (existing_property .node , property )
218+ return self :refresh ()
219+ end
220+ local property_end = properties :end_ ()
221+ vim .api .nvim_buf_set_lines (0 , property_end - 1 , property_end - 1 , false , { self :_apply_indent (property ) })
222+ return self :refresh ()
223+ end
224+
225+ --- @param property_name string
226+ --- @return table | nil
227+ function Headline :get_property (property_name )
228+ local properties = self :properties ()
229+ if not properties then
230+ return nil
231+ end
232+
233+ for _ , node in ipairs (ts_utils .get_named_children (properties )) do
234+ local name = node :field (' name' )[1 ]
235+ local value = node :field (' value' )[1 ]
236+ if name and query .get_node_text (name , 0 ):lower () == property_name :lower () then
237+ return {
238+ node = node ,
239+ name = name ,
240+ value = value and query .get_node_text (value , 0 ),
241+ }
242+ end
243+ end
244+ end
245+
246+ --- Return the line number where content can be appended
247+ ---
248+ --- @return number
249+ function Headline :get_append_line ()
250+ local properties = self :properties ()
251+ if properties then
252+ return properties :end_ ()
253+ end
254+ local plan = self :plan ()
255+ if plan then
256+ return plan :end_ ()
257+ end
258+ return self .headline :end_ ()
259+ end
260+
163261--- @return Table<string , userdata>
164262function Headline :dates ()
165263 local plan = self :plan ()
@@ -341,4 +439,9 @@ function Headline:_remove_date(type)
341439 end
342440end
343441
442+ --- @param text table | string
443+ function Headline :_apply_indent (text )
444+ return config :apply_indent (text , self :level () + 1 )
445+ end
446+
344447return Headline
0 commit comments