summaryrefslogtreecommitdiff
path: root/modules/org-agenda-config.el
blob: c034aa05f8369d1b1b8fde7dfca73350106f3492 (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
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
;;; org-agenda-config --- Org-Agenda/Todo Config -*- lexical-binding: t; -*-
;; author Craig Jennings <c@cjennings.net>

;;; Commentary:

;; Agenda views are tied to the F8 (fate) key.
;; f8   - A daily schedule with task items with a scheduled date or deadline of
;;        the current day. This is followed by a task list containing tasks from
;;        all agenda sources.
;; C-f8 - A task list containing all tasks from all agenda sources
;; M-f8 - A task list containing all tasks from the current org-mode buffer.

;; NOTE:
;; Files that contain information relevant to the agenda will be found in the
;; following places: the schedule-file, org-roam notes tagged as 'projects' and
;; project todo.org files found in project-dir and code-dir. The function
;; that rebuilds the agenda list.

;; How the agenda is created:
;; In order to stay current, the files containing agenda information are queried
;; before calling the functions in the section org-agenda functions to display
;; the data.

;; This way, we can maximize flexibility and limit the agenda-files to a smaller
;; set of files for a scoped agenda.

;;; Code:

(with-eval-after-load 'org-roam

  ;; ----------------------------- Org TODO Settings ---------------------------

  (setq org-todo-keywords '((sequence "TODO(t)" "PROJECT(p)" "DOING(i)"
                                      "WAITING(w)" "VERIFY(v)" "STALLED(s)"
                                      "DELEGATED(x)" "|"
                                      "FAILED(f)" "DONE(d)" "CANCELLED(c)")))

  (setq org-todo-keyword-faces
        '(("TODO"      . "green")
          ("PROJECT"   . "blue")
          ("DOING"     . "yellow")
          ("WAITING"   . "white")
          ("VERIFY"    . "orange")
          ("STALLED"   . "light blue")
          ("DELEGATED" . "green")
          ("FAILED"    . "red")
          ("DONE"      . "dark grey")
          ("CANCELLED" . "dark grey")))

  (setq org-highest-priority ?A)
  (setq org-lowest-priority ?D)
  (setq org-default-priority ?C)
  (setq org-priority-faces '((?A . (:foreground "Cyan" :weight bold))
                             (?B . (:foreground "Yellow"))
                             (?C . (:foreground "Green"))
                             (?D . (:foreground "Grey"))))

  (setq org-enforce-todo-dependencies t)
  (setq org-enforce-todo-checkbox-dependencies t)
  (setq org-deadline-warning-days 7)    ;; warn me w/in a week of deadlines
  (setq org-log-done nil)               ;; don't log when tasks was done

  ;; inherit parents properties (no schedules or deadlines)
  (setq org-use-property-inheritance t)

  ;; ------------------ Org TODO Next/Previous Set Keybindings -----------------

  (add-hook 'org-agenda-mode-hook (lambda ()
                                  (local-set-key (kbd "s-<right>")  #'org-agenda-todo-nextset)
                                  (local-set-key (kbd "s-<left>")  #'org-agenda-todo-previousset)))

  ;; ------------------------------ Org Super Agenda -----------------------------

  (use-package org-super-agenda
    :config (org-super-agenda-mode))

;;;; ORG AGENDA VIEW DEFINITIONS
  (defun cj/agenda-today-view()
    "This agenda from all tasks that are scheduled or have a deadline."
    (setq org-super-agenda-groups
          '((:log t)  ; Automatically named "Log"
            (:name "SCHEDULED AND DUE"
                   :time-grid t
                   :deadline past
                   :deadline today
                   :scheduled past
                   :scheduled today)
            (:habit t)
            (:name "DUE SOON"
                   :deadline future)
            (:name "LESS IMPORTANT"
                   :scheduled future
                   :order 100)
            (:discard (:anything t)))))

  (defun cj/agenda-all-view()
    "This agenda is built from all tasks."
    (setq org-super-agenda-groups
          '(
            (:name "Ready To Go"
                   :todo "STAGED"
                   :todo "READY"
                   :order 5)
            (:name "Due Today"
                   :deadline past
                   :deadline today
                   :order 2)
            (:name "Empty Projects"
                   :todo "PROJECT"
                   :order 85)
            (:name "Delegated"
                   :todo "DELEGATED"
                   :order 50)
            (:name "Scheduled Later"
                   :scheduled future
                   :order 75)
            (:name "Scheduled Today"
                   :scheduled today
                   :scheduled past
                   :order 4)
            (:name "In Progress"
                   :todo "DOING"
                   :order 7)
            (:name "High Priority"
                   :priority "A"
                   :order 10)
            (:name "Waiting"
                   :todo "WAITING"
                   :order 60)
            (:name "Upcoming"
                   :deadline future
                   :order 30)
            (:name "Next Priority"
                   :priority "B"
                   :order 70)
            (:name "Everything Else"
                   :anything t
                   :order 90))))

  ;; ------------------------------ Add Agenda Time ------------------------------

  (defun cj/add-agenda-time (s)
    "Add an event with time S to appear underneath the line-at-point.
This allows a line to show in an agenda without being scheduled or a deadline."
    (interactive "sTime: ")
    (defvar cj/timeformat "%Y-%m-%d %a")
    (org-end-of-line)
    (save-excursion
      (open-line 1)
      (forward-line 1)
      (insert (concat "<" (format-time-string cj/timeformat (current-time)) " " s ">" ))))

  (global-set-key (kbd "M-t")       #'cj/add-agenda-time)

  ;; ---------------------------- Org Agenda Settings ----------------------------

  (setq org-agenda-prefix-format '((agenda   . " %i %-25:c%?-12t% s")
                                   (timeline . "  % s")
								   (todo     . " %i %-25:c")
								   (tags     . " %i %-12:c")
								   (search   . " %i %-12:c")))
  (setq org-agenda-dim-blocked-tasks 'invisible)
  (setq org-agenda-skip-scheduled-if-done nil)
  (setq org-agenda-skip-include-deadlines t)
  (setq org-agenda-remove-tags t)
  (setq org-agenda-compact-blocks t)

  ;; ------------------------ Add Files To Org Agenda List -----------------------
  ;; finds files named 'todo.org' (case insensitive) and adds them to
  ;; org-agenda-files list.

  (defun cj/add-files-to-org-agenda-files (directory)
	"Recursively searches for files named 'todo.org'.
Searches in DIRECTORY and adds them to org-project-files."
    (interactive "D")
	(setq org-agenda-files
		  (append org-agenda-files
				  (directory-files-recursively directory "^[Tt][Oo][Dd][Oo]\\.[Oo][Rr][Gg]$" t))))

  ;; NOTE: the following functions require org-roam functionality
  (with-eval-after-load 'org-roam-config

  ;; ---------------------------- Rebuild Org Agenda ---------------------------

  (defun cj/build-org-agenda-list ()
    "Rebuilds the org agenda list."
	(interactive)
	;; reset org-agenda-files to inbox-file
	(setq org-agenda-files (list inbox-file))
    (let ((new-files
           (append
            (cj/org-roam-list-notes-by-tag "Project"))))
      (dolist (file new-files)
        (unless (member file org-agenda-files)
          (setq org-agenda-files (cons file org-agenda-files)))))

	(cj/add-files-to-org-agenda-files projects-dir)
	(cj/add-files-to-org-agenda-files code-dir))

  ;; build org-agenda-list for the first time once emacs init is complete.
  (add-hook 'emacs-startup-hook 'cj/build-org-agenda-list)

    ;; ------------------------ Org Agenda Display Functions -----------------------

    (defun cj/agenda-all-agenda-files-day ()
      "Display an \'org-agenda\' schedule with tasks covering today.
The contents of the agenda will be built from org-project-files and org-roam
files that have project in their filetag."
      (interactive)
      (cj/build-org-agenda-list)
      (setq org-agenda-span 'day)
      (cj/agenda-today-view)
      (org-agenda "a" "a"))
    (global-set-key (kbd "<f8>")      #'cj/agenda-all-agenda-files-day)


    (defun cj/agenda-all-agenda-files-week ()
      "Display an 'org-agenda' schedule with tasks covering this week.
The contents of the agenda will be built from org-project-files and org-roam
files that have project in their filetag."
      (interactive)
      (cj/build-org-agenda-list)
      (setq org-agenda-span 'week)
      (cj/agenda-today-view)
      (org-agenda "a" "a"))
    (global-set-key (kbd "s-<f8>")    #'cj/agenda-all-agenda-files-week)

    (defun cj/todo-list-all-agenda-files ()
      "Displays an 'org-agenda' todo list.
The contents of the agenda will be built from org-project-files and org-roam
files that have project in their filetag."
      (interactive)
      (cj/build-org-agenda-list)
      (cj/agenda-all-view)
      (org-agenda "a" "t"))
    (global-set-key (kbd "C-<f8>")    #'cj/todo-list-all-agenda-files)

    (defun cj/todo-list-from-this-buffer ()
      "Displays an 'org-agenda' todo list built from the current buffer.
   If the current buffer isn't an org buffer, inform the user."
      (interactive)
      (if (eq major-mode 'org-mode)
          (let ((org-agenda-files (list buffer-file-name)))
            (cj/agenda-all-view)
            (org-agenda "a" "t"))
        (message (concat "Your org agenda request based on '" (buffer-name (current-buffer))
                         "' failed because it's not an org buffer."))))
    (global-set-key (kbd "M-<f8>")    #'cj/todo-list-from-this-buffer)

    ) ;; end with-eval-after-load 'org-roam-config
  ) ;; end with-eval-after-load 'org-roam

(provide 'org-agenda-config)
;;; org-agenda-config.el ends here