Compare commits

..

6 Commits

Author SHA1 Message Date
Ingo Karkat
b7ffb96695 Pull archive() in-line and delegate via recursive call, also for report.
The report action should delegate to archive; it previously (half) did this via duplicated code (and forgot to defragment empty lines, so the tally could be off, and kept silent about the archiving).

The do action directly invoked archive(); if the user had extended / modified the archive action via an eponymous custom action, it would not run. Therefore, always invoke archive through another call of todo.sh, so that a possible custom action is considered.
2012-01-13 23:46:08 +01:00
Ingo Karkat
67e0d9dd98 Support "preserve line numbers" in deduplicate. 2012-01-13 23:27:58 +01:00
Ingo Karkat
1160ae1276 Fix deduplicate for non-printable (and non-ASCII) characters. 2012-01-13 22:44:35 +01:00
Ingo Karkat
534184e4dd Rework fixed archive deduplication into new deduplicate action.
As per discussion on the mailing list (http://tech.groups.yahoo.com/group/todotxt/message/3775), the automatic deduplication during archiving is unexpected and difficult to enforce in other implementations. Rather, make this a separate (optional) action.
2012-01-13 22:41:33 +01:00
Paul Roub
cd2f585fb6 explained the sed duplicate-removal pattern 2012-01-09 10:34:05 -05:00
Paul Roub
492d98e50a Fix typo in duplicate removal on archive, per discussion at http://tech.groups.yahoo.com/group/todotxt/message/3775 2012-01-08 12:14:08 -05:00
10 changed files with 86 additions and 398 deletions

View File

@@ -21,7 +21,6 @@ h2. Quick Links
* Original anemic release by "Gina Trapani":http://ginatrapani.org on 5/11/2006. * Original anemic release by "Gina Trapani":http://ginatrapani.org on 5/11/2006.
* Raised to great heights by "brainy and dedicated volunteers":http://github.com/ginatrapani/todo.txt-cli/network. * Raised to great heights by "brainy and dedicated volunteers":http://github.com/ginatrapani/todo.txt-cli/network.
* Licensed under the "GPL":http://www.gnu.org/copyleft/gpl.html * Licensed under the "GPL":http://www.gnu.org/copyleft/gpl.html
* "Add-on Directory":https://github.com/ginatrapani/todo.txt-cli/wiki/Todo.sh-Add-on-Directory * "Add-on Directory":http://wiki.github.com/ginatrapani/todo.txt-cli/todosh-add-on-directory
https://github.com/ginatrapani/todo.txt-cli/wiki/Creating-and-Installing-Add-ons
* "Changelog":http://wiki.github.com/ginatrapani/todo.txt-cli/todosh-changelog * "Changelog":http://wiki.github.com/ginatrapani/todo.txt-cli/todosh-changelog
* "Known Bugs":http://github.com/ginatrapani/todo.txt-cli/issues * "Known Bugs":http://github.com/ginatrapani/todo.txt-cli/issues

View File

@@ -45,8 +45,6 @@ test_expect_success 'null listpri a' '
cat > expect <<EOF cat > expect <<EOF
-- --
TODO: 0 of 0 tasks shown TODO: 0 of 0 tasks shown
DONE: 0 of 0 tasks shown
total 0 of 0 tasks shown
EOF EOF
test_expect_success 'null lsa' ' test_expect_success 'null lsa' '

View File

@@ -53,18 +53,6 @@ test_todo_session 'checking TODOTXT_FINAL_FILTER' <<EOF
TODO: 3 of 3 tasks shown TODO: 3 of 3 tasks shown
EOF EOF
#
# check the custom hiding
#
test_todo_session 'checking HIDE_CUSTOM_SUBSTITUTION' <<EOF
>>> HIDE_CUSTOM_SUBSTITUTION='[tT]h' todo.sh ls
2 aaa zzz is line should be first.
3 bbb yyy is line should be second.
1 ccc xxx is line should be ird.
--
TODO: 3 of 3 tasks shown
EOF
# #
# check the filtering of TERM # check the filtering of TERM
# #

View File

@@ -1,150 +0,0 @@
#!/bin/sh
test_description='listall functionality
'
. ./test-lib.sh
cat > todo.txt <<EOF
smell the uppercase Roses +flowers @outside
x 2011-08-08 tend the garden @outside
notice the sunflowers
x 2011-12-26 go outside +wakeup
(A) stop
EOF
cat > done.txt <<EOF
x 2011-12-01 eat breakfast
x 2011-12-05 smell the coffee +wakeup
EOF
test_todo_session 'basic listall' <<EOF
>>> todo.sh -p listall
5 (A) stop
3 notice the sunflowers
1 smell the uppercase Roses +flowers @outside
2 x 2011-08-08 tend the garden @outside
0 x 2011-12-01 eat breakfast
0 x 2011-12-05 smell the coffee +wakeup
4 x 2011-12-26 go outside +wakeup
--
TODO: 5 of 5 tasks shown
DONE: 2 of 2 tasks shown
total 7 of 7 tasks shown
EOF
test_todo_session 'listall highlighting' <<EOF
>>> todo.sh listall
5 (A) stop
3 notice the sunflowers
1 smell the uppercase Roses +flowers @outside
2 x 2011-08-08 tend the garden @outside
0 x 2011-12-01 eat breakfast
0 x 2011-12-05 smell the coffee +wakeup
4 x 2011-12-26 go outside +wakeup
--
TODO: 5 of 5 tasks shown
DONE: 2 of 2 tasks shown
total 7 of 7 tasks shown
EOF
test_todo_session 'listall nonverbose' <<EOF
>>> TODOTXT_VERBOSE=0 todo.sh -p listall
5 (A) stop
3 notice the sunflowers
1 smell the uppercase Roses +flowers @outside
2 x 2011-08-08 tend the garden @outside
0 x 2011-12-01 eat breakfast
0 x 2011-12-05 smell the coffee +wakeup
4 x 2011-12-26 go outside +wakeup
EOF
test_todo_session 'listall filtering' <<EOF
>>> todo.sh -p listall @outside
1 smell the uppercase Roses +flowers @outside
2 x 2011-08-08 tend the garden @outside
--
TODO: 2 of 5 tasks shown
DONE: 0 of 2 tasks shown
total 2 of 7 tasks shown
>>> todo.sh -p listall the
3 notice the sunflowers
1 smell the uppercase Roses +flowers @outside
2 x 2011-08-08 tend the garden @outside
0 x 2011-12-05 smell the coffee +wakeup
--
TODO: 3 of 5 tasks shown
DONE: 1 of 2 tasks shown
total 4 of 7 tasks shown
>>> todo.sh -p listall breakfast
0 x 2011-12-01 eat breakfast
--
TODO: 0 of 5 tasks shown
DONE: 1 of 2 tasks shown
total 1 of 7 tasks shown
>>> todo.sh -p listall doesnotmatch
--
TODO: 0 of 5 tasks shown
DONE: 0 of 2 tasks shown
total 0 of 7 tasks shown
EOF
cat >> done.txt <<EOF
x 2010-01-01 old task 1
x 2010-01-01 old task 2
x 2010-01-01 old task 3
x 2010-01-01 old task 4
EOF
test_todo_session 'listall number width' <<EOF
>>> todo.sh -p listall
5 (A) stop
3 notice the sunflowers
1 smell the uppercase Roses +flowers @outside
0 x 2010-01-01 old task 1
0 x 2010-01-01 old task 2
0 x 2010-01-01 old task 3
0 x 2010-01-01 old task 4
2 x 2011-08-08 tend the garden @outside
0 x 2011-12-01 eat breakfast
0 x 2011-12-05 smell the coffee +wakeup
4 x 2011-12-26 go outside +wakeup
--
TODO: 5 of 5 tasks shown
DONE: 6 of 6 tasks shown
total 11 of 11 tasks shown
>>> TODOTXT_VERBOSE=0 todo.sh add new task 1
>>> TODOTXT_VERBOSE=0 todo.sh add new task 2
>>> TODOTXT_VERBOSE=0 todo.sh add new task 3
>>> TODOTXT_VERBOSE=0 todo.sh add new task 4
>>> TODOTXT_VERBOSE=0 todo.sh add new task 5
>>> todo.sh -p listall
05 (A) stop
06 new task 1
07 new task 2
08 new task 3
09 new task 4
10 new task 5
03 notice the sunflowers
01 smell the uppercase Roses +flowers @outside
00 x 2010-01-01 old task 1
00 x 2010-01-01 old task 2
00 x 2010-01-01 old task 3
00 x 2010-01-01 old task 4
02 x 2011-08-08 tend the garden @outside
00 x 2011-12-01 eat breakfast
00 x 2011-12-05 smell the coffee +wakeup
04 x 2011-12-26 go outside +wakeup
--
TODO: 10 of 10 tasks shown
DONE: 6 of 6 tasks shown
total 16 of 16 tasks shown
EOF
test_done

View File

@@ -82,9 +82,9 @@ EOF
cat > todo.txt <<EOF cat > todo.txt <<EOF
normal task normal task
a bold task a bold action
something else something else
a bold task a bold action
something more something more
EOF EOF
test_todo_session 'deduplicate with non-printable duplicates' <<EOF test_todo_session 'deduplicate with non-printable duplicates' <<EOF
@@ -92,7 +92,7 @@ test_todo_session 'deduplicate with non-printable duplicates' <<EOF
TODO: 1 duplicate task(s) removed TODO: 1 duplicate task(s) removed
>>> todo.sh -p ls >>> todo.sh -p ls
2 a bold task 2 a bold action
1 normal task 1 normal task
3 something else 3 something else
5 something more 5 something more

View File

@@ -1,96 +0,0 @@
#!/bin/sh
test_description='report functionality
This test checks the reporting and the format of the report file.
'
. ./test-lib.sh
cat > todo.txt <<EOF
(B) smell the uppercase Roses +flowers @outside
stop and think
smell the coffee +wakeup
make the coffee +wakeup
visit http://example.com
EOF
test_todo_session 'create new report' <<EOF
>>> todo.sh report
TODO: $HOME/todo.txt archived.
2009-02-13T04:40:00 5 0
TODO: Report file updated.
>>> todo.sh -p list
1 (B) smell the uppercase Roses +flowers @outside
4 make the coffee +wakeup
3 smell the coffee +wakeup
2 stop and think
5 visit http://example.com
--
TODO: 5 of 5 tasks shown
EOF
test_todo_session 'report of done tasks' <<EOF
>>> todo.sh -A do 3
3 x 2009-02-13 smell the coffee +wakeup
TODO: 3 marked as done.
x 2009-02-13 smell the coffee +wakeup
TODO: $HOME/todo.txt archived.
>>> todo.sh report
TODO: $HOME/todo.txt archived.
2009-02-13T04:40:00 4 1
TODO: Report file updated.
>>> todo.sh -p list
1 (B) smell the uppercase Roses +flowers @outside
3 make the coffee +wakeup
2 stop and think
4 visit http://example.com
--
TODO: 4 of 4 tasks shown
EOF
test_todo_session 'report performs archiving' <<EOF
>>> todo.sh -a do 3
3 x 2009-02-13 make the coffee +wakeup
TODO: 3 marked as done.
>>> todo.sh report
x 2009-02-13 make the coffee +wakeup
TODO: $HOME/todo.txt archived.
2009-02-13T04:40:00 3 2
TODO: Report file updated.
>>> todo.sh -p list
1 (B) smell the uppercase Roses +flowers @outside
2 stop and think
3 visit http://example.com
--
TODO: 3 of 3 tasks shown
>>> todo.sh -p listfile done.txt
2 x 2009-02-13 make the coffee +wakeup
1 x 2009-02-13 smell the coffee +wakeup
--
DONE: 2 of 2 tasks shown
EOF
test_todo_session 'report is unchanged when no changes' <<EOF
>>> cat report.txt
2009-02-13T04:40:00 5 0
2009-02-13T04:40:00 4 1
2009-02-13T04:40:00 3 2
>>> todo.sh report
TODO: $HOME/todo.txt archived.
2009-02-13T04:40:00 3 2
TODO: Report file is up-to-date.
>>> cat report.txt
2009-02-13T04:40:00 5 0
2009-02-13T04:40:00 4 1
2009-02-13T04:40:00 3 2
EOF
test_done

View File

@@ -86,8 +86,14 @@ TODO: 5 of 5 tasks shown
>>> todo.sh report >>> todo.sh report
TODO: $HOME/todo.txt archived. TODO: $HOME/todo.txt archived.
2009-02-13T04:40:00 5 1
TODO: Report file updated. TODO: Report file updated.
2009-02-13-04:40:00 5 1
>>> todo.sh report
TODO: $HOME/todo.txt archived.
TODO: Report file updated.
2009-02-13-04:40:00 5 1
2009-02-13-04:40:00 5 1
>>> todo.sh append g a >>> todo.sh append g a
usage: todo.sh append ITEM# "TEXT TO APPEND" usage: todo.sh append ITEM# "TEXT TO APPEND"

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"

166
todo.sh
View File

@@ -68,8 +68,6 @@ shorthelp()
report report
shorthelp shorthelp
Actions can be added and overridden using scripts in the actions
directory.
EndHelp EndHelp
# Only list the one-line usage from the add-on actions. This assumes that # Only list the one-line usage from the add-on actions. This assumes that
@@ -165,6 +163,7 @@ help()
Adds FIRST THING I NEED TO DO to your todo.txt on its own line and Adds FIRST THING I NEED TO DO to your todo.txt on its own line and
Adds SECOND THING I NEED TO DO to you todo.txt on its own line. Adds SECOND THING I NEED TO DO to you todo.txt on its own line.
Project and context notation optional. Project and context notation optional.
Quotes optional.
addto DEST "TEXT TO ADD" addto DEST "TEXT TO ADD"
Adds a line of text to any file located in the todo.txt directory. Adds a line of text to any file located in the todo.txt directory.
@@ -204,19 +203,13 @@ help()
list [TERM...] list [TERM...]
ls [TERM...] ls [TERM...]
Displays all tasks that contain TERM(s) sorted by priority with line Displays all tasks that contain TERM(s) sorted by priority with line
numbers. Each task must match all TERM(s) (logical AND); to display numbers. If no TERM specified, lists entire todo.txt.
tasks that contain any TERM (logical OR), use
"TERM1\|TERM2\|..." (with quotes), or TERM1\\\|TERM2 (unquoted).
Hides all tasks that contain TERM(s) preceded by a
minus sign (i.e. -TERM). If no TERM specified, lists entire todo.txt.
listall [TERM...] listall [TERM...]
lsa [TERM...] lsa [TERM...]
Displays all the lines in todo.txt AND done.txt that contain TERM(s) Displays all the lines in todo.txt AND done.txt that contain TERM(s)
sorted by priority with line numbers. Hides all tasks that sorted by priority with line numbers. If no TERM specified, lists
contain TERM(s) preceded by a minus sign (i.e. -TERM). If no entire todo.txt AND done.txt concatenated and sorted.
TERM specified, lists entire todo.txt AND done.txt
concatenated and sorted.
listcon listcon
lsc lsc
@@ -226,8 +219,7 @@ help()
lf [SRC [TERM...]] lf [SRC [TERM...]]
Displays all the lines in SRC file located in the todo.txt directory, Displays all the lines in SRC file located in the todo.txt directory,
sorted by priority with line numbers. If TERM specified, lists sorted by priority with line numbers. If TERM specified, lists
all lines that contain TERM(s) in SRC file. Hides all tasks that all lines that contain TERM in SRC file.
contain TERM(s) preceded by a minus sign (i.e. -TERM).
Without any arguments, the names of all text files in the todo.txt Without any arguments, the names of all text files in the todo.txt
directory are listed. directory are listed.
@@ -235,14 +227,11 @@ help()
lsp [PRIORITY] [TERM...] lsp [PRIORITY] [TERM...]
Displays all tasks prioritized PRIORITY. Displays all tasks prioritized PRIORITY.
If no PRIORITY specified, lists all prioritized tasks. If no PRIORITY specified, lists all prioritized tasks.
If TERM specified, lists only prioritized tasks that contain TERM(s). If TERM specified, lists only prioritized tasks that contain TERM.
Hides all tasks that contain TERM(s) preceded by a minus sign
(i.e. -TERM).
listproj listproj
lsprj lsprj
Lists all the projects (terms that start with a + sign) in Lists all the projects that start with the + sign in todo.txt.
todo.txt.
move ITEM# DEST [SRC] move ITEM# DEST [SRC]
mv ITEM# DEST [SRC] mv ITEM# DEST [SRC]
@@ -260,7 +249,7 @@ help()
p ITEM# PRIORITY p ITEM# PRIORITY
Adds PRIORITY to task on line ITEM#. If the task is already Adds PRIORITY to task on line ITEM#. If the task is already
prioritized, replaces current priority with new PRIORITY. prioritized, replaces current priority with new PRIORITY.
PRIORITY must be a letter between A and Z. PRIORITY must be an uppercase letter between A and Z.
replace ITEM# "UPDATED TODO" replace ITEM# "UPDATED TODO"
Replaces task on line ITEM# with UPDATED TODO. Replaces task on line ITEM# with UPDATED TODO.
@@ -271,6 +260,7 @@ help()
shorthelp shorthelp
List the one-line usage of all built-in and add-on actions. List the one-line usage of all built-in and add-on actions.
EndActionsHelp EndActionsHelp
addonHelp addonHelp
@@ -302,6 +292,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
@@ -664,6 +660,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"
@@ -753,32 +750,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
@@ -786,21 +764,10 @@ _format()
TODOTXT_FINAL_FILTER="cat" TODOTXT_FINAL_FILTER="cat"
fi fi
items=$( items=$(
if [ "$FILE" ]; then sed = "$src" \
sed = "$FILE" | sed "N; s/^/ /; s/ *\(.\{$PADDING,\}\)\n/\1 /" \
else | grep -v "^[ 0-9]\+ *$"
sed =
fi \
| sed -e '''
N
s/^/ /
s/ *\([ 0-9]\{'"$PADDING"',\}\)\n/\1 /
/^[ 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
@@ -835,9 +802,8 @@ _format()
} }
''' \ ''' \
| sed ''' | sed '''
s/'"${HIDE_PROJECTS_SUBSTITUTION:-^}"'//g s/'${HIDE_PROJECTS_SUBSTITUTION:-^}'//g
s/'"${HIDE_CONTEXTS_SUBSTITUTION:-^}"'//g s/'${HIDE_CONTEXTS_SUBSTITUTION:-^}'//g
s/'"${HIDE_CUSTOM_SUBSTITUTION:-^}"'//g
''' \ ''' \
| eval ${TODOTXT_FINAL_FILTER} \ | eval ${TODOTXT_FINAL_FILTER} \
) )
@@ -846,13 +812,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' )
@@ -870,7 +839,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
@@ -1018,7 +989,7 @@ case $action in
# Split multiple depri's, if comma separated change to whitespace separated # Split multiple depri's, if comma separated change to whitespace separated
# Loop the 'depri' function for each item # Loop the 'depri' function for each item
for item in ${*//,/ }; do for item in $(echo $* | tr ',' ' '); do
getTodo "$item" getTodo "$item"
if [[ "$todo" = \(?\)\ * ]]; then if [[ "$todo" = \(?\)\ * ]]; then
@@ -1042,7 +1013,7 @@ case $action in
# Split multiple do's, if comma separated change to whitespace separated # Split multiple do's, if comma separated change to whitespace separated
# Loop the 'do' function for each item # Loop the 'do' function for each item
for item in ${*//,/ }; do for item in $(echo $* | tr ',' ' '); do
getTodo "$item" getTodo "$item"
# Check if this item has already been done # Check if this item has already been done
@@ -1096,21 +1067,8 @@ 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
TOTAL=$( sed -n '$ =' "$TODO_FILE" ) cat "$TODO_FILE" "$DONE_FILE" > "$TMP_FILE"
PADDING=${#TOTAL} _list "$TMP_FILE" "$@"
post_filter_command="awk -v TOTAL=$TOTAL -v PADDING=$PADDING '{ \$1 = sprintf(\"%\" PADDING \"d\", (\$1 > TOTAL ? 0 : \$1)); print }' "
cat "$TODO_FILE" "$DONE_FILE" | TODOTXT_VERBOSE=0 _format '' "$PADDING" "$@"
if [ $TODOTXT_VERBOSE -gt 0 ]; then
TDONE=$( sed -n '$ =' "$DONE_FILE" )
TASKNUM=$(TODOTXT_PLAIN=1 TODOTXT_VERBOSE=0 _format "$TODO_FILE" 1 "$@" | sed -n '$ =')
DONENUM=$(TODOTXT_PLAIN=1 TODOTXT_VERBOSE=0 _format "$DONE_FILE" 1 "$@" | sed -n '$ =')
echo "--"
echo "$(getPrefix "$TODO_FILE"): ${TASKNUM:-0} of ${TOTAL:-0} tasks shown"
echo "$(getPrefix "$DONE_FILE"): ${DONENUM:-0} of ${TDONE:-0} tasks shown"
echo "total $((TASKNUM + DONENUM)) of $((TOTAL + TDONE)) tasks shown"
fi
;; ;;
"listfile" | "lf" ) "listfile" | "lf" )
@@ -1234,27 +1192,25 @@ note: PRIORITY must be anywhere from A to Z."
# action. # action.
"$TODO_FULL_SH" archive "$TODO_FULL_SH" archive
NUMLINES=$( sed -n '$ =' "$TODO_FILE" )
if [ ${NUMLINES:-0} = "0" ]; then
echo "datetime todos dones" >> "$REPORT_FILE"
fi
#now report
TOTAL=$( sed -n '$ =' "$TODO_FILE" ) TOTAL=$( sed -n '$ =' "$TODO_FILE" )
TDONE=$( sed -n '$ =' "$DONE_FILE" ) TDONE=$( sed -n '$ =' "$DONE_FILE" )
NEWDATA="${TOTAL:-0} ${TDONE:-0}" TECHO=$(echo $(date +%Y-%m-%d-%T); echo ' '; echo ${TOTAL:-0}; echo ' ';
LASTREPORT=$(sed -ne '$p' "$REPORT_FILE") echo ${TDONE:-0})
LASTDATA=${LASTREPORT#* } # Strip timestamp. echo $TECHO >> "$REPORT_FILE"
if [ "$LASTDATA" = "$NEWDATA" ]; then
echo "$LASTREPORT"
[ $TODOTXT_VERBOSE -gt 0 ] && echo "TODO: Report file is up-to-date."
else
NEWREPORT="$(date +%Y-%m-%dT%T) ${NEWDATA}"
echo "${NEWREPORT}" >> "$REPORT_FILE"
echo "${NEWREPORT}"
[ $TODOTXT_VERBOSE -gt 0 ] && echo "TODO: Report file updated." [ $TODOTXT_VERBOSE -gt 0 ] && echo "TODO: Report file updated."
fi cat "$REPORT_FILE"
;; ;;
"deduplicate" ) "deduplicate" )
if [ $TODOTXT_PRESERVE_LINE_NUMBERS = 0 ]; then if [ $TODOTXT_PRESERVE_LINE_NUMBERS = 0 ]; then
deduplicateSedCommand='d' deduplicateSedCommand='d'
else else
deduplicateSedCommand='s/^.*//; p' deduplicateSedCommand='{ s/^.*//; p; b }'
fi fi
# To determine the difference when deduplicated lines are preserved, only # To determine the difference when deduplicated lines are preserved, only
@@ -1265,25 +1221,17 @@ note: PRIORITY must be anywhere from A to Z."
# We start with an empty hold space on the first line. For each line: # We start with an empty hold space on the first line. For each line:
# G - appends newline + hold space to the pattern space # G - appends newline + hold space to the pattern space
# s/\n/&&/; - double up the first new line so we catch adjacent dups # s/\n/&&/; - double up the first new line so we catch adjacent dups
# /^\([^\n]*\n\).*\n\1/b dedup # /^\([^\n]*\n\).*\n\1/
# If the first line of the hold space shows up again later as an # If the first line of the hold space shows up again later as an
# entire line, it's a duplicate. Jump to the "dedup" label, where # entire line, it's a duplicate.
# either of the following is executed, depending on whether empty # d; - Delete the current pattern space, quit this line
# lines should be preserved: # and move on to the next, or:
# d - Delete the current pattern space, quit this line and # { s/^.*//; p; b }; - Clear the task text, print this line and move on
# move on to the next, or: # to the next.
# s/^.*//; p - Clear the task text, print this line and move on to # s/\n//; - else, drop the doubled newline
# the next.
# s/\n//; - else (no duplicate), drop the doubled newline
# h; - replace the hold space with the expanded pattern space # h; - replace the hold space with the expanded pattern space
# P; - print up to the first newline (that is, the input line) # P; - print up to the first newline (that is, the input line)
# b - end processing of the current line sed -i.bak -n 'G; s/\n/&&/; /^\([^\n]*\n\).*\n\1/'"$deduplicateSedCommand"'; s/\n//; h; P' "$TODO_FILE"
sed -i.bak -n \
-e 'G; s/\n/&&/; /^\([^\n]*\n\).*\n\1/b dedup' \
-e 's/\n//; h; P; b' \
-e ':dedup' \
-e "$deduplicateSedCommand" \
"$TODO_FILE"
newTaskNum=$( sed -e '/./!d' "$TODO_FILE" | sed -n '$ =' ) newTaskNum=$( sed -e '/./!d' "$TODO_FILE" | sed -n '$ =' )
deduplicateNum=$(( originalTaskNum - newTaskNum )) deduplicateNum=$(( originalTaskNum - newTaskNum ))
@@ -1297,3 +1245,5 @@ note: PRIORITY must be anywhere from A to Z."
* ) * )
usage;; usage;;
esac esac
cleanup

View File

@@ -38,28 +38,20 @@ _todo()
+*) completions=$(TODOTXT_VERBOSE=0 todo.sh command listproj);; +*) completions=$(TODOTXT_VERBOSE=0 todo.sh command listproj);;
@*) completions=$(TODOTXT_VERBOSE=0 todo.sh command listcon);; @*) completions=$(TODOTXT_VERBOSE=0 todo.sh command listcon);;
*) if [[ "$cur" =~ ^[0-9]+$ ]]; then *) if [[ "$cur" =~ ^[0-9]+$ ]]; then
local item=$(TODOTXT_VERBOSE=0 todo.sh -@ -+ -p -x command ls "^ *${cur} " | head -n 1)
# Remove the (padded) task number; we prepend the # Remove the (padded) task number; we prepend the
# user-provided $cur instead. # user-provided $cur.
# Remove the timestamp prepended by the -t option, item=${item#* }
# and the done date (for done tasks); there's no
# todo.txt option for that yet. # Remove the timestamp prepended by the -t option;
# But keep priority and "x"; they're short and may # there's no todo.txt option for that yet.
# provide useful context. item=${item#[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] }
# Remove any trailing whitespace; the Bash
# completion inserts a trailing space itself.
# Finally, limit the output to a single line just as
# a safety check of the ls action output.
local todo=$( \
TODOTXT_VERBOSE=0 todo.sh -@ -+ -p -x command ls "^ *${cur} " | \
sed -e 's/^ *[0-9]\+ //' -e 's/\((.) \)[0-9]\{2,4\}-[0-9]\{2\}-[0-9]\{2\} /\1/' \
-e 's/\([xX] \)\([0-9]\{2,4\}-[0-9]\{2\}-[0-9]\{2\} \)\{1,2\}/\1/' \
-e 's/[[:space:]]*$//' \
-e '1q' \
)
# Append task text as a shell comment. This # Append task text as a shell comment. This
# completion can be a safety check before a # completion can be a safety check before a
# destructive todo.txt operation. # destructive todo.txt operation.
[ "$todo" ] && COMPREPLY[0]="$cur # $todo" [ "$item" ] && COMPREPLY[0]="$cur # $item"
return 0 return 0
else else
return 0 return 0