Damnit, todo list MY WAY
Ruby Shell
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Failed to load latest commit information.



An ultra fast command line todo list manager, with some strong opinions about workflow.


Every command is mapped to a single character. If you want to be fast, you need to get the key strokes down.

l = list
a = add (or all when used with list)
d = done
b = bump
r = recur
c = completion (to help enable shell tab completion)

Here is how it fits together:

gem install xtdo

alias t=xtdo # Recommended!

t a some task          # Add to list
t l a                  # All tasks
t b 0 some task        # Move task to TODAY
t a 0 another task     # New task on today list, shortcut letter
t l                    # Today's tasks
t d another task       # It is done!
t b 1w some task       # Actually we will to it next week
t r a 1d,thu bin night # Bin night every Thursday
t r a 1m,4 pay rent    # Pay rent on the 4th of the month
t r d pay rent         # Bah who wants to pay rent

t l c                  # List all tasks in a format suitable for tab completion
t r c                  # List all recurring tasks for completion

There is a command line completion script for ZSH in bin/xtdo_completion.zsh that you should use, since it auto completes task names for you. I don't know the best way to install this yet.

By default tasks are stored in ~/.xtdo. Customize this by setting the XTDO_PATH environment variable. I store mine in Dropbox.

More speed!

Load paths and gems and friends can add about 300ms to the load time of xtdo. Unacceptable! I haven't worked out a neat way around this yet, but for now my hack is to create my own script to run xtdo which I place in my path, with load paths hard coded in to it. This has the benefit of also working if you switch gemsets. Here is mine, yours will look slightly different:


$LOAD_PATH.unshift "/Users/xavier/.rvm/gems/ruby-1.9.2-p0/gems/xtdo-0.2.1/lib"

require 'xtdo'
file = ENV['XTDO_PATH'] || "~/.xtdo"
result = Xtdo.run file, ARGV.join(" ")
puts result if result && result.is_a?(String) && result.length > 0


I used to use a small subset of Things.app, and I really dug the workflow. I spend my life on the command-line though. Existing command line apps didn't quite match my workflow, or were too slow.

Xtdo is fast in the sense that you type very little to make it do things, but also in that it is extremely quick to respond to commands - you will never notice any delay.


Requires ruby 1.9.2. Will not run on any variant of 1.8.


Refactors accepted, as long as they don't turn everything into a First Class Object. I see no reason why this code should require more than one file. I will likely not accept any features that I will not use personally.

There are no runtime external dependencies. Let's keep it that way.


I am dog-fooding this and happy with it. AFAIK no one else is using it. I would like the proper install with speed hacks and shell completion to be easier. This file plus the comprehensive integration specs is the only documentation.