Org Agenda Configuration

Table of Contents

A literate programming configuration for fancy agenda and todo lists.

Introduction

All the code we describe in this file needs loading after org.

(with-eval-after-load "org"
  (add-to-list 'org-modules 'org-protocol))

Grouping

Typical agendas have an order to them, but the org-super-agenda project allows you to get specific as well as group them under headings.

Unless you specify otherwise, this is the grouping we'll use:

(use-package org-super-agenda
  :after org
  :init
  (setq org-super-agenda-date-format "%A (%e)"
        org-super-agenda-groups
        '((:name "Accomplishments"
           :todo ("DONE" "CANCELED")
           :order 4)
          (:name "End of Day"
           :habit t
           :order 2)
          (:name "Uncompleted Work"
           :todo "DOING"
           :scheduled past
           :order 0)
          (:name "Today's Tasks"
           :date today
           :order 1)
          (:name "Today's Tasks"
           :scheduled today
           :order 1)
          (:name "Future Work"
           :todo "TODO"
           :scheduled future
           :order 3))))

The task matches a group based on the code order, but the :order tag allows me to display them in a different order.

The following super agenda is just for today and should be smaller:

(setq ha-org-super-agenda-today
      '((:name "Finished"
               :todo ("DONE" "CANCELED")
               :order 4)
        (:name "End of Day"
               :habit t
               :order 2)
        (:name "Today's Tasks"
               :todo "DOING"
               :scheduled past
               :date today
               :order 0)))

Query Views

The org-ql project gives us a query language of sorts (based on s-expressions).

By putting all queries under org-ql-views, we can then call M-x query and select the view to display:

(use-package org-ql
  :after org
  :config
  ;; Often used 'subgroup' that defines a work task
  (setq ha-org-ql-typical-work-tasks
        '(and (tags "work")

              ;; I will always be Supporting the onboarding projects,
              ;; but don't show them (but show descendants):
              (not (and (tags "onboarding")
                        (heading "^Support ")))

              ;; Show a blocking subtask instead of the parent:
              (or (not (children))
                  (not (descendants (todo "TODO" "DOING"))))

              (not (habit))
              (not (done))))

  (setq org-ql-views
        (list (cons "Overview: Today"
                    (list :buffers-files #'org-agenda-files
                          :query `(or (closed :on today)
                                      (and (habit)
                                           (not (done))
                                           (scheduled :to today))
                                      (and ,ha-org-ql-typical-work-tasks
                                           (or (deadline auto)
                                               (todo "DOING")
                                               (scheduled :to today)
                                               (ts-active :on today))))
                          :sort '(priority date)
                          :super-groups 'ha-org-super-agenda-today
                          :title "Today in Me"))

              (cons "Overview: Tomorrow"
                    (list :buffers-files #'org-agenda-files
                          :query '(and (not (done))
                                       (tags "work")
                                       (scheduled :from tomorrow :to tomorrow))
                          :sort '(priority date)
                          :super-groups 'ha-org-super-agenda-today
                          :title "Overview: Tomorrow's tasks"))

              (cons "Calendar: Today"
                    (list :buffers-files #'org-agenda-files
                          :query '(ts-active :on today)
                          :title "Today"
                          :super-groups 'ha-org-super-agenda-today
                          :sort '(priority))))))

Agenda Interface

We can create a function to start this:

(defun ha-todays-agenda ()
  "Display an agenda for today, including tasks and scheduled entries."
  (interactive)
  (org-ql-view "Overview: Today"))

And of course, a keybinding:

(ha-leader "a a" '("my agenda" . ha-todays-agenda))