-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathtodo
executable file
·67 lines (60 loc) · 1.87 KB
/
todo
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
#!/bin/sh
# todo: minimal command-line todo list.
# this is actually a reimplementation of an hello world program I wrote in
# go and in c before, but i figured a shell script is more than enough for
# my needs. highly inspired by https://github.com/sjl/t
list="$HOME/.todo"
trim() {
echo "$@" | awk '{
for (i = 1; i <= NF; i++) {
gsub(/^[[:space:]]+|[[:space:]]+$/, "", $i);
printf "%s%s", $i, (i == NF ? "" : OFS);
}
}'
}
validate() {
echo "$@" | awk '{
for (i = 1; i <= NF; i++)
if ($i !~ /^[0-9]+$/ || $i <= 0)
exit 1;
}'
}
die() {
echo "error:" "$@" >&2
exit 1
}
[ -f "$list" ] || touch "$list"
case "$1" in
"-h" | "--help")
echo "usage: todo [-x|-e|-n] [id...] [-|desc...]"
;;
"")
awk '{ printf "%2d ", NR; print }' "$list"
;;
"-x")
shift
ids="$(trim "$@")"
# shellcheck disable=SC2015
[ -n "$ids" ] && validate "$ids" || die "invalid or missing todo id(s)"
sed -n "$(echo "$ids" | sed -e 's/[[:space:]]\+/p;/g' -e 's/$/p;/')" "$list" >> "$list.x"
tail "$list.x" > "$list.x.$$.tmp" && mv "$list.x.$$.tmp" "$(readlink -f "$list.x")"
sed "$(echo "$ids" | sed -e 's/[[:space:]]\+/d;/g' -e 's/$/d;/')" "$list" > "$list.$$.tmp" && mv "$list.$$.tmp" "$(readlink -f "$list")"
;;
"-e")
id="$(trim "$2")"
validate "$id" || die "invalid todo id"
vim "+$id" "$list" # +[num] is vim specific, that's why the editor is hardcoded here.
;;
"-n")
shift
ids="$(trim "$@")"
validate "$ids" || die "invalid todo id(s)"
sed -n "$(echo "$ids" | sed -e 's/[[:space:]]\+/p;/g' -e 's/$/p;/')" "$list"
;;
"-")
cat >> "$list"
;;
*)
echo "$@" >> "$list"
;;
esac