| ---------------------------------------- | |
| 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]. | |
| [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… | |
| 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 activit… | |
| echo "usage: todo (--archive) # show completed ta… | |
| echo "usage: todo (--done or -d) [name or #] # complete and arch… | |
| ;; | |
| -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 |