[org] Customize habit view

master
Jacopo De Simoi 5 years ago
parent 176efe3667
commit 0440a0cfc8
  1. 110
      global.org

@ -769,6 +769,116 @@
#+begin_src emacs-lisp
(setq org-use-speed-commands t)
#+end_src
Improve the org-habit graph thing
#+begin_src emacs-lisp
(setq org-habit-regular-glyph ?□
org-habit-today-glyph ?□
org-habit-completed-glyph ?▣)
(defun wilder/org-habit-build-graph (habit starting current ending)
"Build a graph for the given HABIT, from STARTING to ENDING.
CURRENT gives the current time between STARTING and ENDING, for
the purpose of drawing the graph. It need not be the actual
current time."
(let* ((all-done-dates (sort (org-habit-done-dates habit) #'<))
(done-dates all-done-dates)
(scheduled (org-habit-scheduled habit))
(s-repeat (org-habit-scheduled-repeat habit))
(start (time-to-days starting))
(now (time-to-days current))
(end (time-to-days ending))
(graph (make-string (- end start) org-habit-regular-glyph))
(index 0)
last-done-date)
(while (and done-dates (< (car done-dates) start))
(setq last-done-date (car done-dates)
done-dates (cdr done-dates)))
(while (< start end)
(let* ((in-the-past-p (< start now))
(todayp (= start now))
(donep (and done-dates (= start (car done-dates))))
(faces
(if (and in-the-past-p
(not last-done-date)
(not (< scheduled now)))
(if (and all-done-dates (= (car all-done-dates) start))
;; This is the very first done of this habit.
'(org-habit-ready-face . org-habit-ready-future-face)
'(org-habit-clear-face . org-habit-clear-future-face))
(org-habit-get-faces
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
;; At the last done date, use current
;; scheduling in all cases.
((null done-dates) scheduled)
((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
;; Compute the scheduled time after the
;; first repeat. This is the closest time
;; past FIRST-DONE which can reach SCHEDULED
;; by a number of S-REPEAT hops.
;;
;; Then, play TODO state change history from
;; the beginning in order to find current
;; scheduled time.
(let* ((first-done (car all-done-dates))
(s (let ((shift (mod (- scheduled first-done)
s-repeat)))
(+ (if (= shift 0) s-repeat shift)
first-done))))
(if (= first-done last-done-date) s
(catch :exit
(dolist (done (cdr all-done-dates) s)
;; Each repeat shifts S by any
;; number of S-REPEAT hops it takes
;; to get past DONE, with a minimum
;; of one hop.
(cl-incf s (* (1+ (/ (max (- done s) 0)
s-repeat))
s-repeat))
(when (= done last-done-date)
(throw :exit s))))))))))
donep)))
markedp face)
(cond
(donep
(aset graph index org-habit-completed-glyph)
(setq markedp t)
(while (and done-dates (= start (car done-dates)))
(setq last-done-date (car done-dates))
(setq done-dates (cdr done-dates))))
(todayp
(aset graph index org-habit-today-glyph)))
(setq face (if (or in-the-past-p todayp)
(car faces)
(cdr faces)))
(when (and in-the-past-p
(not (eq face 'org-habit-overdue-face))
(not markedp))
(setq face (cdr faces)))
(put-text-property index (1+ index) 'face face graph)
(put-text-property index (1+ index)
'help-echo
(concat (format-time-string
(org-time-stamp-format)
(time-add starting (days-to-time (- start (time-to-days starting)))))
(if donep " DONE" ""))
graph))
(setq start (1+ start)
index (1+ index)))
graph))
(advice-add 'org-habit-build-graph :override #'wilder/org-habit-build-graph)
#+end_src
Ideally I should tag some tasks as “break” tasks, which are
suitable to be taken care of during a pomodoro break. Such tasks
should be marked with tags ~:5m:~ and ~:20m:~ according to the

Loading…
Cancel
Save