emacs-orgmode
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [O] Repeaters in plain timestamps


From: François Pinard
Subject: Re: [O] Repeaters in plain timestamps
Date: Fri, 15 Nov 2013 20:10:04 -0500
User-agent: Gnus/5.130008 (Ma Gnus v0.8) Emacs/24.3 (gnu/linux)

Hi, Org people.

Merely revisiting the Org mailing list after many days.  Gosh!  That
list is fairly active! :-)

Quoting an earlier message of mine:

> The manual, section "8.3.2 Repeated tasks", says:

>    Some tasks need to be repeated again and again.  Org mode helps to
>    organize such tasks using a so-called repeater in a DEADLINE, SCHEDULED,
>    or plain timestamp.

> Examples and directions given in the page are related to DEADLINE, and
> a few words suggest that SCHEDULED works the same.  But the page does
> not say how one may handle repeaters with plain timestamps.  I merely
> would like to update them so they show the date for the next
> iteration, a bit like command "t d" already does on a DEADLINE
> repeater.

For what it may be worth, I kludged this code for bumping the following
repeated timestamps on the current line.  I stole most of the code, and
did not write much myself:


(defun fp-org-bump-timestamp ()
  ;; Adapted from (org.el) org-auto-repeat-maybe.
  (interactive)
  (save-excursion
    (beginning-of-line)
    (when (re-search-forward org-ts-regexp (line-end-position) t)
      (let ((ts (match-string 1))
            (whata '(("h" . hour) ("d" . day) ("m" . month) ("y" . year)))
            n time)
        (when (string-match "\\([.+]\\)?\\(\\+[0-9]+\\)\\([hdwmy]\\)" ts)
          (setq n (string-to-number (match-string 2 ts))
                what (match-string 3 ts))
          (if (equal what "w") (setq n (* n 7) what "d"))
          (if (and (equal what "h")
                   (not (string-match "[0-9]\\{1,2\\}:[0-9]\\{2\\}" ts)))
              (user-error "Cannot repeat in Repeat in %d hour(s) because no 
hour has been set" n))
          ;; Preparation, see if we need to modify the start date for the change
          (when (match-end 1)
            (setq time (save-match-data (org-time-string-to-time ts)))
            (cond
             ((equal (match-string 1 ts) ".")
              ;; Shift starting date to today
              (org-timestamp-change
               (- (org-today) (time-to-days time))
               'day))
             ((equal (match-string 1 ts) "+")
              (let ((nshiftmax 10) (nshift 0))
                (while (or (= nshift 0)
                           (<= (time-to-days time)
                               (time-to-days (current-time))))
                  (when (= (incf nshift) nshiftmax)
                    (or (y-or-n-p (message "%d repeater intervals were not 
enough to shift date past today.  Continue? " nshift))
                        (error "Abort")))
                  (org-timestamp-change n (cdr (assoc what whata)))
                  (org-at-timestamp-p t)
                  (setq ts (match-string 1))
                  (setq time (save-match-data (org-time-string-to-time ts)))))
              (org-timestamp-change (- n) (cdr (assoc what whata)))
              ;; rematch, so that we have everything in place for the real shift
              (org-at-timestamp-p t)
              (setq ts (match-string 1))
              (string-match "\\([.+]\\)?\\(\\+[0-9]+\\)\\([hdwmy]\\)" ts))))
          (org-timestamp-change n (cdr (assoc what whata)) nil t))))))



reply via email to

[Prev in Thread] Current Thread [Next in Thread]