org-agenda: Make sure skipping warning/delay days never increases their number

* lisp/org-agenda.el (org-agenda-get-deadlines, org-agenda-get-scheduled):
Use minimum of warning/delay days specified in timestamp cookie and the
limit specified by `org-agenda-skip-deadline-prewarning-if-scheduled' or
`org-agenda-skip-scheduled-delay-if-deadline`, respectively.
* testing/lisp/test-org-agenda.el (test-org-agenda/skip-deadline-prewarning-if-scheduled):
New test.

Link: https://orgmode.org/list/59e48dfe744dc9409ff47183255bc64e92d26d88.camel@timruffing.de

TINYCHANGE
This commit is contained in:
Tim Ruffing 2024-02-13 10:57:29 +01:00 committed by Ihor Radchenko
parent 8651c83991
commit 356072c1d6
No known key found for this signature in database
GPG Key ID: 6470762A7DA11D8B
2 changed files with 52 additions and 14 deletions

View File

@ -6402,14 +6402,14 @@ specification like [h]h:mm."
(org-agenda--timestamp-to-absolute
s base 'future (current-buffer) pos)))))
(diff (- deadline current))
(suppress-prewarning
(max-warning-days
(let ((scheduled
(and org-agenda-skip-deadline-prewarning-if-scheduled
(org-element-property
:raw-value
(org-element-property :scheduled el)))))
(cond
((not scheduled) nil)
((not scheduled) most-positive-fixnum)
;; The current item has a scheduled date, so
;; evaluate its prewarning lead time.
((integerp org-agenda-skip-deadline-prewarning-if-scheduled)
@ -6423,15 +6423,15 @@ specification like [h]h:mm."
org-deadline-warning-days))
;; Set pre-warning to deadline.
(t 0))))
(wdays (or suppress-prewarning (org-get-wdays s))))
(warning-days (min max-warning-days (org-get-wdays s))))
(cond
;; Only display deadlines at their base date, at future
;; repeat occurrences or in today agenda.
((= current deadline) nil)
((= current repeat) nil)
((not today?) (throw :skip nil))
;; Upcoming deadline: display within warning period WDAYS.
((> deadline current) (when (> diff wdays) (throw :skip nil)))
;; Upcoming deadline: display within warning period WARNING-DAYS.
((> deadline current) (when (> diff warning-days) (throw :skip nil)))
;; Overdue deadline: warn about it for
;; `org-deadline-past-days' duration.
(t (when (< org-deadline-past-days (- diff)) (throw :skip nil))))
@ -6484,7 +6484,7 @@ specification like [h]h:mm."
'effort-minutes effort-minutes)
level category tags time))
(face (org-agenda-deadline-face
(- 1 (/ (float diff) (max wdays 1)))))
(- 1 (/ (float diff) (max warning-days 1)))))
(upcoming? (and today? (> deadline today)))
(warntime (org-entry-get (point) "APPT_WARNTIME" 'selective)))
(org-add-props item props
@ -6613,13 +6613,13 @@ scheduled items with an hour specification like [h]h:mm."
(futureschedp (> schedule today))
(habitp (and (fboundp 'org-is-habit-p)
(string= "habit" (org-element-property :STYLE el))))
(suppress-delay
(max-delay-days
(let ((deadline (and org-agenda-skip-scheduled-delay-if-deadline
(org-element-property
:raw-value
(org-element-property :deadline el)))))
(cond
((not deadline) nil)
((not deadline) most-positive-fixnum)
;; The current item has a deadline date, so
;; evaluate its delay time.
((integerp org-agenda-skip-scheduled-delay-if-deadline)
@ -6632,17 +6632,14 @@ scheduled items with an hour specification like [h]h:mm."
(org-agenda--timestamp-to-absolute deadline))
org-scheduled-delay-days))
(t 0))))
(ddays
(delay-days
(cond
;; Nullify delay when a repeater triggered already
;; and the delay is of the form --Xd.
((and (string-match-p "--[0-9]+[hdwmy]" s)
(> schedule (org-agenda--timestamp-to-absolute s)))
0)
(suppress-delay
(let ((org-scheduled-delay-days suppress-delay))
(org-get-wdays s t t)))
(t (org-get-wdays s t)))))
(t (min max-delay-days (org-get-wdays s t))))))
;; Display scheduled items at base date (SCHEDULE), today if
;; scheduled before the current date, and at any repeat past
;; today. However, skip delayed items and items that have
@ -6650,7 +6647,7 @@ scheduled items with an hour specification like [h]h:mm."
(unless (and todayp
habitp
(bound-and-true-p org-habit-show-all-today))
(when (or (and (> ddays 0) (< diff ddays))
(when (or (and (> delay-days 0) (< diff delay-days))
(> diff (or (and habitp org-habit-scheduled-past-days)
org-scheduled-past-days))
(> schedule current)

View File

@ -687,6 +687,47 @@ Sunday 7 January 2024
(should-not (org-agenda-files)))
(org-test-agenda--kill-all-agendas))
(ert-deftest test-org-agenda/skip-deadline-prewarning-if-scheduled ()
"Test `org-agenda-skip-deadline-prewarning-if-scheduled'."
(org-test-at-time
"2024-01-15"
(let ((org-agenda-skip-deadline-prewarning-if-scheduled t))
(org-test-agenda-with-agenda
"* TODO foo\nDEADLINE: <2024-01-20 Sat> SCHEDULED: <2024-01-19 Fri>"
(org-agenda-list nil nil 1)
(should-not (search-forward "In " nil t))))
(let ((org-agenda-skip-deadline-prewarning-if-scheduled 10))
(org-test-agenda-with-agenda
"* TODO foo\nDEADLINE: <2024-01-20 Sat> SCHEDULED: <2024-01-19 Fri>"
(org-agenda-list nil nil 1)
(should (search-forward "In " nil t))))
;; Custom prewarning cookie "-3d", so there should be no warning anyway.
(let ((org-agenda-skip-deadline-prewarning-if-scheduled 10))
(org-test-agenda-with-agenda
"* TODO foo\nDEADLINE: <2024-01-20 Sat -3d> SCHEDULED: <2024-01-19 Fri>"
(org-agenda-list nil nil 1)
(should-not (search-forward "In " nil t))))
(let ((org-agenda-skip-deadline-prewarning-if-scheduled 3))
(org-test-agenda-with-agenda
"* TODO foo\nDEADLINE: <2024-01-20 Sat> SCHEDULED: <2024-01-19 Fri>"
(org-agenda-list nil nil 1)
(should-not (search-forward "In " nil t))))
(let ((org-agenda-skip-deadline-prewarning-if-scheduled nil))
(org-test-agenda-with-agenda
"* TODO foo\nDEADLINE: <2024-01-20 Sat> SCHEDULED: <2024-01-19 Fri>"
(org-agenda-list nil nil 1)
(should (search-forward "In " nil t))))
(let ((org-agenda-skip-deadline-prewarning-if-scheduled 'pre-scheduled))
(org-test-agenda-with-agenda
"* TODO foo\nDEADLINE: <2024-01-20 Sat> SCHEDULED: <2024-01-16 Tue>"
(org-agenda-list nil nil 1)
(should-not (search-forward "In " nil t))))
(let ((org-agenda-skip-deadline-prewarning-if-scheduled 'pre-scheduled))
(org-test-agenda-with-agenda
"* TODO foo\nDEADLINE: <2024-01-20 Sat> SCHEDULED: <2024-01-15 Mon>"
(org-agenda-list nil nil 1)
(should (search-forward "In " nil t))))))
;; agenda redo