Org-mode mailing list
 help / color / Atom feed
From: Bernt Hansen <>
Subject: TODO state tracking in org-mode
Date: Fri, 21 Mar 2008 20:27:34 -0400
Message-ID: <> (raw)

Here's my attempt at documenting how I use task todo keywords and state
change tracking in org-mode.

* Some Background

I am a consultant who works with multiple clients doing programming and
system maintenance projects.

I have multiple org files which are in my org-agenda-files variable so
any tasks added to these end up in my agenda.  I live in the agenda.
Due to the number of tasks I have to work on the 'hot topics' end up
being scheduled so they are 'in my face' on the daily agenda until they
are completed.  Only when the agenda has no pending work to do for today
do I look for NEXT tasks to work on.

I typically have one org file per client with lots of projects and tasks
in it.  I archive completed projects/tasks monthly to de-clutter my org
files.  I throw lots of details into my org files so they tend to get
rather long.  Active Org files for clients are at least 1,000 lines long
normally; one of them is approaching 10,000 lines.  The archives are

* Task States

I have a few different types of tasks in my org files.  They roughly
break down into the following groups with the keywords listed.

 - Notes and documentation
   (these don't get a todo keyword)
 - Purchase Orders
   - OPEN
 - Regular Tasks
   - TODO
   - NEXT
   - DONE

Notes and documentation normally do not get a task todo keyword.  It's
just a heading level under some project which I use to help organize

I use OPEN and CLOSED todo keywords for Purchase orders only -- these
aren't normal tasks where you do things and then they're done.  The
purchase order is OPEN as long as you can bill against it and CLOSED
after that.  This just feels more natural to me than TODO/DONE.

I use ONGOING for tasks that do not have a well defined start and end.
Things like org-mode tuning :), reading email, administrative tasks for
clients etc.  I clock everything (or try to) so when I find I'm working
on something that isn't project specific but is more about organizing
things for a client/project I start clocking the appropriate ONGOING
task until I move on to something else.

All of the remaining task states are for regular tasks.  Tasks normally
go TODO -> NEXT -> DONE.  But things in life rarely go according to plan
so a task will often go to WAITING status, or be postponed indefinitely
(to SOMEDAY), or be CANCELLED without being complete.

* Task State Change Logging

I normally use a Remember template to create new project tasks.  This
creates the new task with a TODO keyword and today's date as the date
the task came into existence.  Subtasks are created when outlining the
project and no dates are normally recorded when they are created.

For a given task I want to record things like the following:

  - Why/What a task is waiting for when it goes to WAITING status
  - When a task is complete
  - When a task is cancelled
  - When a task is reopened (it was complete but now has work to do again)
  - When a task is finished waiting for something
  - When a purchase order is opened or closed

* Setup

I use the following setup in my .emacs for org-mode tasks.  Since I have
multiple org files I don't want to duplicate the settings for every
file.  I use an identical setup for every org file I use so I define
these globally.  I hate maintaining duplicated definitions.

,----[ .emacs settings ]
| (setq org-log-done t
|       org-use-fast-todo-selection t)
| (setq org-todo-keyword-faces
|       '(("TODO"  . (:foreground "red" :weight bold))
| 	("NEXT"  . (:foreground "red" :weight bold))
| 	("DONE"  . (:foreground "forest green" :weight bold))
| 	("WAITING"  . (:foreground "orange" :weight bold))
| 	("CANCELLED"  . (:foreground "forest green" :weight bold))
| 	("SOMEDAY"  . (:foreground "orange" :weight bold))
| 	("OPEN"  . (:foreground "red" :weight bold))
| 	("CLOSED"  . (:foreground "forest green" :weight bold))
| 	("ONGOING"  . (:foreground "orange" :weight bold))))
| (setq org-todo-keywords
|       '((sequence "TODO(t)" "NEXT(n)" "|" "DONE(d!/!)")
| 	(sequence "WAITING(w@/!)" "|" "CANCELLED(c!/!)")
| 	(sequence "SOMEDAY(s!/!)" "|")
| 	(sequence "OPEN(O!)" "|" "CLOSED(C!)")
| 	(sequence "ONGOING(o)" "|")))

Defining org-log-done to true tells org-mode to record a CLOSED: tag and
date/time stamp when a task is completed (either DONE, CANCELLED, or
CLOSED).  Moving the task back to an active todo state removes this tag.

org-todo-keyword-faces defines what colours to use for the various todo
keywords.  It's not strictly necessary but it's nice :)

org-todo-keywords defines the todo keywords and when extra information
should be recorded.  I only use sequence todo keywords. Keywords to the
left of the '|' are todo states and keywords to the right of the '|' are
done (completed) states in the sequence.  S-left and S-right cycles
through the states in the sequence.

  - TODO(t) sets the key 't' to be the fast todo selection key for
    this todo state.  Nothing special is recorded.
  - WAITING(w@/!) defines the WAITING keyword with 'w' as a fast todo
    selection key.  The '@' tells org-mode to record a note and a
    date/time stamp when entering this todo state.  The '/!' tells
    org-mode to also record a date/time stamp when leaving this state.
  - OPEN(O!) sets the key 'O' to be the fast todo selection key for
    this todo state and the '!' tells org-mode to record a date/time
    stamp when entering this state.
  - DONE(d!/!) sets the key 'd' to be the fast todo selection key for
    this state.  The '!' before the '/' tells org-mode to record a
    date/time stamp when entering this todo state and the '!' after
    the '/' tells org-mode to record a date/time stamp when leaving
    this state.

Here's the result of this logging on a sample task.

** DONE New Sample Task
      CLOSED: [2008-03-21 Fri 18:48]
      - State "DONE"       [2008-03-21 Fri 18:48]
      - State "NEXT"       [2008-03-21 Fri 18:47]
      - State "DONE"       [2008-03-21 Fri 18:45]
      - State "ONGOING"    [2008-03-21 Fri 18:44]
      - State "WAITING"    [2008-03-21 Fri 18:34] \\
	For Someone(tm) to finish Something(tm)
      [2008-03-21 Fri]
      1. This task was created on Friday Mar 21, 2008
      2. It moved to WAITING status at 18:34 with a note that it's
         waiting for Someone(tm)
      3. It left WAITING status and went to ONGOING at 18:47
	 ONGOING doesn't normally record a timestamp but since
	 we're leaving the WAITING state a timestamp is recorded
      4. Then it was DONE (we thought)
      5. But it later moved to NEXT because we marked it DONE too early
      6. And then it was finally completely DONE

** CLOSED Sample Purchase Order
	  CLOSED: [2008-03-21 Fri 19:03]
	  - State "CLOSED"     [2008-03-21 Fri 19:03]
	  - State "OPEN"       [2008-03-21 Fri 19:03]

This setup works very well for me.  I'm sure it can still be improved
but I thought I'd share it with the rest of you in case you find it


             reply index

Thread overview: 6+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2008-03-22  0:27 Bernt Hansen [this message]
2008-03-22 13:06 ` Manish
2008-03-23  1:46   ` Bernt Hansen
2008-03-23  4:52     ` Manish
2008-03-23 11:28       ` Bernt Hansen
2008-03-23 12:50         ` Carsten Dominik

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:

  List information:

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \ \ \ \

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link

Org-mode mailing list

Archives are clonable:
	git clone --mirror list/git/0.git

	# If you have public-inbox 1.1+ installed, you may
	# initialize and index your mirror using the following commands:
	public-inbox-init -V2 list list/ \
	public-inbox-index list

Example config snippet for mirrors

Newsgroups are available over NNTP:

AGPL code for this site: git clone