diff --git a/README.org b/README.org index a36be47..23f1ea7 100644 --- a/README.org +++ b/README.org @@ -193,6 +193,7 @@ These selectors take one argument alone, or multiple arguments in a list. + =:children= :: Select any item that has child entries. Argument may be ~t~ to match if it has any children, ~nil~ to match if it has no children, ~todo~ to match if it has children with any to-do keywords, or a string to match if it has children with certain to-do keywords. You might use this to select items that are project top-level headings. Be aware that this may be very slow in non-daily/weekly agenda views because of its recursive nature. + =:date= :: Group items that have a date associated. Argument can be =t= to match items with any date, =nil= to match items without a date, or =today= to match items with today’s date. The =ts-date= text-property is matched against. + =:deadline= :: Group items that have a deadline. Argument can be ~t~ (to match items with any deadline), ~nil~ (to match items that have no deadline), ~past~ (to match items with a deadline in the past), ~today~ (to match items whose deadline is today), or ~future~ (to match items with a deadline in the future). Argument may also be given like ~before DATE~ or ~after DATE~ where DATE is a date string that ~org-time-string-to-absolute~ can process. ++ =:timestamp= :: Group items whose bodies contain an active timestamp. Argument can be ~t~ (to match items with any timestamp), ~past~ (to match items with timestamps in the past), ~today~ (to match items with timestamps set to today), or ~future~ (to match items with timestamps in the future). Argument may also be given like ~before DATE~ or ~after DATE~, where DATE is a date string that ~org-time-string-to-absolute~ can process. + =:effort<= :: Group items that are less than (or equal to) the given effort. Argument is a time-duration string, like ~5~ or ~0:05~ for 5 minutes. + =:effort>= :: Group items that are higher than (or equal to) the given effort. Argument is a time-duration string, like ~5~ or ~0:05~ for 5 minutes. + ~:file-path~ :: Group items whose buffers' filename paths match any of the given regular expressions. diff --git a/org-super-agenda.el b/org-super-agenda.el index 163bc2b..3d6c6d5 100644 --- a/org-super-agenda.el +++ b/org-super-agenda.el @@ -396,6 +396,7 @@ returned by :SECTION-NAME as the first item, a list of items not matching the :TEST as the second, and a list of items matching as the third." (declare (indent defun) + (doc-string 2) (debug (&define symbolp stringp &rest [&or [":section-name" [&or stringp def-form]] [":test" def-form] @@ -498,7 +499,7 @@ DATE', where DATE is a date string that (org-super-agenda--defgroup scheduled "Group items that are scheduled. Argument can be `t' (to match items scheduled for any date), -`nil' (to match items that are not schedule), `past` (to match +`nil' (to match items that are not scheduled), `past' (to match items scheduled for the past), `today' (to match items scheduled for today), or `future' (to match items scheduled for the future). Argument may also be given like `before DATE' or `after @@ -532,6 +533,42 @@ DATE', where DATE is a date string that ((or 'before 'on 'after) target-date)))) (org-super-agenda--compare-dates comparison entry-time compare-date)))))))) +(org-super-agenda--defgroup timestamp + "Group items whose bodies contain an active timestamp. +Argument can be `t' (to match items with any timestamps), `past' (to match items +with timestamps in the past), `today' (to match items with timestamps set to +today), or `future' (to match items with timestamps in the future). Argument +may also be given like `before DATE', `after DATE' or `after DATE', where DATE +is a date string that `org-read-date' can process. Note that relative dates are +supported, e.g. `before +3d' means in the next two days." + :section-name (pcase (car args) + ('t "Active timestamps") + ('today "Active timestamps for today") + ('future "Future active timestamps") + ('past "Past active timestamps") + ('before (concat "Active timestamps before " (cadr args))) + ('on (concat "Active timestamps on " (cadr args))) + ('after (concat "Active timestamps after " (cadr args)))) + :let* ((target-date (pcase (car args) + ((or 'before 'on 'after) + (org-time-string-to-absolute (org-read-date nil nil (cadr args)))))) + (comparison (car args)) + (compare-date + (pcase comparison + ((or 'future 'past 'today) (org-today)) + ((or 'before 'after 'on) target-date)))) + :test (org-super-agenda--when-with-marker-buffer (org-super-agenda--get-marker item) + (let ((limit (org-entry-end-position))) + (cl-macrolet + ((next-timestamp + () + `(when (re-search-forward org-ts-regexp limit :no-error) + (org-time-string-to-absolute (org-read-date nil nil (match-string 1)))))) + (cl-loop for next-ts = (next-timestamp) + while next-ts + thereis (or (eq comparison 't) + (org-super-agenda--compare-dates comparison next-ts compare-date))))))) + (defun org-super-agenda--compare-dates (comparison date-a date-b) "Compare DATE-A and DATE-B according to COMPARISON. COMPARISON should be a symbol, one of: `past' or `before', diff --git a/test/results.el b/test/results.el index de4d9c7..8b8e3d9 100644 --- a/test/results.el +++ b/test/results.el @@ -2199,4 +2199,19 @@ Wednesday 5 July 2017 ambition: In 77 d.: TODO Visit Mars :universe:ambition::space:travel:planet: test: Scheduled: TODO [#C] Get haircut :personal:@town: ambition: TODO Practice leaping tall ! :universe:ambition::personal: -")) \ No newline at end of file +" "98d4ed62b31456728bdfc66c8210b1ea" "Day-agenda (W27): +Wednesday 5 July 2017 + + Future timestamps + test: NEXT Meet with the Elder Council +" "7b77cb34ad6f2bf523dc25b647310fd0" "Day-agenda (W27): +Wednesday 5 July 2017 + + Past timestamps + test: NEXT Time Travellers' Convention +" "7b77cb34ad6f2bf523dc25b647310fd0" "Day-agenda (W27): +Wednesday 5 July 2017 + + Relative timestamps + test: NEXT Release the Kraken +")) diff --git a/test/test.el b/test/test.el index 7158fec..8881fa0 100644 --- a/test/test.el +++ b/test/test.el @@ -728,23 +728,44 @@ already loaded." (should (org-super-agenda-test--run :groups '((:not (:todo t)))))) -(ert-deftest org-super-agenda-test--with-retained-sorting () +(ert-deftest org-super-agenda-test--with-kept-order () (should (org-super-agenda-test--run :groups '((:name "Ambitions vs Bills with retained sorting" :and (:todo "TODO" :priority>= "B" :tag "ambition") :and (:todo "TODO" :priority>= "B" :tag "bills") :discard (:anything))) :let* ((org-agenda-sorting-strategy '(priority-down tag-down)) - (org-super-agenda-retain-sorting t))))) + (org-super-agenda-keep-order t))))) -(ert-deftest org-super-agenda-test--without-retained-sorting () +(ert-deftest org-super-agenda-test--without-kept-order () (should (org-super-agenda-test--run :groups '((:name "Ambitions vs Bills without retained sorting" :and (:todo "TODO" :priority>= "B" :tag "ambition") :and (:todo "TODO" :priority>= "B" :tag "bills") :discard (:anything))) :let* ((org-agenda-sorting-strategy '(priority-down tag-down)) - (org-super-agenda-retain-sorting nil))))) + (org-super-agenda-keep-order nil))))) + +(ert-deftest org-super-agenda-test--future-timestamps () + (should (org-super-agenda-test--run + :groups '((:name "Future timestamps" + :and (:tag "appointment" :timestamp future) + :discard (:anything))) + :let* ((org-agenda-sorting-strategy '(priority-down tag-down)))))) + +(ert-deftest org-super-agenda-test--past-timestamps () + (should (org-super-agenda-test--run + :groups '((:name "Past timestamps" + :and (:tag "appointment" :timestamp past) + :discard (:anything))) + :let* ((org-agenda-sorting-strategy '(priority-down tag-down)))))) + +(ert-deftest org-super-agenda-test--past-timestamps () + (should (org-super-agenda-test--run + :groups '((:name "Relative timestamps" + :and (:tag "appointment" :timestamp (on "+3d")) + :discard (:anything))) + :let* ((org-agenda-sorting-strategy '(priority-down tag-down)))))) (ert-deftest org-super-agenda-test--:order () ;; DONE: Works. diff --git a/test/test.org b/test/test.org index 249d869..6b497e4 100644 --- a/test/test.org +++ b/test/test.org @@ -78,6 +78,12 @@ If I don't, the frobnicator will probably fall off halfway to Mars... Gotta buy one first, though. +** NEXT Meet with the Elder Council :appointment: +<2021-10-03 So> +** NEXT Time Travellers' Convention :appointment: +<1566-10-05 Mo> +** NEXT Release the Kraken :appointment: +<2017-07-08 Mo> ** Recurring :PROPERTIES: :agenda-group: recurring