diff --git a/doc/org-manual.org b/doc/org-manual.org index 5f55e9bd5..3758d8cd4 100644 --- a/doc/org-manual.org +++ b/doc/org-manual.org @@ -6337,6 +6337,10 @@ special repeaters =++= and =.+=. For example: ,** TODO Check the batteries in the smoke detectors DEADLINE: <2005-11-01 Tue .+1m> Marking this DONE will shift the date to one month after today. + +,** TODO Wash my hands + DEADLINE: <2019-04-05 08:00 Sun .+1h> + Marking this DONE shifts the date to exactly one hour from now. #+end_example #+vindex: org-agenda-skip-scheduled-if-deadline-is-shown diff --git a/etc/ORG-NEWS b/etc/ORG-NEWS index 2b60f2939..e90ac60e3 100644 --- a/etc/ORG-NEWS +++ b/etc/ORG-NEWS @@ -353,6 +353,17 @@ to the resulting HTML file. Org refile variables and functions have been moved to a new file. +*** Handle repeated tasks with =.+= type and hours step + +A task using a =.+= repeater and hours step is repeated starting from +now. E.g., + +#+begin_example +,,** TODO Wash my hands + DEADLINE: <2019-04-05 08:00 Sun .+1h> + Marking this DONE shifts the date to exactly one hour from now. +#+end_example + *** The end of a 7 years old bug This bug [[https://lists.gnu.org/archive/html/emacs-orgmode/2013-08/msg00072.html][originally reported]] by Matt Lundin and investigated by Andrew diff --git a/lisp/org.el b/lisp/org.el index 06891b8bd..57682fd16 100644 --- a/lisp/org.el +++ b/lisp/org.el @@ -10146,9 +10146,13 @@ This function is run automatically after each state change to a DONE state." (repeater-type (match-string 1 ts))) (cond ((equal "." repeater-type) - ;; Shift starting date to today. - (org-timestamp-change (- (org-today) (time-to-days time)) - 'day)) + ;; Shift starting date to today, or now if + ;; repeater is by hours. + (if (equal what "h") + (org-timestamp-change + (floor (- (org-time-stamp-to-now ts t)) 60) 'minute) + (org-timestamp-change + (- (org-today) (time-to-days time)) 'day))) ((equal "+" repeater-type) (let ((nshiftmax 10) (nshift 0)) diff --git a/testing/lisp/test-org.el b/testing/lisp/test-org.el index dc4a6a59f..6751610a4 100644 --- a/testing/lisp/test-org.el +++ b/testing/lisp/test-org.el @@ -6686,6 +6686,28 @@ Paragraph" (org-test-with-temp-text "* TODO H\n<2012-03-29 Thu +2h>" (org-todo "DONE") (buffer-string)))) + ;; Handle every repeater type using hours step. + (should + (string-match-p + "2014-03-04 .* 02:00" + (org-test-at-time "<2014-03-04 02:35>" + (org-test-with-temp-text "* TODO H\n<2014-03-03 18:00 +8h>" + (org-todo "DONE") + (buffer-string))))) + (should + (string-match-p + "2014-03-04 .* 10:00" + (org-test-at-time "<2014-03-04 02:35>" + (org-test-with-temp-text "* TODO H\n<2014-03-03 18:00 ++8h>" + (org-todo "DONE") + (buffer-string))))) + (should + (string-match-p + "2014-03-04 .* 10:35" + (org-test-at-time "<2014-03-04 02:35>" + (org-test-with-temp-text "* TODO H\n<2014-03-03 18:00 .+8h>" + (org-todo "DONE") + (buffer-string))))) ;; Do not repeat inactive time stamps with a repeater. (should-not (string-match-p