---------------------------------------- CLI Tricks: todo March 22nd, 2018 ---------------------------------------- This is part of a series of phlog entries where I will share some of my command line tricks, tips, and scripts. ## todo ## Everyone has a to-do app they love. Many of us have rolled our own. This is mine. It's another bash function that's auto sourced by my .bash_profile, offers bash-completion, and has a built in archiver. ### The Idea ### I organize my daily life in tmux by using sessions. I'm currently in a session named "personal". I also have "work" and "writing" and "music" and others. My goals for my to-do list manager are: - Super simple cli interface - Sync data between machines (again, cheating with dropbox here) - Contextual to-do list based on tmux session with fallback - Add items - Remove items by number or regex (good for groups of tasks) - Archive things I remove and add a timestamp (good for timesheets) - A little help is nice - Bash-completion all the things ### How to use it ### $ todo -a "Some task" > 1 - Some task $ todo -a Another task > 1 - Some task > 2 - Another task $ todo -d 1 > 2 - Another task Simple, right? You don't need to quote the todo item unless you're using special characters. You can pass the -d flag a number to remove that item, or a string and it'll do a regex match. Need more help on how to use it? Type: $ todo --help ### Requirements ### An environment variable called "$TODOFILE" is required that points to a specific text document where you want your to-do list saved. If you are in a tmux session, todo will use the directory of your $TODOFILE but rename the txt file to match your session name. Archives are saved in a file called XXXX.archive.txt where XXXX is your TODOFILE or session name. It probably requires GNU sed as well, but I haven't checked. ### The Source ### You can find the latest source here: [0]. (HTM) [0] tomasino's dotfiles - todo function #!/usr/bin/env bash # Todo List & Completion _todo() { local iter use cur cur=${COMP_WORDS[COMP_CWORD]} use=$( awk '{gsub(/ /,"\\ ")}8' "$TODOFILE" ) use="${use//\\ /___}" for iter in $use; do if [[ $iter =~ ^$cur ]]; then COMPREPLY+=( "${iter//___/ }" ) fi done } todo() { : "${TODO:?'TODO ENV Var not set. Please set to path of default todo file.'}" # If we are in a tmux session, name the file with the session name # If not in tmux, use the full $TODO env var for path/file if echo "$TERM" | grep -Fq screen && test "$TMUX" ; then sessname=$(tmux display -p '#S') todopath=$(dirname "$TODO") TODOFILE=$todopath/$sessname".txt" TODOARCHIVEFILE=$todopath/$sessname".archive.txt" else TODOFILE=$TODO TODOARCHIVEFILE=${TODO%.*}.archive.txt fi if [ $# -eq 0 ]; then if [ -f "$TODOFILE" ] ; then awk '{ print NR, "-", $0 }' "$TODOFILE" fi else case "$1" in -h|--help) echo "todo - Command Line Todo List Manager" echo " " echo "Creates a text-based todo list and provides basic operations to add and remove elements from the list. If using TMUX, the todo list is session based, using the name of your active session." echo " " echo "usage: todo # display todo list" echo "usage: todo (--help or -h) # show this help" echo "usage: todo (--add or -a) [activity name] # add a new activity to list" echo "usage: todo (--archive) # show completed tasks in archive list" echo "usage: todo (--done or -d) [name or #] # complete and archive activity" ;; -a|--add) echo "${*:2}" >> "$TODOFILE" ;; --archive) if [ -f "$TODOARCHIVEFILE" ] ; then cat "$TODOARCHIVEFILE" fi ;; -d|--done) re='^[0-9]+$' if ! [[ "$2" =~ $re ]] ; then match=$(sed -n "/$2/p" "$TODOFILE" 2> /dev/null) sed -i "" -e "/$2/d" "$TODOFILE" 2> /dev/null else match=$(sed -n "$2p" "$TODOFILE" 2> /dev/null) sed -i "" -e "$2d" "$TODOFILE" 2> /dev/null fi if [ ! -z "$match" ]; then echo "$(date +"%Y-%m-%d %H:%M:%S") - $match" >> "$TODOARCHIVEFILE" fi ;; esac fi } complete -F _todo todo