Skip to content

Instantly share code, notes, and snippets.

@moechofe
Last active May 20, 2025 13:40
Show Gist options
  • Save moechofe/f55a0e1e62ad765c197a84f3ae8567aa to your computer and use it in GitHub Desktop.
Save moechofe/f55a0e1e62ad765c197a84f3ae8567aa to your computer and use it in GitHub Desktop.
Mini Bash Todo
#!/bin/bash
# File that contains the tasks
DATA=$HOME/.config/todo.lst
touch $DATA
esc=$(printf '\033')
tab=$'\t'
# Highlight search term.
light()
{
[[ -z $1 ]] && cat || sed "s/\($1\)/${esc}[7m\\1${esc}[27m/g"
}
# Will colorize the @tag according to it's hash. Mark as bold @tag that contains numbers or uppercase letters.
color()
{
awk -F $'\t' '{chk="cksum|awk \"{print $2}\""; print $2|& chk; close(chk,"to"); while(chk |& getline color > 0) bold=match($2,/^@[A-Z|0-9][A-Z|0-9]*$/); printf("\033[%sm%s\t\033[%dm%s\033[39m\t%s\t%s\033[0m\n",bold,$1,color%6+31,$2,$3,$4); close(chk)}'\
| perl -pe "s/([^\w])\*([\s\w]+)\*([^\w])/\$1${esc}[4m\$2${esc}[24m\$3/"
}
# Format the output in columns.
col()
{
column -s$'\t' -t
}
while getopts "ha" o; do
case $o in
h)
cat << EOF
TODO - Simple task manager
This script is a simple task manager that allows you to add, list, and mark tasks as done.
It uses a text file to store the tasks and allows you to open it in your favorite text editor.
Sauce: https://gist.github.com/moechofe/f55a0e1e62ad765c197a84f3ae8567aa
Usage:
todo List undone tasks
todo TERM List undone tasks and highlight TERM
todo NUM Show task number NUM
todo ed Open tasks list in text editor
todo @TAG TASK Add the TASK with TAG
todo NUM ok|done Mark the task number NUM has done
todo ok|done NUM Mark the task number NUM has done
todo -h Show this help message
todo -a Show all tasks with description
Arguments:
TERM Search term (no spaces)
NUM Task number (digits only)
TAG Task tag (no spaces)
TASK Task title, can contain description after 1 dot+space (. )
EOF
exit 1;;
a)
# last all
cat "$DATA"\
| awk -F$'\t' '{gsub(/\. +/,".\n\t\t\t",$4); printf("%s\t%s\t%s\t%s\n",$2,$3,$1,$4)}'\
| color "${1:-}"\
| light "$2"\
| col
exit 0;;
esac
done
# editor
if [[ $# -eq 1 ]] && [[ $1 == "ed" ]]; then
eval "${EDITOR:-vim} $DATA"
# mark as done
elif [[ $# -eq 2 ]] && [[ $2 =~ ([oO][kK]|[dD][oO][nN][eE]) ]] && [[ $1 =~ ^[0-9][0-9]*$ ]]; then
sed -i "s#^\(-\+\t\)\($1\t.*\)#$(date -u +"%Y-%m-%dT%H:%M:%SZ")\t\\2#" "$DATA"
# mark as done
elif [[ $# -eq 2 ]] && [[ $1 =~ ([oO][kK]|[dD][oO][nN][eE]) ]] && [[ $2 =~ ^[0-9][0-9]*$ ]]; then
sed -i "s#^\(-\+\t\)\($2\t.*\)#$(date -u +"%Y-%m-%dT%H:%M:%SZ")\t\\2#" "$DATA"
# add a task
elif [[ $# -gt 1 ]] && [[ $1 =~ ^(@..*)$ ]]; then
id=0
[[ -f "$DATA" ]] && id=$(cat "$DATA" | awk -F"$tab" '{print $2}' | sed 's/^#//' | sort -nr | head -1)
((id++))
echo "${@:2}"\
| awk -F"$tab" -v i="$id" -v p="${BASH_REMATCH[1]}" '{f=$1;$1="";printf("--------------------\t%s\t%s\t%s\n",i,p,f,$0)}'\
>>"$DATA"
# show one task
elif [[ $# -eq 1 ]] && [[ $1 =~ ^[0-9][0-9]*$ ]]; then
cat "$DATA"\
| grep "^[0-9A-Z:-][0-9A-Z:-]*$tab$1$tab"\
| awk -F$'\t' '{gsub(/\. +/,".\n\t\t",$4); printf("%s\t%s\t%s\n",$2,$3,$4)}'\
| color "${1:-}"\
| col
# list all tasks
else
cat "$DATA"\
| grep '^-'\
| awk -F"$tab" '{sub(/\. .*/,"...",$4); printf("%s\t%s\t%s\n",$2,$3,$4)}'\
| color "${1:-}"\
| light "$1"\
| col
fi
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment