From fd9b002ce13c10e2be13de193ac9f9911a9a6a28 Mon Sep 17 00:00:00 2001 From: "David A. Harding" Date: Sat, 7 Mar 2009 13:05:40 -0500 Subject: [PATCH 01/12] Hiding Priority, Context, and Project . Adds three new switches that hide priorty, context, and project text in list output. . Changes proposed by Dave Hein. Original patch by Dave Hein. Revised patch by David A. Harding. Thread starts at http://tech.groups.yahoo.com/group/todotxt/message/1848 --- todo.sh | 92 +++++++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 89 insertions(+), 3 deletions(-) diff --git a/todo.sh b/todo.sh index 808777e..a430be8 100644 --- a/todo.sh +++ b/todo.sh @@ -119,6 +119,12 @@ help() Options: + -@ + Hide context names in list output. Use twice to show context + names (default). + -+ + Hide project names in list output. Use twice to show project + names (default). -d CONFIG_FILE Use a configuration file other than the default ~/todo.cfg -f @@ -127,6 +133,9 @@ help() Display this help message -p Plain mode turns off colors + -P + Hide priority labels in list output. Use twice to show + priority labels (default). -a Don't auto-archive tasks automatically on completion -n @@ -195,9 +204,50 @@ PRESERVE_LINE_NUMBERS=1 AUTO_ARCHIVE=1 DATE_ON_ADD=0 -while getopts ":fhpnatvVd:" Option +while getopts ":fhpnatvV+@Pd:" Option do case $Option in + '@' ) + ## HIDE_CONTEXT_NAMES starts at zero (false); increment it to one + ## (true) the first time this flag is seen. Each time the flag + ## is seen after that, increment it again so that an even + ## number hides project names and an odd number shows project + ## names. + : $(( HIDE_CONTEXT_NAMES++ )) + if [ $(( $HIDE_CONTEXT_NAMES % 2 )) -eq 0 ] + then + ## Zero or even value -- show context names + unset HIDE_CONTEXTS_SUBSTITUTION + else + ## One or odd value -- hide context names + # + ## Match: \(^\|[[:space:]] beginning of line or a space + ## @ literal context label + ## [^[:space:]]\+ Anything besides whitespace one + ## or more times + HIDE_CONTEXTS_SUBSTITUTION="\(^\|[[:space:]]\)@[^[:space:]]\+" + fi + ;; + '+' ) + ## HIDE_PROJECT_NAMES starts at zero (false); increment it to one + ## (true) the first time this flag is seen. Each time the flag + ## is seen after that, increment it again so that an even + ## number hides project names and an odd number shows project + ## names. + : $(( HIDE_PROJECT_NAMES++ )) + if [ $(( $HIDE_PROJECT_NAMES % 2 )) -eq 0 ] + then + ## Zero or even value -- show project names + unset HIDE_PROJECTS_SUBSTITUTION + else + ## One or odd value -- hide project names + ## Match: \(^\|[[:space:]] beginning of line or a space + ## @ literal context label + ## [^[:space:]]\+ Anything besides whitespace one + ## or more times + HIDE_PROJECTS_SUBSTITUTION="\(^\|[[:space:]]\)+[^[:space:]]\+" + fi + ;; a ) AUTO_ARCHIVE=0 ;; @@ -216,6 +266,22 @@ do p ) PLAIN=1 ;; + P ) + ## HIDE_PRIORITY_LABELS starts at zero (false); increment it to one + ## (true) the first time this flag is seen. Each time the flag + ## is seen after that, increment it again so that an even + ## number hides project names and an odd number shows project + ## names. + : $(( HIDE_PRIORITY_LABELS++ )) + if [ $(( $HIDE_PRIORITY_LABELS % 2 )) -eq 0 ] + then + ## Zero or even value -- show priority labels + unset HIDE_PRIORITY_SUBSTITUTION + else + ## One or odd value -- hide priority labels + HIDE_PRIORITY_SUBSTITUTION="([A-Z])[[:space:]]" + fi + ;; t ) DATE_ON_ADD=1 ;; @@ -414,8 +480,22 @@ case $action in "list" | "ls" ) item=$2 if [ -z "$item" ]; then - echo -e "`sed = "$TODO_FILE" | sed 'N; s/^/ /; s/ *\(.\{2,\}\)\n/\1 /' | sed 's/^ /0/' | sort -f -k2 | sed '/^[0-9][0-9] x /!s/\(.*(A).*\)/'$PRI_A'\1'$DEFAULT'/g' | sed '/^[0-9][0-9] x /!s/\(.*(B).*\)/'$PRI_B'\1'$DEFAULT'/g' | sed '/^[0-9][0-9] x /!s/\(.*(C).*\)/'$PRI_C'\1'$DEFAULT'/g' | sed '/^[0-9][0-9] x /!s/\(.*([A-Z]).*\)/'$PRI_X'\1'$DEFAULT'/'`" echo "--" + echo -e "$( \ + sed = "$TODO_FILE" \ + | sed 'N; s/^/ /; s/ *\(.\{2,\}\)\n/\1 /' \ + | sed 's/^ /0/' \ + | sort -f -k2 \ + | sed '/^[0-9][0-9] x /! { + s/\(.*(A).*\)/'$PRI_A'\1 '$DEFAULT'/g; + s/\(.*(B).*\)/'$PRI_B'\1 '$DEFAULT'/g; + s/\(.*(C).*\)/'$PRI_C'\1 '$DEFAULT'/g; + s/\(.*([A-Z]).*\)/'$PRI_X'\1'$DEFAULT'/g; + }' \ + | sed 's/'${HIDE_PRIORITY_SUBSTITUTION:-^}'//g' \ + | sed 's/'${HIDE_PROJECTS_SUBSTITUTION:-^}'//g' \ + | sed 's/'${HIDE_CONTEXTS_SUBSTITUTION:-^}'//g' \ + )" NUMTASKS=$(wc -l "$TODO_FILE" | sed 's/^[[:space:]]*\([0-9]*\).*/\1/') echo "TODO: $NUMTASKS tasks in $TODO_FILE." else @@ -445,7 +525,13 @@ case $action in do command=`echo "$command" | grep -i $i ` done - command=`echo "$command" | sort -f -k2` + command=$( \ + echo "$command" \ + | sort -f -k2 \ + | sed 's/'${HIDE_PRIORITY_SUBSTITUTION:-^}'//g' \ + | sed 's/'${HIDE_PROJECTS_SUBSTITUTION:-^}'//g' \ + | sed 's/'${HIDE_CONTEXTS_SUBSTITUTION:-^}'//g' \ + ) echo -e "$command" fi cleanup ;; From 20e68927754017a9600f23054f05d9e7db5208f8 Mon Sep 17 00:00:00 2001 From: "David A. Harding" Date: Sat, 7 Mar 2009 16:15:15 -0500 Subject: [PATCH 02/12] Run .todo.actions.d Before Builtins . Let users override default commands by creating a script in ~/.todo.actions.d/ with the same name as a default command. Idea by Don Harper and David A. Harding; patch by Harding. . The patch adds the following logic and increases the indent level for the case statement: . +if [ -d "$HOME/.todo.actions.d" -a -x "$HOME/.todo.actions.d/$action" ] +then + CFG_FILE="$CFG_FILE" "$HOME/.todo.actions.d/$action" "$@" +else + case $action in --- todo.sh | 733 ++++++++++++++++++++++++++++---------------------------- 1 file changed, 365 insertions(+), 368 deletions(-) diff --git a/todo.sh b/todo.sh index a430be8..c3cff81 100644 --- a/todo.sh +++ b/todo.sh @@ -332,425 +332,422 @@ shopt -s extglob # == HANDLE ACTION == action=$( printf "%s\n" "$1" | tr 'A-Z' 'a-z' ) -case $action in -"add" | "a") - if [[ -z "$2" && $FORCE = 0 ]]; then - echo -n "Add: " - read input - else - [ -z "$2" ] && die "usage: $0 add \"TODO ITEM\"" - shift - input=$* - fi +if [ -d "$HOME/.todo.actions.d" -a -x "$HOME/.todo.actions.d/$action" ] +then + CFG_FILE="$CFG_FILE" "$HOME/.todo.actions.d/$action" "$@" +else + case $action in + "add" | "a") + if [[ -z "$2" && $FORCE = 0 ]]; then + echo -n "Add: " + read input + else + [ -z "$2" ] && die "usage: $0 add \"TODO ITEM\"" + shift + input=$* + fi - if [[ $DATE_ON_ADD = 1 ]]; then - now=`date '+%Y-%m-%d'` - input="$now $input" - fi - echo "$input" >> "$TODO_FILE" - TASKNUM=$(wc -l "$TODO_FILE" | sed 's/^[[:space:]]*\([0-9]*\).*/\1/') - [[ $VERBOSE = 1 ]] && echo "TODO: '$input' added on line $TASKNUM." - cleanup;; + if [[ $DATE_ON_ADD = 1 ]]; then + now=`date '+%Y-%m-%d'` + input="$now $input" + fi + echo "$input" >> "$TODO_FILE" + TASKNUM=$(wc -l "$TODO_FILE" | sed 's/^[[:space:]]*\([0-9]*\).*/\1/') + [[ $VERBOSE = 1 ]] && echo "TODO: '$input' added on line $TASKNUM." + cleanup;; -"addto" ) - [ -z "$2" ] && die "usage: $0 addto DEST \"TODO ITEM\"" - dest="$TODO_DIR/$2" - [ -z "$3" ] && die "usage: $0 addto DEST \"TODO ITEM\"" - shift - shift - input=$* + "addto" ) + [ -z "$2" ] && die "usage: $0 addto DEST \"TODO ITEM\"" + dest="$TODO_DIR/$2" + [ -z "$3" ] && die "usage: $0 addto DEST \"TODO ITEM\"" + shift + shift + input=$* - if [ -f "$dest" ]; then - echo "$input" >> "$dest" - TASKNUM=$(wc -l "$dest" | sed 's/^[[:space:]]*\([0-9]*\).*/\1/') - [[ $VERBOSE = 1 ]] && echo "TODO: '$input' added to $dest on line $TASKNUM." - else - echo "TODO: Destination file $dest does not exist." - fi - cleanup;; + if [ -f "$dest" ]; then + echo "$input" >> "$dest" + TASKNUM=$(wc -l "$dest" | sed 's/^[[:space:]]*\([0-9]*\).*/\1/') + [[ $VERBOSE = 1 ]] && echo "TODO: '$input' added to $dest on line $TASKNUM." + else + echo "TODO: Destination file $dest does not exist." + fi + cleanup;; -"append" | "app" ) - errmsg="usage: $0 append ITEM# \"TEXT TO APPEND\"" - shift; item=$1; shift + "append" | "app" ) + errmsg="usage: $0 append ITEM# \"TEXT TO APPEND\"" + shift; item=$1; shift - [ -z "$item" ] && die "$errmsg" - [[ "$item" = +([0-9]) ]] || die "$errmsg" - todo=$(sed "$item!d" "$TODO_FILE") - [ -z "$todo" ] && die "$item: No such todo." - if [[ -z "$1" && $FORCE = 0 ]]; then - echo -n "Append: " - read input - else - input=$* - fi - if sed -i.bak $item" s|^.*|& $input|" "$TODO_FILE"; then - newtodo=$(sed "$item!d" "$TODO_FILE") - [[ $VERBOSE = 1 ]] && echo "$item: $newtodo" - else - echo "TODO: Error appending task $item." - fi - cleanup;; + [ -z "$item" ] && die "$errmsg" + [[ "$item" = +([0-9]) ]] || die "$errmsg" + todo=$(sed "$item!d" "$TODO_FILE") + [ -z "$todo" ] && die "$item: No such todo." + if [[ -z "$1" && $FORCE = 0 ]]; then + echo -n "Append: " + read input + else + input=$* + fi + if sed -i.bak $item" s|^.*|& $input|" "$TODO_FILE"; then + newtodo=$(sed "$item!d" "$TODO_FILE") + [[ $VERBOSE = 1 ]] && echo "$item: $newtodo" + else + echo "TODO: Error appending task $item." + fi + cleanup;; -"archive" ) - archive;; + "archive" ) + archive;; -"del" | "rm" ) - # replace deleted line with a blank line when PRESERVE_LINE_NUMBERS is 1 - errmsg="usage: $0 del ITEM#" - item=$2 - [ -z "$item" ] && die "$errmsg" + "del" | "rm" ) + # replace deleted line with a blank line when PRESERVE_LINE_NUMBERS is 1 + errmsg="usage: $0 del ITEM#" + item=$2 + [ -z "$item" ] && die "$errmsg" - if [ -z "$3" ]; then + if [ -z "$3" ]; then - [[ "$item" = +([0-9]) ]] || die "$errmsg" - if sed -ne "$item p" "$TODO_FILE" | grep "^."; then - DELETEME=$(sed "$2!d" "$TODO_FILE") + [[ "$item" = +([0-9]) ]] || die "$errmsg" + if sed -ne "$item p" "$TODO_FILE" | grep "^."; then + DELETEME=$(sed "$2!d" "$TODO_FILE") - if [ $FORCE = 0 ]; then - echo "Delete '$DELETEME'? (y/n)" - read ANSWER - else - ANSWER="y" - fi - if [ "$ANSWER" = "y" ]; then - if [ $PRESERVE_LINE_NUMBERS = 0 ]; then - # delete line (changes line numbers) - sed -i.bak -e $2"s/^.*//" -e '/./!d' "$TODO_FILE" - else - # leave blank line behind (preserves line numbers) - sed -i.bak -e $2"s/^.*//" "$TODO_FILE" - fi - [[ $VERBOSE = 1 ]] && echo "TODO: '$DELETEME' deleted." - cleanup - else - echo "TODO: No tasks were deleted." - fi - else - echo "$item: No such todo." - fi - else - sed -i.bak -e $item"s/$3/ /g" "$TODO_FILE" - [[ $VERBOSE = 1 ]] && echo "TODO: $3 removed from $item." - fi ;; + if [ $FORCE = 0 ]; then + echo "Delete '$DELETEME'? (y/n)" + read ANSWER + else + ANSWER="y" + fi + if [ "$ANSWER" = "y" ]; then + if [ $PRESERVE_LINE_NUMBERS = 0 ]; then + # delete line (changes line numbers) + sed -i.bak -e $2"s/^.*//" -e '/./!d' "$TODO_FILE" + else + # leave blank line behind (preserves line numbers) + sed -i.bak -e $2"s/^.*//" "$TODO_FILE" + fi + [[ $VERBOSE = 1 ]] && echo "TODO: '$DELETEME' deleted." + cleanup + else + echo "TODO: No tasks were deleted." + fi + else + echo "$item: No such todo." + fi + else + sed -i.bak -e $item"s/$3/ /g" "$TODO_FILE" + [[ $VERBOSE = 1 ]] && echo "TODO: $3 removed from $item." + fi ;; -"depri" | "dp" ) - item=$2 - errmsg="usage: $0 depri ITEM#" + "depri" | "dp" ) + item=$2 + errmsg="usage: $0 depri ITEM#" - todo=$(sed "$item!d" "$TODO_FILE") - [ -z "$todo" ] && die "$item: No such todo." - [[ "$item" = +([0-9]) ]] || die "$errmsg" + todo=$(sed "$item!d" "$TODO_FILE") + [ -z "$todo" ] && die "$item: No such todo." + [[ "$item" = +([0-9]) ]] || die "$errmsg" - sed -e $item"s/^(.*) //" "$TODO_FILE" > /dev/null 2>&1 + sed -e $item"s/^(.*) //" "$TODO_FILE" > /dev/null 2>&1 - if [ "$?" -eq 0 ]; then - #it's all good, continue - sed -i.bak -e $2"s/^(.*) //" "$TODO_FILE" - NEWTODO=$(sed "$2!d" "$TODO_FILE") - [[ $VERBOSE = 1 ]] && echo -e "`echo "$item: $NEWTODO"`" - [[ $VERBOSE = 1 ]] && echo "TODO: $item deprioritized." - cleanup - else - die "$errmsg" - fi;; + if [ "$?" -eq 0 ]; then + #it's all good, continue + sed -i.bak -e $2"s/^(.*) //" "$TODO_FILE" + NEWTODO=$(sed "$2!d" "$TODO_FILE") + [[ $VERBOSE = 1 ]] && echo -e "`echo "$item: $NEWTODO"`" + [[ $VERBOSE = 1 ]] && echo "TODO: $item deprioritized." + cleanup + else + die "$errmsg" + fi;; -"do" ) - errmsg="usage: $0 do ITEM#" - item=$2 - [ -z "$item" ] && die "$errmsg" - [[ "$item" = +([0-9]) ]] || die "$errmsg" + "do" ) + errmsg="usage: $0 do ITEM#" + item=$2 + [ -z "$item" ] && die "$errmsg" + [[ "$item" = +([0-9]) ]] || die "$errmsg" - todo=$(sed "$item!d" "$TODO_FILE") - [ -z "$todo" ] && die "$item: No such todo." + todo=$(sed "$item!d" "$TODO_FILE") + [ -z "$todo" ] && die "$item: No such todo." - now=`date '+%Y-%m-%d'` - # remove priority once item is done - sed -i.bak $item"s/^(.*) //" "$TODO_FILE" - sed -i.bak $item"s|^|&x $now |" "$TODO_FILE" - newtodo=$(sed "$item!d" "$TODO_FILE") - [[ $VERBOSE = 1 ]] && echo "$item: $newtodo" - [[ $VERBOSE = 1 ]] && echo "TODO: $item marked as done." + now=`date '+%Y-%m-%d'` + # remove priority once item is done + sed -i.bak $item"s/^(.*) //" "$TODO_FILE" + sed -i.bak $item"s|^|&x $now |" "$TODO_FILE" + newtodo=$(sed "$item!d" "$TODO_FILE") + [[ $VERBOSE = 1 ]] && echo "$item: $newtodo" + [[ $VERBOSE = 1 ]] && echo "TODO: $item marked as done." - if [ $AUTO_ARCHIVE = 1 ]; then - archive - fi - cleanup ;; + if [ $AUTO_ARCHIVE = 1 ]; then + archive + fi + cleanup ;; -"list" | "ls" ) - item=$2 - if [ -z "$item" ]; then - echo "--" - echo -e "$( \ - sed = "$TODO_FILE" \ - | sed 'N; s/^/ /; s/ *\(.\{2,\}\)\n/\1 /' \ - | sed 's/^ /0/' \ - | sort -f -k2 \ - | sed '/^[0-9][0-9] x /! { - s/\(.*(A).*\)/'$PRI_A'\1 '$DEFAULT'/g; - s/\(.*(B).*\)/'$PRI_B'\1 '$DEFAULT'/g; - s/\(.*(C).*\)/'$PRI_C'\1 '$DEFAULT'/g; - s/\(.*([A-Z]).*\)/'$PRI_X'\1'$DEFAULT'/g; - }' \ - | sed 's/'${HIDE_PRIORITY_SUBSTITUTION:-^}'//g' \ - | sed 's/'${HIDE_PROJECTS_SUBSTITUTION:-^}'//g' \ - | sed 's/'${HIDE_CONTEXTS_SUBSTITUTION:-^}'//g' \ - )" - NUMTASKS=$(wc -l "$TODO_FILE" | sed 's/^[[:space:]]*\([0-9]*\).*/\1/') - echo "TODO: $NUMTASKS tasks in $TODO_FILE." - else - command=`sed = "$TODO_FILE" | sed 'N; s/^/ /; s/ *\(.\{2,\}\)\n/\1 /' | sed 's/^ /0/' | sort -f -k2 | sed '/^[0-9][0-9] x /!s/\(.*(A).*\)/'$PRI_A'\1'$DEFAULT'/g' | sed '/^[0-9][0-9] x /!s/\(.*(B).*\)/'$PRI_B'\1'$DEFAULT'/g' | sed '/^[0-9][0-9] x /!s/\(.*(C).*\)/'$PRI_C'\1'$DEFAULT'/g' | sed '/^[0-9][0-9] x /!s/\(.*([A-Z]).*\)/'$PRI_X'\1'$DEFAULT'/' | grep -i $item ` - shift - shift - for i in $* - do - command=`echo "$command" | grep -i $i ` - done - command=`echo "$command" | sort -f -k2` - echo -e "$command" - fi - cleanup ;; + "list" | "ls" ) + item=$2 + if [ -z "$item" ]; then + echo "--" + echo -e "$( \ + sed = "$TODO_FILE" \ + | sed 'N; s/^/ /; s/ *\(.\{2,\}\)\n/\1 /' \ + | sed 's/^ /0/' \ + | sort -f -k2 \ + | sed '/^[0-9][0-9] x /! { + s/\(.*(A).*\)/'$PRI_A'\1 '$DEFAULT'/g; + s/\(.*(B).*\)/'$PRI_B'\1 '$DEFAULT'/g; + s/\(.*(C).*\)/'$PRI_C'\1 '$DEFAULT'/g; + s/\(.*([A-Z]).*\)/'$PRI_X'\1'$DEFAULT'/g; + }' \ + | sed 's/'${HIDE_PRIORITY_SUBSTITUTION:-^}'//g' \ + | sed 's/'${HIDE_PROJECTS_SUBSTITUTION:-^}'//g' \ + | sed 's/'${HIDE_CONTEXTS_SUBSTITUTION:-^}'//g' \ + )" + NUMTASKS=$(wc -l "$TODO_FILE" | sed 's/^[[:space:]]*\([0-9]*\).*/\1/') + echo "TODO: $NUMTASKS tasks in $TODO_FILE." + else + command=`sed = "$TODO_FILE" | sed 'N; s/^/ /; s/ *\(.\{2,\}\)\n/\1 /' | sed 's/^ /0/' | sort -f -k2 | sed '/^[0-9][0-9] x /!s/\(.*(A).*\)/'$PRI_A'\1'$DEFAULT'/g' | sed '/^[0-9][0-9] x /!s/\(.*(B).*\)/'$PRI_B'\1'$DEFAULT'/g' | sed '/^[0-9][0-9] x /!s/\(.*(C).*\)/'$PRI_C'\1'$DEFAULT'/g' | sed '/^[0-9][0-9] x /!s/\(.*([A-Z]).*\)/'$PRI_X'\1'$DEFAULT'/' | grep -i $item ` + shift + shift + for i in $* + do + command=`echo "$command" | grep -i $i ` + done + command=`echo "$command" | sort -f -k2` + echo -e "$command" + fi + cleanup ;; -"listall" | "lsa" ) - item=$2 - cat "$TODO_FILE" "$DONE_FILE" > "$TMP_FILE" + "listall" | "lsa" ) + item=$2 + cat "$TODO_FILE" "$DONE_FILE" > "$TMP_FILE" - if [ -z "$item" ]; then - echo -e "`sed = "$TMP_FILE" | sed 'N; s/^/ /; s/ *\(.\{3,\}\)\n/\1 /' | sed 's/^ /00/' | sed 's/^ /0/' | sort -f -k2 | sed '/^[0-9][0-9][0-9] x /!s/\(.*(A).*\)/'$PRI_A'\1'$DEFAULT'/g' | sed '/^[0-9][0-9][0-9] x /!s/\(.*(B).*\)/'$PRI_B'\1'$DEFAULT'/g' | sed '/^[0-9][0-9][0-9] x /!s/\(.*(C).*\)/'$PRI_C'\1'$DEFAULT'/g' | sed '/^[0-9][0-9][0-9] x /!s/\(.*([A-Z]).*\)/'$PRI_X'\1'$DEFAULT'/'`" - else - command=`sed = "$TMP_FILE" | sed 'N; s/^/ /; s/ *\(.\{3,\}\)\n/\1 /' | sed 's/^ /00/' | sed 's/^ /0/' | sort -f -k2 | sed '/^[0-9][0-9][0-9] x /!s/\(.*(A).*\)/'$PRI_A'\1'$DEFAULT'/g' | sed '/^[0-9][0-9][0-9] x /!s/\(.*(B).*\)/'$PRI_B'\1'$DEFAULT'/g' | sed '/^[0-9][0-9][0-9] x /!s/\(.*(C).*\)/'$PRI_C'\1'$DEFAULT'/g' | sed '/^[0-9][0-9][0-9] x /!s/\(.*([A-Z]).*\)/'$PRI_X'\1'$DEFAULT'/' | grep -i $item ` - shift - shift - for i in $* - do - command=`echo "$command" | grep -i $i ` - done - command=$( \ - echo "$command" \ - | sort -f -k2 \ - | sed 's/'${HIDE_PRIORITY_SUBSTITUTION:-^}'//g' \ - | sed 's/'${HIDE_PROJECTS_SUBSTITUTION:-^}'//g' \ - | sed 's/'${HIDE_CONTEXTS_SUBSTITUTION:-^}'//g' \ - ) - echo -e "$command" - fi - cleanup ;; + if [ -z "$item" ]; then + echo -e "`sed = "$TMP_FILE" | sed 'N; s/^/ /; s/ *\(.\{3,\}\)\n/\1 /' | sed 's/^ /00/' | sed 's/^ /0/' | sort -f -k2 | sed '/^[0-9][0-9][0-9] x /!s/\(.*(A).*\)/'$PRI_A'\1'$DEFAULT'/g' | sed '/^[0-9][0-9][0-9] x /!s/\(.*(B).*\)/'$PRI_B'\1'$DEFAULT'/g' | sed '/^[0-9][0-9][0-9] x /!s/\(.*(C).*\)/'$PRI_C'\1'$DEFAULT'/g' | sed '/^[0-9][0-9][0-9] x /!s/\(.*([A-Z]).*\)/'$PRI_X'\1'$DEFAULT'/'`" + else + command=`sed = "$TMP_FILE" | sed 'N; s/^/ /; s/ *\(.\{3,\}\)\n/\1 /' | sed 's/^ /00/' | sed 's/^ /0/' | sort -f -k2 | sed '/^[0-9][0-9][0-9] x /!s/\(.*(A).*\)/'$PRI_A'\1'$DEFAULT'/g' | sed '/^[0-9][0-9][0-9] x /!s/\(.*(B).*\)/'$PRI_B'\1'$DEFAULT'/g' | sed '/^[0-9][0-9][0-9] x /!s/\(.*(C).*\)/'$PRI_C'\1'$DEFAULT'/g' | sed '/^[0-9][0-9][0-9] x /!s/\(.*([A-Z]).*\)/'$PRI_X'\1'$DEFAULT'/' | grep -i $item ` + shift + shift + for i in $* + do + command=`echo "$command" | grep -i $i ` + done + command=$( \ + echo "$command" \ + | sort -f -k2 \ + | sed 's/'${HIDE_PRIORITY_SUBSTITUTION:-^}'//g' \ + | sed 's/'${HIDE_PROJECTS_SUBSTITUTION:-^}'//g' \ + | sed 's/'${HIDE_CONTEXTS_SUBSTITUTION:-^}'//g' \ + ) + echo -e "$command" + fi + cleanup ;; -"listfile" | "lf" ) - src="$TODO_DIR/$2" + "listfile" | "lf" ) + src="$TODO_DIR/$2" - if [ -z "$3" ]; then - item="" - else - item=$3 - fi - if [ -f "$src" ]; then - if [ -z "$item" ]; then - echo -e "`sed = "$src" | sed 'N; s/^/ /; s/ *\(.\{2,\}\)\n/\1 /' | sed 's/^ /0/' | sort -f -k2 | sed '/^[0-9][0-9] x /!s/\(.*(A).*\)/'$PRI_A'\1'$DEFAULT'/g' | sed '/^[0-9][0-9] x /!s/\(.*(B).*\)/'$PRI_B'\1'$DEFAULT'/g' | sed '/^[0-9][0-9] x /!s/\(.*(C).*\)/'$PRI_C'\1'$DEFAULT'/g' | sed '/^[0-9][0-9] x /!s/\(.*([A-Z]).*\)/'$PRI_X'\1'$DEFAULT'/'`" - if [ $VERBOSE = 1 ]; then - echo "--" - NUMTASKS=$( sed '/./!d' "$src" | wc -l | sed 's/^[[:space:]]*\([0-9]*\).*/\1/') - echo "TODO: $NUMTASKS lines in $src." - fi - else - command=`sed = "$src" | sed 'N; s/^/ /; s/ *\(.\{2,\}\)\n/\1 /' | sed 's/^ /0/' | sort -f -k2 | sed '/^[0-9][0-9] x /!s/\(.*(A).*\)/'$PRI_A'\1'$DEFAULT'/g' | sed '/^[0-9][0-9] x /!s/\(.*(B).*\)/'$PRI_B'\1'$DEFAULT'/g' | sed '/^[0-9][0-9] x /!s/\(.*(C).*\)/'$PRI_C'\1'$DEFAULT'/g' | sed '/^[0-9][0-9] x /!s/\(.*([A-Z]).*\)/'$PRI_X'\1'$DEFAULT'/' | grep -i $item ` - shift - shift - for i in $* - do - command=`echo "$command" | grep -i $i ` - done - command=`echo "$command" | sort -f -k2` - echo -e "$command" - fi - else - echo "TODO: File $src does not exist." - fi - cleanup ;; + if [ -z "$3" ]; then + item="" + else + item=$3 + fi + if [ -f "$src" ]; then + if [ -z "$item" ]; then + echo -e "`sed = "$src" | sed 'N; s/^/ /; s/ *\(.\{2,\}\)\n/\1 /' | sed 's/^ /0/' | sort -f -k2 | sed '/^[0-9][0-9] x /!s/\(.*(A).*\)/'$PRI_A'\1'$DEFAULT'/g' | sed '/^[0-9][0-9] x /!s/\(.*(B).*\)/'$PRI_B'\1'$DEFAULT'/g' | sed '/^[0-9][0-9] x /!s/\(.*(C).*\)/'$PRI_C'\1'$DEFAULT'/g' | sed '/^[0-9][0-9] x /!s/\(.*([A-Z]).*\)/'$PRI_X'\1'$DEFAULT'/'`" + if [ $VERBOSE = 1 ]; then + echo "--" + NUMTASKS=$( sed '/./!d' "$src" | wc -l | sed 's/^[[:space:]]*\([0-9]*\).*/\1/') + echo "TODO: $NUMTASKS lines in $src." + fi + else + command=`sed = "$src" | sed 'N; s/^/ /; s/ *\(.\{2,\}\)\n/\1 /' | sed 's/^ /0/' | sort -f -k2 | sed '/^[0-9][0-9] x /!s/\(.*(A).*\)/'$PRI_A'\1'$DEFAULT'/g' | sed '/^[0-9][0-9] x /!s/\(.*(B).*\)/'$PRI_B'\1'$DEFAULT'/g' | sed '/^[0-9][0-9] x /!s/\(.*(C).*\)/'$PRI_C'\1'$DEFAULT'/g' | sed '/^[0-9][0-9] x /!s/\(.*([A-Z]).*\)/'$PRI_X'\1'$DEFAULT'/' | grep -i $item ` + shift + shift + for i in $* + do + command=`echo "$command" | grep -i $i ` + done + command=`echo "$command" | sort -f -k2` + echo -e "$command" + fi + else + echo "TODO: File $src does not exist." + fi + cleanup ;; -"listcon" | "lsc" ) - gawk '{for(i = 1; i <= NF; i++) print $i}' "$TODO_FILE" | grep '@' | sort | uniq - cleanup ;; + "listcon" | "lsc" ) + gawk '{for(i = 1; i <= NF; i++) print $i}' "$TODO_FILE" | grep '@' | sort | uniq + cleanup ;; -"listproj" | "lsprj" ) - gawk '{for(i = 1; i <= NF; i++) print $i}' "$TODO_FILE" | grep '+' | sort | uniq - cleanup ;; + "listproj" | "lsprj" ) + gawk '{for(i = 1; i <= NF; i++) print $i}' "$TODO_FILE" | grep '+' | sort | uniq + cleanup ;; -"listpri" | "lsp" ) - pri=$( printf "%s\n" "$2" | tr 'a-z' 'A-Z' ) - errmsg="usage: $0 listpri PRIORITY -note: PRIORITY must a single letter from A to Z." + "listpri" | "lsp" ) + pri=$( printf "%s\n" "$2" | tr 'a-z' 'A-Z' ) + errmsg="usage: $0 listpri PRIORITY + note: PRIORITY must a single letter from A to Z." - if [ -z "$pri" ]; then - echo -e "`sed = "$TODO_FILE" | sed 'N; s/^/ /; s/ *\(.\{2,\}\)\n/\1 /' | sed 's/^ /0/' | sort -f -k2 | sed 's/^ /0/' | sort -f -k2 | sed '/^[0-9][0-9] x /!s/\(.*(A).*\)/'$PRI_A'\1'$DEFAULT'/g' | sed '/^[0-9][0-9] x /!s/\(.*(B).*\)/'$PRI_B'\1'$DEFAULT'/g' | sed '/^[0-9][0-9] x /!s/\(.*(C).*\)/'$PRI_C'\1'$DEFAULT'/g' | sed '/^[0-9][0-9] x /!s/\(.*([A-Z]).*\)/'$PRI_X'\1'$DEFAULT'/'`" | grep \([A-Z]\) - if [ $VERBOSE = 1 ]; then - echo "--" - NUMTASKS=$(grep \([A-Z]\) "$TODO_FILE" | wc -l | sed 's/^[[:space:]]*\([0-9]*\).*/\1/') - echo "TODO: $NUMTASKS prioritized tasks in $TODO_FILE." - fi - else - [[ "$pri" = +([A-Z]) ]] || die "$errmsg" + if [ -z "$pri" ]; then + echo -e "`sed = "$TODO_FILE" | sed 'N; s/^/ /; s/ *\(.\{2,\}\)\n/\1 /' | sed 's/^ /0/' | sort -f -k2 | sed 's/^ /0/' | sort -f -k2 | sed '/^[0-9][0-9] x /!s/\(.*(A).*\)/'$PRI_A'\1'$DEFAULT'/g' | sed '/^[0-9][0-9] x /!s/\(.*(B).*\)/'$PRI_B'\1'$DEFAULT'/g' | sed '/^[0-9][0-9] x /!s/\(.*(C).*\)/'$PRI_C'\1'$DEFAULT'/g' | sed '/^[0-9][0-9] x /!s/\(.*([A-Z]).*\)/'$PRI_X'\1'$DEFAULT'/'`" | grep \([A-Z]\) + if [ $VERBOSE = 1 ]; then + echo "--" + NUMTASKS=$(grep \([A-Z]\) "$TODO_FILE" | wc -l | sed 's/^[[:space:]]*\([0-9]*\).*/\1/') + echo "TODO: $NUMTASKS prioritized tasks in $TODO_FILE." + fi + else + [[ "$pri" = +([A-Z]) ]] || die "$errmsg" - echo -e "`sed = "$TODO_FILE" | sed 'N; s/^/ /; s/ *\(.\{2,\}\)\n/\1 /' | sed 's/^ /0/' | sort -f -k2 | sed 's/^ /0/' | sort -f -k2 | sed '/^[0-9][0-9] x /!s/\(.*(A).*\)/'$PRI_A'\1'$DEFAULT'/g' | sed '/^[0-9][0-9] x /!s/\(.*(B).*\)/'$PRI_B'\1'$DEFAULT'/g' | sed '/^[0-9][0-9] x /!s/\(.*(C).*\)/'$PRI_C'\1'$DEFAULT'/g' | sed '/^[0-9][0-9] x /!s/\(.*([A-Z]).*\)/'$PRI_X'\1'$DEFAULT'/'`" | grep \($pri\) - if [ $VERBOSE = 1 ]; then - echo "--" - NUMTASKS=$(grep \($pri\) "$TODO_FILE" | wc -l | sed 's/^[[:space:]]*\([0-9]*\).*/\1/') - echo "TODO: $NUMTASKS tasks prioritized $pri in $TODO_FILE." - fi - fi - cleanup;; + echo -e "`sed = "$TODO_FILE" | sed 'N; s/^/ /; s/ *\(.\{2,\}\)\n/\1 /' | sed 's/^ /0/' | sort -f -k2 | sed 's/^ /0/' | sort -f -k2 | sed '/^[0-9][0-9] x /!s/\(.*(A).*\)/'$PRI_A'\1'$DEFAULT'/g' | sed '/^[0-9][0-9] x /!s/\(.*(B).*\)/'$PRI_B'\1'$DEFAULT'/g' | sed '/^[0-9][0-9] x /!s/\(.*(C).*\)/'$PRI_C'\1'$DEFAULT'/g' | sed '/^[0-9][0-9] x /!s/\(.*([A-Z]).*\)/'$PRI_X'\1'$DEFAULT'/'`" | grep \($pri\) + if [ $VERBOSE = 1 ]; then + echo "--" + NUMTASKS=$(grep \($pri\) "$TODO_FILE" | wc -l | sed 's/^[[:space:]]*\([0-9]*\).*/\1/') + echo "TODO: $NUMTASKS tasks prioritized $pri in $TODO_FILE." + fi + fi + cleanup;; -"move" | "mv" ) - # replace moved line with a blank line when PRESERVE_LINE_NUMBERS is 1 - errmsg="usage: $0 mv ITEM# DEST [SRC]" - item=$2 - dest="$TODO_DIR/$3" - src="$TODO_DIR/$4" + "move" | "mv" ) + # replace moved line with a blank line when PRESERVE_LINE_NUMBERS is 1 + errmsg="usage: $0 mv ITEM# DEST [SRC]" + item=$2 + dest="$TODO_DIR/$3" + src="$TODO_DIR/$4" - [ -z "$item" ] && die "$errmsg" - [ -z "$4" ] && src="$TODO_FILE" - [ -z "$dest" ] && die "$errmsg" + [ -z "$item" ] && die "$errmsg" + [ -z "$4" ] && src="$TODO_FILE" + [ -z "$dest" ] && die "$errmsg" - [[ "$item" = +([0-9]) ]] || die "$errmsg" + [[ "$item" = +([0-9]) ]] || die "$errmsg" - if [ -f "$src" ]; then - if [ -f "$dest" ]; then - if sed -ne "$item p" "$src" | grep "^."; then - MOVEME=$(sed "$item!d" "$src") - if [ $FORCE = 0 ]; then - echo "Move '$MOVEME' from $src to $dest? (y/n)" - read ANSWER - else - ANSWER="y" - fi - if [ "$ANSWER" = "y" ]; then - if [ $PRESERVE_LINE_NUMBERS = 0 ]; then - # delete line (changes line numbers) - sed -i.bak -e $item"s/^.*//" -e '/./!d' "$src" - else - # leave blank line behind (preserves line numbers) - sed -i.bak -e $item"s/^.*//" "$src" - fi - echo "$MOVEME" >> "$dest" + if [ -f "$src" ]; then + if [ -f "$dest" ]; then + if sed -ne "$item p" "$src" | grep "^."; then + MOVEME=$(sed "$item!d" "$src") + if [ $FORCE = 0 ]; then + echo "Move '$MOVEME' from $src to $dest? (y/n)" + read ANSWER + else + ANSWER="y" + fi + if [ "$ANSWER" = "y" ]; then + if [ $PRESERVE_LINE_NUMBERS = 0 ]; then + # delete line (changes line numbers) + sed -i.bak -e $item"s/^.*//" -e '/./!d' "$src" + else + # leave blank line behind (preserves line numbers) + sed -i.bak -e $item"s/^.*//" "$src" + fi + echo "$MOVEME" >> "$dest" - [[ $VERBOSE = 1 ]] && echo "TODO: '$MOVEME' moved from '$src' to '$dest'." - cleanup - else - echo "TODO: No tasks moved." - fi - else - echo "$item: No such item in $src." - fi - else - echo "TODO: Destination file $dest does not exist." - fi - else - echo "TODO: Source file $src does not exist." - fi - cleanup;; + [[ $VERBOSE = 1 ]] && echo "TODO: '$MOVEME' moved from '$src' to '$dest'." + cleanup + else + echo "TODO: No tasks moved." + fi + else + echo "$item: No such item in $src." + fi + else + echo "TODO: Destination file $dest does not exist." + fi + else + echo "TODO: Source file $src does not exist." + fi + cleanup;; -"prepend" | "prep" ) - errmsg="usage: $0 prepend ITEM# \"TEXT TO PREPEND\"" - shift; item=$1; shift + "prepend" | "prep" ) + errmsg="usage: $0 prepend ITEM# \"TEXT TO PREPEND\"" + shift; item=$1; shift - [ -z "$item" ] && die "$errmsg" - [[ "$item" = +([0-9]) ]] || die "$errmsg" + [ -z "$item" ] && die "$errmsg" + [[ "$item" = +([0-9]) ]] || die "$errmsg" - todo=$(sed "$item!d" "$TODO_FILE") - [ -z "$todo" ] && die "$item: No such todo." + todo=$(sed "$item!d" "$TODO_FILE") + [ -z "$todo" ] && die "$item: No such todo." - if [[ -z "$1" && $FORCE = 0 ]]; then - echo -n "Prepend: " - read input - else - input=$* - fi + if [[ -z "$1" && $FORCE = 0 ]]; then + echo -n "Prepend: " + read input + else + input=$* + fi - if sed -i.bak $item" s|^.*|$input &|" "$TODO_FILE"; then - newtodo=$(sed "$item!d" "$TODO_FILE") - [[ $VERBOSE = 1 ]] && echo "$item: $newtodo" - else - echo "TODO: Error prepending task $item." - fi - cleanup;; + if sed -i.bak $item" s|^.*|$input &|" "$TODO_FILE"; then + newtodo=$(sed "$item!d" "$TODO_FILE") + [[ $VERBOSE = 1 ]] && echo "$item: $newtodo" + else + echo "TODO: Error prepending task $item." + fi + cleanup;; -"pri" | "p" ) - item=$2 - newpri=$( printf "%s\n" "$3" | tr 'a-z' 'A-Z' ) + "pri" | "p" ) + item=$2 + newpri=$( printf "%s\n" "$3" | tr 'a-z' 'A-Z' ) - errmsg="usage: $0 pri ITEM# PRIORITY -note: PRIORITY must be anywhere from A to Z." + errmsg="usage: $0 pri ITEM# PRIORITY + note: PRIORITY must be anywhere from A to Z." - [ "$#" -ne 3 ] && die "$errmsg" - [[ "$item" = +([0-9]) ]] || die "$errmsg" - [[ "$newpri" = +([A-Z]) ]] || die "$errmsg" + [ "$#" -ne 3 ] && die "$errmsg" + [[ "$item" = +([0-9]) ]] || die "$errmsg" + [[ "$newpri" = +([A-Z]) ]] || die "$errmsg" - sed -e $item"s/^(.*) //" -e $item"s/^/($newpri) /" "$TODO_FILE" > /dev/null 2>&1 + sed -e $item"s/^(.*) //" -e $item"s/^/($newpri) /" "$TODO_FILE" > /dev/null 2>&1 - if [ "$?" -eq 0 ]; then - #it's all good, continue - sed -i.bak -e $2"s/^(.*) //" -e $2"s/^/($newpri) /" "$TODO_FILE" - NEWTODO=$(sed "$2!d" "$TODO_FILE") - [[ $VERBOSE = 1 ]] && echo -e "`echo "$item: $NEWTODO"`" - [[ $VERBOSE = 1 ]] && echo "TODO: $item prioritized ($newpri)." - cleanup - else - die "$errmsg" - fi;; + if [ "$?" -eq 0 ]; then + #it's all good, continue + sed -i.bak -e $2"s/^(.*) //" -e $2"s/^/($newpri) /" "$TODO_FILE" + NEWTODO=$(sed "$2!d" "$TODO_FILE") + [[ $VERBOSE = 1 ]] && echo -e "`echo "$item: $NEWTODO"`" + [[ $VERBOSE = 1 ]] && echo "TODO: $item prioritized ($newpri)." + cleanup + else + die "$errmsg" + fi;; -"replace" ) - errmsg="usage: $0 replace ITEM# \"UPDATED ITEM\"" - shift; item=$1; shift + "replace" ) + errmsg="usage: $0 replace ITEM# \"UPDATED ITEM\"" + shift; item=$1; shift - [ -z "$item" ] && die "$errmsg" - [[ "$item" = +([0-9]) ]] || die "$errmsg" + [ -z "$item" ] && die "$errmsg" + [[ "$item" = +([0-9]) ]] || die "$errmsg" - todo=$(sed "$item!d" "$TODO_FILE") - [ -z "$todo" ] && die "$item: No such todo." + todo=$(sed "$item!d" "$TODO_FILE") + [ -z "$todo" ] && die "$item: No such todo." - if [[ -z "$1" && $FORCE = 0 ]]; then - echo -n "Replacement: " - read input - else - input=$* - fi + if [[ -z "$1" && $FORCE = 0 ]]; then + echo -n "Replacement: " + read input + else + input=$* + fi - sed -i.bak $item" s|^.*|$input|" "$TODO_FILE" - [[ $VERBOSE = 1 ]] && NEWTODO=$(head -$item "$TODO_FILE" | tail -1) - [[ $VERBOSE = 1 ]] && echo "replaced with" - [[ $VERBOSE = 1 ]] && echo "$item: $NEWTODO" - cleanup;; + sed -i.bak $item" s|^.*|$input|" "$TODO_FILE" + [[ $VERBOSE = 1 ]] && NEWTODO=$(head -$item "$TODO_FILE" | tail -1) + [[ $VERBOSE = 1 ]] && echo "replaced with" + [[ $VERBOSE = 1 ]] && echo "$item: $NEWTODO" + cleanup;; -"report" ) - #archive first - sed '/^x /!d' "$TODO_FILE" >> "$DONE_FILE" - sed -i.bak '/^x /d' "$TODO_FILE" + "report" ) + #archive first + sed '/^x /!d' "$TODO_FILE" >> "$DONE_FILE" + sed -i.bak '/^x /d' "$TODO_FILE" - NUMLINES=$(wc -l "$TODO_FILE" | sed 's/^[[:space:]]*\([0-9]*\).*/\1/') - if [ $NUMLINES = "0" ]; then - echo "datetime todos dones" >> "$REPORT_FILE" - fi - #now report - TOTAL=$(cat "$TODO_FILE" | wc -l | sed 's/^[ \t]*//') - TDONE=$(cat "$DONE_FILE" | wc -l | sed 's/^[ \t]*//') - TECHO=$(echo $(date +%Y-%m-%d-%T); echo ' '; echo $TOTAL; echo ' '; - echo $TDONE) - echo $TECHO >> "$REPORT_FILE" - [[ $VERBOSE = 1 ]] && echo "TODO: Report file updated." - cat "$REPORT_FILE" - cleanup;; + NUMLINES=$(wc -l "$TODO_FILE" | sed 's/^[[:space:]]*\([0-9]*\).*/\1/') + if [ $NUMLINES = "0" ]; then + echo "datetime todos dones" >> "$REPORT_FILE" + fi + #now report + TOTAL=$(cat "$TODO_FILE" | wc -l | sed 's/^[ \t]*//') + TDONE=$(cat "$DONE_FILE" | wc -l | sed 's/^[ \t]*//') + TECHO=$(echo $(date +%Y-%m-%d-%T); echo ' '; echo $TOTAL; echo ' '; + echo $TDONE) + echo $TECHO >> "$REPORT_FILE" + [[ $VERBOSE = 1 ]] && echo "TODO: Report file updated." + cat "$REPORT_FILE" + cleanup;; -* ) - usage - if [ -d "$HOME/.todo.actions.d" ]; then - if [ -x "$HOME/.todo.actions.d/$action" ]; then - CFG_FILE="$CFG_FILE" "$HOME/.todo.actions.d/$action" "$@" - else - usage - fi - else - usage - fi -esac + * ) + usage + ;; + esac +fi From e6649e6293d211be398cd69e6e5f26ca4def51d6 Mon Sep 17 00:00:00 2001 From: "David A. Harding" Date: Sun, 8 Mar 2009 11:25:12 -0400 Subject: [PATCH 03/12] Removed Extended Regexes from Hiding Code . Dave Hein noticed the extended regular expressions (regex) in the original patch don't work by default on Mac OS X (FreeBSD sed). Now using his suggested regex format: [[:space:]]@[^[:space:]]\{1,\} . Also changed: I misapplied part of the patch originally. That's now fixed. I expanded part of the regular expression in the list sub-expression so that I could change part of the coloring code. --- todo.sh | 47 +++++++++++++++++++++++++---------------------- 1 file changed, 25 insertions(+), 22 deletions(-) diff --git a/todo.sh b/todo.sh index c3cff81..27a23c8 100644 --- a/todo.sh +++ b/todo.sh @@ -220,12 +220,7 @@ do unset HIDE_CONTEXTS_SUBSTITUTION else ## One or odd value -- hide context names - # - ## Match: \(^\|[[:space:]] beginning of line or a space - ## @ literal context label - ## [^[:space:]]\+ Anything besides whitespace one - ## or more times - HIDE_CONTEXTS_SUBSTITUTION="\(^\|[[:space:]]\)@[^[:space:]]\+" + HIDE_CONTEXTS_SUBSTITUTION='[[:space:]]@[^[:space:]]\{1,\}' fi ;; '+' ) @@ -241,11 +236,7 @@ do unset HIDE_PROJECTS_SUBSTITUTION else ## One or odd value -- hide project names - ## Match: \(^\|[[:space:]] beginning of line or a space - ## @ literal context label - ## [^[:space:]]\+ Anything besides whitespace one - ## or more times - HIDE_PROJECTS_SUBSTITUTION="\(^\|[[:space:]]\)+[^[:space:]]\+" + HIDE_PROJECTS_SUBSTITUTION='[[:space:]][+][^[:space:]]\{1,\}' fi ;; a ) @@ -484,7 +475,6 @@ else "list" | "ls" ) item=$2 if [ -z "$item" ]; then - echo "--" echo -e "$( \ sed = "$TODO_FILE" \ | sed 'N; s/^/ /; s/ *\(.\{2,\}\)\n/\1 /' \ @@ -494,23 +484,42 @@ else s/\(.*(A).*\)/'$PRI_A'\1 '$DEFAULT'/g; s/\(.*(B).*\)/'$PRI_B'\1 '$DEFAULT'/g; s/\(.*(C).*\)/'$PRI_C'\1 '$DEFAULT'/g; - s/\(.*([A-Z]).*\)/'$PRI_X'\1'$DEFAULT'/g; + s/\(.*([D-Z]).*\)/'$PRI_X'\1 '$DEFAULT'/g; }' \ | sed 's/'${HIDE_PRIORITY_SUBSTITUTION:-^}'//g' \ | sed 's/'${HIDE_PROJECTS_SUBSTITUTION:-^}'//g' \ | sed 's/'${HIDE_CONTEXTS_SUBSTITUTION:-^}'//g' \ )" + echo "--" NUMTASKS=$(wc -l "$TODO_FILE" | sed 's/^[[:space:]]*\([0-9]*\).*/\1/') echo "TODO: $NUMTASKS tasks in $TODO_FILE." else - command=`sed = "$TODO_FILE" | sed 'N; s/^/ /; s/ *\(.\{2,\}\)\n/\1 /' | sed 's/^ /0/' | sort -f -k2 | sed '/^[0-9][0-9] x /!s/\(.*(A).*\)/'$PRI_A'\1'$DEFAULT'/g' | sed '/^[0-9][0-9] x /!s/\(.*(B).*\)/'$PRI_B'\1'$DEFAULT'/g' | sed '/^[0-9][0-9] x /!s/\(.*(C).*\)/'$PRI_C'\1'$DEFAULT'/g' | sed '/^[0-9][0-9] x /!s/\(.*([A-Z]).*\)/'$PRI_X'\1'$DEFAULT'/' | grep -i $item ` + command=$( + sed = "$TODO_FILE" \ + | sed 'N; s/^/ /; s/ *\(.\{2,\}\)\n/\1 /' \ + | sed 's/^ /0/' \ + | sort -f -k2 \ + | sed '/^[0-9][0-9] x /! { + s/\(.*(A).*\)/'$PRI_A'\1 '$DEFAULT'/g; + s/\(.*(B).*\)/'$PRI_B'\1 '$DEFAULT'/g; + s/\(.*(C).*\)/'$PRI_C'\1 '$DEFAULT'/g; + s/\(.*([D-Z]).*\)/'$PRI_X'\1 '$DEFAULT'/g; + }' \ + | grep -i $item + ) shift shift for i in $* do command=`echo "$command" | grep -i $i ` done - command=`echo "$command" | sort -f -k2` + command=$( \ + echo "$command" \ + | sort -f -k2 \ + | sed 's/'${HIDE_PRIORITY_SUBSTITUTION:-^}'//g' \ + | sed 's/'${HIDE_PROJECTS_SUBSTITUTION:-^}'//g' \ + | sed 's/'${HIDE_CONTEXTS_SUBSTITUTION:-^}'//g' \ + ) echo -e "$command" fi cleanup ;; @@ -529,13 +538,7 @@ else do command=`echo "$command" | grep -i $i ` done - command=$( \ - echo "$command" \ - | sort -f -k2 \ - | sed 's/'${HIDE_PRIORITY_SUBSTITUTION:-^}'//g' \ - | sed 's/'${HIDE_PROJECTS_SUBSTITUTION:-^}'//g' \ - | sed 's/'${HIDE_CONTEXTS_SUBSTITUTION:-^}'//g' \ - ) + command=`echo "$command" | sort -f -k2` echo -e "$command" fi cleanup ;; From 98646a575a29fff8b75b1a881ca96c50128f9ef1 Mon Sep 17 00:00:00 2001 From: "David A. Harding" Date: Sun, 8 Mar 2009 11:46:26 -0400 Subject: [PATCH 04/12] Exit If .todo.actions.d Script Is Run . Suggested by Philippe Teuwen, this patch undoes a lot of the unnecessary formating changes in my previous patch. --- todo.sh | 857 ++++++++++++++++++++++++++++---------------------------- 1 file changed, 430 insertions(+), 427 deletions(-) diff --git a/todo.sh b/todo.sh index 27a23c8..016d280 100644 --- a/todo.sh +++ b/todo.sh @@ -323,434 +323,437 @@ shopt -s extglob # == HANDLE ACTION == action=$( printf "%s\n" "$1" | tr 'A-Z' 'a-z' ) +## Run and quit if there's a actions script if [ -d "$HOME/.todo.actions.d" -a -x "$HOME/.todo.actions.d/$action" ] then CFG_FILE="$CFG_FILE" "$HOME/.todo.actions.d/$action" "$@" -else - case $action in - "add" | "a") - if [[ -z "$2" && $FORCE = 0 ]]; then - echo -n "Add: " - read input - else - [ -z "$2" ] && die "usage: $0 add \"TODO ITEM\"" - shift - input=$* - fi - - if [[ $DATE_ON_ADD = 1 ]]; then - now=`date '+%Y-%m-%d'` - input="$now $input" - fi - echo "$input" >> "$TODO_FILE" - TASKNUM=$(wc -l "$TODO_FILE" | sed 's/^[[:space:]]*\([0-9]*\).*/\1/') - [[ $VERBOSE = 1 ]] && echo "TODO: '$input' added on line $TASKNUM." - cleanup;; - - "addto" ) - [ -z "$2" ] && die "usage: $0 addto DEST \"TODO ITEM\"" - dest="$TODO_DIR/$2" - [ -z "$3" ] && die "usage: $0 addto DEST \"TODO ITEM\"" - shift - shift - input=$* - - if [ -f "$dest" ]; then - echo "$input" >> "$dest" - TASKNUM=$(wc -l "$dest" | sed 's/^[[:space:]]*\([0-9]*\).*/\1/') - [[ $VERBOSE = 1 ]] && echo "TODO: '$input' added to $dest on line $TASKNUM." - else - echo "TODO: Destination file $dest does not exist." - fi - cleanup;; - - "append" | "app" ) - errmsg="usage: $0 append ITEM# \"TEXT TO APPEND\"" - shift; item=$1; shift - - [ -z "$item" ] && die "$errmsg" - [[ "$item" = +([0-9]) ]] || die "$errmsg" - todo=$(sed "$item!d" "$TODO_FILE") - [ -z "$todo" ] && die "$item: No such todo." - if [[ -z "$1" && $FORCE = 0 ]]; then - echo -n "Append: " - read input - else - input=$* - fi - if sed -i.bak $item" s|^.*|& $input|" "$TODO_FILE"; then - newtodo=$(sed "$item!d" "$TODO_FILE") - [[ $VERBOSE = 1 ]] && echo "$item: $newtodo" - else - echo "TODO: Error appending task $item." - fi - cleanup;; - - "archive" ) - archive;; - - "del" | "rm" ) - # replace deleted line with a blank line when PRESERVE_LINE_NUMBERS is 1 - errmsg="usage: $0 del ITEM#" - item=$2 - [ -z "$item" ] && die "$errmsg" - - if [ -z "$3" ]; then - - [[ "$item" = +([0-9]) ]] || die "$errmsg" - if sed -ne "$item p" "$TODO_FILE" | grep "^."; then - DELETEME=$(sed "$2!d" "$TODO_FILE") - - if [ $FORCE = 0 ]; then - echo "Delete '$DELETEME'? (y/n)" - read ANSWER - else - ANSWER="y" - fi - if [ "$ANSWER" = "y" ]; then - if [ $PRESERVE_LINE_NUMBERS = 0 ]; then - # delete line (changes line numbers) - sed -i.bak -e $2"s/^.*//" -e '/./!d' "$TODO_FILE" - else - # leave blank line behind (preserves line numbers) - sed -i.bak -e $2"s/^.*//" "$TODO_FILE" - fi - [[ $VERBOSE = 1 ]] && echo "TODO: '$DELETEME' deleted." - cleanup - else - echo "TODO: No tasks were deleted." - fi - else - echo "$item: No such todo." - fi - else - sed -i.bak -e $item"s/$3/ /g" "$TODO_FILE" - [[ $VERBOSE = 1 ]] && echo "TODO: $3 removed from $item." - fi ;; - - "depri" | "dp" ) - item=$2 - errmsg="usage: $0 depri ITEM#" - - todo=$(sed "$item!d" "$TODO_FILE") - [ -z "$todo" ] && die "$item: No such todo." - [[ "$item" = +([0-9]) ]] || die "$errmsg" - - sed -e $item"s/^(.*) //" "$TODO_FILE" > /dev/null 2>&1 - - if [ "$?" -eq 0 ]; then - #it's all good, continue - sed -i.bak -e $2"s/^(.*) //" "$TODO_FILE" - NEWTODO=$(sed "$2!d" "$TODO_FILE") - [[ $VERBOSE = 1 ]] && echo -e "`echo "$item: $NEWTODO"`" - [[ $VERBOSE = 1 ]] && echo "TODO: $item deprioritized." - cleanup - else - die "$errmsg" - fi;; - - "do" ) - errmsg="usage: $0 do ITEM#" - item=$2 - [ -z "$item" ] && die "$errmsg" - [[ "$item" = +([0-9]) ]] || die "$errmsg" - - todo=$(sed "$item!d" "$TODO_FILE") - [ -z "$todo" ] && die "$item: No such todo." - - now=`date '+%Y-%m-%d'` - # remove priority once item is done - sed -i.bak $item"s/^(.*) //" "$TODO_FILE" - sed -i.bak $item"s|^|&x $now |" "$TODO_FILE" - newtodo=$(sed "$item!d" "$TODO_FILE") - [[ $VERBOSE = 1 ]] && echo "$item: $newtodo" - [[ $VERBOSE = 1 ]] && echo "TODO: $item marked as done." - - if [ $AUTO_ARCHIVE = 1 ]; then - archive - fi - cleanup ;; - - - "list" | "ls" ) - item=$2 - if [ -z "$item" ]; then - echo -e "$( \ - sed = "$TODO_FILE" \ - | sed 'N; s/^/ /; s/ *\(.\{2,\}\)\n/\1 /' \ - | sed 's/^ /0/' \ - | sort -f -k2 \ - | sed '/^[0-9][0-9] x /! { - s/\(.*(A).*\)/'$PRI_A'\1 '$DEFAULT'/g; - s/\(.*(B).*\)/'$PRI_B'\1 '$DEFAULT'/g; - s/\(.*(C).*\)/'$PRI_C'\1 '$DEFAULT'/g; - s/\(.*([D-Z]).*\)/'$PRI_X'\1 '$DEFAULT'/g; - }' \ - | sed 's/'${HIDE_PRIORITY_SUBSTITUTION:-^}'//g' \ - | sed 's/'${HIDE_PROJECTS_SUBSTITUTION:-^}'//g' \ - | sed 's/'${HIDE_CONTEXTS_SUBSTITUTION:-^}'//g' \ - )" - echo "--" - NUMTASKS=$(wc -l "$TODO_FILE" | sed 's/^[[:space:]]*\([0-9]*\).*/\1/') - echo "TODO: $NUMTASKS tasks in $TODO_FILE." - else - command=$( - sed = "$TODO_FILE" \ - | sed 'N; s/^/ /; s/ *\(.\{2,\}\)\n/\1 /' \ - | sed 's/^ /0/' \ - | sort -f -k2 \ - | sed '/^[0-9][0-9] x /! { - s/\(.*(A).*\)/'$PRI_A'\1 '$DEFAULT'/g; - s/\(.*(B).*\)/'$PRI_B'\1 '$DEFAULT'/g; - s/\(.*(C).*\)/'$PRI_C'\1 '$DEFAULT'/g; - s/\(.*([D-Z]).*\)/'$PRI_X'\1 '$DEFAULT'/g; - }' \ - | grep -i $item - ) - shift - shift - for i in $* - do - command=`echo "$command" | grep -i $i ` - done - command=$( \ - echo "$command" \ - | sort -f -k2 \ - | sed 's/'${HIDE_PRIORITY_SUBSTITUTION:-^}'//g' \ - | sed 's/'${HIDE_PROJECTS_SUBSTITUTION:-^}'//g' \ - | sed 's/'${HIDE_CONTEXTS_SUBSTITUTION:-^}'//g' \ - ) - echo -e "$command" - fi - cleanup ;; - - "listall" | "lsa" ) - item=$2 - cat "$TODO_FILE" "$DONE_FILE" > "$TMP_FILE" - - if [ -z "$item" ]; then - echo -e "`sed = "$TMP_FILE" | sed 'N; s/^/ /; s/ *\(.\{3,\}\)\n/\1 /' | sed 's/^ /00/' | sed 's/^ /0/' | sort -f -k2 | sed '/^[0-9][0-9][0-9] x /!s/\(.*(A).*\)/'$PRI_A'\1'$DEFAULT'/g' | sed '/^[0-9][0-9][0-9] x /!s/\(.*(B).*\)/'$PRI_B'\1'$DEFAULT'/g' | sed '/^[0-9][0-9][0-9] x /!s/\(.*(C).*\)/'$PRI_C'\1'$DEFAULT'/g' | sed '/^[0-9][0-9][0-9] x /!s/\(.*([A-Z]).*\)/'$PRI_X'\1'$DEFAULT'/'`" - else - command=`sed = "$TMP_FILE" | sed 'N; s/^/ /; s/ *\(.\{3,\}\)\n/\1 /' | sed 's/^ /00/' | sed 's/^ /0/' | sort -f -k2 | sed '/^[0-9][0-9][0-9] x /!s/\(.*(A).*\)/'$PRI_A'\1'$DEFAULT'/g' | sed '/^[0-9][0-9][0-9] x /!s/\(.*(B).*\)/'$PRI_B'\1'$DEFAULT'/g' | sed '/^[0-9][0-9][0-9] x /!s/\(.*(C).*\)/'$PRI_C'\1'$DEFAULT'/g' | sed '/^[0-9][0-9][0-9] x /!s/\(.*([A-Z]).*\)/'$PRI_X'\1'$DEFAULT'/' | grep -i $item ` - shift - shift - for i in $* - do - command=`echo "$command" | grep -i $i ` - done - command=`echo "$command" | sort -f -k2` - echo -e "$command" - fi - cleanup ;; - - - "listfile" | "lf" ) - src="$TODO_DIR/$2" - - if [ -z "$3" ]; then - item="" - else - item=$3 - fi - if [ -f "$src" ]; then - if [ -z "$item" ]; then - echo -e "`sed = "$src" | sed 'N; s/^/ /; s/ *\(.\{2,\}\)\n/\1 /' | sed 's/^ /0/' | sort -f -k2 | sed '/^[0-9][0-9] x /!s/\(.*(A).*\)/'$PRI_A'\1'$DEFAULT'/g' | sed '/^[0-9][0-9] x /!s/\(.*(B).*\)/'$PRI_B'\1'$DEFAULT'/g' | sed '/^[0-9][0-9] x /!s/\(.*(C).*\)/'$PRI_C'\1'$DEFAULT'/g' | sed '/^[0-9][0-9] x /!s/\(.*([A-Z]).*\)/'$PRI_X'\1'$DEFAULT'/'`" - if [ $VERBOSE = 1 ]; then - echo "--" - NUMTASKS=$( sed '/./!d' "$src" | wc -l | sed 's/^[[:space:]]*\([0-9]*\).*/\1/') - echo "TODO: $NUMTASKS lines in $src." - fi - else - command=`sed = "$src" | sed 'N; s/^/ /; s/ *\(.\{2,\}\)\n/\1 /' | sed 's/^ /0/' | sort -f -k2 | sed '/^[0-9][0-9] x /!s/\(.*(A).*\)/'$PRI_A'\1'$DEFAULT'/g' | sed '/^[0-9][0-9] x /!s/\(.*(B).*\)/'$PRI_B'\1'$DEFAULT'/g' | sed '/^[0-9][0-9] x /!s/\(.*(C).*\)/'$PRI_C'\1'$DEFAULT'/g' | sed '/^[0-9][0-9] x /!s/\(.*([A-Z]).*\)/'$PRI_X'\1'$DEFAULT'/' | grep -i $item ` - shift - shift - for i in $* - do - command=`echo "$command" | grep -i $i ` - done - command=`echo "$command" | sort -f -k2` - echo -e "$command" - fi - else - echo "TODO: File $src does not exist." - fi - cleanup ;; - - "listcon" | "lsc" ) - gawk '{for(i = 1; i <= NF; i++) print $i}' "$TODO_FILE" | grep '@' | sort | uniq - cleanup ;; - - "listproj" | "lsprj" ) - gawk '{for(i = 1; i <= NF; i++) print $i}' "$TODO_FILE" | grep '+' | sort | uniq - cleanup ;; - - - "listpri" | "lsp" ) - pri=$( printf "%s\n" "$2" | tr 'a-z' 'A-Z' ) - errmsg="usage: $0 listpri PRIORITY - note: PRIORITY must a single letter from A to Z." - - if [ -z "$pri" ]; then - echo -e "`sed = "$TODO_FILE" | sed 'N; s/^/ /; s/ *\(.\{2,\}\)\n/\1 /' | sed 's/^ /0/' | sort -f -k2 | sed 's/^ /0/' | sort -f -k2 | sed '/^[0-9][0-9] x /!s/\(.*(A).*\)/'$PRI_A'\1'$DEFAULT'/g' | sed '/^[0-9][0-9] x /!s/\(.*(B).*\)/'$PRI_B'\1'$DEFAULT'/g' | sed '/^[0-9][0-9] x /!s/\(.*(C).*\)/'$PRI_C'\1'$DEFAULT'/g' | sed '/^[0-9][0-9] x /!s/\(.*([A-Z]).*\)/'$PRI_X'\1'$DEFAULT'/'`" | grep \([A-Z]\) - if [ $VERBOSE = 1 ]; then - echo "--" - NUMTASKS=$(grep \([A-Z]\) "$TODO_FILE" | wc -l | sed 's/^[[:space:]]*\([0-9]*\).*/\1/') - echo "TODO: $NUMTASKS prioritized tasks in $TODO_FILE." - fi - else - [[ "$pri" = +([A-Z]) ]] || die "$errmsg" - - echo -e "`sed = "$TODO_FILE" | sed 'N; s/^/ /; s/ *\(.\{2,\}\)\n/\1 /' | sed 's/^ /0/' | sort -f -k2 | sed 's/^ /0/' | sort -f -k2 | sed '/^[0-9][0-9] x /!s/\(.*(A).*\)/'$PRI_A'\1'$DEFAULT'/g' | sed '/^[0-9][0-9] x /!s/\(.*(B).*\)/'$PRI_B'\1'$DEFAULT'/g' | sed '/^[0-9][0-9] x /!s/\(.*(C).*\)/'$PRI_C'\1'$DEFAULT'/g' | sed '/^[0-9][0-9] x /!s/\(.*([A-Z]).*\)/'$PRI_X'\1'$DEFAULT'/'`" | grep \($pri\) - if [ $VERBOSE = 1 ]; then - echo "--" - NUMTASKS=$(grep \($pri\) "$TODO_FILE" | wc -l | sed 's/^[[:space:]]*\([0-9]*\).*/\1/') - echo "TODO: $NUMTASKS tasks prioritized $pri in $TODO_FILE." - fi - fi - cleanup;; - - "move" | "mv" ) - # replace moved line with a blank line when PRESERVE_LINE_NUMBERS is 1 - errmsg="usage: $0 mv ITEM# DEST [SRC]" - item=$2 - dest="$TODO_DIR/$3" - src="$TODO_DIR/$4" - - [ -z "$item" ] && die "$errmsg" - [ -z "$4" ] && src="$TODO_FILE" - [ -z "$dest" ] && die "$errmsg" - - [[ "$item" = +([0-9]) ]] || die "$errmsg" - - if [ -f "$src" ]; then - if [ -f "$dest" ]; then - if sed -ne "$item p" "$src" | grep "^."; then - MOVEME=$(sed "$item!d" "$src") - if [ $FORCE = 0 ]; then - echo "Move '$MOVEME' from $src to $dest? (y/n)" - read ANSWER - else - ANSWER="y" - fi - if [ "$ANSWER" = "y" ]; then - if [ $PRESERVE_LINE_NUMBERS = 0 ]; then - # delete line (changes line numbers) - sed -i.bak -e $item"s/^.*//" -e '/./!d' "$src" - else - # leave blank line behind (preserves line numbers) - sed -i.bak -e $item"s/^.*//" "$src" - fi - echo "$MOVEME" >> "$dest" - - [[ $VERBOSE = 1 ]] && echo "TODO: '$MOVEME' moved from '$src' to '$dest'." - cleanup - else - echo "TODO: No tasks moved." - fi - else - echo "$item: No such item in $src." - fi - else - echo "TODO: Destination file $dest does not exist." - fi - else - echo "TODO: Source file $src does not exist." - fi - cleanup;; - - "prepend" | "prep" ) - errmsg="usage: $0 prepend ITEM# \"TEXT TO PREPEND\"" - shift; item=$1; shift - - [ -z "$item" ] && die "$errmsg" - [[ "$item" = +([0-9]) ]] || die "$errmsg" - - todo=$(sed "$item!d" "$TODO_FILE") - [ -z "$todo" ] && die "$item: No such todo." - - if [[ -z "$1" && $FORCE = 0 ]]; then - echo -n "Prepend: " - read input - else - input=$* - fi - - if sed -i.bak $item" s|^.*|$input &|" "$TODO_FILE"; then - newtodo=$(sed "$item!d" "$TODO_FILE") - [[ $VERBOSE = 1 ]] && echo "$item: $newtodo" - else - echo "TODO: Error prepending task $item." - fi - cleanup;; - - "pri" | "p" ) - item=$2 - newpri=$( printf "%s\n" "$3" | tr 'a-z' 'A-Z' ) - - errmsg="usage: $0 pri ITEM# PRIORITY - note: PRIORITY must be anywhere from A to Z." - - [ "$#" -ne 3 ] && die "$errmsg" - [[ "$item" = +([0-9]) ]] || die "$errmsg" - [[ "$newpri" = +([A-Z]) ]] || die "$errmsg" - - sed -e $item"s/^(.*) //" -e $item"s/^/($newpri) /" "$TODO_FILE" > /dev/null 2>&1 - - if [ "$?" -eq 0 ]; then - #it's all good, continue - sed -i.bak -e $2"s/^(.*) //" -e $2"s/^/($newpri) /" "$TODO_FILE" - NEWTODO=$(sed "$2!d" "$TODO_FILE") - [[ $VERBOSE = 1 ]] && echo -e "`echo "$item: $NEWTODO"`" - [[ $VERBOSE = 1 ]] && echo "TODO: $item prioritized ($newpri)." - cleanup - else - die "$errmsg" - fi;; - - "replace" ) - errmsg="usage: $0 replace ITEM# \"UPDATED ITEM\"" - shift; item=$1; shift - - [ -z "$item" ] && die "$errmsg" - [[ "$item" = +([0-9]) ]] || die "$errmsg" - - todo=$(sed "$item!d" "$TODO_FILE") - [ -z "$todo" ] && die "$item: No such todo." - - if [[ -z "$1" && $FORCE = 0 ]]; then - echo -n "Replacement: " - read input - else - input=$* - fi - - sed -i.bak $item" s|^.*|$input|" "$TODO_FILE" - [[ $VERBOSE = 1 ]] && NEWTODO=$(head -$item "$TODO_FILE" | tail -1) - [[ $VERBOSE = 1 ]] && echo "replaced with" - [[ $VERBOSE = 1 ]] && echo "$item: $NEWTODO" - cleanup;; - - "report" ) - #archive first - sed '/^x /!d' "$TODO_FILE" >> "$DONE_FILE" - sed -i.bak '/^x /d' "$TODO_FILE" - - NUMLINES=$(wc -l "$TODO_FILE" | sed 's/^[[:space:]]*\([0-9]*\).*/\1/') - if [ $NUMLINES = "0" ]; then - echo "datetime todos dones" >> "$REPORT_FILE" - fi - #now report - TOTAL=$(cat "$TODO_FILE" | wc -l | sed 's/^[ \t]*//') - TDONE=$(cat "$DONE_FILE" | wc -l | sed 's/^[ \t]*//') - TECHO=$(echo $(date +%Y-%m-%d-%T); echo ' '; echo $TOTAL; echo ' '; - echo $TDONE) - echo $TECHO >> "$REPORT_FILE" - [[ $VERBOSE = 1 ]] && echo "TODO: Report file updated." - cat "$REPORT_FILE" - cleanup;; - - * ) - usage - ;; - esac + cleanup fi + +## Only run if $action isn't found in .todo.actions.d +case $action in +"add" | "a") + if [[ -z "$2" && $FORCE = 0 ]]; then + echo -n "Add: " + read input + else + [ -z "$2" ] && die "usage: $0 add \"TODO ITEM\"" + shift + input=$* + fi + + if [[ $DATE_ON_ADD = 1 ]]; then + now=`date '+%Y-%m-%d'` + input="$now $input" + fi + echo "$input" >> "$TODO_FILE" + TASKNUM=$(wc -l "$TODO_FILE" | sed 's/^[[:space:]]*\([0-9]*\).*/\1/') + [[ $VERBOSE = 1 ]] && echo "TODO: '$input' added on line $TASKNUM." + cleanup;; + +"addto" ) + [ -z "$2" ] && die "usage: $0 addto DEST \"TODO ITEM\"" + dest="$TODO_DIR/$2" + [ -z "$3" ] && die "usage: $0 addto DEST \"TODO ITEM\"" + shift + shift + input=$* + + if [ -f "$dest" ]; then + echo "$input" >> "$dest" + TASKNUM=$(wc -l "$dest" | sed 's/^[[:space:]]*\([0-9]*\).*/\1/') + [[ $VERBOSE = 1 ]] && echo "TODO: '$input' added to $dest on line $TASKNUM." + else + echo "TODO: Destination file $dest does not exist." + fi + cleanup;; + +"append" | "app" ) + errmsg="usage: $0 append ITEM# \"TEXT TO APPEND\"" + shift; item=$1; shift + + [ -z "$item" ] && die "$errmsg" + [[ "$item" = +([0-9]) ]] || die "$errmsg" + todo=$(sed "$item!d" "$TODO_FILE") + [ -z "$todo" ] && die "$item: No such todo." + if [[ -z "$1" && $FORCE = 0 ]]; then + echo -n "Append: " + read input + else + input=$* + fi + if sed -i.bak $item" s|^.*|& $input|" "$TODO_FILE"; then + newtodo=$(sed "$item!d" "$TODO_FILE") + [[ $VERBOSE = 1 ]] && echo "$item: $newtodo" + else + echo "TODO: Error appending task $item." + fi + cleanup;; + +"archive" ) + archive;; + +"del" | "rm" ) + # replace deleted line with a blank line when PRESERVE_LINE_NUMBERS is 1 + errmsg="usage: $0 del ITEM#" + item=$2 + [ -z "$item" ] && die "$errmsg" + + if [ -z "$3" ]; then + + [[ "$item" = +([0-9]) ]] || die "$errmsg" + if sed -ne "$item p" "$TODO_FILE" | grep "^."; then + DELETEME=$(sed "$2!d" "$TODO_FILE") + + if [ $FORCE = 0 ]; then + echo "Delete '$DELETEME'? (y/n)" + read ANSWER + else + ANSWER="y" + fi + if [ "$ANSWER" = "y" ]; then + if [ $PRESERVE_LINE_NUMBERS = 0 ]; then + # delete line (changes line numbers) + sed -i.bak -e $2"s/^.*//" -e '/./!d' "$TODO_FILE" + else + # leave blank line behind (preserves line numbers) + sed -i.bak -e $2"s/^.*//" "$TODO_FILE" + fi + [[ $VERBOSE = 1 ]] && echo "TODO: '$DELETEME' deleted." + cleanup + else + echo "TODO: No tasks were deleted." + fi + else + echo "$item: No such todo." + fi + else + sed -i.bak -e $item"s/$3/ /g" "$TODO_FILE" + [[ $VERBOSE = 1 ]] && echo "TODO: $3 removed from $item." + fi ;; + +"depri" | "dp" ) + item=$2 + errmsg="usage: $0 depri ITEM#" + + todo=$(sed "$item!d" "$TODO_FILE") + [ -z "$todo" ] && die "$item: No such todo." + [[ "$item" = +([0-9]) ]] || die "$errmsg" + + sed -e $item"s/^(.*) //" "$TODO_FILE" > /dev/null 2>&1 + + if [ "$?" -eq 0 ]; then + #it's all good, continue + sed -i.bak -e $2"s/^(.*) //" "$TODO_FILE" + NEWTODO=$(sed "$2!d" "$TODO_FILE") + [[ $VERBOSE = 1 ]] && echo -e "`echo "$item: $NEWTODO"`" + [[ $VERBOSE = 1 ]] && echo "TODO: $item deprioritized." + cleanup + else + die "$errmsg" + fi;; + +"do" ) + errmsg="usage: $0 do ITEM#" + item=$2 + [ -z "$item" ] && die "$errmsg" + [[ "$item" = +([0-9]) ]] || die "$errmsg" + + todo=$(sed "$item!d" "$TODO_FILE") + [ -z "$todo" ] && die "$item: No such todo." + + now=`date '+%Y-%m-%d'` + # remove priority once item is done + sed -i.bak $item"s/^(.*) //" "$TODO_FILE" + sed -i.bak $item"s|^|&x $now |" "$TODO_FILE" + newtodo=$(sed "$item!d" "$TODO_FILE") + [[ $VERBOSE = 1 ]] && echo "$item: $newtodo" + [[ $VERBOSE = 1 ]] && echo "TODO: $item marked as done." + + if [ $AUTO_ARCHIVE = 1 ]; then + archive + fi + cleanup ;; + + +"list" | "ls" ) + item=$2 + if [ -z "$item" ]; then + echo -e "$( \ + sed = "$TODO_FILE" \ + | sed 'N; s/^/ /; s/ *\(.\{2,\}\)\n/\1 /' \ + | sed 's/^ /0/' \ + | sort -f -k2 \ + | sed '/^[0-9][0-9] x /! { + s/\(.*(A).*\)/'$PRI_A'\1 '$DEFAULT'/g; + s/\(.*(B).*\)/'$PRI_B'\1 '$DEFAULT'/g; + s/\(.*(C).*\)/'$PRI_C'\1 '$DEFAULT'/g; + s/\(.*([D-Z]).*\)/'$PRI_X'\1 '$DEFAULT'/g; + }' \ + | sed 's/'${HIDE_PRIORITY_SUBSTITUTION:-^}'//g' \ + | sed 's/'${HIDE_PROJECTS_SUBSTITUTION:-^}'//g' \ + | sed 's/'${HIDE_CONTEXTS_SUBSTITUTION:-^}'//g' \ + )" + echo "--" + NUMTASKS=$(wc -l "$TODO_FILE" | sed 's/^[[:space:]]*\([0-9]*\).*/\1/') + echo "TODO: $NUMTASKS tasks in $TODO_FILE." + else + command=$( + sed = "$TODO_FILE" \ + | sed 'N; s/^/ /; s/ *\(.\{2,\}\)\n/\1 /' \ + | sed 's/^ /0/' \ + | sort -f -k2 \ + | sed '/^[0-9][0-9] x /! { + s/\(.*(A).*\)/'$PRI_A'\1 '$DEFAULT'/g; + s/\(.*(B).*\)/'$PRI_B'\1 '$DEFAULT'/g; + s/\(.*(C).*\)/'$PRI_C'\1 '$DEFAULT'/g; + s/\(.*([D-Z]).*\)/'$PRI_X'\1 '$DEFAULT'/g; + }' \ + | grep -i $item + ) + shift + shift + for i in $* + do + command=`echo "$command" | grep -i $i ` + done + command=$( \ + echo "$command" \ + | sort -f -k2 \ + | sed 's/'${HIDE_PRIORITY_SUBSTITUTION:-^}'//g' \ + | sed 's/'${HIDE_PROJECTS_SUBSTITUTION:-^}'//g' \ + | sed 's/'${HIDE_CONTEXTS_SUBSTITUTION:-^}'//g' \ + ) + echo -e "$command" + fi + cleanup ;; + +"listall" | "lsa" ) + item=$2 + cat "$TODO_FILE" "$DONE_FILE" > "$TMP_FILE" + + if [ -z "$item" ]; then + echo -e "`sed = "$TMP_FILE" | sed 'N; s/^/ /; s/ *\(.\{3,\}\)\n/\1 /' | sed 's/^ /00/' | sed 's/^ /0/' | sort -f -k2 | sed '/^[0-9][0-9][0-9] x /!s/\(.*(A).*\)/'$PRI_A'\1'$DEFAULT'/g' | sed '/^[0-9][0-9][0-9] x /!s/\(.*(B).*\)/'$PRI_B'\1'$DEFAULT'/g' | sed '/^[0-9][0-9][0-9] x /!s/\(.*(C).*\)/'$PRI_C'\1'$DEFAULT'/g' | sed '/^[0-9][0-9][0-9] x /!s/\(.*([A-Z]).*\)/'$PRI_X'\1'$DEFAULT'/'`" + else + command=`sed = "$TMP_FILE" | sed 'N; s/^/ /; s/ *\(.\{3,\}\)\n/\1 /' | sed 's/^ /00/' | sed 's/^ /0/' | sort -f -k2 | sed '/^[0-9][0-9][0-9] x /!s/\(.*(A).*\)/'$PRI_A'\1'$DEFAULT'/g' | sed '/^[0-9][0-9][0-9] x /!s/\(.*(B).*\)/'$PRI_B'\1'$DEFAULT'/g' | sed '/^[0-9][0-9][0-9] x /!s/\(.*(C).*\)/'$PRI_C'\1'$DEFAULT'/g' | sed '/^[0-9][0-9][0-9] x /!s/\(.*([A-Z]).*\)/'$PRI_X'\1'$DEFAULT'/' | grep -i $item ` + shift + shift + for i in $* + do + command=`echo "$command" | grep -i $i ` + done + command=`echo "$command" | sort -f -k2` + echo -e "$command" + fi + cleanup ;; + + +"listfile" | "lf" ) + src="$TODO_DIR/$2" + + if [ -z "$3" ]; then + item="" + else + item=$3 + fi + if [ -f "$src" ]; then + if [ -z "$item" ]; then + echo -e "`sed = "$src" | sed 'N; s/^/ /; s/ *\(.\{2,\}\)\n/\1 /' | sed 's/^ /0/' | sort -f -k2 | sed '/^[0-9][0-9] x /!s/\(.*(A).*\)/'$PRI_A'\1'$DEFAULT'/g' | sed '/^[0-9][0-9] x /!s/\(.*(B).*\)/'$PRI_B'\1'$DEFAULT'/g' | sed '/^[0-9][0-9] x /!s/\(.*(C).*\)/'$PRI_C'\1'$DEFAULT'/g' | sed '/^[0-9][0-9] x /!s/\(.*([A-Z]).*\)/'$PRI_X'\1'$DEFAULT'/'`" + if [ $VERBOSE = 1 ]; then + echo "--" + NUMTASKS=$( sed '/./!d' "$src" | wc -l | sed 's/^[[:space:]]*\([0-9]*\).*/\1/') + echo "TODO: $NUMTASKS lines in $src." + fi + else + command=`sed = "$src" | sed 'N; s/^/ /; s/ *\(.\{2,\}\)\n/\1 /' | sed 's/^ /0/' | sort -f -k2 | sed '/^[0-9][0-9] x /!s/\(.*(A).*\)/'$PRI_A'\1'$DEFAULT'/g' | sed '/^[0-9][0-9] x /!s/\(.*(B).*\)/'$PRI_B'\1'$DEFAULT'/g' | sed '/^[0-9][0-9] x /!s/\(.*(C).*\)/'$PRI_C'\1'$DEFAULT'/g' | sed '/^[0-9][0-9] x /!s/\(.*([A-Z]).*\)/'$PRI_X'\1'$DEFAULT'/' | grep -i $item ` + shift + shift + for i in $* + do + command=`echo "$command" | grep -i $i ` + done + command=`echo "$command" | sort -f -k2` + echo -e "$command" + fi + else + echo "TODO: File $src does not exist." + fi + cleanup ;; + +"listcon" | "lsc" ) + gawk '{for(i = 1; i <= NF; i++) print $i}' "$TODO_FILE" | grep '@' | sort | uniq + cleanup ;; + +"listproj" | "lsprj" ) + gawk '{for(i = 1; i <= NF; i++) print $i}' "$TODO_FILE" | grep '+' | sort | uniq + cleanup ;; + + +"listpri" | "lsp" ) + pri=$( printf "%s\n" "$2" | tr 'a-z' 'A-Z' ) + errmsg="usage: $0 listpri PRIORITY +note: PRIORITY must a single letter from A to Z." + + if [ -z "$pri" ]; then + echo -e "`sed = "$TODO_FILE" | sed 'N; s/^/ /; s/ *\(.\{2,\}\)\n/\1 /' | sed 's/^ /0/' | sort -f -k2 | sed 's/^ /0/' | sort -f -k2 | sed '/^[0-9][0-9] x /!s/\(.*(A).*\)/'$PRI_A'\1'$DEFAULT'/g' | sed '/^[0-9][0-9] x /!s/\(.*(B).*\)/'$PRI_B'\1'$DEFAULT'/g' | sed '/^[0-9][0-9] x /!s/\(.*(C).*\)/'$PRI_C'\1'$DEFAULT'/g' | sed '/^[0-9][0-9] x /!s/\(.*([A-Z]).*\)/'$PRI_X'\1'$DEFAULT'/'`" | grep \([A-Z]\) + if [ $VERBOSE = 1 ]; then + echo "--" + NUMTASKS=$(grep \([A-Z]\) "$TODO_FILE" | wc -l | sed 's/^[[:space:]]*\([0-9]*\).*/\1/') + echo "TODO: $NUMTASKS prioritized tasks in $TODO_FILE." + fi + else + [[ "$pri" = +([A-Z]) ]] || die "$errmsg" + + echo -e "`sed = "$TODO_FILE" | sed 'N; s/^/ /; s/ *\(.\{2,\}\)\n/\1 /' | sed 's/^ /0/' | sort -f -k2 | sed 's/^ /0/' | sort -f -k2 | sed '/^[0-9][0-9] x /!s/\(.*(A).*\)/'$PRI_A'\1'$DEFAULT'/g' | sed '/^[0-9][0-9] x /!s/\(.*(B).*\)/'$PRI_B'\1'$DEFAULT'/g' | sed '/^[0-9][0-9] x /!s/\(.*(C).*\)/'$PRI_C'\1'$DEFAULT'/g' | sed '/^[0-9][0-9] x /!s/\(.*([A-Z]).*\)/'$PRI_X'\1'$DEFAULT'/'`" | grep \($pri\) + if [ $VERBOSE = 1 ]; then + echo "--" + NUMTASKS=$(grep \($pri\) "$TODO_FILE" | wc -l | sed 's/^[[:space:]]*\([0-9]*\).*/\1/') + echo "TODO: $NUMTASKS tasks prioritized $pri in $TODO_FILE." + fi + fi + cleanup;; + +"move" | "mv" ) + # replace moved line with a blank line when PRESERVE_LINE_NUMBERS is 1 + errmsg="usage: $0 mv ITEM# DEST [SRC]" + item=$2 + dest="$TODO_DIR/$3" + src="$TODO_DIR/$4" + + [ -z "$item" ] && die "$errmsg" + [ -z "$4" ] && src="$TODO_FILE" + [ -z "$dest" ] && die "$errmsg" + + [[ "$item" = +([0-9]) ]] || die "$errmsg" + + if [ -f "$src" ]; then + if [ -f "$dest" ]; then + if sed -ne "$item p" "$src" | grep "^."; then + MOVEME=$(sed "$item!d" "$src") + if [ $FORCE = 0 ]; then + echo "Move '$MOVEME' from $src to $dest? (y/n)" + read ANSWER + else + ANSWER="y" + fi + if [ "$ANSWER" = "y" ]; then + if [ $PRESERVE_LINE_NUMBERS = 0 ]; then + # delete line (changes line numbers) + sed -i.bak -e $item"s/^.*//" -e '/./!d' "$src" + else + # leave blank line behind (preserves line numbers) + sed -i.bak -e $item"s/^.*//" "$src" + fi + echo "$MOVEME" >> "$dest" + + [[ $VERBOSE = 1 ]] && echo "TODO: '$MOVEME' moved from '$src' to '$dest'." + cleanup + else + echo "TODO: No tasks moved." + fi + else + echo "$item: No such item in $src." + fi + else + echo "TODO: Destination file $dest does not exist." + fi + else + echo "TODO: Source file $src does not exist." + fi + cleanup;; + +"prepend" | "prep" ) + errmsg="usage: $0 prepend ITEM# \"TEXT TO PREPEND\"" + shift; item=$1; shift + + [ -z "$item" ] && die "$errmsg" + [[ "$item" = +([0-9]) ]] || die "$errmsg" + + todo=$(sed "$item!d" "$TODO_FILE") + [ -z "$todo" ] && die "$item: No such todo." + + if [[ -z "$1" && $FORCE = 0 ]]; then + echo -n "Prepend: " + read input + else + input=$* + fi + + if sed -i.bak $item" s|^.*|$input &|" "$TODO_FILE"; then + newtodo=$(sed "$item!d" "$TODO_FILE") + [[ $VERBOSE = 1 ]] && echo "$item: $newtodo" + else + echo "TODO: Error prepending task $item." + fi + cleanup;; + +"pri" | "p" ) + item=$2 + newpri=$( printf "%s\n" "$3" | tr 'a-z' 'A-Z' ) + + errmsg="usage: $0 pri ITEM# PRIORITY +note: PRIORITY must be anywhere from A to Z." + + [ "$#" -ne 3 ] && die "$errmsg" + [[ "$item" = +([0-9]) ]] || die "$errmsg" + [[ "$newpri" = +([A-Z]) ]] || die "$errmsg" + + sed -e $item"s/^(.*) //" -e $item"s/^/($newpri) /" "$TODO_FILE" > /dev/null 2>&1 + + if [ "$?" -eq 0 ]; then + #it's all good, continue + sed -i.bak -e $2"s/^(.*) //" -e $2"s/^/($newpri) /" "$TODO_FILE" + NEWTODO=$(sed "$2!d" "$TODO_FILE") + [[ $VERBOSE = 1 ]] && echo -e "`echo "$item: $NEWTODO"`" + [[ $VERBOSE = 1 ]] && echo "TODO: $item prioritized ($newpri)." + cleanup + else + die "$errmsg" + fi;; + +"replace" ) + errmsg="usage: $0 replace ITEM# \"UPDATED ITEM\"" + shift; item=$1; shift + + [ -z "$item" ] && die "$errmsg" + [[ "$item" = +([0-9]) ]] || die "$errmsg" + + todo=$(sed "$item!d" "$TODO_FILE") + [ -z "$todo" ] && die "$item: No such todo." + + if [[ -z "$1" && $FORCE = 0 ]]; then + echo -n "Replacement: " + read input + else + input=$* + fi + + sed -i.bak $item" s|^.*|$input|" "$TODO_FILE" + [[ $VERBOSE = 1 ]] && NEWTODO=$(head -$item "$TODO_FILE" | tail -1) + [[ $VERBOSE = 1 ]] && echo "replaced with" + [[ $VERBOSE = 1 ]] && echo "$item: $NEWTODO" + cleanup;; + +"report" ) + #archive first + sed '/^x /!d' "$TODO_FILE" >> "$DONE_FILE" + sed -i.bak '/^x /d' "$TODO_FILE" + + NUMLINES=$(wc -l "$TODO_FILE" | sed 's/^[[:space:]]*\([0-9]*\).*/\1/') + if [ $NUMLINES = "0" ]; then + echo "datetime todos dones" >> "$REPORT_FILE" + fi + #now report + TOTAL=$(cat "$TODO_FILE" | wc -l | sed 's/^[ \t]*//') + TDONE=$(cat "$DONE_FILE" | wc -l | sed 's/^[ \t]*//') + TECHO=$(echo $(date +%Y-%m-%d-%T); echo ' '; echo $TOTAL; echo ' '; + echo $TDONE) + echo $TECHO >> "$REPORT_FILE" + [[ $VERBOSE = 1 ]] && echo "TODO: Report file updated." + cat "$REPORT_FILE" + cleanup;; + +* ) + usage + ;; +esac From 7b2c9f080a3cc59db8fad6e92478d9bfad30c90f Mon Sep 17 00:00:00 2001 From: "David A. Harding" Date: Sun, 8 Mar 2009 12:08:04 -0400 Subject: [PATCH 05/12] Merged In Gina's Latest --- todo.cfg | 56 ++++++++++++++++++++++++++++---------------------------- todo.sh | 2 ++ 2 files changed, 30 insertions(+), 28 deletions(-) diff --git a/todo.cfg b/todo.cfg index 7e7c27f..b42cd09 100644 --- a/todo.cfg +++ b/todo.cfg @@ -1,41 +1,41 @@ # === EDIT FILE LOCATIONS BELOW === # Your todo.txt directory -#TODO_DIR="/Users/gina/Documents/todo" -TODO_DIR="C:/Documents and Settings/gina/My Documents" +#export TODO_DIR="/Users/gina/Documents/todo" +export TODO_DIR="C:/Documents and Settings/gina/My Documents" # Your todo/done/report.txt locations -TODO_FILE="$TODO_DIR/todo.txt" -DONE_FILE="$TODO_DIR/done.txt" -REPORT_FILE="$TODO_DIR/report.txt" -TMP_FILE="$TODO_DIR/todo.tmp" +export TODO_FILE="$TODO_DIR/todo.txt" +export DONE_FILE="$TODO_DIR/done.txt" +export REPORT_FILE="$TODO_DIR/report.txt" +export TMP_FILE="$TODO_DIR/todo.tmp" # == EDIT FILE LOCATIONS ABOVE === # === COLOR MAP === -NONE='' -BLACK='\\033[0;30m' -RED='\\033[0;31m' -GREEN='\\033[0;32m' -BROWN='\\033[0;33m' -BLUE='\\033[0;34m' -PURPLE='\\033[0;35m' -CYAN='\\033[0;36m' -LIGHT_GREY='\\033[0;37m' -DARK_GREY='\\033[1;30m' -LIGHT_RED='\\033[1;31m' -LIGHT_GREEN='\\033[1;32m' -YELLOW='\\033[1;33m' -LIGHT_BLUE='\\033[1;34m' -LIGHT_PURPLE='\\033[1;35m' -LIGHT_CYAN='\\033[1;36m' -WHITE='\\033[1;37m' -DEFAULT='\\033[0m' +export NONE='' +export BLACK='\\033[0;30m' +export RED='\\033[0;31m' +export GREEN='\\033[0;32m' +export BROWN='\\033[0;33m' +export BLUE='\\033[0;34m' +export PURPLE='\\033[0;35m' +export CYAN='\\033[0;36m' +export LIGHT_GREY='\\033[0;37m' +export DARK_GREY='\\033[1;30m' +export LIGHT_RED='\\033[1;31m' +export LIGHT_GREEN='\\033[1;32m' +export YELLOW='\\033[1;33m' +export LIGHT_BLUE='\\033[1;34m' +export LIGHT_PURPLE='\\033[1;35m' +export LIGHT_CYAN='\\033[1;36m' +export WHITE='\\033[1;37m' +export DEFAULT='\\033[0m' # === PRIORITY COLORS === -PRI_A=$YELLOW # color for A priority -PRI_B=$GREEN # color for B priority -PRI_C=$LIGHT_BLUE # color for C priority -PRI_X=$WHITE # color for rest of them +export PRI_A=$YELLOW # color for A priority +export PRI_B=$GREEN # color for B priority +export PRI_C=$LIGHT_BLUE # color for C priority +export PRI_X=$WHITE # color for rest of them diff --git a/todo.sh b/todo.sh index 016d280..035e8e3 100644 --- a/todo.sh +++ b/todo.sh @@ -204,6 +204,8 @@ PRESERVE_LINE_NUMBERS=1 AUTO_ARCHIVE=1 DATE_ON_ADD=0 +export VERBOSE PLAIN CFG_FILE FORCE PRESERVE_LINE_NUMBERS AUTO_ARCHIVE DATE_ON_ADD + while getopts ":fhpnatvV+@Pd:" Option do case $Option in From 47c7ba75b3ba651faadcf9223e414e5bc51d17ec Mon Sep 17 00:00:00 2001 From: Ed Blackman Date: Sun, 8 Mar 2009 18:41:27 -0400 Subject: [PATCH 06/12] Remove now-redundant export of CFG_FILE --- todo.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/todo.sh b/todo.sh index 035e8e3..9c306fa 100644 --- a/todo.sh +++ b/todo.sh @@ -328,7 +328,7 @@ action=$( printf "%s\n" "$1" | tr 'A-Z' 'a-z' ) ## Run and quit if there's a actions script if [ -d "$HOME/.todo.actions.d" -a -x "$HOME/.todo.actions.d/$action" ] then - CFG_FILE="$CFG_FILE" "$HOME/.todo.actions.d/$action" "$@" + "$HOME/.todo.actions.d/$action" "$@" cleanup fi From db6676717079be729233724bbdb70b6e069585fb Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Mon, 9 Mar 2009 10:09:32 +0100 Subject: [PATCH 07/12] Add TODOTXT_UNDEF_CUSTOM_ACTIONS for recursive call of todo.sh from actions And replace tabs by spaces. To illustrate the interest of this new variable, here is an action to replace the original add to allow a priority to be set when adding. The action itself relies on the original add, therefore the need for this new envvar. action=$1 shift [ "$action" = "usage" ] && { echo " add pri PRIORITY \"THING I NEED TO DO +project @context\"" echo " add an item and prioritize it in one step" echo "" exit } . $TODOTXT_CFG_FILE TODOTXT_UNDEF_CUSTOM_ACTIONS=1 PRIORITY=false if [ x"$1" = x"pri" -o x"$1" = x"p" ] && [[ x"$2" =~ x[a-zA-Z] ]]; then PRIORITY=$2 shift shift fi if $TODO_SH add "$@" && [ $PRIORITY != false ]; then # figure out the line of what we just added, and "do" it line=`wc -l "$TODO_FILE" | cut -d' ' -f1` $TODO_SH pri "$line" $PRIORITY fi --- todo.sh | 66 +++++++++++++++++++++++++++++---------------------------- 1 file changed, 34 insertions(+), 32 deletions(-) diff --git a/todo.sh b/todo.sh index f9997d8..85bf518 100755 --- a/todo.sh +++ b/todo.sh @@ -158,6 +158,7 @@ help() TODOTXT_PLAIN=1 is same as option -p TODOTXT_DATE_ON_ADD=1 is same as option -t TODOTXT_VERBOSE=1 is same as option -v + TODOTXT_UNDEF_CUSTOM_ACTIONS=1 disables .todo.actions.d EndHelp if [ -d "$HOME/.todo.actions.d" ] @@ -209,37 +210,37 @@ while getopts ":fhpnatvV+@Pd:" Option do case $Option in '@' ) - ## HIDE_CONTEXT_NAMES starts at zero (false); increment it to one - ## (true) the first time this flag is seen. Each time the flag - ## is seen after that, increment it again so that an even - ## number hides project names and an odd number shows project - ## names. - : $(( HIDE_CONTEXT_NAMES++ )) - if [ $(( $HIDE_CONTEXT_NAMES % 2 )) -eq 0 ] - then - ## Zero or even value -- show context names - unset HIDE_CONTEXTS_SUBSTITUTION - else - ## One or odd value -- hide context names - HIDE_CONTEXTS_SUBSTITUTION='[[:space:]]@[^[:space:]]\{1,\}' - fi - ;; + ## HIDE_CONTEXT_NAMES starts at zero (false); increment it to one + ## (true) the first time this flag is seen. Each time the flag + ## is seen after that, increment it again so that an even + ## number hides project names and an odd number shows project + ## names. + : $(( HIDE_CONTEXT_NAMES++ )) + if [ $(( $HIDE_CONTEXT_NAMES % 2 )) -eq 0 ] + then + ## Zero or even value -- show context names + unset HIDE_CONTEXTS_SUBSTITUTION + else + ## One or odd value -- hide context names + HIDE_CONTEXTS_SUBSTITUTION='[[:space:]]@[^[:space:]]\{1,\}' + fi + ;; '+' ) - ## HIDE_PROJECT_NAMES starts at zero (false); increment it to one - ## (true) the first time this flag is seen. Each time the flag - ## is seen after that, increment it again so that an even - ## number hides project names and an odd number shows project - ## names. - : $(( HIDE_PROJECT_NAMES++ )) - if [ $(( $HIDE_PROJECT_NAMES % 2 )) -eq 0 ] - then - ## Zero or even value -- show project names - unset HIDE_PROJECTS_SUBSTITUTION - else - ## One or odd value -- hide project names - HIDE_PROJECTS_SUBSTITUTION='[[:space:]][+][^[:space:]]\{1,\}' - fi - ;; + ## HIDE_PROJECT_NAMES starts at zero (false); increment it to one + ## (true) the first time this flag is seen. Each time the flag + ## is seen after that, increment it again so that an even + ## number hides project names and an odd number shows project + ## names. + : $(( HIDE_PROJECT_NAMES++ )) + if [ $(( $HIDE_PROJECT_NAMES % 2 )) -eq 0 ] + then + ## Zero or even value -- show project names + unset HIDE_PROJECTS_SUBSTITUTION + else + ## One or odd value -- hide project names + HIDE_PROJECTS_SUBSTITUTION='[[:space:]][+][^[:space:]]\{1,\}' + fi + ;; a ) TODOTXT_AUTO_ARCHIVE=0 ;; @@ -295,6 +296,7 @@ TODOTXT_FORCE=${TODOTXT_FORCE:-0} TODOTXT_PRESERVE_LINE_NUMBERS=${TODOTXT_PRESERVE_LINE_NUMBERS:-1} TODOTXT_AUTO_ARCHIVE=${TODOTXT_AUTO_ARCHIVE:-1} TODOTXT_DATE_ON_ADD=${TODOTXT_DATE_ON_ADD:-0} +TODOTXT_UNDEF_CUSTOM_ACTIONS=${TODOTXT_UNDEF_CUSTOM_ACTIONS:-0} [ -e "$TODOTXT_CFG_FILE" ] || { CFG_FILE_ALT="$HOME/.todo.cfg" @@ -305,7 +307,7 @@ TODOTXT_DATE_ON_ADD=${TODOTXT_DATE_ON_ADD:-0} fi } -export TODOTXT_VERBOSE TODOTXT_PLAIN TODOTXT_CFG_FILE TODOTXT_FORCE TODOTXT_PRESERVE_LINE_NUMBERS TODOTXT_AUTO_ARCHIVE TODOTXT_DATE_ON_ADD +export TODOTXT_VERBOSE TODOTXT_PLAIN TODOTXT_CFG_FILE TODOTXT_FORCE TODOTXT_PRESERVE_LINE_NUMBERS TODOTXT_AUTO_ARCHIVE TODOTXT_DATE_ON_ADD TODOTXT_UNDEF_CUSTOM_ACTIONS TODO_SH="$0" export TODO_SH @@ -339,7 +341,7 @@ shopt -s extglob action=$( printf "%s\n" "$1" | tr 'A-Z' 'a-z' ) ## Run and quit if there's a actions script -if [ -d "$HOME/.todo.actions.d" -a -x "$HOME/.todo.actions.d/$action" ] +if [ $TODOTXT_UNDEF_CUSTOM_ACTIONS = 0 -a -d "$HOME/.todo.actions.d" -a -x "$HOME/.todo.actions.d/$action" ] then "$HOME/.todo.actions.d/$action" "$@" cleanup From 88caf44e9e1f0dfd8812879374de905faba0c201 Mon Sep 17 00:00:00 2001 From: "David A. Harding" Date: Mon, 9 Mar 2009 14:10:21 -0400 Subject: [PATCH 08/12] Override Overrides Using "command" New action, "command", forces todo.sh to use builtins and ignore any .todo.actions.d scripts. For example, if there is an executable .todo.actions.d/ls: ## Run .todo.actions.d/ls todo.sh ls ## Run builtin todo.sh ls todo.sh command ls This mimicks bash's behaviour: ## Use the default echo harding@ziggy:~$ echo 'foo\nbar' foo\nbar ## Alias the echo command to "echo -e" harding@ziggy:~$ alias echo='echo -e' harding@ziggy:~$ echo 'foo\nbar' foo bar ## Force bash to call the default echo command harding@ziggy:~$ command echo 'foo\nbar' foo\nbar --- todo.sh | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/todo.sh b/todo.sh index 85bf518..029c9d7 100755 --- a/todo.sh +++ b/todo.sh @@ -49,6 +49,10 @@ help() archive Moves done items from todo.txt to done.txt and removes blank lines. + command [ACTIONS] + Runs the remaining arguments using only todo.sh builtins. + Will not call any .todo.actions.d scripts. + del NUMBER [TERM] rm NUMBER [TERM] Deletes the item on line NUMBER in todo.txt. @@ -158,7 +162,6 @@ help() TODOTXT_PLAIN=1 is same as option -p TODOTXT_DATE_ON_ADD=1 is same as option -t TODOTXT_VERBOSE=1 is same as option -v - TODOTXT_UNDEF_CUSTOM_ACTIONS=1 disables .todo.actions.d EndHelp if [ -d "$HOME/.todo.actions.d" ] @@ -296,7 +299,6 @@ TODOTXT_FORCE=${TODOTXT_FORCE:-0} TODOTXT_PRESERVE_LINE_NUMBERS=${TODOTXT_PRESERVE_LINE_NUMBERS:-1} TODOTXT_AUTO_ARCHIVE=${TODOTXT_AUTO_ARCHIVE:-1} TODOTXT_DATE_ON_ADD=${TODOTXT_DATE_ON_ADD:-0} -TODOTXT_UNDEF_CUSTOM_ACTIONS=${TODOTXT_UNDEF_CUSTOM_ACTIONS:-0} [ -e "$TODOTXT_CFG_FILE" ] || { CFG_FILE_ALT="$HOME/.todo.cfg" @@ -307,7 +309,7 @@ TODOTXT_UNDEF_CUSTOM_ACTIONS=${TODOTXT_UNDEF_CUSTOM_ACTIONS:-0} fi } -export TODOTXT_VERBOSE TODOTXT_PLAIN TODOTXT_CFG_FILE TODOTXT_FORCE TODOTXT_PRESERVE_LINE_NUMBERS TODOTXT_AUTO_ARCHIVE TODOTXT_DATE_ON_ADD TODOTXT_UNDEF_CUSTOM_ACTIONS +export TODOTXT_VERBOSE TODOTXT_PLAIN TODOTXT_CFG_FILE TODOTXT_FORCE TODOTXT_PRESERVE_LINE_NUMBERS TODOTXT_AUTO_ARCHIVE TODOTXT_DATE_ON_ADD TODO_SH="$0" export TODO_SH @@ -340,14 +342,22 @@ shopt -s extglob # == HANDLE ACTION == action=$( printf "%s\n" "$1" | tr 'A-Z' 'a-z' ) -## Run and quit if there's a actions script -if [ $TODOTXT_UNDEF_CUSTOM_ACTIONS = 0 -a -d "$HOME/.todo.actions.d" -a -x "$HOME/.todo.actions.d/$action" ] +## If the first argument is "command", run the rest of the arguments +## using todo.sh builtins. +## Else, run a actions script with the name of the command if it exists +## or fallback to using a builtin +if [ "$action" == command ] +then + shift + action=$( printf "%s\n" "$1" | tr 'A-Z' 'a-z' ) +elif [ -d "$HOME/.todo.actions.d" -a -x "$HOME/.todo.actions.d/$action" ] then "$HOME/.todo.actions.d/$action" "$@" cleanup fi ## Only run if $action isn't found in .todo.actions.d +action=$( printf "%s\n" "$1" | tr 'A-Z' 'a-z' ) case $action in "add" | "a") if [[ -z "$2" && $TODOTXT_FORCE = 0 ]]; then From 4ee8c332eddde2640e0ad6b6a33cce4ff8a6c81b Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Mon, 9 Mar 2009 20:43:42 +0100 Subject: [PATCH 09/12] Remove redundant code --- todo.sh | 1 - 1 file changed, 1 deletion(-) diff --git a/todo.sh b/todo.sh index 029c9d7..4698383 100755 --- a/todo.sh +++ b/todo.sh @@ -349,7 +349,6 @@ action=$( printf "%s\n" "$1" | tr 'A-Z' 'a-z' ) if [ "$action" == command ] then shift - action=$( printf "%s\n" "$1" | tr 'A-Z' 'a-z' ) elif [ -d "$HOME/.todo.actions.d" -a -x "$HOME/.todo.actions.d/$action" ] then "$HOME/.todo.actions.d/$action" "$@" From 717f052f13e2f5d168dbc73fd0ee429fa84415ad Mon Sep 17 00:00:00 2001 From: "David A. Harding" Date: Mon, 9 Mar 2009 16:19:30 -0400 Subject: [PATCH 10/12] Only Reset Action When Necessary plus Comments --- todo.sh | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/todo.sh b/todo.sh index 4698383..67c3c75 100755 --- a/todo.sh +++ b/todo.sh @@ -348,7 +348,10 @@ action=$( printf "%s\n" "$1" | tr 'A-Z' 'a-z' ) ## or fallback to using a builtin if [ "$action" == command ] then + ## Get rid of "command" from arguments list shift + ## Reset action to new first argument + action=$( printf "%s\n" "$1" | tr 'A-Z' 'a-z' ) elif [ -d "$HOME/.todo.actions.d" -a -x "$HOME/.todo.actions.d/$action" ] then "$HOME/.todo.actions.d/$action" "$@" @@ -356,7 +359,6 @@ then fi ## Only run if $action isn't found in .todo.actions.d -action=$( printf "%s\n" "$1" | tr 'A-Z' 'a-z' ) case $action in "add" | "a") if [[ -z "$2" && $TODOTXT_FORCE = 0 ]]; then From 87959a8aa8cdc91c83688ae7809518d3b77bd522 Mon Sep 17 00:00:00 2001 From: "David A. Harding" Date: Wed, 11 Mar 2009 17:42:15 -0400 Subject: [PATCH 11/12] Set ls As the Default Action . Suggested by mbrubeck --- todo.sh | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/todo.sh b/todo.sh index 67c3c75..5ae5f45 100755 --- a/todo.sh +++ b/todo.sh @@ -162,6 +162,7 @@ help() TODOTXT_PLAIN=1 is same as option -p TODOTXT_DATE_ON_ADD=1 is same as option -t TODOTXT_VERBOSE=1 is same as option -v + TODOTXT_DEFAULT_ACTION="ls" default action EndHelp if [ -d "$HOME/.todo.actions.d" ] @@ -319,7 +320,12 @@ export TODO_SH . "$TODOTXT_CFG_FILE" -[ -z "$1" ] && usage +## Run the default action if no action called on command line +if [ -z "$1" ] +then + exec $0 ${TODOTXT_DEFAULT_ACTION:-ls} +fi + [ -d "$TODO_DIR" ] || die "Fatal Error: $TODO_DIR is not a directory" cd "$TODO_DIR" || die "Fatal Error: Unable to cd to $TODO_DIR" From 6bc374c5f280e74debf30ea853112cc790ab0dca Mon Sep 17 00:00:00 2001 From: "David A. Harding" Date: Wed, 11 Mar 2009 17:54:25 -0400 Subject: [PATCH 12/12] Revert "Set ls As the Default Action" This reverts commit 87959a8aa8cdc91c83688ae7809518d3b77bd522. --- todo.sh | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/todo.sh b/todo.sh index 5ae5f45..67c3c75 100755 --- a/todo.sh +++ b/todo.sh @@ -162,7 +162,6 @@ help() TODOTXT_PLAIN=1 is same as option -p TODOTXT_DATE_ON_ADD=1 is same as option -t TODOTXT_VERBOSE=1 is same as option -v - TODOTXT_DEFAULT_ACTION="ls" default action EndHelp if [ -d "$HOME/.todo.actions.d" ] @@ -320,12 +319,7 @@ export TODO_SH . "$TODOTXT_CFG_FILE" -## Run the default action if no action called on command line -if [ -z "$1" ] -then - exec $0 ${TODOTXT_DEFAULT_ACTION:-ls} -fi - +[ -z "$1" ] && usage [ -d "$TODO_DIR" ] || die "Fatal Error: $TODO_DIR is not a directory" cd "$TODO_DIR" || die "Fatal Error: Unable to cd to $TODO_DIR"