June 23, 2011

Task Management from the CLI to Android with Todo.txt

In the never-ending quest for task-management software, most Linux users gravitate towards fancy GUIs, multi-faceted import/export, and endless customization. Sadly, all that achieves is a cornucopia of incompatible GUI to-do managers, and when one goes dormant, the others are no help. But if you take the "less is more" approach instead, you'll find todo.txt a worthy alternative. Todo.txt stores its data in a flat text file that any application can read, but it gives you full access from the command line as well as from Android and other mobile devices.

Technically speaking, the command line interface is properly called either todo.txt-cli (which is the name of its public Github project) or todo.sh (which is the name of the actual script you use to add, update, prioritize, and assign tasks). But for most people, todo.txt is the preferred moniker, because it highlights the key feature — the plain-text, human-readable, and "future-proof" todo file. The CLI script is the canonical way to access and change the file, but its simple format had led to a healthy ecosystem of other front-ends, including web-based and Android interfaces.


The principle of todo.txt evolves directly from a simple text file listing one task per line, with a minimum of syntax added on. In fact, according to the wiki documentation, there are just three features that todo.txt views as essential: prioritization, projects, and contexts. Prioritization simply allows you to sort tasks by importance, and is denoted with parentheses: (A) is a "most important" task, (B) is second-most important, and so on. Each "project" is a grouping of related tasks, and a project name is indicated with a plus sign, such as +RoofRepair, +Thesis, or +WorldDomination. Contexts are directly borrowed from the Getting Things Done (GTD) approach popularized by David Allen, and are denoted with an at sign, such as @home, @phone, or @undergroundlair.

The kicker is that none of these syntactic features are required. A perfectly valid entry in todo.txt is as simple as:

Buy root beer

... but you can layer on the other features as desired, and with the exception of priorities, in whatever order feel natural. All of the following are valid entries as well:

(A) Buy root beer
Solve Rubik's Cube +SelfImprovement @work
(D) +Music +Backyard Install Outdoor Speakers @home
Find lost wallet @home @office @car @park +Life +Finances +RememberingThings

Priorities have to come first, for parseablity's sake — that way if you need to add the task "Turn my side business into a registered 501(C)(3)," it's unambiguous. Some of the front-ends also add creation dates, and if you use them, they either have to come first or directly after a priority indicator, using the YYYY-MM-DD format. This also prevents ambiguity.

Your task list can also include completed items — for various reasons, you may need to retain them in the file even after you are finished with them. The official syntax for a completed item is that it starts with an X (or a lowercase x) followed by a space. Which means if "X-ray" or "X-Men" happen to start one of your to-do items, be sure not to forget the hyphen. If a completed item has a date immediately following the initial X-and-space, this is officially interpreted as the completion date. That could result in some ambiguity in tasks that already started with a date, depending on the front-end you use, so several of the add-ons use their own metadata format such as due:YYYY-MM-DD. But you don't need to worry about that to get started.

CLI Goodness

The file format, therefore, is simple. Using it is also simple, thanks to the todo.sh shell script. The downloads page hosts bundles in .tar.gz and .zip archive formats, which hints that the package is usable on a variety of operating systems. The latest release is version 2.7, from August 2010. Inside the archive you'll find two files: todo.sh (the script) and todo.cfg (its configuration file).

The todo.sh script is written for Bash, the default shell on most Linux distros. But when it says Bash, it means Bash: not csh, sh, ksh, or that shell your lab partner wrote. Quite a few users have posted questions on the mailing list about mysterious errors that trace back to not having Bash installed, and the system falling back on a slightly-incompatible shell.

You can install todo.sh anywhere, just make sure you make it executable with chmod +x todo.sh. Open the todo.cfg configuration file in a text editor, and edit the "Your todo.txt directory" line to reflect where you want to keep your main todo.txt file, archives, and various ancillary files. If you're not sure, try /home/yourusername/.todo — but also make sure to create the directory you specify. You can dig into the config file some more and play with color settings and list-sorting preferences, but that is optional.

