summaryrefslogtreecommitdiff
path: root/modules/org-agenda-config.el
diff options
context:
space:
mode:
authorCraig Jennings <c@cjennings.net>2024-04-07 13:41:34 -0500
committerCraig Jennings <c@cjennings.net>2024-04-07 13:41:34 -0500
commit754bbf7a25a8dda49b5d08ef0d0443bbf5af0e36 (patch)
treef1190704f78f04a2b0b4c977d20fe96a828377f1 /modules/org-agenda-config.el
new repository
Diffstat (limited to 'modules/org-agenda-config.el')
-rw-r--r--modules/org-agenda-config.el254
1 files changed, 254 insertions, 0 deletions
diff --git a/modules/org-agenda-config.el b/modules/org-agenda-config.el
new file mode 100644
index 00000000..c034aa05
--- /dev/null
+++ b/modules/org-agenda-config.el
@@ -0,0 +1,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