summaryrefslogtreecommitdiff
path: root/elchemy-dashboard.el
blob: fe9101744d6a8fd139002c550e6fd1d0c537b2f3 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
(defun elchemy/create-dashboard (&optional RECREATE)
  "Create the user dashboard"
  (interactive)
  (let ((buffer (get-buffer-create "*Dashboard*")))
    (switch-to-buffer buffer)
    (unless (and buffer-read-only (not RECREATE))
      (read-only-mode -1)
      (erase-buffer)
      (when (file-exists-p (concat elchemy/elchemy-root elchemy/dashboard-splash))
	(insert-image (create-image (concat elchemy/elchemy-root elchemy/dashboard-splash) nil nil :scale 0.25))
	(insert "\n"))
      (let ((start (point)))
	(insert "Elchemy Dashboard")
	(add-text-properties start (point)
			     `(face (:height ,elchemy/dashboard/header-size))))
      (insert "\n")
      (when (file-exists-p (concat elchemy/elchemy-root elchemy/elchemy-headings-file))
	(elchemy/display-tabular-button-alist
	 (elchemy/read-alist-file (concat elchemy/elchemy-root elchemy/elchemy-headings-file))
	 elchemy/dashboard/heading-columns elchemy/dashboard/heading-padding)
	(insert "\n"))
      (when (file-exists-p (concat elchemy/elchemy-root elchemy/elchemy-projects-file))
	(let ((start (point)))
	  (insert "Projects")
	  (add-text-properties start (point)
			       `(face (:height ,elchemy/dashboard/subheader-size))))
	(insert "\n")
	(elchemy/display-tabular-button-alist
	 (elchemy/read-alist-file (concat elchemy/elchemy-root elchemy/elchemy-projects-file))
	 elchemy/dashboard/projects-columns elchemy/dashboard/projects-padding)
	(insert "\n"))
      (ignore-errors
	(setq agenda-items (mapcar #'(lambda (x) (elchemy/get-agenda-items x 3)) elchemy/dashboard-agenda-titles)
	      agenda-max-count (apply 'max (mapcar #'(lambda (x) (length x)) agenda-items))
	      agenda-max-length (apply 'max (mapcar #'(lambda (x) (apply 'max (mapcar #'(lambda (y) (length y)) x))) agenda-items))
	      agenda-heading-format-string "")
	(let ((start (point)))
	  (insert "Agenda")
	  (add-text-properties start (point)
			       `(face (:height ,elchemy/dashboard/subheader-size))))
	(insert "\n")
	(dotimes (_ (- (length elchemy/dashboard-agenda-titles) 1))
	  (setq agenda-heading-format-string (concat agenda-heading-format-string "%-" (format "%d" (+ agenda-max-length elchemy/dashboard/agenda-padding)) "s")))
	(setq agenda-heading-format-string (concat agenda-heading-format-string "%s\n"))
	(insert (apply 'format agenda-heading-format-string elchemy/dashboard-agenda-titles))
	(dotimes (i agenda-max-count)
	  (dotimes (c (length elchemy/dashboard-agenda-titles))
	    (if (eq (% (+ c 1) (length elchemy/dashboard-agenda-titles)) 0)
		(insert (format "%s\n"
				(elchemy/replace-nil (nth i (nth c agenda-items)))))
	      (insert (format
		       (concat "%-" (format "%d" (+ agenda-max-length elchemy/dashboard/agenda-padding)) "s")
		       (elchemy/replace-nil (nth i (nth c agenda-items)))))
	      )))
	(insert "\n")
	(let ((start (point)))
	  (insert "Overdue")
	  (add-text-properties start (point)
			       `(face (:height ,elchemy/dashboard/subheader-size))))
	(insert "\n")
	(setq overdue-s (elchemy/format-processed-agenda (mapcar 'elchemy/process-agenda-heading (org-ql-select (org-agenda-files) `(and (todo "STRT" "WAIT" "TODO" "CYCL") (ts :from ,(- elchemy/schedule-lookahead) :to today)) :sort '(todo priority date)))))
	(if (eq (length overdue-s) 0)
	    (insert "Yay, nothing here!\n")
	  (insert overdue-s))
	(insert "\n")
	(let ((start (point)))
	  (insert "Upcoming")
	  (add-text-properties start (point)
			       `(face (:height ,elchemy/dashboard/subheader-size))))
	(insert "\n")
	(setq upcoming-s (elchemy/format-processed-agenda (mapcar 'elchemy/process-agenda-heading (org-ql-select (org-agenda-files) `(and (todo "STRT" "WAIT" "TODO" "CYCL") (ts :from today :to ,elchemy/schedule-lookahead)) :sort '(todo priority date)))))
	(if (eq (length upcoming-s) 0)
	    (if (eq (length overdue-s) 0)
		(insert "You are free!\n")
	      (insert "Time to work on that backlog!\n"))
	  (insert upcoming-s))
	(insert "\n"))
      (insert (buttonize "Refresh" '(lambda (x) (elchemy/recreate-dashboard))))
      (insert "\n")
      (button-mode +1)
      (read-only-mode +1)
      (local-set-key (kbd "r") 'elchemy/recreate-dashboard)
      (goto-char (point-min)))))

(defun elchemy/recreate-dashboard ()
  "Recreate the dashboard"
  (interactive)
  (elchemy/create-dashboard t))

(provide 'elchemy-dashboard)