#!/bin/bash set -e [ -n "$DEBUG" ] && set -x _todo_files=(".todo.md" ".org.md" "TODO" "todo.org" "todo.md") _todo_file="" has_todo_file() { cwd=$(pwd) for f in "${_todo_files[@]}"; do test -f "$cwd/$f" && _todo_file="$cwd/$f" && return 0 done return 1 } print_org() { awk ' function filename() { n = split(FILENAME, a, "/") return a[n] } function res() { return "\033[0;10m" } function bold(s) { return "" s res() } function red(s) { "tput setaf 1" | getline redc; return redc s res() } function green(s) { "tput setaf 2" | getline greenc; return greenc s res() } function blue(s) { "tput setaf 5" | getline bluec; return bluec s res() } function magenta(s) { "tput setaf 191" | getline magc; return magc s res() } { if ($1 ~ /^#+/) block=$0 // support TODO files if ($1 ~ /^(-|*)/) { // detect status strings match($0, /\s(TODO|WIP|WAITING|DONE)\s/, arr) if (filename() == "TODO" && arr[1] == "") { $0 = gensub(/(^[\w]*(-|\*))/, "\\1 TODO", "1", $0) } tasks[block][arr[1]][i++]=$0 } } END { for (b in tasks) { print b for (status in tasks[b]) { for (t in tasks[b][status]) { txt = tasks[b][status][t] txt = gensub(/(TODO)/, red("\\1"), "1", txt) txt = gensub(/(WIP)/, blue("\\1"), "1", txt) txt = gensub(/(DONE)/, green("\\1"), "1", txt) txt = gensub(/(\?\?\?)/, bold(magenta("\\1")), "1", txt) print txt } } printf "\n" } }' $1 } print_shell_hook() { case $1 in bash) cat <<-EOF __todo_oldpwd="$(\builtin pwd -L)" function __todo_precmd() { \builtin local -r retval="$?" \builtin local pwd_tmp pwd_tmp="$(\builtin pwd -L)" if [[ \${__todo_oldpwd} != "\${pwd_tmp}" ]]; then __todo_oldpwd="\${pwd_tmp}" \command ${0} fi return "\${retval}" } if [[ \${PROMPT_COMMAND:=} != *'__todo_precmd'* ]]; then PROMPT_COMMAND="__todo_precmd;\${PROMPT_COMMAND#;}" fi EOF ;; zsh) cat <<-EOF __todo_oldpwd="$(\builtin pwd -L)" function __todo_hook() { \builtin local -r retval="$?" \builtin local pwd_tmp if [[ \${__todo_oldpwd} != "\${pwd_tmp}" ]]; then __todo_oldpwd="\${pwd_tmp}" \command ${0} fi return "\${retval}" } typeset -ag precmd_functions; if [[ -z \${precmd_functions[(r)__todo_hook]} ]]; then precmd_functions+=__todo_hook; fi" EOF ;; cd) echo "cd() { builtin cd \"\$@\" && $0; }" ;; -h | --help | *) echo "usage: todo hook " echo "" echo "use like this: eval \$(todo hook )" echo "" echo "supported integrations:" echo " - zsh: run todo as a precmd hook" echo " (this can get quite annoying when you're in a direcory that has a todo file)" echo " - cd: run todo as a post-cd hook" echo "" exit 1 ;; esac } case "$1" in hook) shift print_shell_hook "$1" ;; -h | --help) echo "usage: todo [-r] [hook ]" echo "A quite stupid todo/agenda script that reminds you of things you need to do" echo "" echo " -r, --recursive walk the file tree, searching for todos" echo " shell integration, you should eval this" echo "" exit 0 ;; -r | --recursive | -R) while read FILE; do hr "todo [$FILE]" print_org $FILE done < <(rg --files ${_todo_files[@]/#/-g }) ;; *) if [ -f "$1" ]; then print_org $1 exit 0 fi if has_todo_file; then hr "todo" print_org $_todo_file hr "" fi ;; esac