;;; org-habit.el --- The habit tracking code for Org-mode
-;; Copyright (C) 2009, 2010 Free Software Foundation, Inc.
+;; Copyright (C) 2009-2012 Free Software Foundation, Inc.
;; Author: John Wiegley <johnw at gnu dot org>
;; Keywords: outlines, hypermedia, calendar, wp
;; Homepage: http://orgmode.org
-;; Version: 7.01
;;
;; This file is part of GNU Emacs.
;;
:group 'org-habit
:type 'boolean)
+(defcustom org-habit-today-glyph ?!
+ "Glyph character used to identify today."
+ :group 'org-habit
+ :type 'character)
+
+(defcustom org-habit-completed-glyph ?*
+ "Glyph character used to show completed days on which a task was done."
+ :group 'org-habit
+ :type 'character)
+
(defface org-habit-clear-face
'((((background light)) (:background "#8270f9"))
(((background dark)) (:background "blue")))
(assert (org-is-habit-p (point)))
(let* ((scheduled (org-get-scheduled-time (point)))
(scheduled-repeat (org-get-repeat org-scheduled-string))
- (sr-days (org-habit-duration-to-days scheduled-repeat))
(end (org-entry-end-position))
- (habit-entry (org-no-properties (nth 5 (org-heading-components))))
- closed-dates deadline dr-days)
+ (habit-entry (org-no-properties (nth 4 (org-heading-components))))
+ closed-dates deadline dr-days sr-days)
(if scheduled
(setq scheduled (time-to-days scheduled))
(error "Habit %s has no scheduled date" habit-entry))
(unless scheduled-repeat
- (error "Habit %s has no scheduled repeat period" habit-entry))
+ (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))
(unless (> sr-days 0)
(error "Habit %s scheduled repeat period is less than 1d" habit-entry))
(when (string-match "/\\([0-9]+[dwmy]\\)" scheduled-repeat)
habit-entry scheduled-repeat))
(setq deadline (+ scheduled (- dr-days sr-days))))
(org-back-to-heading t)
- (while (re-search-forward "- State \"DONE\".*\\[\\([^]]+\\)\\]" end t)
- (push (time-to-days
- (org-time-string-to-time (match-string-no-properties 1)))
- closed-dates))
+ (let* ((maxdays (+ org-habit-preceding-days org-habit-following-days))
+ (reversed org-log-states-order-reversed)
+ (search (if reversed 're-search-forward 're-search-backward))
+ (limit (if reversed end (point)))
+ (count 0))
+ (unless reversed (goto-char end))
+ (while (and (< count maxdays)
+ (funcall search "- State \"DONE\".*\\[\\([^]]+\\)\\]" limit t))
+ (push (time-to-days
+ (org-time-string-to-time (match-string-no-properties 1)))
+ closed-dates)
+ (setq count (1+ count))))
(list scheduled sr-days deadline dr-days closed-dates))))
(defsubst org-habit-scheduled (habit)
"Determine the relative priority of a habit.
This must take into account not just urgency, but consistency as well."
(let ((pri 1000)
- (now (time-to-days
- (or moment
- (time-subtract (current-time)
- (list 0 (* 3600 org-extend-today-until) 0)))))
+ (now (if moment (time-to-days moment) (org-today)))
(scheduled (org-habit-scheduled habit))
(deadline (org-habit-deadline habit)))
;; add 10 for every day past the scheduled date, and subtract for every
(days-to-time
(- start (time-to-days starting))))))
- (aset graph index ?*)
+ (aset graph index org-habit-completed-glyph)
(setq markedp t)
(put-text-property
index (1+ index) 'help-echo
(setq last-done-date (car done-dates)
done-dates (cdr done-dates))))
(if todayp
- (aset graph index ?!)))
+ (aset graph index org-habit-today-glyph)))
(setq face (if (or in-the-past-p todayp)
(car faces)
(cdr faces)))
(provide 'org-habit)
-;; arch-tag: 64e070d9-bd09-4917-bd44-44465f5ed348
-
;;; org-habit.el ends here