Compare commits

..

2 Commits

Author SHA1 Message Date
Ingo Karkat
d7a43c4143 Strip trailing whitespace when completing tasks. 2012-01-09 15:41:04 +01:00
Ingo Karkat
248c56367f Remove task date(s) when completing prioritized and done tasks.
Replace the primitive substitutions inside the completion function with a call to sed (instead of calling head), and supply more powerful substitutions there.
2012-01-09 15:23:22 +01:00
5 changed files with 37 additions and 206 deletions

View File

@@ -1,35 +0,0 @@
#!/bin/sh
test_description='archive functionality
Ensure we can archive items successfully.
'
. ./test-lib.sh
cat > todo.txt <<EOF
one
two
three
one
x done
four
EOF
test_todo_session 'archive with duplicates' <<EOF
>>> todo.sh archive
x done
TODO: $HOME/todo.txt archived.
EOF
test_todo_session 'list after archive' <<EOF
>>> todo.sh ls
5 four
1 one
4 one
3 three
2 two
--
TODO: 5 of 5 tasks shown
EOF
test_done

View File

@@ -1,103 +0,0 @@
#!/bin/sh
test_description='deduplicate functionality
Ensure we can deduplicate items successfully.
'
. ./test-lib.sh
cat > todo.txt <<EOF
duplicated
two
x done
duplicated
double task
double task
three
EOF
test_todo_session 'deduplicate and preserve line numbers' <<EOF
>>> todo.sh deduplicate
TODO: 2 duplicate task(s) removed
>>> todo.sh -p ls
5 double task
1 duplicated
7 three
2 two
3 x done
--
TODO: 5 of 5 tasks shown
EOF
test_todo_session 'deduplicate without duplicates' <<EOF
>>> todo.sh deduplicate
TODO: No duplicate tasks found
EOF
cat > todo.txt <<EOF
duplicated
two
x done
duplicated
double task
double task
three
EOF
test_todo_session 'deduplicate and delete lines' <<EOF
>>> todo.sh -n deduplicate
TODO: 2 duplicate task(s) removed
>>> todo.sh -p ls
4 double task
1 duplicated
5 three
2 two
3 x done
--
TODO: 5 of 5 tasks shown
EOF
cat > todo.txt <<EOF
one
duplicated
three
duplicated
duplicated
six
duplicated
EOF
test_todo_session 'deduplicate more than two occurrences' <<EOF
>>> todo.sh deduplicate
TODO: 3 duplicate task(s) removed
>>> todo.sh -p ls
2 duplicated
1 one
6 six
3 three
--
TODO: 4 of 4 tasks shown
EOF
cat > todo.txt <<EOF
normal task
a bold action
something else
a bold action
something more
EOF
test_todo_session 'deduplicate with non-printable duplicates' <<EOF
>>> todo.sh deduplicate
TODO: 1 duplicate task(s) removed
>>> todo.sh -p ls
2 a bold action
1 normal task
3 something else
5 something more
--
TODO: 4 of 4 tasks shown
EOF
test_done

View File

@@ -85,12 +85,10 @@ TODO: $HOME/todo.txt archived.
TODO: 5 of 5 tasks shown TODO: 5 of 5 tasks shown
>>> todo.sh report >>> todo.sh report
TODO: $HOME/todo.txt archived.
TODO: Report file updated. TODO: Report file updated.
2009-02-13-04:40:00 5 1 2009-02-13-04:40:00 5 1
>>> todo.sh report >>> todo.sh report
TODO: $HOME/todo.txt archived.
TODO: Report file updated. TODO: Report file updated.
2009-02-13-04:40:00 5 1 2009-02-13-04:40:00 5 1
2009-02-13-04:40:00 5 1 2009-02-13-04:40:00 5 1

73
todo.sh
View File

