My Personal Task Manager
I’ve tried dozens of productivity and task mangement software but nothing’s stuck. I keep returning to handwritten lists desperately wishing for a digital solution that works for me. So I decided to build one myself.
I wanted to:
- minimize context switching required to edit/add tasks
- mimic the experience of using pen and paper as much as possible
- take no more than 30 minutes to write the first version.
My Task Manager
I wrote two shell commands: l(ong)t(ask)
, and, s(hort)t(ask)
:
- All arguments to
lt
andst
are appended to thelong-tasks.md
andshort-tasks.md
file respectively. - Executing
lt
orst
without any arguments shows the first 10 lines fromlong-tasks.md
orshort-tasks.md
respectively. - Executing
t(asks)
shows the first 10 lines from bothlong-tasks.md
andshort-tasks.md
Source
The core of my task manager is a simple function w(rite)t(ask)
that takes a filename and the task as arguments.
wt() {
file="$1"
if [ ! -f "$file" ]; then
touch "$file"
fi
# shift the args to remove the file name
shift 1
if [ "$#" -eq 0 ]; then
# show the first 10 lines from $file
head "$file" | bat -l markdown
return 0
fi
# append to the end of file
echo "- $*" >> "$file"
return 0
}
I found this simple tool to be quite usable and I really loved how I could add tasks from my terminal without opening any file or switching to a new application.
But, after a while I found that I wanted to group similar tasks together in each file.
Tags and Task Context
I decided to group similar tasks under markdown headers.
However, adding a task to the end of the file no longer works, we need to add a task to the correct sub-heading.
Users can specify the heading for task by setting a task context: st ctx Travel
Future invocations to st|lt
will add the task under the right heading.
st done
clear’s the task context
Context Source
Setting and clearing a context is done via the TASK_CONTEXT
environment variable. Adding the task under the correct heading for a context is handled by a single gsed
command.
Overall, the new wt()
function looks like the following:
wt() {
file="$1"
if [ ! -f "$file" ]; then
touch "$file"
fi
# shift the args to remove the file name
shift 1
if [ "$#" -eq 0 ]; then
# show the first 10 lines from $file
head $file | bat -l markdown
return 0
fi
if [ "$1" = "done" ]; then
# clear the task context
export TASK_CONTEXT=""
return 0
fi
if [ "$1" = "ctx" ]; then
# set the task context and shift the args
shift 1
export TASK_CONTEXT="$*"
return 0
fi
if [ -z "$TASK_CONTEXT" ]; then
# append to the end of file if no context is set
echo "- $*" >> "$file"
return 0
fi
# append task at the top of heading determined by $TASK_CONTEXT
gsed -i "/${TASK_CONTEXT}/a - $*" "$file"
}
I also wrote a custom starship.rs
plugin to display the current task manager context so I don’t have to remember what I set the context to previously.
[custom.task-ps1]
command = "echo $TASK_CONTEXT"
when = ''' test $TASK_CONTEXT != "" '''
format = 'updating [$output]($style) '
Thoughts so far
tasks
has replaced all other analog and digital tools I used to keep track of my to-do list. I can easily write and organize my thougts and tasks without loosing my train of thought and I don’t have to put in a lot of effort to prune/maintain each list.
If you’d like to try it out, you can checkout the project here on GitHub.