The Chronicle

of a ColdFusion Expatriate

Dig Into Org Mode

January 30, 2016

Org mode was one of the main reasons I tried Emacs (and left behind 15 years of Vim), and now it is a central part of how I organize my work. Org mode can help you take notes, track tasks, build agendas, process tabular data, and more. It’s so flexible that everyone uses it differently.

I use Org mode primarily to capture tasks and keep track of their progress. I sometimes take notes in Org mode, but I haven’t completely fleshed out my note-taking and searching workflow, so I’ll talk mostly about task management here.

Org Setup Essentials

Before you can start building a refined Org workflow, you need to set up some basics.

Define Your Todo States

Org mode keeps track of the state that a task is in by applying a keyword to it, usually something like “TODO” or “DONE.” The keyword appears at the beginning of every task and Org lets you cycle through them easily to track task progress. When you use a list of keywords that describe a progression of states, Org calls that a “sequence.”

You can also configure multiple sequences of task states and use key bindings to toggle between the sequences, but I haven’t found a use for that feature myself… Yet.

The easiest way to set your default task sequence is by setting org-todo-keywords, like this:

(setq org-todo-keywords
      '((sequence "TODO" "IN-PROGRESS" "WAITING" "|" "DONE" "CANCELED")))

The observant among you will notice three things about this configuration:

  • It is a list of lists. This supports the multiple sequences I mentioned above.
  • My sequence starts with the symbol “sequence.” That tells Org that the following items are a sequence of states rather than a list of task types.
  • One of the items is a pipe. The pipe is optional, but if it is present, the task states following it will all be considered by Org to mean “complete.” I use it to mark tasks as DONE or CANCELED.

If you wish to configure your task states differently in each Org file, you can use a line like this at the top (the syntax, including the pipe, is the same):

#+TODO: TODO IN-PROGRESS WAITING | DONE CANCELED

Even more about Org states is covered in Workflow states in the Org manual.

Define Your Agenda Files

I keep all of my Org files in a single directory in my Dropbox (~/Dropbox/org). I like to keep a single file for tasks and a single file for notes, but you can absolutely break it up into as many files as you wish, or create a new file for each meeting or set of notes.

For pure task management, Org’s agenda features are so rich that it almost doesn’t make sense to edit the task file itself, so I keep all tasks in a single file, ~/Dropbox/org/tasks.org.

The “agenda” is a specific feature of Org that lets you view summaries of the data in your task files, manipulate their parameters, and even use search and tags to build your own custom views. Before you can do any of that, you need to teach Org where to look for all of the files you wish to include in your agenda.

You can do that by setting org-agenda-files:

(setq org-agenda-files '("~/Dropbox/org/"))

If you know a little Elisp you may notice that the variable is set to a list. If you store your task files in more than one location, you can supply each of those locations in the list (like '("/dir/one" "/dir/two") and so on).

Basic Usage

Now that you’ve set all this stuff up, how do you actually use it?

I use two major entry points into the Org system: “agenda,” and “capture.” Let’s talk about them one at a time.

Using the Agenda

The agenda is a ridiculously powerful feature of Org Mode. In addition to being a dynamic daily or weekly interactive task list, it is also a front-end for searching and generating other types of customized reports. You can think of it as a way to summarize Org data.

I use the agenda chiefly to display my weekly tasks. When you have org-agenda-files configured, you can simply call org-agenda-list to generate an agenda, which, by default, will be the weekly display. Because I use the agenda as my primary interface to a lot of my work, I prefer to open the agenda by itself in the current frame. To do that, I wrote a small function and assigned it to a key binding:

(defun air-pop-to-org-agenda (split)
  "Visit the org agenda, in the current window or a SPLIT."
  (interactive "P")
  (org-agenda-list)
  (when (not split)
    (delete-other-windows)))

(define-key global-map (kbd "C-c t a") 'air-pop-to-org-agenda)

The “air” part is just a namespace prefix that I use for all of my custom functions for historical reasons I won’t go into; the important part is the split argument, which allows me to optionally allow the window to split as it does normally by specifying a prefix.

When the interactive call specifies “P”, the function will be passed an argument with a “truthy” or “falsy” value depending on whether the prefix key was pressed. In practice what that means is if you invoke the function by pressing C-u followed by the key the function is bound to, prefix will be true, otherwise it will be false.

In the example above, C-c t a opens the agenda list and deletes all other windows, whereas C-u C-c t a (which I use much less often), allows the other windows to remain open.

My mnemonic for these key bindings is t for “todo” and a for “agenda.” My other Org-related bindings all start the same way.

The agenda view is only useful if you have saved tasks with either DEADLINE or SCHEDULED dates. Without dates associated with the tasks, Org wouldn’t know where to place them in the agenda. I’ll talk more about scheduling in the following section.

Essential Agenda Keys

The agenda list is interactive. To see all of the keys available, just invoke the mode help with C-h m from within the agenda list. Here are the most critical ones that I use all the time:

Press TAB to reveal the Org file that the item at point comes from. I use this when I need to get in there and edit the notes within that item or make more involved changes. I also bound RET to the function org-agenda-switch-to, which does the same thing but doesn’t use a split.

I have re-bound my motion keys because I use Evil, but the arrow keys move among items by default, and n and p will move between headings (like days of the week).

Pressing S-Left or S-Right while on a task will change the task’s scheduled or deadline date by one day in either direction. I use this mostly to push out stuff I know I’m not going to get to today.

Press t on a task to cycle its current state (e.g. from “TODO” to “IN-PROGRESS,” etc.)

Following the pattern used by many other Emacs packages, pressing g anywhere in the agenda will redraw it (recomputing days, statuses, etc.) I use this right after I’ve changed a date or cycled the state of a task so that things are displayed where they should be.

Finally, and perhaps most importantly, press s anywhere in the agenda view to save all Org buffers that provide data to the agenda. When you make changes to task states, dates, and so on, Org edits the buffers containing those items, but won’t save them automatically. Press s to make sure everything’s saved, once you’re happy with your changes.

As with all systems in Emacs, use the mode help to see what other keys are available and re-bind the ones that don’t feel right.

Using Capture

Once you’re funneling all of your tasks through Org Mode, you’ll need a way to very quickly add new tasks no matter what else you’re doing. The Org mechanism for this is called “capture,” and it allows you to add items to Org files from anywhere in Emacs.

You can actually add any type of item to any file, but I use it simply to add task items to my task list. The simplest way to invoke capture is to simply call org-capture, typically via a binding. When you call that function, a split will open prompting you to select a “template,” and you probably won’t have any so you’ll only be given the option to “C,” customize, or “q,” abort.

So let’s create a template. You can do this by setting the variable org-capture-templates and the format of the data is more straightforward than it looks at first:

(setq org-capture-templates
      '(("a" "My TODO task format." entry
         (file "todo.org")
         "* TODO %?
SCHEDULED: %t")))

The value of org-capture-templates is a list of template entries where each entry contains a single letter key for selecting or identifying the template (“a” above), a descriptive name, a type (“entry” above), the target for the entry (above I have used a filename, which will be relative to org-directory), and finally the template text itself.

A large number of variables are available within your template text, and targets other than a filename are also possible. All of that is documented in the manual for org-capture-templates (C-h v org-capture-templates RET).

In my template I have used %t to insert a timestamp, and I’ve specified %? to place the cursor right after the “TODO” keyword when the template is shown. You are under no obligation to follow my, or anyone’s, format here. I always want my new tasks to be scheduled so that they appear in my agenda, so I’ve added that bit of metadata to my capture template.

Now that you have a capture template, calling org-capture will show its name along with its key in the menu, and pressing that key (“a” in my example above), opens a split with the template contents so you can edit it as necessary, then of course press C-c C-c to save and close the capture or C-c C-k to abort (that is noted in the window itself as well).

I only have one template and I don’t want to have to press two keys to capture it, so I’ve wrapped my own function around it:

(defun air-org-task-capture ()
  "Capture a task with my default template."
  (interactive)
  (org-capture nil "a"))

All that does is call org-capture with its optional template key argument. Now you can bind that to a global key and you’re off to the races!

(define-key global-map (kbd "C-c c") 'air-org-task-capture)

When I press C-c c, a split opens with my scheduled task template and I can just type in the subject line and press C-c C-c to save it. This has saved me hours and allowed me to enter tasks quickly into my agenda without having to navigate buffers or think too much.

Useful Tweaks

After using this system for a while you inevitably find ways in which it could work better for you, and since Org is such a monster, there is almost always some configuration you can tweak to fix it. These are the tweaks I have found that work for me and their descriptions:

(setq org-agenda-text-search-extra-files '(agenda-archives))

When you perform a text search (the “s” selection from the org-agenda pop-up), include the archives for all of the files in Org’s agenda files list. If you archive things regularly, which I do, this helps you dig stuff out of there when you’re looking for it.

(setq org-blank-before-new-entry (quote ((heading) (plain-list-item))))

I tend to leave a blank line at the end of the content of each task entry. This causes Org to automatically place a blank line before a new heading or plain text list item, just the way I like it.

(setq org-enforce-todo-dependencies t)

This one is pretty awesome; it forces you to mark all child tasks as “DONE” before you can mark the parent as “DONE.” The agenda view already has the notion of “blocked” tasks (those with incomplete child tasks), which should appear dimmed (that, of course, is also customizable). This makes it even harder to slack off on your work.

(setq org-log-done (quote time))

I like to know when tasks have changed status. Setting this option causes Org to insert an annotation in a task when it is marked as done including a timestamp of when exactly that happened.

(setq org-log-redeadline (quote time))

Adding yet further auditing, this option causes Org to insert annotations when you change the deadline of a task, which will note the previous deadline date and when it was changed. Very useful for figuring out how many times you “kicked the can down the road.”

(setq org-log-reschedule (quote time))

This does the same as above, but for the scheduled dates, which I use more often.

Conclusions

Org Mode is much more vast than one blog post could describe, but hopefully this will give you a jumping-off point for starting a delightful and effective task management workflow using Org!

As always, if you have questions about any of this or want to sing my praises, drop a comment down below.

Comments