@@ -50,7 +50,6 @@ shorthelp()
append|app ITEM# "TEXT TO APPEND" append|app ITEM# "TEXT TO APPEND"
archive archive
command [ACTIONS] command [ACTIONS]
deduplicate
del|rm ITEM# [TERM] del|rm ITEM# [TERM]
depri|dp ITEM#[, ITEM#, ITEM#, ...] depri|dp ITEM#[, ITEM#, ITEM#, ...]
do ITEM#[, ITEM#, ITEM#, ...] do ITEM#[, ITEM#, ITEM#, ...]
@@ -181,9 +180,6 @@ help()
Runs the remaining arguments using only todo.sh builtins. Runs the remaining arguments using only todo.sh builtins.
Will not call any .todo.actions.d scripts. Will not call any .todo.actions.d scripts.
deduplicate
Removes duplicate lines from todo.txt.
del ITEM# [TERM] del ITEM# [TERM]
rm ITEM# [TERM] rm ITEM# [TERM]
Deletes the task on line ITEM# in todo.txt. Deletes the task on line ITEM# in todo.txt.
@@ -357,6 +353,20 @@ getNewtodo()
[ -z "$newtodo" ] && die "$(getPrefix "$2"): No updated task $item." [ -z "$newtodo" ] && die "$(getPrefix "$2"): No updated task $item."
} }
archive()
{
#defragment blank lines
sed -i.bak -e '/./!d' "$TODO_FILE"
[ $TODOTXT_VERBOSE -gt 0 ] && grep "^x " "$TODO_FILE"
grep "^x " "$TODO_FILE" >> "$DONE_FILE"
sed -i.bak '/^x /d' "$TODO_FILE"
cp "$TODO_FILE" "$TMP_FILE"
sed -n 'G; s/\n/&&/; /^\([ ~-]*\n\).*\n\1/d; s/\n//; h; P' "$TMP_FILE" > "$TODO_FILE"
if [ $TODOTXT_VERBOSE -gt 0 ]; then
echo "TODO: $TODO_FILE archived."
fi
}
replaceOrPrepend() replaceOrPrepend()
{ {
action=$1; shift action=$1; shift
@@ -923,15 +933,7 @@ case $action in
;; ;;
"archive" ) "archive" )
# defragment blank lines archive;;
sed -i.bak -e '/./!d' "$TODO_FILE"
[ $TODOTXT_VERBOSE -gt 0 ] && grep "^x " "$TODO_FILE"
grep "^x " "$TODO_FILE" >> "$DONE_FILE"
sed -i.bak '/^x /d' "$TODO_FILE"
if [ $TODOTXT_VERBOSE -gt 0 ]; then
echo "TODO: $TODO_FILE archived."
fi
;;
"del" | "rm" ) "del" | "rm" )
# replace deleted line with a blank line when TODOTXT_PRESERVE_LINE_NUMBERS is 1 # replace deleted line with a blank line when TODOTXT_PRESERVE_LINE_NUMBERS is 1
@@ -1033,9 +1035,7 @@ case $action in
done done
if [ $TODOTXT_AUTO_ARCHIVE = 1 ]; then if [ $TODOTXT_AUTO_ARCHIVE = 1 ]; then
# Recursively invoke the script to allow overriding of the archive archive
# action.
"$TODO_FULL_SH" archive
fi fi
;; ;;
@@ -1188,9 +1188,8 @@ note: PRIORITY must be anywhere from A to Z."
"report" ) "report" )
#archive first #archive first
# Recursively invoke the script to allow overriding of the archive sed '/^x /!d' "$TODO_FILE" >> "$DONE_FILE"
# action. sed -i.bak '/^x /d' "$TODO_FILE"
"$TODO_FULL_SH" archive
NUMLINES=$( sed -n '$ =' "$TODO_FILE" ) NUMLINES=$( sed -n '$ =' "$TODO_FILE" )
if [ ${NUMLINES:-0} = "0" ]; then if [ ${NUMLINES:-0} = "0" ]; then
@@ -1206,42 +1205,6 @@ note: PRIORITY must be anywhere from A to Z."
cat "$REPORT_FILE" cat "$REPORT_FILE"
;; ;;
"deduplicate" )
if [ $TODOTXT_PRESERVE_LINE_NUMBERS = 0 ]; then
deduplicateSedCommand='d'
else
deduplicateSedCommand='{ s/^.*//; p; b }'
fi
# To determine the difference when deduplicated lines are preserved, only
# non-empty lines must be counted.
originalTaskNum=$( sed -e '/./!d' "$TODO_FILE" | sed -n '$ =' )
# Look for duplicate lines and discard the second occurrence.
# We start with an empty hold space on the first line. For each line:
# G - appends newline + hold space to the pattern space
# s/\n/&&/; - double up the first new line so we catch adjacent dups
# /^\([^\n]*\n\).*\n\1/
# If the first line of the hold space shows up again later as an
# entire line, it's a duplicate.
# d; - Delete the current pattern space, quit this line
# and move on to the next, or:
# { s/^.*//; p; b }; - Clear the task text, print this line and move on
# to the next.
# s/\n//; - else, drop the doubled newline
# h; - replace the hold space with the expanded pattern space
# P; - print up to the first newline (that is, the input line)
sed -i.bak -n 'G; s/\n/&&/; /^\([^\n]*\n\).*\n\1/'"$deduplicateSedCommand"'; s/\n//; h; P' "$TODO_FILE"
newTaskNum=$( sed -e '/./!d' "$TODO_FILE" | sed -n '$ =' )
deduplicateNum=$(( originalTaskNum - newTaskNum ))
if [ $deduplicateNum -eq 0 ]; then
echo "TODO: No duplicate tasks found"
else
echo "TODO: $deduplicateNum duplicate task(s) removed"
fi
;;
* ) * )
usage;; usage;;
esac esac

View File

@@ -38,20 +38,28 @@ _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. # user-provided $cur instead.
item=${item#* } # Remove the timestamp prepended by the -t option,
# and the done date (for done tasks); there's no
# Remove the timestamp prepended by the -t option; # todo.txt option for that yet.
# there's no todo.txt option for that yet. # But keep priority and "x"; they're short and may
item=${item#[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] } # provide useful context.
# 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.
[ "$item" ] && COMPREPLY[0]="$cur # $item" [ "$todo" ] && COMPREPLY[0]="$cur # $todo"
return 0 return 0
else else
return 0 return 0