0
0
Fork 1
mirror of https://git.savannah.gnu.org/git/emacs/org-mode.git synced 2024-07-16 20:46:27 +00:00

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

View file

@ -687,6 +687,47 @@ Sunday 7 January 2024
(should-not (org-agenda-files))) (should-not (org-agenda-files)))
(org-test-agenda--kill-all-agendas)) (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 ;; agenda redo