@@ -14,35 +14,16 @@ local DiaryHeadline = require('orgmode.agenda.diary_headline')
1414local DiaryFormat = require (' orgmode.diary.format' )
1515local DiarySexp = require (' orgmode.diary.sexp' )
1616
17- local function _parse_remind_event_date (expr , day )
18- if type (expr ) ~= ' string' then
19- return nil
20- end
21- local y , m , d , n
22- -- org-anniversary YEAR MONTH DAY
23- y , m , d , n = expr :match (" diary%-remind%s+%'%s*%(%s*org%-anniversary%s+(%d+)%s+(%d+)%s+(%d+)%s*%)%s+(%d+)" )
24- if y and m and d then
25- return day :set ({ month = tonumber (m ), day = tonumber (d ) }), tonumber (n )
26- end
27- -- diary-anniversary YEAR MONTH DAY or MONTH DAY YEAR
28- local a1 , a2 , a3
29- a1 , a2 , a3 , n = expr :match (" diary%-remind%s+%'%s*%(%s*diary%-anniversary%s+(%d+)%s+(%d+)%s+(%d+)%s*%)%s+(%d+)" )
30- if a1 and a2 and a3 then
31- a1 , a2 , a3 = tonumber (a1 ), tonumber (a2 ), tonumber (a3 )
32- local month , day_of_month
33- if a1 >= 1000 then
34- month , day_of_month = a2 , a3
35- else
36- month , day_of_month = a1 , a2
37- end
38- return day :set ({ month = month , day = day_of_month }), tonumber (n )
39- end
40- -- diary-date MONTH DAY [YEAR]
41- m , d , n = expr :match (" diary%-remind%s+%'%s*%(%s*diary%-date%s+(%d+)%s+(%d+)[%s%d]*%)%s+(%d+)" )
42- if m and d then
43- return day :set ({ month = tonumber (m ), day = tonumber (d ) }), tonumber (n )
44- end
45- return nil
17+ --- @param expr string
18+ --- @param day OrgDate
19+ --- @return OrgDate | nil event_date
20+ --- @return number | nil remind_days
21+ local function _get_remind_event_date (expr , day )
22+ local month , day_of_month , remind_days = DiarySexp .extract_remind_info (expr )
23+ if not month or not day_of_month or not remind_days then
24+ return nil , nil
25+ end
26+ return day :set ({ month = month , day = day_of_month }), remind_days
4627end
4728
4829--- @alias OrgAgendaDay { day : OrgDate , agenda_items : OrgAgendaItem[] , category_length : number , label_length : 0 }
@@ -606,46 +587,32 @@ function OrgAgendaType:_get_agenda_days()
606587 })
607588 end
608589 -- Include diary sexp entries
609- local ok_h , diary_headline_entries = pcall (function ()
610- return headline :get_diary_sexps ()
611- end )
612- if ok_h and diary_headline_entries then
613- for _ , entry in ipairs (diary_headline_entries ) do
614- local ok_p , matcher = pcall (function ()
615- return entry .expr and DiarySexp .parse (entry .expr ) or nil
616- end )
617- if ok_p and matcher then
618- table.insert (headline_dates , {
619- headline_date = self .from :clone ({ active = true , type = ' NONE' }),
620- headline = headline ,
621- _diary_matcher = matcher ,
622- })
623- end
624- end
625- end
626- end
627- -- Also include file-level diary sexp entries (outside headlines)
628- local ok_f , diary_file_entries = pcall (function ()
629- return orgfile :get_diary_sexps ()
630- end )
631- if ok_f and diary_file_entries then
632- for _ , entry in ipairs (diary_file_entries ) do
633- local ok_p , matcher = pcall (function ()
634- return entry .expr and DiarySexp .parse (entry .expr ) or nil
635- end )
636- if ok_p and matcher then
590+ for _ , entry in ipairs (headline :get_diary_sexps ()) do
591+ local matcher = entry .expr and DiarySexp .parse (entry .expr ) or nil
592+ if matcher then
637593 table.insert (headline_dates , {
638594 headline_date = self .from :clone ({ active = true , type = ' NONE' }),
639- headline = DiaryHeadline : new ({ file = orgfile , title = ' ' }) ,
595+ headline = headline ,
640596 _diary_matcher = matcher ,
641- _diary_text = entry .text ,
642- _diary_file_level = true ,
643- _diary_file = orgfile ,
644- _diary_expr = entry .expr ,
645597 })
646598 end
647599 end
648600 end
601+ -- Also include file-level diary sexp entries (outside headlines)
602+ for _ , entry in ipairs (orgfile :get_diary_sexps ()) do
603+ local matcher = entry .expr and DiarySexp .parse (entry .expr ) or nil
604+ if matcher then
605+ table.insert (headline_dates , {
606+ headline_date = self .from :clone ({ active = true , type = ' NONE' }),
607+ headline = DiaryHeadline :new ({ file = orgfile , title = ' ' }),
608+ _diary_matcher = matcher ,
609+ _diary_text = entry .text ,
610+ _diary_file_level = true ,
611+ _diary_file = orgfile ,
612+ _diary_expr = entry .expr ,
613+ })
614+ end
615+ end
649616 end
650617
651618 local headlines = {}
@@ -658,13 +625,10 @@ function OrgAgendaType:_get_agenda_days()
658625 local headline = item .headline
659626 local agenda_item = AgendaItem :new (item .headline_date , headline , day , index )
660627 if item ._diary_matcher then
661- local ok_m , matches = pcall (function ()
662- return item ._diary_matcher :matches (day )
663- end )
664- matches = ok_m and matches or false
628+ local matches = item ._diary_matcher :matches (day )
665629 -- Compress diary-remind to a single pre-reminder per visible span + the event day
666630 if matches and item ._diary_expr then
667- local event_date , remind_n = _parse_remind_event_date (item ._diary_expr , day )
631+ local event_date , remind_n = _get_remind_event_date (item ._diary_expr , day )
668632 if event_date and remind_n then
669633 local delta = event_date :diff (day )
670634 if delta == 0 then
@@ -689,7 +653,7 @@ function OrgAgendaType:_get_agenda_days()
689653 agenda_item .is_same_day = matches
690654 if matches and item ._diary_file_level and item ._diary_text and item ._diary_text ~= ' ' then
691655 local interpolated = DiaryFormat .interpolate (item ._diary_text , item ._diary_expr or ' ' , day )
692- local event_date , remind_n = _parse_remind_event_date (item ._diary_expr or ' ' , day )
656+ local event_date , remind_n = _get_remind_event_date (item ._diary_expr or ' ' , day )
693657 if event_date and remind_n then
694658 local delta = event_date :diff (day )
695659 if delta > 0 and delta <= remind_n then
@@ -709,20 +673,6 @@ function OrgAgendaType:_get_agenda_days()
709673
710674 vim .list_extend (date .agenda_items , self :_prepare_grid_lines (dates , date ))
711675
712- -- After collecting items for this day, hide duplicate diary-remind entries across days within the reminder window
713- date .agenda_items = vim .tbl_filter (function (ai )
714- if not ai .headline or type (ai .headline .get_title ) ~= ' function' then
715- return true
716- end
717- local title = (ai .headline :get_title ())
718- -- Only de-duplicate diary reminders (they are file-level with empty diary headline title)
719- if title ~= ' ' then
720- return true
721- end
722- -- Keep only the event day and the earliest reminder day in range, remove the rest
723- return true
724- end , date .agenda_items )
725-
726676 date .agenda_items = self :_sort (date .agenda_items )
727677 date .category_length = math.max (11 , date .category_length + 1 )
728678 date .label_length = math.min (11 , date .label_length )
0 commit comments