Introduction
************

tdl is a lightweight program for managing a 'to-do' list of pending jobs that you have.

It supports the following features :

  * 1 database per directory, or per tree of directories (tdl searches up through parent directories to find the database, so you can have one per project, for example.)

  * add new entries, mark them done, edit the text of entries

  * add a new entry and immediately mark it done (e.g. to log tasks you did which you tackled immediately you got them.)

  * organise the entries in a tree structure (sub-tasks of other tasks etc)

  * move the tasks around and re-organise the hierarchy.

  * list the tasks in the database (default listing excludes 'done' tasks, but these can be shown too if desired).  The listing is in colour by default, with monochrome output as an option.

  * allows entries to be prioritised (priorities shown in different colours on listing).  The listing can selectively show only entries at or above a given priority level.

  * the start time for tasks can be set, to allow for 'deferred' tasks with start times in the future.  Such tasks are excluded from the default listing.

  * tasks can be marked 'postponed' to avoid them cluttering up the normal listing.

  * track date added and date completed for each task

  * generate report of tasks completed in a given earlier time period (useful if you have to produce a weekly summary of your work done, for example)

  * import and export entries, to allow splitting and merging of databases.

  * written in C

  * runs on a Linux console or in a terminal window.  It currently generates a coloured listing (monochrome is an option), so a colour xterm or rxvt is preferred.

  * tdl can run a single sub-command direct from the command line, or it can run in an interactive mode where several sub-commands can be used within a single run.  If the GNU readline library is available at compile time, the interactive mode features command line editing and various completion and usage hint facilities.

Installation
************

This section discusses installation

Installing tdl from source code
===============================

The procedure for installing tdl from source code is as follows:

 1. Unpack the sources

          gunzip < tdl-1.0.tar.gz | tar xvf -
          cd tdl-1.0

 2. Configure the makefile

     tdl does not use a ./configure mechanism (yet!) to configure options. You have to manually edit Makefile.  The variables you may want to edit are

     CC
          The choice of C compiler

     CFLAGS
          The choice of flags to pass to the C compiler

     prefix
          The parent directory where the binaries and documentation will be installed. You'd normally set this to /usr/local or /usr, unless you use a stow or stow-like approach, or are building a distribution package.

     INC_READLINE
          If you want readline support in the interactive mode (highly recommended), uncomment the appropriate line in the Makefile, and if necessary edit the path for the include directory where readline.h and history.h can be found.  Note that a readline subdirectory is assumed to be suffixed onto whatever path you define.

     LIB_READLINE
          Likewise, edit the path for the directory where libreadline and libhistory can be found.

 3. Compile the sources

          make

 4. Install the software

          make install

 5. (Optional) Build the documentation

     This assumes you have the makeinfo and tex tools on your path.

          make docs

 6. (Optional) Install the documentation

     Currently, there are no Makefile targets for this.  Pick the documentation formats you want to keep and install them manually to the appropriate places.

Notes for package builders
==========================

For building a Slackware package, you could follow the steps above except for the installation

     vi Makefile
     make
     make docs
     mkdir pkg
     make install DESTDIR=./pkg
     (copy appropriate docs into subdirectories of pkg)
     cd pkg
     makepkg tdl.tgz

Packagers for other distributions may be able to adapt this.  (The point the example is making is that Makefile contains support for using a variable DESTDIR in this way.)

An example spec file for RedHat packaging is in the file tdl.spec.sample.

Usage
*****

This section contains examples of using tdl.

Getting started
===============

This section shows how you can get started with tdl.

Let's assume you have a working directory for a project, and you want to maintain a to-do list for things you need to do on that project.  Let's assume the working directory for the project is /home/foobar/myproject.  Then you'd start by entering the following commands into your shell:

     % cd /home/foobar/myproject
     % tdl create

Now, lets say you have some tasks to keep track of:

     % tdl
     tdl> add "Write user guide"
     tdl> add "Write release notes"
     tdl> add "Fix bug where empty data file causes core dump"
     tdl> exit
     %

The above sequence will add 3 tasks to your newly created database.  A few days later, you might come back to the project and think "Hmmm.  What did I need to do next?"  You can enter

     % tdl list
     1 Write user guide
     2 Write release notes
     3 Fix bug where empty data file causes core dump
     %

This shows another feature of tdl.  If you pass a sub-command (and its arguments, if any) on the tdl command line, tdl will execute just that command, and return you to your shell prompt.  However, if you run tdl with no arguments, it will go into its interactive mode.  For a single command like list in this situation, you'd probably find the direct method quicker.

Suppose you fix the bug.  Then you could enter

     % tdl done 3

after which the list command would only show the first two tasks as still being open, like this:

     % tdl list
     1 Write user guide
     2 Write release notes
     %

