diff options
| author | Mattias Engdegård | 2026-03-02 17:10:04 +0100 |
|---|---|---|
| committer | Mattias Engdegård | 2026-03-02 17:35:13 +0100 |
| commit | b223f825f6081982063469986259bf1e1981b2b9 (patch) | |
| tree | 24fca128fcbfeb0774f4f059dc5b150e57475656 | |
| parent | 9a092fd74eaf985855ca060049c954b66b7f8b1f (diff) | |
| download | emacs-scratch/ical-recur.tar.gz emacs-scratch/ical-recur.zip | |
η-reduce icr:make-bysetpos-filterscratch/ical-recur
| -rw-r--r-- | lisp/calendar/icalendar-recur.el | 44 | ||||
| -rw-r--r-- | test/lisp/calendar/icalendar-recur-tests.el | 5 |
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 | ||
| 959 | SETPOS should be a list of positive or negative integers between -366 | 959 | SETPOS should be a list of positive or negative integers between -366 |
| 960 | and 366, indicating a fixed index in a set of recurrences for *one | 960 | and 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 | |||
| 963 | INTERVAL of 1, the SETPOS represent indices in the recurrence instances | 963 | INTERVAL of 1, the SETPOS represent indices in the recurrence instances |
| 964 | generated for a single year. | 964 | generated for a single year. |
| 965 | 965 | ||
| 966 | The returned value is a closure which can be called on the list of | 966 | The returned value is RECURRENCES filtered by index." |
| 967 | recurrences 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)))) |