Using devtodo with multiple projects
I’ve tried (and failed) to use many different pieces of software designed to manage todo lists. The main reasons I’ve failed is because the software either has a high learning curve, bad documentation, or it is cumbersome to use.
I’ve finally struck gold with devtodo. Out of the box, it is almost perfect, but there are a few little issues:
- It expects .todo in the current directory
- It has no ability to track what you are working on.
I’ve managed to work around both of those with some extra functions in my .bash_profile.
Where is my .todo?
I wanted a git-like approach to my todo list. If there is not one in the current directory, check the parent, the grandparent, etc. Eventually, fall-back to ‘Global’ todo list in ${HOME}.
Note: This depends on the rfind function in my previous post.
First, create a function to set the TODO_FILE variable. We’re going to set TASK_FILE here as well, this is referenced further down the page.
set_nearest_todo_file()
{
ntdf_file=$( rfind -name .todo -type f )
if [[ -z "${ntdf_file}" ]]; then
ntdf_file="${HOME}/.todo"
fi
TODO_FILE="${ntdf_file}"
}
set_nearest_task_file()
{
TASK_FILE="${TODO_FILE}-current"
}
Now, we need to call these on cd, pushd, and popd, as well as when the shell is sourced.
cd()
{
if builtin cd "$@"; then
set_nearest_todo_file
set_nearest_task_file
fi
}
pushd()
{
if builtin pushd "$@"; then
set_nearest_todo_file
set_nearest_task_file
fi
}
popd()
{
if builtin popd "$@"; then
set_nearest_todo_file
set_nearest_task_file
fi
}
set_nearest_todo_file
set_nearest_task_file
Next, lets make an alias for td
to call devtodo with our desired
todo_file
td()
{
# Don't print DB notice for .todo in current dir
if [[ "${TODO_FILE}" != "./.todo" ]]; then
# Output DB notice to stderr.
# so we don't mess with output parsers
echo "Using database ${TODO_FILE}" 1>&2
fi
# Specify found DB
devtodo --database ${TODO_FILE} $@
}
Now, when we call td
, we will be referencing the nearest TODO_FILE,
either in the current directory, one of it’s parents, or falling back to
${HOME}.
What am I working on?
This was simple enough. devtodo has aliases for todo (devtodo), tda
(todo –add) and tdd (todo –done). We also added td
above. I’m going
to hijack tdd, and add a new ’t’ command to set a current task.
We already added the neccessary parts to get TASK_FILE above. Now we’re just going to create a function to set a task in that file.
t()
{
if [[ "$*" == "" ]] ; then
if [[ -f "${TASK_FILE}" ]]; then
cat ${TASK_FILE}
fi
else
td $@ | tee ${TASK_FILE}
fi
}
You’ll notice that if we call t
with a parameter, such as t 6
, it
run td 6
, instruct td to show task 6, and copy that output to your
TASK_FILE.
If we simply call t
, it will cat out our TASK_FILE to the screen.
I’ve also hijacked tdd
, the devtodo ‘done’ alias, to clear my
TASK_FILE as well.
tdd()
{
/usr/bin/tdd $@
rm ${TASK_FILE}
}
My workflow
I find this very easy to manage. td
to review my list, t #
to select
my active task, and t
while I’m working to be reminded what I’m doing.
The task number is still in the output of t
. When I’m done, tdd #
marks that task as complete, removes TASK_FILE, and I’m free to start
another task.