Hello,

I want to temporary cancel recurring tasks. Let's say I have tasks, that
only make sense when I'm in my office. Now I'm away for a few months.
The tasks would clutter my agenda. I could comment them, archive them or
use org-cancel-repeater and set the task's state to DONE. But all that
makes it hard to restore the previous state when I'm back in my office.

I think, the clean solution is to set the state of the task to CANCELLED
or STOPPED or something like that, to deactivate the recurring task.
When I activate the task again, the scheduled date and the repeater
should be restored. To achieve that, I tried the following:


;;
;; Deactivate/Activate recurring tasks
;;


;; Prior to Org commit 7d52a8c3cc86c8ce03eda006752af1ab4bed4316
;; there seems to be no way to set the repeater of a, let's say,
;; SCHEDULED property programmatically. So we use this function.
(defun hmw/org-schedule-set-value (val)
  "Sets the value of the SCHEDULED property. This allows for
setting the repeater as well."
  (interactive)
  (save-excursion
    (org-back-to-heading t)
    (let ((bound1 (point))
          (bound0 (save-excursion (outline-next-heading) (point))))
      (when (re-search-forward
             (concat "\\(" org-scheduled-time-regexp "\\)")
             bound0 t)
        (replace-match val t nil nil 2)))))

(defvar hmw/org-scheduled-property-backup "DISABLED-SCHEDULED"
  "Back up the original value of the SCHEDULED property into this
property when deactivating a recurring task. The value is rescued from
this property to initialise the SCHEDULED property when activating the
task again.")

(defvar hmw/org-activated-recurring-task-state "TODO"
  "Switch a recurring task to this state after activating.")

(defvar hmw/org-deactivated-recurring-task-state "CANCELLED"
  "Switch a recurring task to this state after deactivating.")

(defun hmw/org-deactivate-recurring-task ()
  "Deactivate a recurring task. The value of the SCHEDULED property is
stored in the property referenced by `hmw/org-scheduled-property-backup',
so it can be restored later. The task's state is set to the value of
`hmw/org-deactivated-recurring-task-state'." 
  (interactive)
  (when (org-entry-is-todo-p)
    (save-excursion
      (org-back-to-heading t)
      (let* ((pom (point-at-bol))
             (val (org-entry-get pom "SCHEDULED")))
        (when val
          ;; Remove the time stamp meaning. We don't want active
          ;; timestamp to trigger any actions for the deactivated
          ;; task.
          (setq val (replace-regexp-in-string "^<\\(.*\\)>$" "\\1" val))
          (org-entry-put pom hmw/org-scheduled-property-backup val)
          (org-entry-put pom "SCHEDULED" nil)
          (org-todo hmw/org-deactivated-recurring-task-state))))))

(defun hmw/org-activate-recurring-task ()
  "Activate a previously deactivated recurring task. The value of the
SCHEDULED property is retrieved from the property referenced by
`hmw/org-scheduled-property-backup', which is then deleted. The task's 
state is set to the value of `hmw/org-activated-recurring-task-state'."
  (interactive)
  (when (org-entry-is-done-p)
    (save-excursion
      (org-back-to-heading t)
      (let* ((pom (point-at-bol))
             (val (org-entry-get pom hmw/org-scheduled-property-backup)))
        (when val
          ;; For Org commit 7d52a8c3cc86c8ce03eda006752af1ab4bed4316 or
          ;; later use this
          ;;(setq val (replace-regexp-in-string "^\\(.*\\)$" "<\\1>" val))
          ;;(org-entry-put pom "SCHEDULED" val)
          
          ;; For older Org use this
          (org-entry-put pom "SCHEDULED" val)
          (hmw/org-schedule-set-value val)
          
          (org-entry-delete pom hmw/org-scheduled-property-backup)
          (org-todo hmw/org-activated-recurring-task-state))))))
 

The idea is to store the value of the SCHEDULED property somewhere when
the task gets deactivated. Later, on activation, the property value is
restored.

There are two variants. The one above, which should work for Org prior
to commit 7d52a8c3cc86c8ce03eda006752af1ab4bed4316 and also for later
revisions. And one for that commit and later. If you use the newer Org
revision, you optionally can get rid of the function
hw/org-schedule-set-value and follow the comments in
hmw/org-activate-recurring-task.

Regards
hmw

Reply via email to