As I described a few weeks ago, I've been using a complex Getting Things Done system for around fifteen years. I've been using toodledo for my task system but recently I've gotten more interested in Emacs's org-mode. I've realized that I've been missing features and not knowing it; as one simple example, it's very easy to have multiple sets of tags in org-mode.
Below I'll describe how I have org-mode configured so far.
Table of Contents
- Files and directory structure
- Task intake: org-capture
- Archiving and refiling
- Tags and states
- SCHEDULED vs. DEADLINE
- Agendas and viewing consolidated tasks
- checklists and org-checklist
- Lessons learned so far
Files and directory structure
I have a Dropbox folder
org/ at the path
~/Dropbox/org. Inside this directory I have several files:
- "someday/maybe" ideas that are not otherwise tracked.
- home goals.org
- experimental place for "someday/maybe" home ideas.
- I configured this as where
- Non-project todo items.
- Stuff I'm doing right now, mainly to make using orgzly easier.
- Default place where orgzly saves tasks.1
- Location for larger projects with many todo items.
- web site ideas.org
- experimental place for "someday/maybe" web site ideas.
- work ideas.org
- experimental place for "someday/maybe" work ideas.
I am still experimenting with what files make the most sense. With org-mode you can do searches across many files at once, so I'm still figuring out when to use separate files. The main factor in using separate files seems to be orgzly's file synchronization.
Task intake: org-capture
One way to create tasks is just to go to a file and start typing. This is really strange to me, because you can tell you're just using a text file. But if you have a list of tasks this can be the fastest way, hitting
M-S-RET after each item to create a new line.
However, if you're doing other stuff and want to create a task on the fly, org-capture is really useful.
(use-package org :ensure org-plus-contrib :config ; really long config section omitted ; not sure if I need this: (setq org-default-notes-file "~/Dropbox/org/inbox.org") (setq org-capture-templates '(("t" "Todo [inbox]" entry (file+headline "~/Dropbox/org/inbox.org" "Tasks") "* TODO %i%?\n%a") ("n" "Todo [inbox, no link]" entry (file+headline "~/Dropbox/org/inbox.org" "Tasks") "* TODO %i%?\n") ("b" "Backlog" entry (file+headline "~/Dropbox/org/backlog.org" "Backlog") "* %i%?\n%a"))) :bind (; other bindings removed ("C-c c" . org-capture)))
With the above, I can hit
C-c c to capture something; I then have three options:
tto capture a todo item with a link
nto capture a todo item without a link
bto capture a backlog item (i.e. idea)
The "link" is a link to wherever you were when you created the todo. For example I hit
C-c c t right here and the link was to
file:~/Dropbox/jb.com/org/_posts/2019-02-23-org-todo-setup.org::*Task%20intake:%20org-capture. That is a link to the section of the org-mode file that I'm using to write this article!
This is especially helpful if I'm reading email (in Emacs); I can hit
C-c c t and create a todo that links to an email. In the todo later I can click the link to get back to that same email!
Archiving and refiling
Archiving is built into org-mode directly, I believe. If you're on a heading you want to archive, you can hit
C-c C-x C-a to archive that item. If you archive a task in
main-todo.org, the archive file will by default be
main-todo.org_archive. Archiving just moves your todo to another file for preservation.
Refiling lets you move a todo from one physical file to another. Here's how I set this up:
(setq org-refile-targets '((("~/Dropbox/org/main-todo.org") :maxlevel . 3) (("~/Dropbox/org/projects.org") :maxlevel . 3) (("~/Dropbox/org/backlog.org") :maxlevel . 3) (("~/Dropbox/org/now.org") :maxlevel . 3) ))
When you're on a heading, if you hit
C-c C-w, you'll be presented with all the headings down to level 3 for each of these files. This makes it easy to process
inbox.org or other files to move content to the right place.
Tags and states
Here are my todo "proper" settings:
(setq org-todo-keyword-faces '(("WORKING" . "orange") ("CANCELLED" . "grey"))) (setq org-todo-keywords '((sequence "TODO(t)" "WORKING(n)" "WAITING(w@/!)" "POSTPONED(p)" "|" "DONE(d@/!)" "CANCELLED(c)")))
This means that tasks can be in the states TODO, WORKING, WAITING, POSTPONED, DONE, or CANCELLED. The extra stuff after each keyword defines a shortcut key and whether a log entry should be added. For example
w is the keyboard shortcut,
@ means "note with timestamp" and
/! means "add a timestamp even if I bailed on writing a note."
With those "states" defined, I next defined my contexts:
(setq org-tag-alist '( (:startgroup . nil) ("home" . ?h) ("work" . ?w) (:endgroup . nil) (:startgroup . nil) ("@errands" . ?e) ("@house" . ?s) ("@now" . ?n) ("@online" . ?o) ("@phone" . ?p) ("@campus" . ?c) ("@office" . ?f) (:endgroup . nil) ))
This is a neat thing that toodledo didn't have–you can have different "groups" of tags, where you can only choose one item from the group. My group #1 is either home or work; my group #2 is the GTD "context" i.e. where you need to be to do this work.
Theoretically for example I could have a "work" task with a context of "house," if I needed to be home to do it but the task was for work. This has helped me move past GTD's insistence that your context is the only thing you should be tracking, and it also makes searching for work vs. home tasks much easier.
SCHEDULED vs. DEADLINE
To set dates on tasks, when you're on the task you can use
C-c C-d to set the DEADLINE date and/or
C-c C-s to set the SCHEDULED date. (You could also manually type these in.)
DEADLINE best corresponds to the due date of a task. Just like normal in GTD, the date should only be set if it's a real due date.
SCHEDULED best corresponds to the start date of a task. There are a few org-agenda options to hide tasks with a future scheduled date:
(setq org-agenda-todo-ignore-scheduled 'future) (setq org-agenda-tags-todo-honor-ignore-options t) (setq org-agenda-skip-deadline-prewarning-if-scheduled t)
Agendas and viewing consolidated tasks
The last big piece is configuring org-agenda to show me a summary of tasks to be done. To set org-agenda up, at a minimum you need to tell it what files to read:
(setq org-agenda-files (list "~/Dropbox/org/inbox.org" "~/Dropbox/org/main-todo.org" "~/Dropbox/org/orgzly-inbox.org" "~/Dropbox/org/projects.org")) ; also bind "C-c a" to org-agenda e.g. via use-package
After adding the keybinding, I can hit
C-c a to get to the org-agenda list of options, one of which is
a for agenda:
C-c a a in total. This lets me see the default org-agenda.
configuring custom org-agenda options
I'd like to have more control over what I see in org-agenda than the default view. This is done through as many parentheses as possible:
(setq org-agenda-custom-commands (("w" "Work agenda" ; Priority A ((tags-todo "PRIORITY=\"A\"&-home" ((org-agenda-overriding-header "Priority A"))) ; Due soon (tags-todo "-PRIORITY=\"A\"&DEADLINE<=\"<+7d>\"&-home" ((org-agenda-overriding-header "Due soon"))) ; Project list (tags "LEVEL=2&-home" ((org-agenda-files '("~/Dropbox/org/projects.org")) (org-agenda-overriding-header "Projects"))) (tags-todo (concat "-home&-TODO=\"WAITING\"&-FILE=\"" (expand-file-name "~/Dropbox/org/projects.org") "\"") ((org-agenda-overriding-header "All non-project tasks"))) ) ((org-agenda-compact-blocks t))) ;; options set here apply to the entire block ("h" "Home agenda" ; Priority A ((tags-todo "PRIORITY=\"A\"&-work" ((org-agenda-overriding-header "Priority A"))) ; Due soon (tags-todo "-PRIORITY=\"A\"&DEADLINE<=\"<+7d>\"&-work" ((org-agenda-overriding-header "Due soon"))) ; Project list (tags "LEVEL=2&-work" ((org-agenda-files '("~/Dropbox/org/projects.org")) (org-agenda-overriding-header "Projects"))) (tags-todo (concat "-work&-TODO=\"WAITING\"&-FILE=\"" (expand-file-name "~/Dropbox/org/projects.org") "\"") ((org-agenda-overriding-header "All non-project tasks")))) ((org-agenda-compact-blocks t))) ;; options set here apply to the entire block ("W" "Waiting" ((tags-todo "WAITING" ((org-agenda-overriding-header "Waiting tasks")))) )))
The above defines three org-agenda keys:
w ("work agenda"),
h ("home agenda"), and
W ("waiting"). I'm going to go through each of the sections within "work agenda:"
Priority A tasks
; Priority A ((tags-todo "PRIORITY=\"A\"&-home" ((org-agenda-overriding-header "Priority A")))
First, show me the "Priority A" tasks, only if they don't have a "home" tag. Very notably, tags get inherited, so if you have a block like so:
* example heading :home: ** TODO thing #1
"thing #1" gets the ":home:" tag. This means I can have a section tagged "home" called "Random home tasks" and nothing underneath it will show up if I hide the "home" tag.
; Due soon (tags-todo "-PRIORITY=\"A\"&DEADLINE<=\"<+7d>\"&-home" ((org-agenda-overriding-header "Due soon")))
Next, I want to see anything with a deadline within 7 days, and I don't want to see anything tagged PRIORITY "A" because I already saw that.
; Project list (tags "LEVEL=2&-home" ((org-agenda-files '("~/Dropbox/org/projects.org")) (org-agenda-overriding-header "Projects")))
Next, I want to see the "LEVEL 2" headings from the projects file unless they have a "home" task. THIS IS AMAZING. I'll see any tasks due soon because of the Due soon rule. Otherwise, I don't want my task system cluttered up with dozens of project tasks–I just want to remember that these projects are happening.
(tags-todo (concat "-home&-TODO=\"WAITING\"&-FILE=\"" (expand-file-name "~/Dropbox/org/projects.org") "\"") ((org-agenda-overriding-header "All non-project tasks"))) )
Finally, I want to see all the non-project tasks that aren't in a "waiting" state. There's a special property "FILE" that lets you filter on a file, so I can filter out all the "projects.org" files. (FILE is apparently populated with the complete path, which is why I need to call
checklists and org-checklist
I really like org-mode's checklist option–these checklists don't show up in my org-agenda view, but they help me remember to do parts of my tasks. For example I can have a task:
* TODO test-task - [ ] do this - [ ] do that - [ ] do the other thing
and I can then check the boxes with
C-c C-c as I complete them. This has been extremely helpful to me so that I can focus on one task that may have many parts to it.
I especially like using these checklists with repeating tasks. I'm using
org-plus-contrib rather than just
org because I want access to
(add-to-list 'org-modules 'org-checklist) (require 'org-checklist)
This module will look for a property
** TODO Weekly home tasks DEADLINE: <2019-03-03 Sun +1w> SCHEDULED: <2019-02-25 Mon +1w> :PROPERTIES: :RESET_CHECK_BOXES: t :END: - [ ] process paper inbox - [ ] clean fridge - [ ] clear out onetab tabs - [ ] review w/f and follow-up email
When this task is marked complete, the checklists will become unchecked again.
Lessons learned so far
I'm still halfway using toodledo and halfway using org-mode. So far I've found that org-mode is much less intrusive for todo intake; I can be checking my email and quickly add a task rather than having to switch to my web browser to type up a task with more context (because previously my email and task systems weren't integrated at all).
I also really like how projects and non-projects can be blended with this system. I've always had to use separate systems in the past.
This is to reduce the chance of orgzly editing a file that has also been edited elsewhere; orgzly doesn't have a good merge function so it's easy to have to throw away content if you aren't synchronizing.