Merge remote-tracking branch 'upstream/master'
This commit is contained in:
95
todo.sh
95
todo.sh
@@ -254,7 +254,7 @@ actionsHelp()
|
||||
listpri [PRIORITIES] [TERM...]
|
||||
lsp [PRIORITIES] [TERM...]
|
||||
Displays all tasks prioritized PRIORITIES.
|
||||
PRIORITIES can be a single one (A) or a range (A-C).
|
||||
PRIORITIES can be a [concatenation of] single (A) or range (A-C).
|
||||
If no PRIORITIES specified, lists all prioritized tasks.
|
||||
If TERM specified, lists only prioritized tasks that contain TERM(s).
|
||||
Hides all tasks that contain TERM(s) preceded by a minus sign
|
||||
@@ -349,14 +349,14 @@ dieWithHelp()
|
||||
case "$1" in
|
||||
help) help;;
|
||||
shorthelp) shorthelp;;
|
||||
esac
|
||||
esac >&2
|
||||
shift
|
||||
|
||||
die "$@"
|
||||
}
|
||||
die()
|
||||
{
|
||||
echo "$*"
|
||||
echo >&2 "$*"
|
||||
exit 1
|
||||
}
|
||||
|
||||
@@ -364,12 +364,11 @@ confirm()
|
||||
{
|
||||
[ $TODOTXT_FORCE = 0 ] || return 0
|
||||
|
||||
printf %s "${1:?}? (y/n) "
|
||||
local readArgs=(-e -r)
|
||||
[ -n "${BASH_VERSINFO:-}" ] && [ \( ${BASH_VERSINFO[0]} -eq 4 -a ${BASH_VERSINFO[1]} -ge 1 \) -o ${BASH_VERSINFO[0]} -gt 4 ] &&
|
||||
readArgs+=(-N 1) # Bash 4.1+ supports -N nchars
|
||||
local answer
|
||||
read "${readArgs[@]}" answer
|
||||
read -p "${1:?}? (y/n) " "${readArgs[@]}" answer
|
||||
echo
|
||||
[ "$answer" = "y" ]
|
||||
}
|
||||
@@ -451,28 +450,38 @@ replaceOrPrepend()
|
||||
getTodo "$item"
|
||||
|
||||
if [[ -z "$1" && $TODOTXT_FORCE = 0 ]]; then
|
||||
echo -n "$querytext"
|
||||
read -r -i "$todo" -e input
|
||||
read -p "$querytext" -r -i "$todo" -e input
|
||||
else
|
||||
input=$*
|
||||
fi
|
||||
|
||||
# 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
|
||||
@@ -826,11 +835,6 @@ _addto() {
|
||||
fi
|
||||
}
|
||||
|
||||
shellquote()
|
||||
{
|
||||
typeset -r qq=\'; printf %s\\n "'${1//\'/${qq}\\${qq}${qq}}'";
|
||||
}
|
||||
|
||||
filtercommand()
|
||||
{
|
||||
filter=${1:-}
|
||||
@@ -845,13 +849,13 @@ filtercommand()
|
||||
then
|
||||
## First character isn't a dash: hide lines that don't match
|
||||
## this $search_term
|
||||
filter="${filter:-}${filter:+ | }grep -i $(shellquote "$search_term")"
|
||||
printf -v filter '%sgrep -i %q' "${filter:-}${filter:+ | }" "$search_term"
|
||||
else
|
||||
## First character is a dash: hide lines that match this
|
||||
## $search_term
|
||||
#
|
||||
## Remove the first character (-) before adding to our filter command
|
||||
filter="${filter:-}${filter:+ | }grep -v -i $(shellquote "${search_term:1}")"
|
||||
printf -v filter '%sgrep -v -i %q' "${filter:-}${filter:+ | }" "${search_term:1}"
|
||||
fi
|
||||
done
|
||||
|
||||
@@ -1045,7 +1049,18 @@ listWordsWithSigil()
|
||||
| sort -u
|
||||
}
|
||||
|
||||
export -f cleaninput getPrefix getTodo getNewtodo shellquote filtercommand _list listWordsWithSigil getPadding _format die
|
||||
hasCustomAction()
|
||||
{
|
||||
[ -d "${1:?}" ] || return 1
|
||||
[ -x "$1/${2:?}" ] && return 0
|
||||
if [ -h "$1/$2" ] && [ ! -e "$1/$2" ]
|
||||
then
|
||||
dieWithHelp "$2" "Fatal Error: Broken link to custom action: '$1/$2'"
|
||||
fi
|
||||
return 1
|
||||
}
|
||||
|
||||
export -f cleaninput getPrefix getTodo getNewtodo filtercommand _list listWordsWithSigil getPadding _format die
|
||||
|
||||
# == HANDLE ACTION ==
|
||||
action=$( printf "%s\n" "$ACTION" | tr '[:upper:]' '[:lower:]' )
|
||||
@@ -1060,11 +1075,11 @@ then
|
||||
shift
|
||||
## Reset action to new first argument
|
||||
action=$( printf "%s\n" "$1" | tr '[:upper:]' '[:lower:]' )
|
||||
elif [ -d "$TODO_ACTIONS_DIR/$action" ] && [ -x "$TODO_ACTIONS_DIR/$action/$action" ]
|
||||
elif hasCustomAction "$TODO_ACTIONS_DIR/$action" "$action"
|
||||
then
|
||||
"$TODO_ACTIONS_DIR/$action/$action" "$@"
|
||||
exit $?
|
||||
elif [ -d "$TODO_ACTIONS_DIR" ] && [ -x "$TODO_ACTIONS_DIR/$action" ]
|
||||
elif hasCustomAction "$TODO_ACTIONS_DIR" "$action"
|
||||
then
|
||||
"$TODO_ACTIONS_DIR/$action" "$@"
|
||||
exit $?
|
||||
@@ -1074,8 +1089,7 @@ fi
|
||||
case $action in
|
||||
"add" | "a")
|
||||
if [[ -z "$2" && $TODOTXT_FORCE = 0 ]]; then
|
||||
echo -n "Add: "
|
||||
read -e -r input
|
||||
read -p "Add: " -e -r input
|
||||
else
|
||||
[ -z "$2" ] && die "usage: $TODO_SH add \"TODO ITEM\""
|
||||
shift
|
||||
@@ -1086,8 +1100,7 @@ case $action in
|
||||
|
||||
"addm")
|
||||
if [[ -z "$2" && $TODOTXT_FORCE = 0 ]]; then
|
||||
echo -n "Add: "
|
||||
read -e -r input
|
||||
read -p "Add: " -e -r input
|
||||
else
|
||||
[ -z "$2" ] && die "usage: $TODO_SH addm \"TODO ITEM\""
|
||||
shift
|
||||
@@ -1127,8 +1140,7 @@ case $action in
|
||||
getTodo "$item"
|
||||
|
||||
if [[ -z "$1" && $TODOTXT_FORCE = 0 ]]; then
|
||||
echo -n "Append: "
|
||||
read -e -r input
|
||||
read -p "Append: " -e -r input
|
||||
else
|
||||
input=$*
|
||||
fi
|
||||
@@ -1179,7 +1191,7 @@ case $action in
|
||||
echo "TODO: $item deleted."
|
||||
fi
|
||||
else
|
||||
echo "TODO: No tasks were deleted."
|
||||
die "TODO: No tasks were deleted."
|
||||
fi
|
||||
else
|
||||
sed -i.bak \
|
||||
@@ -1209,6 +1221,7 @@ case $action in
|
||||
|
||||
# Split multiple depri's, if comma separated change to whitespace separated
|
||||
# Loop the 'depri' function for each item
|
||||
status=0
|
||||
for item in ${*//,/ }; do
|
||||
getTodo "$item"
|
||||
|
||||
@@ -1220,9 +1233,11 @@ case $action in
|
||||
echo "TODO: $item deprioritized."
|
||||
fi
|
||||
else
|
||||
echo "TODO: $item is not prioritized."
|
||||
echo >&2 "TODO: $item is not prioritized."
|
||||
status=1
|
||||
fi
|
||||
done
|
||||
exit $status
|
||||
;;
|
||||
|
||||
"do" | "done" )
|
||||
@@ -1233,6 +1248,7 @@ case $action in
|
||||
|
||||
# Split multiple do's, if comma separated change to whitespace separated
|
||||
# Loop the 'do' function for each item
|
||||
status=0
|
||||
for item in ${*//,/ }; do
|
||||
getTodo "$item"
|
||||
|
||||
@@ -1248,15 +1264,17 @@ case $action in
|
||||
echo "TODO: $item marked as done."
|
||||
fi
|
||||
else
|
||||
echo "TODO: $item is already marked done."
|
||||
echo >&2 "TODO: $item is already marked done."
|
||||
status=1
|
||||
fi
|
||||
done
|
||||
|
||||
if [ $TODOTXT_AUTO_ARCHIVE = 1 ]; then
|
||||
# Recursively invoke the script to allow overriding of the archive
|
||||
# action.
|
||||
"$TODO_FULL_SH" archive
|
||||
"$TODO_FULL_SH" archive || status=$?
|
||||
fi
|
||||
exit $status
|
||||
;;
|
||||
|
||||
"help" )
|
||||
@@ -1336,7 +1354,7 @@ case $action in
|
||||
"listpri" | "lsp" )
|
||||
shift ## was "listpri", new $1 is priority to list or first TERM
|
||||
|
||||
pri=$(printf "%s\n" "$1" | tr '[:lower:]' '[:upper:]' | grep -e '^[A-Z]$' -e '^[A-Z]-[A-Z]$') && shift || pri="A-Z"
|
||||
pri=$(set -o pipefail; printf "%s\n" "$1" | grep '^\([A-Za-z]\|[A-Za-z]-[A-Za-z]\|[A-Z][A-Z-]*[A-Z]\)$' | tr '[:lower:]' '[:upper:]') && shift || pri="A-Z"
|
||||
post_filter_command="${post_filter_command:-}${post_filter_command:+ | }grep '^ *[0-9]\+ ([${pri}]) '"
|
||||
_list "$TODO_FILE" "$@"
|
||||
;;
|
||||
@@ -1372,7 +1390,7 @@ case $action in
|
||||
echo "TODO: $item moved from '$src' to '$dest'."
|
||||
fi
|
||||
else
|
||||
echo "TODO: No tasks moved."
|
||||
die "TODO: No tasks moved."
|
||||
fi
|
||||
;;
|
||||
|
||||
@@ -1383,6 +1401,7 @@ case $action in
|
||||
|
||||
"pri" | "p" )
|
||||
shift
|
||||
status=0
|
||||
while [ "$#" -gt 0 ] ; do
|
||||
item=$1
|
||||
newpri=$( printf "%s\n" "$2" | tr '[:lower:]' '[:upper:]' )
|
||||
@@ -1414,10 +1433,12 @@ note: PRIORITY must be anywhere from A to Z."
|
||||
fi
|
||||
fi
|
||||
if [ "$oldpri" = "$newpri" ]; then
|
||||
echo "TODO: $item already prioritized ($newpri)."
|
||||
echo >&2 "TODO: $item already prioritized ($newpri)."
|
||||
status=1
|
||||
fi
|
||||
shift; shift
|
||||
done
|
||||
exit $status
|
||||
;;
|
||||
|
||||
"replace" )
|
||||
@@ -1485,7 +1506,7 @@ note: PRIORITY must be anywhere from A to Z."
|
||||
newTaskNum=$( sed -e '/./!d' "$TODO_FILE" | sed -n '$ =' )
|
||||
deduplicateNum=$(( originalTaskNum - newTaskNum ))
|
||||
if [ $deduplicateNum -eq 0 ]; then
|
||||
echo "TODO: No duplicate tasks found"
|
||||
die "TODO: No duplicate tasks found"
|
||||
else
|
||||
echo "TODO: $deduplicateNum duplicate task(s) removed"
|
||||
fi
|
||||
|
||||
Reference in New Issue
Block a user