-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathtodo.sh
executable file
·175 lines (155 loc) · 4.84 KB
/
todo.sh
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
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
#!/usr/bin/env bash
IFS=$'\n\t'
set -euo pipefail
# Enable extglob so that we can more-easily match against numbers
shopt -s extglob
# Make sure that the needed files and directory all exist
mkdir -p "$HOME/.local/share/todo_list"
todoFile="$HOME/.local/share/todo_list/current_list"
touch "$todoFile"
doneFile="$HOME/.local/share/todo_list/done_list"
touch "$doneFile"
# If the "todo_list" directory is a git repository, commits changes to any files
# in the directory.
function commitChanges() {
if [ -e "$HOME/.local/share/todo_list/.git" ] ; then
(
cd "$HOME/.local/share/todo_list"
git add .
git commit -m "$1" 2>/dev/null || true
)
fi
}
# Displays the current to-do list with line numbers
function displayTodo() {
# Clear the display before updating the display
clear
# Iterate over every line of the text file, and spit out the contents
lineNum=0
while IFS='' read -r line ; do
lineNum=$((lineNum+1))
# Do not show the leading timestamp
echo "$lineNum $(echo "$line" | cut -d ' ' -f 2-)"
done < "$todoFile"
}
# Moves the most-recent task into the "done" list
function finishTask() {
# Get the last line of the todo file
lastLine="$(tail -n 1 "$todoFile")"
# If the line had contents...
if [[ "${lastLine:-}" != "" ]] ; then
# Split off the start date for the task, add the current system time,
# and add the info into the "done" list.
date="$(echo "$lastLine" | cut -d ' ' -f 1)"
task="$(echo "$lastLine" | cut -d ' ' -f 2-)"
echo "$date $(date -Is) $task" >> "$doneFile"
# Then use sed to remove the task from the current list
sed -i ".old" '$d' "$todoFile"
commitChanges "Finish current task: $task"
fi
}
# "Resumes" the given task number by moving it to the bottom of the to-do list
function resumeTask() {
# Grab the specified line number
line="$1"
task="$(awk "NR == $1" "$todoFile")"
# If the line had contents...
if [[ "${task:-}" != "" ]] ; then
# Remove the line from the to-do list...
awk "NR != $1" "$todoFile" > "$todoFile.tmp"
mv "$todoFile.tmp" "$todoFile"
# And append it back onto the file
echo "$task" >> "$todoFile"
task="$(echo "$task" | cut -d ' ' -f 2-)"
commitChanges "Resume task $1: $task"
fi
}
# "Pops" the given task number and puts it into the "done" list
function popTask() {
# Grab the specified line number
line="$1"
task="$(awk "NR == $1" "$todoFile")"
# If the line had contents...
if [[ "${task:-}" != "" ]] ; then
# Remove the line from the to-do list...
awk "NR != $1" "$todoFile" > "$todoFile.tmp"
mv "$todoFile.tmp" "$todoFile"
# Split off the start date for the task, add the current system time,
# and add the info into the "done" list.
date="$(echo "$line" | cut -d ' ' -f 1)"
task="$(echo "$line" | cut -d ' ' -f 2-)"
echo "$date $(date -Is) $task" >> "$doneFile"
commitChanges "Finished task $1: $task"
fi
}
# Allows the user to edit the current task
function editTask() {
# Grab the current task
task="$(tail -n 1 "$todoFile")"
# If the line had contents...
if [[ "${task:-}" != "" ]] ; then
# Split off the start date for the task
date="$(echo "$task" | cut -d ' ' -f 1)"
task="$(echo "$task" | cut -d ' ' -f 2-)"
# Ask the user to make their modification to the task
read -e -i "$task" task
# Remove the current task from the list, and then add it back on with
# the modification(s)
sed -i ".old" '$d' "$todoFile"
echo "$date $task" >> "$todoFile"
commitChanges "Modified current task to: $task"
fi
}
# Clears the "finished" task list
function clearFinished() {
> "$doneFile"
commitChanges "Clear finished task list"
}
# Creates a new task
function createTask() {
echo "$(date -Is) $1" >> "$todoFile"
commitChanges "Create new task: $1"
}
displayTodo
userInput=
while read -r userInput
do
doDisplay=true
case "$userInput" in
quit | q)
exit
;;
"pop" | p | "done" | d)
finishTask
;;
"finished" | f)
clear
less "$doneFile"
;;
"clear-finished" | cf)
clearFinished
;;
"edit" | e)
editTask
;;
+([0-9]))
resumeTask "$userInput"
;;
+([0-9])p | p+([0-9]))
popTask "${userInput//p/}"
;;
"")
true
;;
[a-zA-Z])
echo "Unknown command '$userInput'"
read -r userInput
;;
**)
createTask "$userInput"
;;
esac
if $doDisplay ; then
displayTodo
fi
done