diff options
| -rw-r--r-- | todo.go | 12 | ||||
| -rw-r--r-- | todolist/app.go | 17 | ||||
| -rw-r--r-- | todolist/formatter.go | 11 | ||||
| -rw-r--r-- | todolist/parser.go | 62 | ||||
| -rw-r--r-- | todolist/parser_test.go | 26 | ||||
| -rw-r--r-- | todolist/todo_item.go | 1 | ||||
| -rw-r--r-- | todolist/todos.json | 2 |
7 files changed, 130 insertions, 1 deletions
@@ -122,6 +122,16 @@ func usage() { yellow.Println("\ttodo d 33") fmt.Println("\tDeletes a todo with id 33\n") + blueBold.Println("\nManipulating notes") + yellow.Println("\ttodo an 12 check http://this.web.site") + fmt.Println("\tAdds notes \"check http://this.web.site\" to the todo with id 12\n") + yellow.Println("\ttodo ln 12") + fmt.Println("\tLists notes of the todo with id 12\n") + yellow.Println("\ttodo dn 12 3") + fmt.Println("\tDeletes the 3rd note of the todo with id 12\n") + yellow.Println("\ttodo en 12 3 check http://that.web.site") + fmt.Println("\tEditing the 3rd note of the todo with id 12 to \"http://that.web.site\" \n") + blueBold.Println("\nGarbage Collection") yellow.Println("\ttodo gc") fmt.Println("\tDeletes all archived todos.\n") @@ -153,6 +163,8 @@ func routeInput(command string, input string) { app.EditTodo(input) case "ex", "expand": app.ExpandTodo(input) + case "an", "ln", "dn", "en": + app.ManipulateNotes(input) case "gc": app.GarbageCollect() case "p", "prioritize": diff --git a/todolist/app.go b/todolist/app.go index 367cc2f..2919234 100644 --- a/todolist/app.go +++ b/todolist/app.go @@ -132,6 +132,23 @@ func (a *App) ExpandTodo(input string) { fmt.Println("Todo expanded.") } +func (a *App) ManipulateNotes(input string) { + a.Load() + id, todo := a.getId(input) + parser := &Parser{} + if id == -1 { + return + } + + retStr := parser.ParseNotes(todo, input) + if retStr != "" { + a.Save() + if retStr != "list" { + fmt.Println("Notes " + retStr + "ed.") + } + } +} + func (a *App) ArchiveCompleted() { a.Load() for _, todo := range a.TodoList.Todos() { diff --git a/todolist/formatter.go b/todolist/formatter.go index c0f3313..847be04 100644 --- a/todolist/formatter.go +++ b/todolist/formatter.go @@ -43,6 +43,17 @@ func (f *Formatter) Print() { f.Writer.Flush() } +func (f *Formatter) PrintNotes() { + cyan := color.New(color.FgCyan).SprintFunc() + todo := f.GroupedTodos.Groups[""][0] + f.printTodo(todo) + for nid, note := range todo.Notes { + fmt.Fprintf(f.Writer, " %s\t%s\t\n", + cyan(strconv.Itoa(nid)), note) + } + f.Writer.Flush() +} + func (f *Formatter) printTodo(todo *Todo) { yellow := color.New(color.FgYellow) if todo.IsPriority { diff --git a/todolist/parser.go b/todolist/parser.go index cdfb179..42af133 100644 --- a/todolist/parser.go +++ b/todolist/parser.go @@ -83,6 +83,68 @@ func (p *Parser) Contexts(input string) []string { return p.matchWords(input, r) } +func (p *Parser) ParseNotes(todo *Todo, input string) string { + r, _ := regexp.Compile(`(\w+) \d+\s*(.*)?`) + matches := r.FindStringSubmatch(input) + switch matches[1] { + case "an": + todo.Notes = append(todo.Notes, matches[2]) + return "add" + + case "ln": + groups := map[string][]*Todo{} + groups[""] = append(groups[""], todo) + formatter := NewFormatter(&GroupedTodos{Groups: groups}) + formatter.PrintNotes() + return "list" + + case "dn": + rmid, err := p.getNoteID(matches[2]) + if err != nil { + return "" + } + + for id, _ := range todo.Notes { + if id == rmid { + todo.Notes = append(todo.Notes[:rmid], todo.Notes[rmid+1:]...) + return "delete" + } + } + fmt.Println("Could not found note id") + return "" + + case "en": + r1, _ := regexp.Compile(`(\d)+\s+(.*)?`) + tail := r1.FindStringSubmatch(matches[2]) + edid, err := p.getNoteID(tail[1]) + if err != nil { + return "" + } + + for id, _ := range todo.Notes { + if id == edid { + todo.Notes[id] = tail[2] + return "edit" + } + } + + fmt.Println("Could not found note id") + return "" + } + + fmt.Println("Could not match command or id") + return "" +} + +func (p *Parser) getNoteID(input string) (int, error) { + ret, err := strconv.Atoi(input) + if err != nil { + fmt.Println("wrong note id") + return -1, err + } + return ret, nil +} + func (p *Parser) hasDue(input string) bool { r1, _ := regexp.Compile(`due \w+$`) r2, _ := regexp.Compile(`due \w+ \d+$`) diff --git a/todolist/parser_test.go b/todolist/parser_test.go index 476edaa..2c4fd25 100644 --- a/todolist/parser_test.go +++ b/todolist/parser_test.go @@ -74,6 +74,32 @@ func TestParseContexts(t *testing.T) { } } +func TestParseNotes(t *testing.T) { + parser := &Parser{} + todo := parser.ParseNewTodo("add search engine survey") + + if parser.ParseNotes(todo, "an 1 www.google.com") != "add" { + t.Error("Expected Notes to be added") + } + if todo.Notes[0] != "www.google.com" { + t.Error("Expected note 1 to be 'www.google.com' but got", todo.Notes[0]) + } + + if parser.ParseNotes(todo, "en 1 0 www.duckduckgo.com") != "edit" { + t.Error("Expected Notes to be editted") + } + if todo.Notes[0] != "www.duckduckgo.com" { + t.Error("Expected note 1 to be 'www.duckduckgo.com' but got", todo.Notes[0]) + } + + if parser.ParseNotes(todo, "dn 1 0") != "delete" { + t.Error("Expected Notes to be deleted") + } + if len(todo.Notes) != 0 { + t.Error("Expected no note") + } +} + func TestDueToday(t *testing.T) { assert := assert.New(t) parser := &Parser{} diff --git a/todolist/todo_item.go b/todolist/todo_item.go index 0c30707..5b9bcbc 100644 --- a/todolist/todo_item.go +++ b/todolist/todo_item.go @@ -15,6 +15,7 @@ type Todo struct { CompletedDate string `json:"completedDate"` Archived bool `json:"archived"` IsPriority bool `json:"isPriority"` + Notes []string `json:"notes"` } func NewTodo() *Todo { diff --git a/todolist/todos.json b/todolist/todos.json index 7f511ed..39593be 100644 --- a/todolist/todos.json +++ b/todolist/todos.json @@ -1 +1 @@ -[{"id":1,"subject":"this is the first subject","projects":["test1"],"contexts":["root"],"due":"2016-04-04","completed":false,"completedDate":"","archived":true,"isPriority":false},{"id":2,"subject":" audit userify for 2FA","projects":["test1"],"contexts":["root","more"],"due":"","completed":true,"completedDate":"","archived":false,"isPriority":false}]
\ No newline at end of file +[{"id":1,"subject":"this is the first subject","projects":["test1"],"contexts":["root"],"due":"2016-04-04","completed":false,"completedDate":"","archived":true,"isPriority":false,"notes":null},{"id":2,"subject":" audit userify for 2FA","projects":["test1"],"contexts":["root","more"],"due":"","completed":true,"completedDate":"","archived":false,"isPriority":false,"notes":null}]
\ No newline at end of file |
