summary refs log tree commit diff
path: root/bin/todo
diff options
context:
space:
mode:
authorRobert Günzler <r@gnzler.io>2020-01-26 17:16:07 +0100
committerRobert Günzler <r@gnzler.io>2020-01-26 18:00:59 +0100
commitf5d56602df70950de6b7d40966b00c9939c81763 (patch)
treeb50ffeb5496fe3525cc1bab2629389ced95435b7 /bin/todo
Intial commit of v2
See https://drewdevault.com/2019/12/30/dotfiles.html
Diffstat (limited to 'bin/todo')
-rwxr-xr-xbin/todo128
1 files changed, 128 insertions, 0 deletions
diff --git a/bin/todo b/bin/todo
new file mode 100755
index 0000000..1fe3c62
--- /dev/null
+++ b/bin/todo
@@ -0,0 +1,128 @@
+#!/bin/bash
+
+_todo_files=(".todo.md" ".org.md", "TODO")
+_todo_file=""
+
+has_todo_file() {
+    cwd=`pwd`
+    for f in ${_todo_files[@]}; do
+      [[ -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
+
+    if ($1 ~ /^.*(-|*)/) {
+        // support TODO files
+        if (filename() == "TODO") {
+            $0 = gensub(/(^[\w]*(-|*))/, "\\1 TODO", "1", $0)
+        }
+
+        match($0, /\s(TODO|WIP|WAITING|DONE|\?\?\?)\s/, arr)
+        if (arr[1] != "") {
+            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
+        zsh)
+            echo "_orgdown_hook() {$0;}
+typeset -ag precmd_functions;
+if [[ -z \${precmd_functions[(r)_orgdown_hook]} ]]; then
+  precmd_functions+=_orgdown_hook;
+fi"
+            ;;
+        cd)
+            echo "cd() { builtin cd \"\$@\" && $0; }"
+            ;;
+        -h|--help|*)
+            echo "usage: todo hook <integration>"
+            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 <integration>]"
+        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 " <integration>      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 })
+        ;;
+    *)
+        [ -f "$1" ] && { print_org $1; exit 0; }
+        has_todo_file && {
+          hr "todo"
+          print_org $_todo_file
+        }
+        ;;
+esac