aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMattias Engdegård2026-03-02 17:10:04 +0100
committerMattias Engdegård2026-03-02 17:35:13 +0100
commitb223f825f6081982063469986259bf1e1981b2b9 (patch)
tree24fca128fcbfeb0774f4f059dc5b150e57475656
parent9a092fd74eaf985855ca060049c954b66b7f8b1f (diff)
downloademacs-scratch/ical-recur.tar.gz
emacs-scratch/ical-recur.zip
η-reduce icr:make-bysetpos-filterscratch/ical-recur
-rw-r--r--lisp/calendar/icalendar-recur.el44
-rw-r--r--test/lisp/calendar/icalendar-recur-tests.el5
2 files changed, 23 insertions, 26 deletions
diff --git a/lisp/calendar/icalendar-recur.el b/lisp/calendar/icalendar-recur.el
index 4de4d00281f..696112c653d 100644
--- a/lisp/calendar/icalendar-recur.el
+++ b/lisp/calendar/icalendar-recur.el
@@ -953,8 +953,8 @@ BYSECOND=... clause; see `icalendar-recur' for the possible values."
953 (BYMINUTE (icr:refine-byminute interval values vtimezone)) 953 (BYMINUTE (icr:refine-byminute interval values vtimezone))
954 (BYSECOND (icr:refine-bysecond interval values vtimezone)))) 954 (BYSECOND (icr:refine-bysecond interval values vtimezone))))
955 955
956(defun icr:make-bysetpos-filter (setpos) 956(defun icr:bysetpos-filter (setpos recurrences)
957 "Return a filter on values for the indices in SETPOS. 957 "Filter RECURRENCES on values for the indices in SETPOS.
958 958
959SETPOS should be a list of positive or negative integers between -366 959SETPOS should be a list of positive or negative integers between -366
960and 366, indicating a fixed index in a set of recurrences for *one 960and 366, indicating a fixed index in a set of recurrences for *one
@@ -963,25 +963,24 @@ an `icalendar-recur'. For example, in a YEARLY recurrence rule with an
963INTERVAL of 1, the SETPOS represent indices in the recurrence instances 963INTERVAL of 1, the SETPOS represent indices in the recurrence instances
964generated for a single year. 964generated for a single year.
965 965
966The returned value is a closure which can be called on the list of 966The returned value is RECURRENCES filtered by index."
967recurrences for one interval to filter it by index." 967 (let* ((len (length recurrences))
968 (lambda (dts) 968 (keep-indices (mapcar
969 (let* ((len (length dts)) 969 (lambda (pos)
970 (keep-indices (mapcar 970 ;; sequence indices are 0-based, POS's are 1-based:
971 (lambda (pos) 971 (if (< pos 0)
972 ;; sequence indices are 0-based, POS's are 1-based: 972 (+ pos len)
973 (if (< pos 0) 973 (1- pos)))
974 (+ pos len) 974 setpos))
975 (1- pos))) 975 (r nil)
976 setpos)) 976 (i 0)
977 (r nil) 977 (dts recurrences))
978 (i 0)) 978 (while dts
979 (while dts 979 (when (memq i keep-indices)
980 (when (memq i keep-indices) 980 (push (car dts) r))
981 (push (car dts) r)) 981 (incf i)
982 (incf i) 982 (pop dts))
983 (pop dts)) 983 (nreverse r)))
984 (nreverse r))))
985 984
986(defun icr:refine-from-clauses (interval recur-value dtstart 985(defun icr:refine-from-clauses (interval recur-value dtstart
987 &optional vtimezone) 986 &optional vtimezone)
@@ -1225,8 +1224,7 @@ retrieved on subsequent calls with the same arguments."
1225 (keep-indices (ical:recur-by* 'BYSETPOS recur-value)) 1224 (keep-indices (ical:recur-by* 'BYSETPOS recur-value))
1226 (pos-recs 1225 (pos-recs
1227 (if keep-indices 1226 (if keep-indices
1228 (funcall (icr:make-bysetpos-filter keep-indices) 1227 (icr:bysetpos-filter keep-indices sub-recs)
1229 sub-recs)
1230 sub-recs)) 1228 sub-recs))
1231 ;; Remove any recurrences before DTSTART or after UNTIL 1229 ;; Remove any recurrences before DTSTART or after UNTIL
1232 ;; (both of which are inclusive bounds): 1230 ;; (both of which are inclusive bounds):
diff --git a/test/lisp/calendar/icalendar-recur-tests.el b/test/lisp/calendar/icalendar-recur-tests.el
index 655be9b8c7a..028319035c7 100644
--- a/test/lisp/calendar/icalendar-recur-tests.el
+++ b/test/lisp/calendar/icalendar-recur-tests.el
@@ -117,13 +117,12 @@ END:VTIMEZONE
117;; Tests for basic functions: 117;; Tests for basic functions:
118 118
119(ert-deftest ict:recur-bysetpos-filter () 119(ert-deftest ict:recur-bysetpos-filter ()
120 "Test that `icr:make-bysetpos-filter' filters correctly by position" 120 "Test that `icr:bysetpos-filter' filters correctly by position"
121 (let* ((t1 (list 1 1 2024)) 121 (let* ((t1 (list 1 1 2024))
122 (t2 (list 2 1 2024)) 122 (t2 (list 2 1 2024))
123 (t3 (list 12 30 2024)) 123 (t3 (list 12 30 2024))
124 (dts (list t1 t2 t3)) 124 (dts (list t1 t2 t3))
125 (filter (icr:make-bysetpos-filter (list 1 -1))) 125 (filtered (icr:bysetpos-filter (list 1 -1) dts)))
126 (filtered (funcall filter dts)))
127 (should (member t1 filtered)) 126 (should (member t1 filtered))
128 (should (member t3 filtered)) 127 (should (member t3 filtered))
129 (should-not (member t2 filtered)))) 128 (should-not (member t2 filtered))))