replace: Completely merge given priority / date with existing

So that any combination of priority / date entered in the replacement will replace the corresponding original ones, but if they are left out, the original ones will be kept.
In essence, omitted stuff will be kept, added stuff will override, only deletion of existing stuff is not possible (but this is replace, after all).

Fixes #386
This commit is contained in:
Ingo Karkat
2022-06-17 23:12:35 +02:00
parent ea32af34e6
commit 28523851d0
2 changed files with 58 additions and 6 deletions

View File

@@ -140,6 +140,18 @@ TODO: Replaced task with:
1 2010-07-04 this also has a new date
EOF
cat /dev/null > todo.txt
test_todo_session 'replace handling prepended priority on add' <<EOF
>>> todo.sh -t add "new task"
1 2009-02-13 new task
TODO: 1 added.
>>> todo.sh replace 1 '(B) this also has a priority now'
1 2009-02-13 new task
TODO: Replaced task with:
1 (B) 2009-02-13 this also has a priority now
EOF
cat /dev/null > todo.txt
test_todo_session 'replace handling priority and prepended date on add' <<EOF
>>> todo.sh -t add "new task"
@@ -156,6 +168,18 @@ TODO: Replaced task with:
1 (A) 2009-02-13 this is just a new one
EOF
cat /dev/null > todo.txt
test_todo_session 'replace handling prepended priority and date on add' <<EOF
>>> todo.sh -t add "new task"
1 2009-02-13 new task
TODO: 1 added.
>>> todo.sh replace 1 '(C) 2010-07-04 this also has a priority and new date'
1 2009-02-13 new task
TODO: Replaced task with:
1 (C) 2010-07-04 this also has a priority and new date
EOF
echo '(A) 2009-02-13 this is just a new one' > todo.txt
test_todo_session 'replace with prepended date replaces existing date' <<EOF
>>> todo.sh replace 1 2010-07-04 this also has a new date
@@ -164,6 +188,14 @@ TODO: Replaced task with:
1 (A) 2010-07-04 this also has a new date
EOF
echo '(A) 2009-02-13 this is just a new one' > todo.txt
test_todo_session 'replace with prepended priority replaces existing priority' <<EOF
>>> todo.sh replace 1 '(B) this also has a new priority'
1 (A) 2009-02-13 this is just a new one
TODO: Replaced task with:
1 (B) 2009-02-13 this also has a new priority
EOF
echo '2009-02-13 this is just a new one' > todo.txt
test_todo_session 'replace with prepended priority and date replaces existing date' <<EOF
>>> todo.sh replace 1 '(B) 2010-07-04 this also has a new date'
@@ -172,4 +204,13 @@ TODO: Replaced task with:
1 (B) 2010-07-04 this also has a new date
EOF
echo '(A) 2009-02-13 this is just a new one' > todo.txt
test_todo_session 'replace with prepended priority and date replaces existing priority and date' <<EOF
>>> todo.sh replace 1 '(B) 2010-07-04 this also has a new prio+date'
1 (A) 2009-02-13 this is just a new one
TODO: Replaced task with:
1 (B) 2010-07-04 this also has a new prio+date
EOF
test_done

23
todo.sh
View File

@@ -459,20 +459,31 @@ replaceOrPrepend()
# Retrieve existing priority and prepended date
local -r priAndDateExpr='^\((.) \)\{0,1\}\([0-9]\{2,4\}-[0-9]\{2\}-[0-9]\{2\} \)\{0,1\}'
priority=$(sed -e "$item!d" -e "${item}s/${priAndDateExpr}.*/\\1/" "$TODO_FILE")
prepdate=$(sed -e "$item!d" -e "${item}s/${priAndDateExpr}.*/\\2/" "$TODO_FILE")
if [ "$prepdate" ] && [ "$action" = "replace" ] && [ "$(echo "$input"|sed -e "s/${priAndDateExpr}.*/\\1\\2/")" ]; then
originalPriority=$(sed -e "$item!d" -e "${item}s/${priAndDateExpr}.*/\\1/" "$TODO_FILE")
priority="$originalPriority"
originalPrepdate=$(sed -e "$item!d" -e "${item}s/${priAndDateExpr}.*/\\2/" "$TODO_FILE")
prepdate="$originalPrepdate"
if [ "$action" = "replace" ]; then
replacementPrepdate="$(echo "$input"|sed -e "s/${priAndDateExpr}.*/\\2/")"
if [ "$replacementPrepdate" ]; then
# If the replaced text starts with a [priority +] date, it will replace
# the existing date, too.
prepdate=
prepdate="$replacementPrepdate"
fi
replacementPriority="$(echo "$input"|sed -e "s/${priAndDateExpr}.*/\\1/")"
if [ "$replacementPriority" ]; then
# If the replaced text starts with a priority, it will replace
# the existing priority, too.
priority="$replacementPriority"
fi
input="$(echo "$input"|sed -e "s/${priAndDateExpr}//")"
fi
# Temporarily remove any existing priority and prepended date, perform the
# change (replace/prepend) and re-insert the existing priority and prepended
# date again.
cleaninput "for sed"
sed -i.bak -e "$item s/^${priority}${prepdate}//" -e "$item s|^.*|${priority}${prepdate}${input}${backref}|" "$TODO_FILE"
sed -i.bak -e "$item s/^${originalPriority}${originalPrepdate}//" -e "$item s|^.*|${priority}${prepdate}${input}${backref}|" "$TODO_FILE"
if [ "$TODOTXT_VERBOSE" -gt 0 ]; then
getNewtodo "$item"
case "$action" in