org-agenda: Fix meaning of 'repeated-after-deadline value of `org-agenda-skip-scheduled-if-deadline-is-shown'

* lisp/org-agenda.el (org-agenda-skip-scheduled-if-deadline-is-shown):
Move 'repeated-after-deadline value into a new custom option.
(org-agenda-skip-scheduled-repeats-after-deadline): Create a new
custom option to make agenda hide scheduled entries repeated past
deadline.
* lisp/org-agenda.el (org-agenda-get-scheduled): Use the new custom
option.  Do not demand deadline to be actually shown when deciding
whether to skip scheduled repeats past deadline.  This fixes a bug
when repeats continue to be displayed if past deadline is not
displayed within agenda span.
* doc/org-manual.org (Repeated tasks): Adjust manual entry, mentioning
the new custom option.
* etc/ORG-NEWS (~repeated-after-deadline~ value of
~org-agenda-skip-scheduled-repeats-after-deadline~ is moved to a new
customization): Announce the change.
*
testing/lisp/test-org-agenda.el (test-org-agenda/skip-scheduled-repeats-after-deadline):
Add new test.

Reported-by: Morgan Smith <Morgan.J.Smith@outlook.com>
Link: https://orgmode.org/list/874jft6vpj.fsf@localhost
This commit is contained in:
Ihor Radchenko 2024-02-07 13:21:34 +01:00
parent 18d98ee655
commit b26745b985
No known key found for this signature in database
GPG Key ID: 6470762A7DA11D8B
4 changed files with 104 additions and 21 deletions

View File

@ -6680,16 +6680,16 @@ special repeaters =++= and =.+=. For example:
Marking this DONE shifts the date to exactly one hour from now.
#+end_example
#+vindex: org-agenda-skip-scheduled-if-deadline-is-shown
#+vindex: org-agenda-skip-scheduled-repeats-after-deadline
You may have both scheduling and deadline information for a specific
task. If the repeater is set for the scheduling information only, you
probably want the repeater to be ignored after the deadline. If so,
set the variable ~org-agenda-skip-scheduled-if-deadline-is-shown~ to
~repeated-after-deadline~. However, any scheduling information
without a repeater is no longer relevant once the task is done, and
thus, removed upon repeating the task. If you want both scheduling
and deadline information to repeat after the same interval, set the
same repeater for both timestamps.
set the variable ~org-agenda-skip-scheduled-repeats-after-deadline~ to
~t~. However, any scheduling information without a repeater is no
longer relevant once the task is done, and thus, removed upon
repeating the task. If you want both scheduling and deadline
information to repeat after the same interval, set the same repeater
for both timestamps.
An alternative to using a repeater is to create a number of copies of
a task subtree, with dates shifted in each copy. The command

View File

@ -469,6 +469,23 @@ The change is breaking when ~org-use-property-inheritance~ is set to ~t~.
The =TEST= parameter is better served by Emacs debugging tools.
** New and changed options
*** ~repeated-after-deadline~ value of ~org-agenda-skip-scheduled-repeats-after-deadline~ is moved to a new customization
A new custom option ~org-agenda-skip-scheduled-repeats-after-deadline~
is introduced in place of ~repeated-after-deadline~ value of
~org-agenda-skip-scheduled-repeats-after-deadline~.
Introducing a new option allow more control over agenda display and
resolves a confusion about the meaning of ~repeated-after-deadline~.
~repeated-after-deadline~ has nothing to do with /showing/ deadline.
It just prevents agenda display repeated scheduled entries past
deadline. The following example illustrates the meaning:
: * TODO Do me every day before Jan, 12th (included)
: SCHEDULED: <2024-01-03 Wed +1d> DEADLINE: <2024-01-05 Fri>
The old customization will continue to work, ensuring backwards compatibility.
*** New custom setting ~org-icalendar-ttl~ for the ~ox-icalendar~ backend
The option ~org-icalendar-ttl~ allows to advise a subscriber to the

View File

