2 # todo, A command line TODO manager
3 # Copyright (C) 2008 Alejandro Mery <amery@geeks.cl>
5 # This program is free software: you can redistribute it and/or modify
6 # it under the terms of the GNU General Public License as published by
7 # the Free Software Foundation, either version 3 of the License, or
8 # (at your option) any later version.
10 # This program is distributed in the hope that it will be useful,
11 # but WITHOUT ANY WARRANTY; without even the implied warranty of
12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 # GNU General Public License for more details.
15 # You should have received a copy of the GNU General Public License
16 # along with this program. If not, see <http://www.gnu.org/licenses/>.
22 [ $# -eq 0 ] ||
echo "ERROR: $*" >&2
24 Usage: $0 [options] [<object>]
25 ${cmd} [-t <tag>*] [<message>] - new entry
26 ${cmd} (-e|--edit) <hash> - edit an entry
27 ${cmd} (-T|--tags) - list tags
28 ${cmd} (-l|--list) [<tag>*] - list entries
29 ${cmd} -L [<tag>*] - list entry hashes
37 echo "Ctrl-C pressed, aborting." >&2
44 echo "$*" |
tr 'a-z' 'A-Z' |
sed \
45 -e 's/^ *//' -e 's/ *$//' -e 's/ */ /g'
50 local hash="$1" hash_1
= entry
=
51 if [ -n "$hash" ]; then
52 hash_1
=$
( echo $hash | cut
-c1 )
53 entry
="$TODODIR/entries/$hash_1/$hash"
54 ls -1 "$entry"* 2> /dev
/null |
head -n 1
60 options
=$
( getopt
-o "t:TLle" -l "tags,list,edit" -- "$@" )
65 # load new arguments list
66 eval set -- "$options"
71 while [ $# -gt 0 ]; do
82 -t) TAGS
="$TAGS $2"; shift ;;
85 -*) todo_usage unknown option
"$1"
95 TODOTMP
="${TMP:-/tmp}/.todo.$$"
97 # find a unique date/hash
99 while [ -z "$DATE" ]; do
100 DATE
=$
(date --rfc-3339=seconds
)
101 DATEHASH
=$
( echo "$DATE" |
sha1sum | cut
-d' ' -f1 )
102 DATEHASH_1
=$
( echo "$DATEHASH" | cut
-c 1 )
103 ENTRYDIR
="$TODODIR/entries/$DATEHASH_1"
104 ENTRY
="$ENTRYDIR/$DATEHASH"
106 if [ -e "$ENTRY" ]; then
114 if [ $# -gt 0 ]; then
115 echo "$*" > "$TODOTMP"
116 echo "Added: $DATE" >> "$TODOTMP"
118 echo "Subject: ..." > "$TODOTMP.empty"
119 echo "Added: $DATE" >> "$TODOTMP.empty"
120 cp "$TODOTMP.empty" "$TODOTMP"
122 ${EDITOR:-vi} "$TODOTMP"
124 if cmp -s "$TODOTMP" "$TODOTMP.empty"; then
125 rm -f "$TODOTMP" "$TODOTMP.empty"
130 mv "$TODOTMP" "$ENTRY"
132 for tag
in $
(todo_sane_tags
$TAGS) INBOX
; do
133 [ -d "$TODODIR/$tag" ] || mkdir
"$TODODIR/$tag"
135 ln -s "../entries/$DATEHASH_1/$DATEHASH" "$TODODIR/$tag/$DATEHASH"
143 ls -1d "$TODODIR"/* |
sed -e "s,^$TODODIR/,," |
grep -v '^entries$'
148 local tags
="$(todo_sane_tags $TAGS $*)"
150 if [ -n "$tags" ]; then
152 ls -1 "$TODODIR/$tag"/*
155 ls -1 "$TODODIR/entries"/*/*
156 fi 2> /dev
/null |
sed -e 's,.*/,,' |
sort -u
161 local hash= entry
= subject
=
162 for hash in $
( $0 -L $
(todo_sane_tags
$TAGS $
* )); do
163 entry
="$( todo_entry $hash )"
164 subject
=$
( grep '^Subject:' "$entry" | cut
-d' ' -f2- )
165 [ -n "$subject" ] || subject
=$
( head -n1 "$entry" )
166 [ -n "$subject" ] || subject
="empty"
168 echo "$hash $subject"
176 if [ ! -s "$entry" ]; then
178 rm -f "$entry" "$TODODIR"/*/"$hash"
185 local entries
= entry
= hash=
187 entry
="$(todo_entry $hash)"
188 [ -z "$entry" ] || entries
="$entries '$entry'"
191 [ -n "$entries" ] ||
return
193 eval "${EDITOR:-vi} $entries"
195 eval "todo_edit_gc $entries"
199 new
) todo_new
"$*" ;;
200 edit
) todo_edit
"$@" ;;
202 list
) todo_list
"$*" ;;
203 list_raw
) todo_list_raw
"$*" ;;