The add, list and done commands may be all that you need in some cases.  However, another useful command is report, which will summarise all the tasks you completed in a given period.  For example, you could list everything you completed in the last 7 days like this

     % tdl report 7d
     - Fix bug where empty data file causes core dump
     %

The other commands in tdl are mostly to do with changing the order of tasks in the database, assigning them priorities, and so on.

Reference
*********

Starting and exiting tdl
========================

tdl has a set of functions that can be accessed in two different ways:

  * Directly from the command line

  * Interactively

In the 'direct' method, the function and its arguments are provided on the command line.  This mode is useful if you only want to perform a single operation.  An example

     % tdl add "A task"
     %

The 'interactive' method is entered when the tdl command is run with no arguments.  In this mode, many tdl operations may be performed within a single run of the program.  This avoids loading and saving the database for each operation, which may have a small performance benefit.  However, if the program is compiled with the readline library, the tab key will provide various completion functions.  An example

     % tdl
     tdl> add "A task"
     tdl> exit
     %

When in interactive mode, these methods can be used to exit and return to the shell:

  * The exit command (see exit command)

  * Hitting Ctrl-D (i.e. end of file on stdin)

  * Hitting Ctrl-C, Ctrl-\ etc.  The associated signals are caught by tdl and it will attempt to save the database.  However, this method is more risky than the first two.

  * The quit command (see quit command).  Caution: this does not save the modified database back to the disk.  Only use it if you want to discard all changes made in this tdl run.

Command line flags
==================

Quiet mode
----------

If the -q flag is specified, various warning and informational messages will be suppressed.

     % tdl -q list

Read-only mode
--------------

If the -R flag is specified, the database will be opened in read-only mode.  In this case, the database will not be locked, and all commands that modify the database will be barred.

This flag can be used together with the -q flag if required.

     % tdl -R list
     % tdl -qR list

Forced unlock
-------------

If the -u flag is specified, the database's lockfile will be removed if it is found.  This is mainly intended for use when an earlier run has left the database locked after a crash.

Care shoule be taken that the database is not currently being accessed by a live process, otherwise updates could be lost by one or other of the processes.

     % tdl -u list

Node specification
==================

Many commands in tdl require you to refer to an existing entry, for example

  * to add a child entry to an existing entry

  * to mark an entry as being done

  * and so on

There are two ways you can refer to existing nodes

  * by the numeric path (as shown by tdl list).

  * by negative numeric path (which is used to refer to a node counted from the end of its parent)

  * by the start of the node's text, as long as enough is specified to identify the node unambiguously amongst its peers.  In this case, the node must be preceded by a single '.' for many commands.

For example, if the database contains

     tdl> list
     1 foo
        1.1 aaa
        1.2 bbb
     2 fee
        2.1 ccc
        2.2 ddd
     3 bar
        3.1 eee
        3.2 fff

then tdl list 1 will show

     tdl> list
     1 foo
        1.1 aaa
        1.2 bbb

and tdl list .fe will show

     .fe fee
        .fe.1 ccc
        .fe.2 ddd

tdl list .f will fail since it is ambiguous which node (1 or 2) is being referenced.

tdl list -- -1 will show

     -1 bar
        -1.1 eee
        -1.2 fff

