summaryrefslogtreecommitdiff
path: root/lisp/org-habit.el
diff options
context:
space:
mode:
Diffstat (limited to 'lisp/org-habit.el')
-rw-r--r--lisp/org-habit.el66
1 files changed, 52 insertions, 14 deletions
diff --git a/lisp/org-habit.el b/lisp/org-habit.el
index 6013756..338aabc 100644
--- a/lisp/org-habit.el
+++ b/lisp/org-habit.el
@@ -1,6 +1,6 @@
;;; org-habit.el --- The habit tracking code for Org-mode
-;; Copyright (C) 2009-2014 Free Software Foundation, Inc.
+;; Copyright (C) 2009-2015 Free Software Foundation, Inc.
;; Author: John Wiegley <johnw at gnu dot org>
;; Keywords: outlines, hypermedia, calendar, wp
@@ -165,6 +165,7 @@ Returns a list with the following elements:
2: Optional deadline (nil if not present)
3: If deadline, the repeater for the deadline, otherwise nil
4: A list of all the past dates this todo was mark closed
+ 5: Repeater type as a string
This list represents a \"habit\" for the rest of this module."
(save-excursion
@@ -174,7 +175,7 @@ This list represents a \"habit\" for the rest of this module."
(scheduled-repeat (org-get-repeat org-scheduled-string))
(end (org-entry-end-position))
(habit-entry (org-no-properties (nth 4 (org-heading-components))))
- closed-dates deadline dr-days sr-days)
+ closed-dates deadline dr-days sr-days sr-type)
(if scheduled
(setq scheduled (time-to-days scheduled))
(error "Habit %s has no scheduled date" habit-entry))
@@ -182,7 +183,9 @@ This list represents a \"habit\" for the rest of this module."
(error
"Habit '%s' has no scheduled repeat period or has an incorrect one"
habit-entry))
- (setq sr-days (org-habit-duration-to-days scheduled-repeat))
+ (setq sr-days (org-habit-duration-to-days scheduled-repeat)
+ sr-type (progn (string-match "[\\.+]?\\+" scheduled-repeat)
+ (org-match-string-no-properties 0 scheduled-repeat)))
(unless (> sr-days 0)
(error "Habit %s scheduled repeat period is less than 1d" habit-entry))
(when (string-match "/\\([0-9]+[dwmy]\\)" scheduled-repeat)
@@ -197,17 +200,33 @@ This list represents a \"habit\" for the rest of this module."
(reversed org-log-states-order-reversed)
(search (if reversed 're-search-forward 're-search-backward))
(limit (if reversed end (point)))
- (count 0))
+ (count 0)
+ (re (format
+ "^[ \t]*-[ \t]+\\(?:State \"%s\".*%s%s\\)"
+ (regexp-opt org-done-keywords)
+ org-ts-regexp-inactive
+ (let ((value (cdr (assq 'done org-log-note-headings))))
+ (if (not value) ""
+ (concat "\\|"
+ (org-replace-escapes
+ (regexp-quote value)
+ `(("%d" . ,org-ts-regexp-inactive)
+ ("%D" . ,org-ts-regexp)
+ ("%s" . "\"\\S-+\"")
+ ("%S" . "\"\\S-+\"")
+ ("%t" . ,org-ts-regexp-inactive)
+ ("%T" . ,org-ts-regexp)
+ ("%u" . ".*?")
+ ("%U" . ".*?")))))))))
(unless reversed (goto-char end))
- (while (and (< count maxdays)
- (funcall search (format "- State \"%s\".*\\[\\([^]]+\\)\\]"
- (regexp-opt org-done-keywords))
- limit t))
+ (while (and (< count maxdays) (funcall search re limit t))
(push (time-to-days
- (org-time-string-to-time (match-string-no-properties 1)))
+ (org-time-string-to-time
+ (or (org-match-string-no-properties 1)
+ (org-match-string-no-properties 2))))
closed-dates)
(setq count (1+ count))))
- (list scheduled sr-days deadline dr-days closed-dates))))
+ (list scheduled sr-days deadline dr-days closed-dates sr-type))))
(defsubst org-habit-scheduled (habit)
(nth 0 habit))
@@ -225,6 +244,8 @@ This list represents a \"habit\" for the rest of this module."
(org-habit-scheduled-repeat habit)))
(defsubst org-habit-done-dates (habit)
(nth 4 habit))
+(defsubst org-habit-repeat-type (habit)
+ (nth 5 habit))
(defsubst org-habit-get-priority (habit &optional moment)
"Determine the relative priority of a habit.
@@ -311,10 +332,27 @@ current time."
(not (< scheduled now)))
'(org-habit-clear-face . org-habit-clear-future-face)
(org-habit-get-faces
- habit start (and in-the-past-p
- (if last-done-date
- (+ last-done-date s-repeat)
- scheduled))
+ habit start
+ (and in-the-past-p last-done-date
+ ;; Compute scheduled time for habit at the
+ ;; time START was current.
+ (let ((type (org-habit-repeat-type habit)))
+ (cond
+ ((equal type ".+")
+ (+ last-done-date s-repeat))
+ ((equal type "+")
+ ;; Since LAST-DONE-DATE, each done
+ ;; mark shifted scheduled date by
+ ;; S-REPEAT.
+ (- scheduled (* (length done-dates) s-repeat)))
+ (t
+ ;; Scheduled time was the first time
+ ;; past LAST-DONE-STATE which can jump
+ ;; to current SCHEDULED time by
+ ;; S-REPEAT hops.
+ (- scheduled
+ (* (/ (- scheduled last-done-date) s-repeat)
+ s-repeat))))))
donep)))
markedp face)
(if donep