@ -894,17 +894,13 @@ the entry is scheduled today or was scheduled previously is not
shown.
When set to the symbol `not-today', skip scheduled previously,
but not scheduled today.
When set to the symbol `repeated-after-deadline', skip scheduled
items if they are repeated beyond the current deadline."
but not scheduled today."
:group 'org-agenda-skip
:group 'org-agenda-daily/weekly
:type '(choice
(const :tag "Never" nil)
(const :tag "Always" t)
(const :tag "Not when scheduled today" not-today)
(const :tag "When repeated past deadline" repeated-after-deadline)))
(const :tag "Not when scheduled today" not-today)))
(defcustom org-agenda-skip-timestamp-if-deadline-is-shown nil
"Non-nil means skip timestamp line if same entry shows because of deadline.
@ -1341,10 +1337,16 @@ When set to the symbol `next' only the first future repeat is shown."
(const :tag "Show all repeated entries" t)
(const :tag "Show next repeated entry" next)
(const :tag "Do not show repeated entries" nil))
:version "26.1"
:package-version '(Org . "9.1")
:safe #'symbolp)
(defcustom org-agenda-skip-scheduled-repeats-after-deadline nil
"Non-nil hides scheduled repeated entries past deadline."
:group 'org-agenda-daily/weekly
:type 'boolean
:package-version '(Org . "9.7")
:safe t)
(defcustom org-agenda-prefer-last-repeat nil
"Non-nil sets date for repeated entries to their last repeat.
@ -6661,18 +6663,25 @@ scheduled items with an hour specification like [h]h:mm."
;; Skip entry if it already appears as a deadline, per
;; `org-agenda-skip-scheduled-if-deadline-is-shown'. This
;; doesn't apply to habits.
(when (or org-agenda-skip-scheduled-repeats-after-deadline
;; FIXME: Backwards-compatibility.
(eq org-agenda-skip-scheduled-if-deadline-is-shown
'repeated-after-deadline))
(let ((deadline
(time-to-days
(when (org-element-property :deadline el)
(org-time-string-to-time
(org-element-interpret-data
(org-element-property :deadline el)))))))
(when (and (or (<= (org-agenda--timestamp-to-absolute s) deadline)
(not (= schedule current)))
(> current deadline))
(throw :skip nil))))
(when (pcase org-agenda-skip-scheduled-if-deadline-is-shown
((guard
(or (not (memq (line-beginning-position 0) deadline-pos))
habitp))
nil)
(`repeated-after-deadline
(let ((deadline (time-to-days
(when (org-element-property :deadline el)
(org-time-string-to-time
(org-element-interpret-data
(org-element-property :deadline el)))))))
(and (<= schedule deadline) (> current deadline))))
(`not-today pastschedp)
(`t t)
(_ nil))

View File

@ -590,6 +590,63 @@ DEADLINE: " (cdr timestamp))))
(org-agenda nil "f")
(buffer-string))))))))))))
(ert-deftest test-org-agenda/skip-scheduled-repeats-after-deadline ()
"Test `org-agenda-skip-scheduled-repeats-after-deadline'."
(cl-assert (not org-agenda-sticky) nil "precondition violation")
(cl-assert (not (org-test-agenda--agenda-buffers))
nil "precondition violation")
(dolist (org-agenda-skip-scheduled-repeats-after-deadline '(nil t))
(org-test-at-time "2024-01-01 8:00"
(org-test-with-temp-text-in-file "
* TODO Do me every day before Jan, 12th (included)
SCHEDULED: <2024-01-03 Wed +1d> DEADLINE: <2024-01-05 Fri>
"
(let ((org-agenda-span 'week)
(org-agenda-files `(,(buffer-file-name))))
;; NOTE: Be aware that `org-agenda-list' may or may not display
;; past scheduled items depending whether the date is today
;; `org-today' or not.
(org-agenda-list nil "<2024-01-01 Mon>")
(set-buffer org-agenda-buffer-name)
(if org-agenda-skip-scheduled-repeats-after-deadline
(should
;; Not displayed after deadline.
(string-match-p
"Week-agenda (W01):
Monday 1 January 2024 W01
[^:]+:In 4 d.: TODO Do me every day before Jan, 12th (included)
Tuesday 2 January 2024
Wednesday 3 January 2024
[^:]+:Scheduled: TODO Do me every day before Jan, 12th (included)
Thursday 4 January 2024
[^:]+:Scheduled: TODO Do me every day before Jan, 12th (included)
Friday 5 January 2024
[^:]+:Scheduled: TODO Do me every day before Jan, 12th (included)
[^:]+:Deadline: TODO Do me every day before Jan, 12th (included)
Saturday 6 January 2024
Sunday 7 January 2024"
(buffer-string)))
(should
;; Displayed after deadline.
(string-match-p
"Week-agenda (W01):
Monday 1 January 2024 W01
[^:]+:In 4 d.: TODO Do me every day before Jan, 12th (included)
Tuesday 2 January 2024
Wednesday 3 January 2024
[^:]+:Scheduled: TODO Do me every day before Jan, 12th (included)
Thursday 4 January 2024
[^:]+:Scheduled: TODO Do me every day before Jan, 12th (included)
Friday 5 January 2024
[^:]+:Scheduled: TODO Do me every day before Jan, 12th (included)
[^:]+:Deadline: TODO Do me every day before Jan, 12th (included)
Saturday 6 January 2024
[^:]+:Scheduled: TODO Do me every day before Jan, 12th (included)
Sunday 7 January 2024
[^:]+:Scheduled: TODO Do me every day before Jan, 12th (included)"
(buffer-string))))))
(org-test-agenda--kill-all-agendas))))
(ert-deftest test-org-agenda/goto-date ()
"Test `org-agenda-goto-date'."
(unwind-protect