(note that tdl list -1 has a different meaning (show 1 level and summarise subordinate levels), and shows

     1 [2/2] foo
     2 [2/2] fee
     3 [2/2] bar

Alphabetical list of all commands
=================================

This section describes each of the tdl subcommands.

above command
-------------

The above command is one of the commands used for re-ordering the entries in the database.  The above and before commands are synonymous.

The arguments of the above comamnd are:

     tdl> above <index_to_insert_above> <index_to_move> ...

The first argument is the index of the entry above which the other entries are to be moved.  The entries corresponding the 2nd index onwards will be placed in argument order above the first entry.

An example:

     tdl> list
     1 Task A
     2 Task B
     3 Task C
     4 Task D
     tdl> above 1 2 4 3
     tdl> list
     1 Task B
     2 Task D
     3 Task C
     4 Task A
     tdl>

You can move entries between levels in the hierarchy, with the restriction that you cannot move a node so that its new parent would be a descendent of itself.

If you want to move entries to the end of the list (i.e. above the bottom of the list), you can use a zero as the index of the reference entry, for example

     tdl> list
     1 Task A
        1.1 Task A_A
        1.2 Task A_B
     2 Task B
     3 Task C
     tdl> above 1.0 3 2
     tdl> list
     1 Task A
        1.1 Task A_A
        1.2 Task A_A
        1.3 Task C
        1.4 Task B
     tdl>

add command
-----------

The add command is run as follows

     tdl> add [@datespec] [parent-index] [priority] "Text for node"

In the simplest case of adding a new top-level entry to the database, with normal priority, starting now, this could be

     tdl> add "Wash the dog"

In a more complex case, to add a high priority entry underneath entry index 1, with the new entry coming live at 11a.m. next Friday, this would be

     tdl> add @+fri-11 1 hi "Wash the dog"

If you have several entries to add at once, you can go into an add mode. Enter a blank line to get back to the tdl> prompt.

     tdl> add
     add> Wash the dog
     add> Wash the car
     add>
     tdl>

To add an entry direct from your shell, there is an additional shortcut (assuming the appropriate symbolic link was created during the installation process):

     % tdla "Wash the dog"
     %

after command
-------------

The after and below commands are synonymous.  See the description of below (see below command).

before command
--------------

The above and before commands are synonymous.  See the description of above (see above command).

below command
-------------

The below command is one of the commands used for re-ordering the entries in the database.  The below and after commands are synonymous.

The arguments of the below command are:

     tdl> below <index_to_insert_below> <index_to_move> ...

The first argument is the index of the entry below which the other entries are to be moved.  The entries corresponding the 2nd index onwards will be placed in argument order above the first entry.

An example:

     tdl> list
     1 Task A
     2 Task B
     3 Task C
     4 Task D
     tdl> below 4 2 1 3
     tdl> list
     1 Task D
     2 Task B
     3 Task A
     4 Task C
     tdl>

You can move entries between levels in the hierarchy, with the restriction that you cannot move a node so that its new parent would be a descendent of itself. This is similar to the description for the above command (see above command).

clone command
-------------

The clone command can be used to make a deep copy of one or more entries and add them as new top-level entries in the database.  You might use this if you have a task with a set of subtasks, and find that the same subtasks apply to some new task.  You could copy the first task, and edit the new top-level task to change its text.

The arguments of the clone command are:

     tdl> clone <index_to_clone> ...

An example is:

     tdl> list
     1 Wash things
       1.1 Car
       1.2 Dog
     tdl> clone 1
     tdl> edit 2 "Polish things"
     tdl> list
     1 Wash things
       1.1 Car
       1.2 Dog
     2 Polish things
       2.1 Car
       2.2 Dog

If you want the cloned entries to be children of an existing entry, use the copyto command (see copyto command).

copyto command
--------------

The copyto command is very similar to the clone command (see clone command).  The difference is that copyto inserts the newly created entries as children of an existing entry, rather than making them new top level entries.

The arguments of the copyto command are:

     tdl> copyto <new_parent_index> <index_to_clone> ...

An example is:

     tdl> list
     1 Household jobs
       1.1 Wash things
         1.1.1 Car
         1.1.2 Dog
     tdl> copyto 1 1.1
     tdl> edit 1.2 "Polish things"

create command
--------------

The create command can only be used direct from the shell command line.  It is not supported when tdl is used in its interactive mode. (This is to avoid confusion over which database file is being accessed if create were used after other commands had already been used in the same session.)

Usually, the create command will create a new .tdldb file in the current directory.  However, if the TDL_DATABASE environment variable is set when tdl is run, the path specified by that variable will be used instead and the database will be created there.  In both cases, the create command will refuse to over-write an existing database; an error message will be generated if that is attempted.

     % tdl create

defer command
-------------

The defer command is used to modify the start-time of one or more existing entries.  Its argument structure is

     tdl> defer @<datespec> <entry_index>[...] ...

where the @ on the datespec is optional because the argument is required, although the @ can be included for consistency with other commands where a datespec is optional.

An example of use is

     tdl> defer @+fri 1 2.1... 5

which defers entries 1, 2.1 and all its children, and 5 until the following Friday.

To list deferred entries, use list -p.

To defer entries indefinitely, see postpone command.

To re-activate deferred or postponed entries, see open command.

delete command
--------------

This command is synonymous with the remove command (see remove command).

The argument structure is

     delete <entry_index>[...] ...

done command
------------

The done command is run as follows

     done [@<datespec>] <entry_index>[...] ...

The done command is used to mark one or more tasks as completed.  Any number of task indices may be specified.

The effects are as follows:

  * The entries no longer appear on the default listing (produced by the list command without the -a option).

  * The entries are eligible to appear on the report list (see report command)

  * The entries are eligible for removal by the purge command (see purge command)

If the string "..." is appended to an index, it means that entry and all its descendents.  This provides a quick way to mark a whole sub-tree of tasks as being completed.

No entry may be marked 'done' if it has any children that are still 'open' (i.e. not marked 'done').  (The ... form of the command marks the deepest entries first to bypass this.)

edit command
------------

The edit command is used to modify the text of an existing entry. Its argument structure is

     tdl> edit <entry_index> [<new_text>]

A single <entry-index> must be given.  If <new-text> is provided, this replaces the text describing the specified entry.  If no <new-text> is provided, you will be prompted with the old text to edit interactively.  (This is only useful if the GNU readline library has been linked in.)

An examples follows.

To change the text for the entry with index 1,

     tdl> edit 1 "New description"

     tdl> list
     1 Wash the dog
     tdl> edit 1
     edit (1)> Wash the dog   (edit 'dog' to 'cat')
     tdl> list
     1 Wash the cat
     tdl>

(Note, in earlier versions, edit could be used to change the start-time of one or more entries.  This is now handled by the defer command (see defer command).)

exit command
------------

The exit command is used to exit from tdl when it is used in interactive mode.  The exit command is not available in the command line mode, where it would not make sense.  An example:

     tdl> exit
     %

The exit command writes any pending updates to the database before exiting.  (Compare the quit command (see quit command), which loses all updates made during the current tdl run.)

export command
--------------

The export command is run as follows

     export <filename> <entry_index> ...

It is used to export one or more tasks (and their subtasks) to another tdl database file.  Perhaps you were keeping all your projects' to-do lists in one combined file, and decide you want to separate the list for a particular project.

An example would be

     tdl> list
     1 Tasks for project X
     2 Tasks for project Y
        2.1 Write manual
        2.2 Write release notes
     tdl> export /home/foobar/project_y/.tdldb 2.1 2.2
     tdl> remove 2...
     tdl> exit

help command
------------

The help command displays help information.  When run without arguments, a list of valid commands is produced.  Note, this list is slightly different depending on whether the help command is used through the interactive readline interface or straight from the shell.

     tdl> help
     tdl, Copyright (C) 2001-2004 Richard P. Curnow
     tdl comes with ABSOLUTELY NO WARRANTY.
     This is free software, and you are welcome to redistribute it
     under certain conditions; see the GNU General Public License for details.

     above    : Move entries above (before) another entry
     add      : Add a new entry to the database
     after    : Move entries after (below) another entry
     below    : Move entries below (after) another entry
     before   : Move entries before (above) another entry
     done     : Mark 1 or more entries as done
     edit     : Change the text and/or start time of an entry
     exit     : Exit program, saving database
     export   : Export entries to another database
     help     : Display help information
     import   : Import entries from another database
     into     : Move entries to end of new parent
     list     : List entries in database (default from top node)
     log      : Add a new entry to the database, mark it done as well
     priority : Change the priority of 1 or more entries
     purge    : Remove old done entries in subtrees
     quit     : Exit program, NOT saving database
     remove   : Remove 1 or more entries from the database
     report   : Report completed tasks in interval
     undo     : Mark 1 or more entries as not done (cancel effect of 'done')
     usage    : Display help information
     version  : Display program version
     which    : Display filename of database being used

     Enter 'help <command-name>' for more help on a particular command

     tdl>

If the help command is passed the name of a sub-command, it shows help for that command.

     tdl> help add
     Description
       Add a new entry to the database

     Synopsis
       add [@<datespec>] [<parent_index>] [<priority>] <entry_text>

     <index>    : 1, 1.1 etc (see output of 'tdl list')
     <priority> : urgent|high|normal|low|verylow
     <datespec> : [-|+][0-9]+[shdwmy][-hh[mm[ss]]]  OR
                  [-|+](sun|mon|tue|wed|thu|fri|sat)[-hh[mm[ss]]] OR
                  [[[cc]yy]mm]dd[-hh[mm[ss]]]
     <text>     : Any text (you'll need to quote it if >1 word)

     tdl>

The help command is synonymous with the usage command.

ignore command
--------------

The ignore command puts one or more entries into an ignored state.  It is actually implemented in the same way as marking them as done, but as though they were done a very long time ago.  Thus, ignored entries will be deleted by any subsequent purge operation.

I added this feature because, when applying remove to several entries, I kept getting tripped up by the indices changing below the entry that was removed (I kept removing the wrong entries later by not using the revised indices).  Instead, I can ignore them and rely on a periodic purge to clean up the database.

Another use for the ignore command would be to move moribund entries into a wastebasket to stop them cluttering up the normal listing, but without removing them entirely in case you need to reprieve them later.

The ignore command is run as follows

     ignore <entry_index>[...] ...

An example is

     ignore 20 21.6.3 25... 28.1

If you need to un-ignore an entry, just undo it (see undo command).

import command
--------------

The import command is used as follows:

     import <filename>

This command is used to merge entries from the TDL database filename into the default database (i.e. the one that most of the other commands would be accessing).

You might use this command if you had a number of separate TDL databases, and wanted to merge their entries to form one combo database.

into command
------------

The into command is used to make one or more entries into sub-entries of another entry.  Its usage is

     into <new_parent_index> <index_to_move> ...

The following example shows it use

     tdl> list
     1 Task A
     2 Task B
     3 Task C
     4 Task D
     tdl> into 1 3 2
     tdl> list
     1 Task A
        1.1 Task C
        1.2 Task B
     2 Task D
     tdl>

The into command is closely related to above, after, before and below.  In fact the following three commands are equivalent

     tdl> into N <indices> ...
     and
     tdl> above N.0 <indices> ...
     and
     tdl> before N.0 <indices> ...

list command
------------

The list command is used to display the tasks in the database.  Its argument structure is:

     list [-v] [-a] [-m] [-p] [-1..9]
          [<min-priority>]
          [<parent_index>|<search_condition>...]

When run with no arguments, the list contains all tasks that are

  * not marked 'done', 'ignored', 'deferred' or 'postponed',

  * at any levels of the database (i.e. any number of components in the task's index), and

  * of priority normal or higher.

The arguments have the following functions:

-v
     This stands for verbose.  It means that more information will be shown for each task.

-a
     This stands for all.  It means that tasks which are 'done', or which are 'deferred' or 'postponed' (by having arrival times in the future), will be shown as well as open tasks.

-p
     This stands for postponed.  It means that tasks which are 'deferred' or 'postponed' are shown as well as open tasks.

-m
     This stands for monochrome.  Normally, ANSI escape sequences are inserted to show the list with colour coding.  This flag stops these sequences being generated.

     If you always want this option, set the TDL_LIST_MONOCHROME environment variable to any value.  If this variable exists, a monochrome listing will be generated.

-1, -2, ..., -9
     These options restrict the depth of the tree which is generated.  For example, with the -1 argument, only the first-level entries in the database are shown.  Sub-entries of these are shown by summary totals.  See below for an example.

<min-priority>
     Normally (at least, if no indices are specified), only tasks with a priority of at least normal are shown in the list.  If you specify this option, tasks of at least the specified priority are shown.  The values you can use are urgent, high, normal, low or verylow.  Each can be abbreviated to just its initial letter.

<parent_index...>
     If you want to list just part of the database, you can specify the indices of the leading entries for the parts you want to see.  Any number of entries can be included (you could even include an index twice if you wanted to for some reason.)

     When you specify indices, the behaviour regarding priority changes.  If no <min-priority> argument was given, the priority of a sub-entry must be at least that of the entry with the given index for it to be shown.  This is most useful when the entire sub-tree has a lower than normal priority.

     If you use the -1 ... -9 options with this option, the depth is counted relative to the depth of the indexed node that you specify.

<search_condition>
     Each search condition specifies a case-insensitive substring match that is applied to all parent indices further on in the arguments.  (If no parent indices are given, all the search conditions are and'ed together and applied to filter all the nodes that would be shown according to the depth, priority etc arguments).

     Each search condition takes one of the following forms

          /substring
          /substring/1

     In each case, an entry will match if substring is actually a substring of the text of that entry.  In the second form (where the number may be 0, 1, 2 or 3), a match occurs if there are up to that many errors in the substring.  An error is a single character inserted, removed or changed.

     This option is most useful if you have a large database and can remember you have an entry somewhere containing particular word(s), but can't remember where it is.

     If you need regular expression matching, the best approach would be to run tdll from the shell and pipe the output to grep.  The internal matching does approximate matches with keys up to 31 characters.

The command is best illustrated by examples.  Suppose the database contains these entries

     1 bibble
        1.1 zzzz
           1.1.1 (DONE) yyyy
           1.1.2 wwww
     2 wibble
        2.1 xxxx
     3 wubble

where wibble and xxxx have priority low.  The following examples show the list command's behaviour.

     tdl> list
     1 bibble
        1.1 zzzz
           1.1.2 wwww
     3 wubble

(Entry 2 and its child are omitted due to priority.  Entry 1.1.1 is omitted because it is done.)

     1 bibble
        1.1 zzzz
           1.1.1 (DONE) yyyy
           1.1.2 wwww
     2 wibble
        2.1 xxxx
     3 wubble

(Passing these arguments shows the missing entries)

     tdl> list -1
     1 [1/1] bibble
     3 wubble

(The list is limited to top level entries.  The [1/1] indices that entry 1 has 1 open child out of a total of 1 children.)

     tdl> list -1 1.1
     1.1 [1/2] zzzz

(This lists the 1.1 subtree, showing that there is 1 open child out of a total of 2 children.)

     tdl> list /ww
           1.1.2 wwww
     tdl> list /ww/1
           1.1.2 wwww
     3 wubble
     tdl>

(In the first case the substring ww must occur exactly in the entry's text.  In the second case, the string wu in wubble matches ww with a single error so a match occurs.)

ls command
----------

This is synonymous with the list command (see list command).  It is provided for people who are too used to typing ls in their shell.

log command
-----------

The log command is very similar to the add command, except that it immediately marks the new entry as done.It is the equivalent of using add followed by done on the new entry.  It is run as follows:

     log [@<datespec>] [<parent_index>] [<priority>] <entry_text>

You might use the log command if complete a new task immediately but want to make sure you log it for use in producing your weekly report (using the report command, see report command.)

If you have several entries to add at once, you can go into an log mode. Enter a blank line to get back to the tdl> prompt.

     tdl> log
     log> Wash the dog
     log> Wash the car
     log>
     tdl>

To add an entry direct from your shell, there is an additional shortcut (assuming the appropriate symbolic link was created during the installation process):

     % tdlg "Wash the dog"
     %

(the ending g on the shortcut was chosen as the final letter of the word log.  The shortcut tdll was already allocated for the list subcommand.)

moveto command
--------------

The moveto and into commands are synonymous.  See the description of into (see into command).

narrow command
--------------

The narrow command can be used to limit the effects of later commands to operate within a particular sub-tree of your database.  Because the indices you specify for the later operations have the common prefix omitted, this can save typing if you have many changes to make within the same subtree.

The usage of the narrow command is

     narrow <new_root_index>

The following example illustrates:

     tdl> add a
     tdl> add b
     tdl> add -1 c
     tdl> add -1 d
     tdl> add -1 e
     tdl> list
     1 a
     2 b
        2.1 c
        2.2 d
        2.3 e
     tdl> narrow 2
     tdl[2]> list
     2 b
     2.1 c
     2.2 d
     2.3 e
     tdl[2]> done 1 2
     tdl[2]> list
     2 b
     2.3 e
     tdl[2]> widen
     tdl>

If your listings are in colour, the common prefix is coloured in blue whilst the paths below the root of the sub-tree are shown in the usual green.  (In monochrome mode, there is no distinction.)

Whilst your view is narrowed, the index of the sub-tree root is shown in square brackets between tdl and > (i.e. [2] in the example above).

If you want to operate on the sub-tree root entry itself whilst you are narrowed, you can use . to specify its index (think: current directory in Unix.)

To reverse the effects of the narrow command, use the widen command (see widen command).

This command is only available when tdl is being run interactively, i.e. when you have a tdl prompt.  It is not available directly from the shell (where it wouldn't make much sense).

open command
------------

The open command is used to reverse the effect of the defer command (see defer command) and postpone command (see postpone command).  Its effect is actually to set the arrival time of the entries to the current time.

The open command is used as follows

     open <index_to_reopen>[...] ...

An example is

     open 20 21... 25.2

postpone command
----------------

The postpone command is used to make 1 more more entries postponed indefinitely.  Its effect is actually to set the arrival time of the entries a long way in the future (i.e. it's an extreme form of the 'deferred' feature available in the add and defer commands.) Postponed entries can be re-activated with the open command (see open command).

The postpone command is used as follows

     postpone <index_to_postpone>[...] ...

An example is

     postpone 20 21... 25.2

To postpone an entry until a specific time in the future, use the defer command (see defer command).

priority command
----------------

The priority command is used to modify the priority of one or more entries.  Its argument structure is

     priority <new_priority> <entry_index>[...] ...

The new_priority argument is the new priority to be assigned.  The values you can use are urgent, high, normal, low or verylow.  Each can be abbreviated to just its initial letter.

You can specify at least one entry_index.  If an index is followed by ..., the whole sub-tree under the referenced entry will be modified too. For example,

     tdl> priority high 2 4.1...

will modify the priority of entry 2, entry 4.1, and all the entries under 4.1, to high.

purge command
-------------

The purge command is used to remove outdated done tasks from the database.  For example, you might want to automatically remove everything you completed more than 2 months ago.

Its argument structure is

     purge <since_datespec> [<ancestor_index> ...]

The since_datespec argument specifies a date.  All entries which were marked 'done' before this date will be completely removed from the database.

The default is to scan the entire database for done tasks that meet the date constraint.  You may specify one or more indices to limit the behaviour.  In this case, only the sub-trees headed by these indices will be considered for purge.

An example:

     tdl> purge -2m 3.1 5

will purge all entries underneath entries 3.1 and 5 which were marked 'done' more than 2 months ago.

quit command
------------

The quit command is used to exit from tdl when it is used in interactive mode.  The quit command is not available in the command line mode, where it would not make sense.  An example

     tdl> quit
     %

The quit command DOES NOT write any pending updates to the database before exiting.  (Compare the exit command (see exit command), which does write all updates made during the current tdl run.)

The main use for the quit command would be to avoid damaging the database if a serious error had been made.

remove command
--------------

The remove command is used to remove entries from the database.  It differs from purge see purge command in that there is no date constraint, and entries do not have to be marked 'done' to be removed.  You might use remove if an open tasks no longer needs to be performed.

The argument structure is

     remove <entry_index>[...] ...

You can specify one or more entry indices to remove.  If an index is followed by ..., tdl will remove the whole sub-tree based at that index.

You cannot remove an entry that has sub-entries below it.  (The ... handling for indices removes the deepest entries first to bypass this.)

An example:

     tdl> remove 1.5.4 19... 20

will remove entries 1.5.4 and 20, as well as everything whose index starts with 19.

The remove command acts immediately to remove the specified entries from the database.  A less aggressive command with similar effects is ignore (see ignore command).

The delete command (see delete command) is provided as a synonmym for the remove command.

report command
--------------

The report command is used to show entries that were marked 'done' within a specific time interval.  Its argument structure is

     report <start_datespec> [<end_datespec>]

One or two date specifications may be given.  If only the start_datespec is provided, the end_datespec defaults to the present time.  The format of both arguments is described separately.  See Datespec.

For example, suppose you have to write a report on what you have done in the last week.  You could use

     tdl> report 1w

The report is produced in a tree structure, mirroring the database structure. Entries which have 'done' children, but which haven't themselves been marked done, have their text surrounded by [[ and ]].  For example

     tdl> list -a
     1 bibble
        1.1 zzzz
           1.1.1 (DONE) yyyy
           1.1.2 wwww
     2 wibble
        2.1 xxxx
     tdl> report 1w
     - [[bibble]]
        - [[zzzz]]
           - yyyy

You could cut-and-paste this text into your report, as a starting point that you can reformat into a report.  Alternatively, if you run the command direct from the shell prompt line, you can redirect the output to a file,

     % tdl report 1w > report.txt
     %

revert command
--------------

The revert command discards any changes made in the session and reloads the in-memory database from disc.  If you have used the save command (see save command) in the session, the database will revert to its state at the most recent save.  Otherwise it will revert to its state when tdl was initially run.

The revert command does not take any arguments.

save command
------------

The save command can be used to write the current in-memory database out to the disc database file.  The behaviour is currently equivalent to the command exit followed by re-running tdl from the shell.

This command is useful if you tend to do long interactive tdl sessions.  It guards against the risks of

 1. accidentally typing quit when you meant exit

 2. machine crashes

 3. running tdl in another window and seeing a stale copy of the database file.

The save command does not take any arguments.

undo command
------------

The undo command reverses the action of the done command see done command.  You can use it to re-open entries, e.g. if you marked them 'done' by mistake.

Its argument structure is

     undo <entry_index>[...] ...

You can specify one or more indices to act on.  If an index is suffixed by ..., tdl will re-open the entire sub-tree based at that index.

usage command
-------------

The usage command is synonymous with the help command. See help command.

version command
---------------

The version command shows the program version.

     tdl> version
     tdl V1.1
     tdl>

which command
-------------

The which command displays the name of the current database file that tdl is using.  An example:

     tdl> which
     ./.tdldb
     tdl>

widen command
-------------

This command reverses the effects of the narrow command (see narrow command).

Its usage is:

     tdl> widen [<n_levels>]

The optional n_levels parameter tells tdl how many levels to widen the view.  If the parameter is not specified, it defaults to 1.  If you try to widen more levels than the depth of the current sub-tree root node, the widening will be silently limited to its depth.

This command is only available when tdl is being run interactively, i.e. when you have a tdl prompt.  It is not available directly from the shell (where it wouldn't make much sense).

Shortcut forms of certain commands
==================================

For convenience, several shortcut commands are provided to access the most common tdl operations.  (These can be used from the shell command line.)

tdla
     This is a shortcut for tdl add, e.g.

          % tdla "A new item"

tdld
     This is a shortcut for tdl delete.

tdlg
     This is a shortcut for tdl log.

tdll
     This is a shortcut for tdl list.

tdls
     This is another shortcut for tdl list.

Interrupting
============

Most programs will stop where they are if you hit Ctrl-C.  This is also true (normally) for tdl.  However, tdl intercepts signals like this so that it can try to write out the database when it is safe to do so.  This avoids the loss of updates made to the database during the current session.

Because of this approach, it is possible that tdl can get stuck in an endless loop if a bug arises.  For this reason, tdl will exit forcibly if Ctrl-C is pressed 4 times.  After the third press, a warning message is printed.

If tdl has to be terminated in this way, the database will not be written back out.  Therefore, any edits made in the current session will be lost.  Also, a stale lock file will be left behind.  The -u command line flag should be used on the next run of tdl to force the removal of this stale lock file.

How tdl finds the databse file to use
=====================================

If the TDL_DATABASE environment variable is set, its value is taken to be the name of the database to use.  This allows for two distinct modes of use:

  * If you set TDL_DATABASE to a fixed filename (with a full path), you can use a single database regardless of your current working directory.

  * If you set TDL_DATABASE to a relative path (e.g. ./.tdldb), you will always use a database in the current working directory.

If this environment variable is not set, tdl finds the database by searching up through the directory tree until it finds a file called .tdldb.  The idea is to allow for one database per project, by placing the database in the parent directory of the project.  Then as long as your current working directory is anywhere within the project tree, the database will be found during the search.

The only exception to this is the create command, which always operates in the current directory (unless TDL_DATABASE is set, in which case this variable's value defines the path to use.)

If you wish to share databases between directory trees in some other way, the recommended method is to use symbolic (or hard) links to make a single database appear to be in more than one directory.

Completion facilities
=====================

When tdl has been compiled to use the readline library, the interactive mode supports a number of completion functions, activated with the tab key.

In particular, the following are supported:

  * Command completion.  If tab is pressed when the command line is empty, a list of possible commands will be shown.  If tab is pressed when a partial command has been typed, the command will be completed immediately if possible, otherwise a list of commands matching the already-typed prefix will be shown.

  * Help completion.  If help or usage is already in the buffer, a list of commands will be shown(as above).  The tab completion works in the same way to complete the name of the command you want a help summary for.

  * Priority completion.  If list or priority is at the start of the input buffer and the current word starts with a letter, tdl will try to complete the name of a priority level if tab is pressed.

  * Open task completion.  If done is at the start of the input buffer, hitting tab will show a list of task indices that are still open.  If part of an index has already been typed, the open task indices for which the typed characters are a prefix will be shown.

  * Postpone completion.  If postpone is at the start of the input buffer, hitting tab will show a list of tasks that may be postponed.  Tasks marked done are excluded.  If open is at the start of the input buffer, hitting tab will show a list of tasks that may be opened.

  * Parameter hints.  If some other command is at the start of the input buffer and tab is pressed, tdl will show a one-line summary of that command's parameters.

How dates are specified
=======================

Date specification   Meaning
-1h   exactly 1 hour ago
-2d   exactly 2 days ago
+1w   exactly 1 week in the future
+1m   exactly 1 month (30 days) in the future
+2y   exactly 2 years in the future
-1d-0815   08:15am yesterday
+1d-08   8am tomorrow
+1w-08   8am on the same day as today next week
+6h-08   8am on the day containing the time 6 hours ahead of now
.-08   8am today
.-20   8pm today
20011020   absolute : 12 noon on 20th October 2001
011020   absolute : 12 noon on 20th October 2001 (current century)
1020   absolute : 12 noon on 20th October 2001 (current century and year)
20   absolute : 12 noon on 20th October 2001 (current century, year and month)
20011020-081500   absolute : 08:15am on 20th October 2001
20011020-0815   absolute : 08:15am on 20th October 2001 (seconds=0)
20011020-08   absolute : 08:00am on 20th October 2001 (minutes=seconds=0)
011020-08   absolute : 08:00am on 20th October 2001 (minutes=seconds=0, current century)
etc   (see below)
-sun   12 noon on the previous Sunday
+sat   12 noon on the following Saturday
+sat-08   8am on the following Saturday
-tue-0815   08:15am on the previous Tuesday
etc   (see below)

In the 'all-numeric' format, the rule is that dates can have fields omitted from the start (assumed to be the current value), and times can have fields omitted from the end (assumed to be zero, except if the hours figure is missing it is assumed to be 12, since most work is done in the day.)

In the 'weekday and time' format, the time rule is the same: missing minutes and seconds are taken as zero and missing hours as 12.  If the weekday is the same as today, the offset is always 7 days in the required direction.  If the weekday is not the same as today, the offset will always be less than 7 days in the required direction.

In the 'relative' format, when a time is included as well, the procedure is as follows.  First the time is determined which is the given number of hours, days etc away from the current time.  Then the specified time on that day is used. The main use for this is to specify times like '8am yesterday'.  Obviously some of the possible uses of this mode are rather far-fetched.

For the weekday and relative formats, the sign is actually optional.  The default sign (implying past (-) or future (+)) will then be assumed depending on the command as shown below:

Command   Default   Reason
add   +   Add entries with deferred start times
edit   +   Add entries with deferred start times
defer   +   Modify start times of entries
done   -   Entries have been completed at some time in the past
log   -   Entries have been completed at some time in the past
report   -   Reporting on earlier completed tasks not future ones
purge   -   Tasks won't be completed in the future, so no need to purge future ones

How tdl saves a backup copy of the database
===========================================

Whenever tdl writes a modified database to disk, it renames the previous database by adding .bak on the end of the filename.  Thus .tdldb is renamed to .tdldb.bak.

If you need to restore the previous .tdldb for any reason (e.g. a gross mistake during editing, or if a bug causes it to be corrupted), you can manually rename .tdldb.bak to .tdldb.

Index specification
===================

Indices may usually be specified as negative values.  This counts from the end of the list.  The commonest use for this is to add children to an entry you've just typed, e.g.

     tdl> add "Parent entry"
     tdl> add -1 "Child entry"
     tdl> add -1 "Child entry"
     tdl> add -1.-1 "Grandchild entry"

There is one example where negative indices are not handled in the usual way. This is with the list command (see list command).  Here, a negative index could be misinterpreted as a depth option.  If you really want negative indices for the list command, terminate the options with -- before providing indices and search patterns.