Ecosyste.ms: Awesome

An open API service indexing awesome lists of open source software.

Awesome Lists | Featured Topics | Projects

https://github.com/remyhonig/org-query

Create complex but readable skip-functions for org-agenda
https://github.com/remyhonig/org-query

Last synced: about 2 months ago
JSON representation

Create complex but readable skip-functions for org-agenda

Awesome Lists containing this project

README

        

[[https://travis-ci.org/remyhonig/org-query][https://travis-ci.org/remyhonig/org-query.svg?branch=master]]

* Problem

I wanted to use the /Getting Things Done/ productivity method for
managing my projects and tasks and the only way I knew how to do this
was by copying the relevant functions from [[http://doc.norang.ca/org-mode.html#Projects][Bernt Hansen]] but when I
wanted to customize the views I discovered this was error-prone and
not very convenient. So I decided to write my own helper functions
which I turned into =org-query=.

* Solution

** Features

*** Selection DSL

To include entries in the agenda blocks you can use queries like this.

#+BEGIN_SRC emacs-lisp
;; Skip the whole tree if the condition is not met
(org-query-select "tree"

;; All criteria must be satisfied
(and

;; Don't match trees under the Someday / Maybe headline
(not (org-query-parent (org-query-stringmatch "^Someday / Maybe")))

;; The headline should have at least one child with a todo state
(org-query-child (org-query-todo))

;; The headline itself should have the NEXT todo state
(org-query-todo '("NEXT"))))
#+END_SRC

This in contrast to the [[https://www.gnu.org/software/emacs/manual/html_node/org/Special-agenda-views.html][standard skip functions]] included in =orgmode=
by default. The problem with those functions is that they cannot be
combined very easily or intuitively.

*** GTD style skipping functions

This package includes a selection of functions that help to implement
GTD-style project management. See the example for their usage.

** Example

*** Orgmode Tree

#+BEGIN_SRC text
* Inbox
** TODO do something
* Areas of Focus
** Finances
*** NEXT implement budget
**** NEXT map current expenditures
**** TODO map current income
**** TODO set budgets
**** TODO setup automatic transactions
*** WAITING change bank
**** DONE transfer all funds to new bank account
**** DONE close previous bank account
**** WAITING verify funds are in new bank account
** Programming
*** TODO create org-query v2
**** NEXT make coffee
**** TODO checkout repo from github
**** WAITING pull request to other project
**** Someday / Maybe
***** TODO caching
** Family
*** NEXT go to the movies
**** DONE choose movie
**** TODO buy tickets
**** TODO pickup tickets
#+END_SRC

*** Agenda View

#+BEGIN_SRC text
============================================================
Task to refile
test: TODO do something

============================================================
Tasks waiting for something
test: WAITING verify funds are in new bank account
test: WAITING pull request to other project

============================================================
Next tasks in active projects
test: NEXT map current expenditures

============================================================
Active projects with a next task
test: NEXT implement budget

============================================================
Active projects without next task
test: NEXT go to the movies

============================================================
Waiting projects
test: WAITING change bank

============================================================
Backlog of active projects
test: TODO map current income
test: TODO set budgets
test: TODO setup automatic transactions
test: TODO buy tickets
test: TODO pickup tickets
#+END_SRC

** Usage

#+name: org-config
#+BEGIN_SRC emacs-lisp
(defun rmh/agendablock-tasks-waiting ()
`(tags-todo "/+WAITING|+DEFERRED"
((org-agenda-overriding-header "Tasks waiting for something")
(org-tags-match-list-sublevels nil)
(org-agenda-skip-function (org-query-select "headline" (not (org-query-gtd-project))))
(org-agenda-todo-ignore-scheduled t)
(org-agenda-todo-ignore-deadlines t)
)))

(defun rmh/agendablock-next-in-active ()
`(tags-todo "/+NEXT"
((org-agenda-overriding-header "Next tasks in active projects")
(org-agenda-skip-function (org-query-select "headline" (org-query-gtd-active-project-next-task)))
(org-tags-match-list-sublevels t)
(org-agenda-todo-ignore-scheduled 't)
(org-agenda-todo-ignore-deadlines 't)
(org-agenda-todo-ignore-with-date 't)
(org-agenda-sorting-strategy
'(todo-state-down effort-up category-keep)))))

(defun rmh/agendablock-backlog-of-active ()
`(tags-todo "/+TODO"
((org-agenda-overriding-header "Backlog of active projects")
(org-agenda-skip-function (org-query-select "headline" (org-query-gtd-backlog-task)))
(org-agenda-todo-ignore-scheduled 't)
(org-agenda-todo-ignore-deadlines 't)
(org-agenda-todo-ignore-with-date 't)
(org-agenda-sorting-strategy
'(category-keep)))))

(defun rmh/agendablock-active-projects-without-next ()
`(tags-todo "/+NEXT"
((org-agenda-overriding-header "Active projects without next task")
(org-agenda-skip-function (org-query-select "tree" (org-query-gtd-active-project-stuck)))
(org-tags-match-list-sublevels 't)
(org-agenda-sorting-strategy
'(category-keep)))))

(defun rmh/agendablock-active-projects-with-next ()
`(tags-todo "/+NEXT"
((org-agenda-overriding-header "Active projects with a next task")
(org-agenda-skip-function (org-query-select "tree" (org-query-gtd-active-project-armed)))
(org-tags-match-list-sublevels 't)
(org-agenda-sorting-strategy
'(category-keep)))))

(defun rmh/agendablock-waiting-projects ()
`(tags-todo "/+WAITING"
((org-agenda-overriding-header "Waiting projects")
(org-agenda-skip-function (org-query-select "tree" (org-query-gtd-project)))
(org-tags-match-list-sublevels 't)
(org-agenda-sorting-strategy
'(category-keep)))))

(defun rmh/agendablock-loose-tasks ()
`(tags-todo "/+TODO"
((org-agenda-overriding-header "Tasks not belonging to a project")
(org-agenda-skip-function
(org-query-select "headline" (and (org-query-gtd-loose-task) (not (org-is-habit-p)))))
(org-agenda-todo-ignore-scheduled 't)
(org-agenda-todo-ignore-deadlines 't)
(org-agenda-todo-ignore-with-date 't)
(org-agenda-sorting-strategy
'(category-keep)))))

(defun rmh/agendablock-checklists ()
`(tags "CHECKLIST"
((org-agenda-overriding-header "Checklists")
(org-tags-match-list-sublevels nil))))

(defun rmh/agendablock-inbox ()
`(tags-todo "LEVEL=2"
((org-agenda-overriding-header "Tasks to refile")
(org-agenda-skip-function (org-query-select "tree" (org-query-gtd-refile)))
(org-tags-match-list-sublevels nil))))

(setq org-agenda-custom-commands
`((" " "Agenda"
((agenda "" ((org-agenda-ndays 1)))
,(rmh/agendablock-inbox)
,(rmh/agendablock-tasks-waiting)
,(rmh/agendablock-next-in-active)
,(rmh/agendablock-active-projects-with-next)
,(rmh/agendablock-active-projects-without-next)
,(rmh/agendablock-waiting-projects)
,(rmh/agendablock-backlog-of-active)
,(rmh/agendablock-checklists))
nil)
("r" "Review Agenda"
((agenda "" ((org-agenda-ndays 1)))
,(rmh/agendablock-inbox)
,(rmh/agendablock-loose-tasks)
,(rmh/agendablock-tasks-waiting)
,(rmh/agendablock-next-in-active)
,(rmh/agendablock-active-projects-with-next)
,(rmh/agendablock-active-projects-without-next)
,(rmh/agendablock-backlog-of-active)
,(rmh/agendablock-checklists))
nil)))
#+END_SRC