UPDATE: As of version 0.4, td depends on python-dateutils for date manipulation functions. Please make sure you have this installed prior to using td.
Introduction
Over a year ago, a friend of mine and I began tinkering with a little todo list program as we played with Python. We just wanted something simple and fast that could be used from the bash prompt without the fuss of a GUI. The result was a little script that we called td
. For the past year, not much changed with it. I did a bit of work on it while learning how to use gnome-vfs, and added the ability to use remote data transparently. A couple of days ago, I began playing with it again. I added a few new and useful features, and decided to make it available to everyone in case somebody out there wanted such a tool. I'll outline the features of the program here.
Installation
The latest tarball of td
can be downloaded from here, and is installable using the GNU autotools. In summary, navigate to the directory that has the downloaded tarball and type the following commands.
$ tar xvzf td-0.4.tar.gz
$ cd td-0.4/
$ ./configure
$ make
$ make install
You should now be able to run the program by typing td
at the command line.
Features
The td
script has the ability to add, delete, complete, prioritize, and archive tasks. This section will document each feature one at a time.
Displaying Tasks
Just running the command td
with no arguments will display a list of outstanding tasks, sorted by descending priority. The output looks like this:
The output contains the item or task number, the priority of the task, the creation date, and the task summary itself. The task number shown in this list is useful for performing various other commands. The last line of output displays the number of shown tasks, and the number hidden (not shown).
Adding a New Task
The add
command adds a new task to the list. For example:
$ td add Remind Jason to schedule his proposal.
This procedure is limited only by what is acceptable at the bash prompt. That is, things like quotes need to be escaped for example.
$ td add These \"quotes\" are escaped.
Deleting a Task
Deleting tasks can be done by specifying the task number to delete. For example,
$ td del 2
The above command will obviously delete task number 2 from the task list. Once deleted, tasks can no longer be accessed.
Deferring a Task
Sometimes you want to add a task to your list now, but don't want it to clutter up your task list until some date in the future. To do this, you would use the defer
command. This command takes several types of parameters to determine the date to defer the task to. For example, the following command will defer task number 4 one week into the future.
$ td def 4 1w
Similar short forms exist for days (d), months (m), and years (y). The defer command also uses the python-dateutils to parse dates described by natural language. For example the following command will defer task number 4 to August 5th of this year:
$ td def 4 aug 5
If no further arguments are given to the defer
command, a list of deferred tasks are displayed with their creation date, and the date they have been deferred to. Deferred tasks will not appear in the regular task list until their defer date is reached.
Undeferring a Task
If a task has been deferred to a future date, it can be made current again by using the undefer
command. Obtain the task number by running td with the defer
command without arguments. The following command will make the deferred task number 2 current again, hence making it display in the regular list of tasks.
$ td undef 2
Task Details
Some tasks require further details to clarify it further, or maybe just a place to store additional braindumps that you'd like to jot down. Details or notes can be added to a task using the details
command. This command will cause your favourite editor to open, allowing you to type your notes. This additional data will be stored with the task data, and can be accessed by running the details
command again on the same task. The following command can be used to added details to task number 4 in the list.
$ td details 4
Display Hidden Tasks
To display all incomplete tasks including the tasks marked hidden, use the hid
command.
$ td hid
This will show all incomplete tasks in the list with an additional column marked "H". Each task that is marked hidden in the list will contain an asterisk in this column.
Prioritizing a Task
Prioritizing tasks can be done using the pri
command. Entering the following command will assign task number 3 to the highest priority.
$ td pri 3 A
Priorities can be any single letter, and the display will be sorted by this key in descending order. Priorities of A, B, and C have distinct colours in the display output. Other priorities are just dark grey. By default, new tasks are given no priority at all. To remove the priority that was previously assigned to a task, run the same command, but exclude the priority.
$ td pri 3
This command will remove the priority from task 3.
Assigning Tasks to a Project
Tasks can be grouped into "projects" in td. To add a task to a specific project, you must include the project's name, prefixed with a "p:" somewhere in the tasks summary. The following command adds a task to the Office project.
$ td add p:Office Call Steve to schedule a meeting.
If you would like to see a list of projects that have outstanding tasks associated with them, you can use the proj
command with no parameters. This will provide a comma separated list of projects. To display a list of tasks assigned to a specific project, run the same command with the project as an argument. This command displays all tasks under the Office project.
$ td proj Office
Already existing tasks may be added to a project using the rep
(replace) command with the "p:" prefixed project in the new summary.
Assigning Tags to a Task
The td program supports "tagging" tasks with searchable tags. This can either be done when adding a new task, or after a task has already been created. To create a task with a set of tags, include the space separated tags in the task summary enclosed in square brackets. The following command creates a new task with the tags "work" and "python":
$ td add [work python]Script the emulator to run tests over night.
If you want to add tags to an already created task, you can use the tags
command. To do this, append the tag with a '+' sign prepended to it. Removing tags from a task can be performed by appending a tag with a '-' sign. For example, the following command adds the tag "work", and removes the tag "python" from task number 5:
$ td tags 5 +work -python
To view a list of tags that have been assigned to any task, use the tags
command with no arguments. This will display all tags as well as the number of tasks that have that tag assigned to them. Also, to see a list of tasks with a give tag or set of tags, use the tags
command with the tags of interest as an argument. For example, the following command will display a list of incomplete tasks that have been tagged with "work" and "python":
$ td tags work python
To view a list of tasks that have no tags assigned to them, use the notag
command with no arguments.
Completing a Task
Tasks can be marked as complete by issuing the do
command. Once marked complete, tasks will no longer appear in the normal display list, and a completion date is assigned to them. The following command will mark task number 2 as being completed.
$ td do 2
Viewing Completed Tasks
As mentioned, once marked complete a task will no longer be listed in the normal task list display. To view all completed tasks, issue the done
command like this:
$ td done
This will display a list containing a task number, creation date, completion date, and task summary. The displayed task number will be useful for performing various commands on completed tasks.
Marking Completed Tasks as Incomplete
If you have marked a task as complete by accident, or otherwise decide that a completed task should be reopened, you may issue the undo
command.
$ td undo 2
The above command will mark the completed task number 2 as incomplete. The task number is the one displayed in the list provided by the done
command. This task will now appear in the normal listing, and has no assigned completion date.
Replacing a Task
You may modify the summary of a given task by using the rep
command. When given a task number, this simply replaces the summary of that task with the new one provided.
$ td rep 3 Fix a spelling mistake in this task.
Searching for Tasks
Tasks can be filtered by providing search patterns to the filt
command. By giving a series of patterns, only those tasks who's summary match all patterns will be displayed. The resulting list will be numbered as if the full list was being displayed, but the tasks which do not match the patterns will be "filtered". This operation uses a smartcase search, which means if any of the given patterns contain at least one upper case letter, then the search will be case sensitive. If none of the letters in the pattern are upper case, then the search will be case insensitive. See the following examples.
$ td filt case insensitive
$ td filt cAse sEnsItiVe
The filt
command can take as many patterns as you wish, in any order. Only the tasks matching all patterns will be displayed.
Archiving Tasks
Once completed, tasks may be archived in a text file in case you would like to keep them for future reference. The text file is stored in ~/.td/td_archive.txt
. The file contains the summary, associated project, the creation date, and the completion date of all archived tasks. This operation permanently removes tasks from the todo list. You may archive a single task by providing its number, or all completed tasks by specifying all
as an argument to the archive
command. If no argument is given, td
will ask you if you would like to archive all completed tasks. Answering "yes" will perform the archiving, anything else will abort. So basically, both of the following commands will work as expected.
$ td archive all
$ td archive 3
Purging Tasks
To just delete all completed tasks (unarchived) without saving them in the archive, issue the purge
command. If given a task number, that task alone will be purged. If no task number is given, the user is asked for confirmation, and all complete tasks are purged.
$ td purge 3
This command will only purge task 3, without confirmation.
$ td purge
This command will prompt the user for confirmation, then purge all completed tasks. Purged tasks are lost, and cannot be recovered.
Getting Help
The td help
command simply prints a message with a terse description of all the available commands, and their usage.
Specifying Your Data Source
This really only applies if you do not have gnome-vfs and its Python bindings installed. To set the data source after first run (see below), you can issue the source
command. Doing this without the presence of gnome-vfs has no effect. However, you can change your data source to a remote file if you do have gnome-vfs installed. For example, the following command will make td
use a remote file to store data over ssh.
$ td source sftp://your.host.com:/home/username/.td/todos.xml
From this point on you can use td as usual, and it will transparently use the data file stored at the given URI. The source
command also takes the "local" argument (see below).
Without GNOME-VFS
If you do not have gnome-vfs and its Python bindings installed, the program will automatically store your todo list in the file ~/.td/todos.xml
. There are no remote data capabilities without using gnome-vfs.
With GNOME-VFS
The presence of gnome-vfs and its Python bindings will be detected when the program is run. On first run, td will ask you to enter a data source. This basically just means that it needs to know where to store your data. If you enter "local" then your data will be stored locally in the file ~/.td/todos.xml
. If you want to use remote data, enter any valid gnome-vfs URI to use that location. For example, the to use a data file stored in your home directory on a remote server, you could use sftp://your.host.com:/home/username/.td/todos.xml
to make td
use that data over ssh.
Types of Tasks
td maintains three types of tasks in its lists. This section will briefly describe each.
Incomplete Tasks
Incomplete tasks are basically any type of task that is not marked as complete. This is the default type when a task is created. These obviously represent tasks that are not yet completed, and which the user wants to appear in the default task list.
Hidden Tasks
These are a subset of incomplete tasks. They are treated the same, except the user doesn't want to see them in the default task list. Reasons for this may be to reduce clutter if for example the task is long term. Other reasons for marking a task as hidden are up to the user. Tasks are marked as hidden when, upon creation, the task summary provided begins with a period ("."), just like hidden files on the Unix file system. To mark a hidden task as no longer being hidden, use the replace command and enter a summary without the leading period. Similarly, to mark an already existing task as hidden, simply replace the current summary with one beginning with a period.
Completed Tasks
Tasks that have been marked as complete with the do
command are no longer displayed in the default task list. To view these tasks, use the done
command. To mark a completed task as incomplete, use the undo
command. Only tasks marked as completed are available to the purge
and archive
commands.
The ~/.tdrc Configuration File
td now looks in $HOME/.tdrc
if it exists for a few optionally configurable settings. This section will describe these settings.
The syntax used by the tdrc file is pretty typical for any configuration file. Entries are generally of the form {KEY} = {VALUE}
. Pretty straightforward stuff. If the file doesn't exist, or only a subset of the options are specified in it, then sane defaults are chosen.
Background Colour
The background
option informs td of the type of background on the user's xterm. If the xterm background is dark, then typically darker coloured text doesn't show up well. Setting this option to dark
instructs td to use brighter colours for its output. Setting it to light
instructs td to use more subtle colouring suitable for light backgrounds. The default value for this option is light
.
Feedback Level
Sets the level of feedback that td should provide to the user. If the value of the feedback
key is set to verbose
, then positive feedback will be provided upon successful completion of commands. If set to terse
then only errors will be displayed. The default value for this option is verbose
.
Preferred Editor
The editor
sets the preferred editor to be used when modifying the notes or details portion of a task. When deciding what editor to use, td will first check the $HOME/.tdrc
file for a value. If none is set, then the value of $EDITOR
is used. If still no value is found then Vim is used. This value can contain either a full path to the executable or just the executable file name provided it can be found in your $PATH
. The default for this option is vim
.
Extra Stuff
I like syntax colouring, and I use Vim for all of my editing. I made a very simple syntax file for editing td task details. It provides colours for the first line of the details file which indicates the project and the task summary. I also like to enter most of my notes in point form, so this syntax file also highlights lines beginning with an asterisk :). I know, I'm lame.
Anyways, this syntax file is available in the td tarball and will be installed into the $PREFIX/share/td/extras/
directory on your file system. To use it, copy it to $HOME/.vim/syntax/
and add the following line to your $HOME/.vim/filetype.vim
file.
autocmd! BufRead,BufNewFile *.td setf td
After doing this, you should see the syntax highlighting the next time you run the details
command in td.
Conclusion
If you decide to use td
or at least try it out, you can probably expect a bug or two. If that is the case, or you need some clarification, feel free to email me so I can help. Although I don't expect there to be much demand for a tool like this one, if somebody besides me would find it useful, I'd like to make it work for them too.