Created
January 3, 2026 22:23
-
-
Save vherrmann/4637284194b214f2a83964b6306883ba to your computer and use it in GitHub Desktop.
Rescheduling repeating todos in org mode without breaking regular schedule
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| (defun iko/org-is-static-repeater () | |
| ;; Is this a repeater that uses the current date for rescheduling (.+) or | |
| ;; a „static“ repeater that uses the last scheduled date (++)? | |
| (when-let ((repeater (org-get-repeat))) | |
| (not (string-prefix-p ".+" repeater)))) | |
| (defun iko/org-entry-put-nil (EPOM PROPERTY VALUE) | |
| (and VALUE (org-entry-put EPOM PROPERTY VALUE))) | |
| (defun iko/org-ts-inactive→active (text) | |
| (when (and text (string-match "\\[\\(.+\\)\\]" text)) | |
| (concat "<" (match-string 1 text) ">"))) | |
| (defun iko/org-ts-active→inactive (text) | |
| (when (and text (string-match "<\\(.+\\)>" text)) | |
| (concat "[" (match-string 1 text) "]"))) | |
| (advice-add | |
| 'org-todo | |
| :around | |
| (defun iko/org-todo-schedule-fix (oldfun &rest r) | |
| (if (iko/org-is-static-repeater) | |
| (let ((prev-scheduled-stamp (org-entry-get nil "SCHEDULED")) | |
| (prev-deadline-stamp (org-entry-get nil "DEADLINE")) | |
| ;; The original timestamps are stored as inactive timestamps | |
| (orig-scheduled-stamp (iko/org-ts-inactive→active (org-entry-get nil "ORIG_SCHEDULED"))) | |
| (orig-deadline-stamp (iko/org-ts-inactive→active (org-entry-get nil "ORIG_DEADLINE")))) | |
| (iko/org-entry-put-nil nil "SCHEDULED" (or orig-scheduled-stamp prev-scheduled-stamp)) | |
| (iko/org-entry-put-nil nil "DEADLINE" (or orig-deadline-stamp prev-deadline-stamp)) | |
| (unwind-protect | |
| (apply oldfun r) | |
| (let ((next-scheduled-stamp (org-entry-get nil "SCHEDULED")) | |
| (next-deadline-stamp (org-entry-get nil "DEADLINE"))) | |
| (if (equal orig-scheduled-stamp next-scheduled-stamp) | |
| (iko/org-entry-put-nil nil "SCHEDULED" prev-scheduled-stamp) | |
| (iko/org-entry-put-nil nil "ORIG_SCHEDULED" | |
| (iko/org-ts-active→inactive next-scheduled-stamp))) | |
| (if (equal orig-deadline-stamp next-deadline-stamp) | |
| (iko/org-entry-put-nil nil "DEADLINE" prev-deadline-stamp) | |
| (iko/org-entry-put-nil nil "ORIG_DEADLINE" | |
| (iko/org-ts-active→inactive next-deadline-stamp)))))) | |
| (apply oldfun r)))) | |
| (advice-add | |
| 'org-schedule | |
| :before | |
| (defun iko/org-schedule-schedule-fix (&rest r) | |
| (when (and (iko/org-is-static-repeater) | |
| (not (org-entry-get nil "ORIG_SCHEDULED"))) | |
| (iko/org-entry-put-nil nil "ORIG_SCHEDULED" (org-entry-get nil "SCHEDULED"))))) | |
| (advice-add | |
| 'org-deadline | |
| :before | |
| (defun iko/org-deadline-schedule-fix (&rest r) | |
| (when (and (iko/org-is-static-repeater) | |
| (not (org-entry-get nil "ORIG_DEADLINE"))) | |
| (iko/org-entry-put-nil nil "ORIG_DEADLINE" (org-entry-get nil "DEADLINE"))))) |
Author
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Let's say it is Saturday and you have a repeating task for your exercise sheet like
that is usually scheduled for Saturday. Let us further assume you do not want do today for whatever reason.
In that case it would be very convenient to be able to reschedule the task without changing the general behavior of it being scheduled for Saturdays.
The following config achieves this by adding properties
ORIG_SCHEDULEDandORIG_DEADLINEwhen changing the todo state such that the original timestamps can be recovered after changing them withorg-scheduleororg-schedule.