The wiki suggests a few other tips, such as adding a Bash alias to save on typing. Adding alias t='todo.sh -d /home/yourusername/todo.cfg' to your .bashrc lets you access todo.sh just by typing t. The -d switch is recommended because todo.sh supports multi-user use in a system-wide installation, and each user needs a separate config file.

Speaking of usage, to add a task to your to-do list, type t add "Write the Great American Novel" — optionally including any +Projects or @contexts as needed. The only rule is that you must place quotes around your task text. To see your list of outstanding tasks, type t list or t ls. Todo.sh will write a numbered list of your tasks (along with a summary) to the screen. The number denotes the order the tasks were added. For example, you might see

01 Write the Great American Novel
02 Quit job
03 Move to @TropicalIsland
TODO: 3 tasks in /home/nate/.todo/todo.txt

If you add a project, context, or priority as an optional filter to the end of a list command, you can see just those tasks that match. So t ls @home shows you your "home" context, t ls +ServerUpgrade your "ServerUpgrade" project, and so on. But you can also pass any chunk of arbitrary text to an todo.sh ls command, and the script will return those to-do items that match it, so t ls cupcakes is perfectly valid, too.

You assign priority flags to tasks with the pri command, followed by the task number (as ls lists it) and the letter of the priority you want to attach (A through Z), such as t pri 16 A. Subsequently, when you do an ls listing, tasks that have priorities assigned will be color-coded and placed at the top of the list, sorted in order. The depri command removes the priority flag from an item.

When you complete a task, mark it with do followed by the task number. In other words, t do 8. Task 8 will be flagged with an "x " in the todo.txt file, and no longer listed for you when you type an ls command.

On top of the basics described here, the todo.txt community has written several add-ons that supply additional functionality, such as grouping ls output by project, assigning "threshold dates" in the future (so that items do not appear in the list until they are slated to start), and pretty PostScript output for printing. These add-ons are scripts that live in their own directory, which is specified in todo.cfg.

Outward Mobility

If you never leave home, a GTD-capable task manager that you can use entirely from the terminal is reason enough to look at todo.txt. In fact, because you can use todo.sh over SSH, maybe you never do need to leave home. For that matter, todo.sh runs perfectly well on Maemo handhelds (if you remember to install Bash) and should work on MeeGo and Android devices, too. But for the sake of argument, let's pretend there are times when the command-line orientation of todo.sh isn't what you want. There are several alternatives to keep your tasks in sync while you're on the move.

The first is Todo.txt Touch, a full-featured Android client written by the todo.sh maintainers. You can download it from Github, or look for it in the Android Market (although it is not free in the market, the code is exactly the same as the freely-downloadable version). It sports on-screen buttons for the basic functions (adding, filtering, and flagging tasks, assigning priorities, contexts, and projects, etc.) and uses Android's built-in text-input mechanisms to enter task details. There is a simple one-click interface to access your list of projects and contexts, which really is nice (even if it is flashier than the shell script's text output....).

More importantly, Todo.txt Touch is designed to sync with a remote storage location. As of right now, the only supported service is Dropbox, but the team indicates that more "cloud" storage services are to come. If you want to keep your Todo.txt Touch and your CLI task lists synchronized, all you need to do is open up your todo.cfg file and point the todo.txt directory variable to the proper location in your Dropbox folder.

But wait, there is more. Those users with iPhones will appreciate todo.txt-web, which is a PHP-and-jQuery based front-end to todo.sh that you can use as a web app. This requires making the todo.txt files writable by your web server, but is otherwise based on the same code. The default CSS styling of the front-end is designed to look like an iPhone web-app, but the code should render equally well in any modern mobile browser.

Finally, for those users that use the Remember The Milk web service, there is a separate Bash script called getmilk.sh that fetches a remote list of RTM tasks and re-formats them into todo.txt-compatible syntax.

Any way you slice it, Todo.txt's power comes directly from the simplicity of its file syntax. You can use the shell script, the Android app, a text editor, or any other tools you devise to edit the file (there is even one written in .Net for Windows users). As long as the applications retain the correct syntax, any of the other front-ends can make use of the result, so you can Get Things Done whether you're in front of the keyboard, on a remote machine, or in the middle of nowhere with only your phone by your side.

Click Here!