Compare commits

..

1 Commits

Author SHA1 Message Date
Ingo Karkat
dfec12e2a4 ENH: Allow listpri filtering with priority ranges.
So far, the listpri action only supports a single priority. Allowing priority ranges (e.g. todo.sh listpri A-C @work) is a simple but useful enhancement.

Note: The syntax extension only clashes with the [TERM] filtering in a few corner cases, and this can be worked around (e.g. "todo.sh listpri A-Z A-Z" lists all prioritized tasks containing the text A-Z).
2012-01-26 13:17:31 +01:00
4 changed files with 42 additions and 159 deletions

View File

@@ -1,57 +1,4 @@
#!/bin/bash #!/bin/sh
[ "x$TERM" != "xdumb" ] && (
export TERM &&
[ -t 1 ] &&
tput bold >/dev/null 2>&1 &&
tput setaf 1 >/dev/null 2>&1 &&
tput sgr0 >/dev/null 2>&1
) &&
color=t
case "$1" in
--no-color)
color=; shift ;;
esac
if test -n "$color"; then
say_color () {
(
export TERM
case "$1" in
error) tput bold; tput setaf 1;; # bold red
skip) tput bold; tput setaf 2;; # bold green
pass) tput setaf 2;; # green
info) tput setaf 3;; # brown
*) test -n "$quiet" && return;;
esac
shift
printf "* %s" "$*"
tput sgr0
echo
)
}
else
say_color() {
test -z "$1" && test -n "$quiet" && return
shift
echo "* $*"
}
fi
get_color()
{
# Only use the supplied color if there are actually instances of that
# type, so that a clean test run does not distract the user by the
# appearance of the error highlighting.
if [ ${1:?} -eq 0 ]
then
echo 'info'
else
echo "${2:-info}"
fi
}
fixed=0 fixed=0
success=0 success=0
@@ -80,8 +27,8 @@ do
done <"$file" done <"$file"
done done
say_color 'info' "$(printf "%-8s%d\n" fixed $fixed)" printf "%-8s%d\n" fixed $fixed
say_color "$(get_color "$success" 'pass')" "$(printf "%-8s%d\n" success $success)" printf "%-8s%d\n" success $success
say_color "$(get_color "$failed" 'error')" "$(printf "%-8s%d\n" failed $failed)" printf "%-8s%d\n" failed $failed
say_color "$(get_color "$broken" 'error')" "$(printf "%-8s%d\n" broken $broken)" printf "%-8s%d\n" broken $broken
say_color 'info' "$(printf "%-8s%d\n" total $total)" printf "%-8s%d\n" total $total

View File

