I was looking for a quick and easy way to track my todo’s at work. One thing I wanted was to see only one task at a time. Because I spend a fair amount of my day on the command line, I thought it would be relatively easy to implement this on the command line.
I keep a .zshrc
file with a handful of functions and aliases. I figured I could probably add a few commands to that file to make this work. Here are the commands I have today.
todo [item] Add an item or edit the todo list
next List the next todo item on my list
soon List the next 10 items on my list
late List items completed lately
mark [item] Mark the current item (or [item]) as done
I decided to keep my todo list in the plain text file ~/todo.txt
. This allows me to use it right now and lets me take an iterative approach to the rest of the tools described here. At first I had a simple alias that just opened my todo list in my favorite editor.
alias todo=$EDIT ~/todo.txt
That uses a variable for my editor. My main editor is currently VS Code so I have a variable assigned to that. This gives me the freedom to switch all my commands to a different editor if I decide to do so in the future.
export EDIT=code
I wanted it to be super easy to add a line to my todo list, without opening my editor, so I wrote a little function to do so. If I don’t include an argument my todo list will still open in my default editor but if I do add an argument it will simply append that to my file.
So, to open my todo.txt file in my favorite editor I still run:
todo
But, to add a new item I can also run:
todo "Make something amazing happen."
Here’s the short function I’m using for the todo
command today.
function todo() {
if [[ $# -eq 0 ]]; then
$EDIT ~/todo.txt
else
echo $* >> ~/todo.txt
fi
}
Most of the time I only want to see my next highest priority item so that I can focus on just that. I keep my todo list in priority order so the most important item is at the top. To view that top item I just need a simple alias that shows me the first line.
alias next="head -1 ~/todo.txt"
Once in a while, however, I’ll want to see a list of the most important upcoming items. I decided that seeing the next 10 items on the list would do the trick. I also wanted them to have a little more fancy output. Here’s my alias for that.
alias soon="head -10 ~/todo.txt | sed 's/^/- /'"
I decided I wanted to keep a history of the items I’ve finished. This has become the most complicated part of this little tool. I wanted to be able to do two things. First, I wanted to be able to mark my most important item, the one I’m working on now, as done. For that I use the mark
command.
Next, I wanted to be able to mark an item done that wasn’t on my todo list. Something that I did in the moment because it was easier than adding it to my list. For that I use the mark
command with an argument. For example:
mark "Added John to the Core team on GitHub."
I wanted to date stamp these finished items so that I would know when I had completed them.
I also wanted to keep backups in case something went wrong when I was adding stuff to this file.
Here’s the full mark
function that I’m using today.
function mark() {
# Backup the file
local timestamp=$(date +'%Y-%m-%d')
cp ~/todo.txt /tmp/todo-${timestamp}.txt
if [ "$#" -eq 1 ]; then
# Use the provided argument
local LINE="$1"
else
# Pull the first line from todo.txt
LINE=$(head -1 ~/todo.txt)
fi
# Output the provided line or first line of todo.txt into the done file and date stamp it
echo "$LINE [$(date +'%Y-%m-%d')]" >> ~/done.txt
# Show the completed item now that we've logged it
tail -1 ~/done.txt
if [ "$#" -eq 0 ]; then
# Output everything but the first line of todo.txt back into todo.txt only if no argument is provided
sed 1d ~/todo.txt > /tmp/todo.txt
mv /tmp/todo.txt ~/todo.txt
fi
}
Once in a while I’ll need to quickly describe what I’ve been up to. This is useful for status meetings, 1-on-1’s, and other times you’re looking for things of interest to talk about. This command shows me the last 10 items I recorded doing.
alias late="tail -r -n 10 ~/done.txt"
Finally, I have a little help
function that shows me all the tools I’ve setup in my .zshrc
file. For my todo list I’ve got the following function.
help() {
echo "Todo:"
echo " todo [item] Add an item or edit the todo list"
echo " next List the next todo item on my list"
echo " soon List the next 10 items on my list"
echo " mark [item] Mark the current item (or [item]) as done"
echo " late List items completely lately"
}
Love it. A concise junction of alias and function usage. Search “shell functions” for my interests.
By Martin on August 18, 2024
Get a monthly digest of what I'm up to.