6

I have a repeating task which repeats every four weeks, e.g.

** TODO wash car
SCHEDULED: <2015-05-18 Wed ++4w>

I would like to be able to postpone this task by, say, two 4 weeks cycles starting today, by calling a lisp function.

From what I have researched so far, I could write something in the order of

(org-schedule
 (org-table-time-seconds-to-string
  (+
   (org-time-string-to-seconds (org-get-scheduled-time))
   (* 2 4 7 24 3600))))

to have the SCHEDULED: date shifted by 8 weeks forward.

How could this be automated to shift the date by the amount specified in the repeater string, e.g. 4w?

On a side note, I am not sure about the correctness of the (org-table-time-seconds-to-string) function use, it is here just to illustrate the idea.

2 Answers2

2

Something like this should do:

(defun yashi/org-timestamp-cycle-up (arg)
  (interactive "p")
  (yashi/org-timestamp-cycle (prefix-numeric-value arg)))

(defun yashi/org-timestamp-cycle-down (arg)
  (interactive "p")
  (yashi/org-timestamp-cycle (- (prefix-numeric-value arg))))

(defun yashi/org-timestamp-cycle (cycle)
  (interactive "p")
  (let ((repeat (org-get-repeat)))
    (string-match "\\([.+]\\)?\\(\\+[0-9]+\\)\\([dwmy]\\)" repeat)
    (let ((n (string-to-number (match-string 2 repeat)))
          (what (match-string 3 repeat))
          (whata '(("d" . day) ("m" . month) ("y" . year))))
      (when (string= what "w")
        (setq what "d" n (* n 7)))
      (org-timestamp-change (* cycle n) (cdr (assoc what whata))))))

(bind-keys :map org-mode-map
           ("S-<right>" . yashi/org-timestamp-cycle-up)
           ("S-<left>" . yashi/org-timestamp-cycle-down))
Yasushi Shoji
  • 2,151
  • 15
  • 35
  • Thanks Yasushi, that seems to be it. One more thing, if you please. How do I map this to a single key command in org-agenda? I suppose the code also needs to find the `SCHEDULED` timestamp for the entry at point, right? – Alexander Shcheblikin Mar 19 '16 at 02:11
2

Here is what I have come up with. Pretty simple.

  (setq
    org-todo-keywords
     '((sequence "TODO(t)" "|" "DONE(d!)" "SKIP(k!)" "CNCL(c@)")))

  (define-key org-agenda-mode-map "K"
    (lambda () (interactive) (org-agenda-todo '"SKIP")))

What this does is temporarily mark the item as SKIP and then immediately mark it as TODO again, while advancing the SCHEDULED: and DEADLINE: timestamps as if it was DONE and making a record about the fact in the :LOGBOOK: along the way.