@@ -180,7 +180,7 @@ test_failure_ () {
test_failure=$(($test_failure + 1)) test_failure=$(($test_failure + 1))
say_color error "FAIL $test_count: $1" say_color error "FAIL $test_count: $1"
shift shift
echo "$@" echo "$@" | sed -e 's/^/ /'
test "$immediate" = "" || { trap - EXIT; exit 1; } test "$immediate" = "" || { trap - EXIT; exit 1; }
} }
@@ -199,9 +199,8 @@ test_debug () {
} }
test_run_ () { test_run_ () {
eval > output 2>&1 "$1" eval >&3 2>&4 "$1"
eval_ret="$?" eval_ret="$?"
cat >&3 output
return 0 return 0
} }
@@ -261,57 +260,6 @@ test_expect_success () {
echo >&3 "" echo >&3 ""
} }
test_expect_output () {
test "$#" = 2 ||
error "bug in the test script: not 2 parameters to test-expect-output"
if ! test_skip "$@"
then
say >&3 "expecting success and output: $2"
test_run_ "$2"
if [ "$?" = 0 -a "$eval_ret" = 0 ]
then
cmp_output=$(test_cmp expect output)
if [ "$?" = 0 ]
then
test_ok_ "$1"
else
test_failure_ "$@" "
$cmp_output"
fi
else
test_failure_ "$@"
fi
fi
echo >&3 ""
}
test_expect_code_and_output () {
test "$#" = 3 ||
error "bug in the test script: not 3 parameters to test-expect-code-and-output"
if ! test_skip "$@"
then
say >&3 "expecting exit code $1 and output: $3"
test_run_ "$3"
if [ "$?" = 0 -a "$eval_ret" = "$1" ]
then
cmp_output=$(test_cmp expect output)
if [ "$?" = 0 ]
then
test_ok_ "$2"
else
test_failure_ "$2" "$3" "
$cmp_output"
fi
else
cmp_output=$(test_cmp expect output)
test_failure_ "$2" "$3" "
* expected exit code $1, actual ${eval_ret}${cmp_output:+
}${cmp_output}"
fi
fi
echo >&3 ""
}
test_expect_code () { test_expect_code () {
test "$#" = 3 || test "$#" = 3 ||
error "bug in the test script: not 3 parameters to test-expect-code" error "bug in the test script: not 3 parameters to test-expect-code"
@@ -323,8 +271,7 @@ test_expect_code () {
then then
test_ok_ "$2" test_ok_ "$2"
else else
test_failure_ "$2" "$3" " test_failure_ "$@"
* expected exit code $1, actual ${eval_ret}"
fi fi
fi fi
echo >&3 "" echo >&3 ""
@@ -595,9 +542,9 @@ test_todo_session () {
"") "")
if [ ! -z "$cmd" ]; then if [ ! -z "$cmd" ]; then
if [ $status = 0 ]; then if [ $status = 0 ]; then
test_expect_output "$1 $subnum" "$cmd" test_expect_success "$1 $subnum" "$cmd > output && test_cmp expect output"
else else
test_expect_code_and_output "$status" "$1 $subnum" "$cmd" test_expect_success "$1 $subnum" "$cmd > output ; test \$? = $status && test_cmp expect output"
fi fi
subnum=$(($subnum + 1)) subnum=$(($subnum + 1))
@@ -613,9 +560,9 @@ test_todo_session () {
done done
if [ ! -z "$cmd" ]; then if [ ! -z "$cmd" ]; then
if [ $status = 0 ]; then if [ $status = 0 ]; then
test_expect_output "$1 $subnum" "$cmd" test_expect_success "$1 $subnum" "$cmd > output && test_cmp expect output"
else else
test_expect_code_and_output "$status" "$1 $subnum" "$cmd" test_expect_success "$1 $subnum" "$cmd > output ; test \$? = $status && test_cmp expect output"
fi fi
fi fi
} }

View File

@@ -8,6 +8,7 @@ export TODO_DIR=`dirname "$0"`
export TODO_FILE="$TODO_DIR/todo.txt" export TODO_FILE="$TODO_DIR/todo.txt"
export DONE_FILE="$TODO_DIR/done.txt" export DONE_FILE="$TODO_DIR/done.txt"
export REPORT_FILE="$TODO_DIR/report.txt" export REPORT_FILE="$TODO_DIR/report.txt"
export TMP_FILE="$TODO_DIR/todo.tmp"
# You can customize your actions directory location # You can customize your actions directory location
#export TODO_ACTIONS_DIR="$HOME/.todo.actions.d" #export TODO_ACTIONS_DIR="$HOME/.todo.actions.d"

68
todo.sh
View File

@@ -303,6 +303,12 @@ die()
exit 1 exit 1
} }
cleanup()
{
[ -f "$TMP_FILE" ] && rm "$TMP_FILE"
return 0
}
cleaninput() cleaninput()
{ {
# Parameters: When $1 = "for sed", performs additional escaping for use # Parameters: When $1 = "for sed", performs additional escaping for use
@@ -665,6 +671,7 @@ ACTION=${1:-$TODOTXT_DEFAULT_ACTION}
[ -d "$TODO_DIR" ] || die "Fatal Error: $TODO_DIR is not a directory" [ -d "$TODO_DIR" ] || die "Fatal Error: $TODO_DIR is not a directory"
( cd "$TODO_DIR" ) || die "Fatal Error: Unable to cd to $TODO_DIR" ( cd "$TODO_DIR" ) || die "Fatal Error: Unable to cd to $TODO_DIR"
[ -w "$TMP_FILE" ] || echo -n > "$TMP_FILE" || die "Fatal Error: Unable to write to $TMP_FILE"
[ -f "$TODO_FILE" ] || cp /dev/null "$TODO_FILE" [ -f "$TODO_FILE" ] || cp /dev/null "$TODO_FILE"
[ -f "$DONE_FILE" ] || cp /dev/null "$DONE_FILE" [ -f "$DONE_FILE" ] || cp /dev/null "$DONE_FILE"
[ -f "$REPORT_FILE" ] || cp /dev/null "$REPORT_FILE" [ -f "$REPORT_FILE" ] || cp /dev/null "$REPORT_FILE"
@@ -754,32 +761,13 @@ _list() {
## Get our search arguments, if any ## Get our search arguments, if any
shift ## was file name, new $1 is first search term shift ## was file name, new $1 is first search term
_format "$src" '' "$@" ## Build the filter.
filter_command=$(filtercommand "${pre_filter_command:-}" "${post_filter_command:-}" "$@")
if [ $TODOTXT_VERBOSE -gt 0 ]; then ## Figure out how much padding we need to use
echo "--" ## We need one level of padding for each power of 10 $LINES uses
echo "$(getPrefix "$src"): ${NUMTASKS:-0} of ${TOTALTASKS:-0} tasks shown" LINES=$( sed -n '$ =' "$src" )
fi PADDING=${#LINES}
}
getPadding()
{
## We need one level of padding for each power of 10 $LINES uses.
LINES=$(sed -n '$ =' "${1:-$TODO_FILE}")
printf %s ${#LINES}
}
_format()
{
# Parameters: $1: todo input file; when empty formats stdin
# $2: ITEM# number width; if empty auto-detects from $1 / $TODO_FILE.
# Precondition: None
# Postcondition: $NUMTASKS and $TOTALTASKS contain statistics (unless $TODOTXT_VERBOSE=0).
FILE=$1
shift
## Figure out how much padding we need to use, unless this was passed to us.
PADDING=${1:-$(getPadding "$FILE")}
shift
## Number the file, then run the filter command, ## Number the file, then run the filter command,
## then sort and mangle output some more ## then sort and mangle output some more
@@ -787,11 +775,7 @@ _format()
TODOTXT_FINAL_FILTER="cat" TODOTXT_FINAL_FILTER="cat"
fi fi
items=$( items=$(
if [ "$FILE" ]; then sed = "$src" \
sed = "$FILE"
else
sed =
fi \
| sed -e ''' | sed -e '''
N N
s/^/ / s/^/ /
@@ -799,9 +783,6 @@ _format()
/^[ 0-9]\{1,\} *$/d /^[ 0-9]\{1,\} *$/d
''' '''
) )
## Build and apply the filter.
filter_command=$(filtercommand "${pre_filter_command:-}" "${post_filter_command:-}" "$@")
if [ "${filter_command}" ]; then if [ "${filter_command}" ]; then
filtered_items=$(echo -n "$items" | eval "${filter_command}") filtered_items=$(echo -n "$items" | eval "${filter_command}")
else else
@@ -847,13 +828,16 @@ _format()
if [ $TODOTXT_VERBOSE -gt 0 ]; then if [ $TODOTXT_VERBOSE -gt 0 ]; then
NUMTASKS=$( echo -n "$filtered_items" | sed -n '$ =' ) NUMTASKS=$( echo -n "$filtered_items" | sed -n '$ =' )
TOTALTASKS=$( echo -n "$items" | sed -n '$ =' ) TOTALTASKS=$( echo -n "$items" | sed -n '$ =' )
echo "--"
echo "$(getPrefix "$FILE"): ${NUMTASKS:-0} of ${TOTALTASKS:-0} tasks shown"
fi fi
if [ $TODOTXT_VERBOSE -gt 1 ]; then if [ $TODOTXT_VERBOSE -gt 1 ]; then
echo "TODO DEBUG: Filter Command was: ${filter_command:-cat}" echo "TODO DEBUG: Filter Command was: ${filter_command:-cat}"
fi fi
} }
export -f cleaninput getPrefix getTodo getNewtodo shellquote filtercommand _list getPadding _format die export -f cleaninput getPrefix getTodo getNewtodo shellquote filtercommand _list die
# == HANDLE ACTION == # == HANDLE ACTION ==
action=$( printf "%s\n" "$ACTION" | tr 'A-Z' 'a-z' ) action=$( printf "%s\n" "$ACTION" | tr 'A-Z' 'a-z' )
@@ -871,7 +855,9 @@ then
elif [ -d "$TODO_ACTIONS_DIR" -a -x "$TODO_ACTIONS_DIR/$action" ] elif [ -d "$TODO_ACTIONS_DIR" -a -x "$TODO_ACTIONS_DIR/$action" ]
then then
"$TODO_ACTIONS_DIR/$action" "$@" "$TODO_ACTIONS_DIR/$action" "$@"
exit $? status=$?
cleanup
exit $status
fi fi
## Only run if $action isn't found in .todo.actions.d ## Only run if $action isn't found in .todo.actions.d
@@ -1097,16 +1083,16 @@ case $action in
"listall" | "lsa" ) "listall" | "lsa" )
shift ## Was lsa; new $1 is first search term shift ## Was lsa; new $1 is first search term
cat "$TODO_FILE" "$DONE_FILE" > "$TMP_FILE"
TOTAL=$( sed -n '$ =' "$TODO_FILE" ) TOTAL=$( sed -n '$ =' "$TODO_FILE" )
PADDING=${#TOTAL}
post_filter_command="awk -v TOTAL=$TOTAL -v PADDING=$PADDING '{ \$1 = sprintf(\"%\" PADDING \"d\", (\$1 > TOTAL ? 0 : \$1)); print }' " post_filter_command="awk -v TOTAL=$TOTAL -v PADDING=${#TOTAL} '{ \$1 = sprintf(\"%\" PADDING \"d\", (\$1 > TOTAL ? 0 : \$1)); print }' "
cat "$TODO_FILE" "$DONE_FILE" | TODOTXT_VERBOSE=0 _format '' "$PADDING" "$@" TODOTXT_VERBOSE=0 _list "$TMP_FILE" "$@"
if [ $TODOTXT_VERBOSE -gt 0 ]; then if [ $TODOTXT_VERBOSE -gt 0 ]; then
TDONE=$( sed -n '$ =' "$DONE_FILE" ) TDONE=$( sed -n '$ =' "$DONE_FILE" )
TASKNUM=$(TODOTXT_PLAIN=1 TODOTXT_VERBOSE=0 _format "$TODO_FILE" 1 "$@" | sed -n '$ =') TASKNUM=$(TODOTXT_PLAIN=1 TODOTXT_VERBOSE=0 _list "$TODO_FILE" "$@" | sed -n '$ =')
DONENUM=$(TODOTXT_PLAIN=1 TODOTXT_VERBOSE=0 _format "$DONE_FILE" 1 "$@" | sed -n '$ =') DONENUM=$(TODOTXT_PLAIN=1 TODOTXT_VERBOSE=0 _list "$DONE_FILE" "$@" | sed -n '$ =')
echo "--" echo "--"
echo "$(getPrefix "$TODO_FILE"): ${TASKNUM:-0} of ${TOTAL:-0} tasks shown" echo "$(getPrefix "$TODO_FILE"): ${TASKNUM:-0} of ${TOTAL:-0} tasks shown"
echo "$(getPrefix "$DONE_FILE"): ${DONENUM:-0} of ${TDONE:-0} tasks shown" echo "$(getPrefix "$DONE_FILE"): ${DONENUM:-0} of ${TDONE:-0} tasks shown"
@@ -1298,3 +1284,5 @@ note: PRIORITY must be anywhere from A to Z."
* ) * )
usage;; usage;;
esac esac
cleanup