diff options
| -rw-r--r-- | todo.go | 6 | ||||
| -rw-r--r-- | todolist/app.go | 28 | ||||
| -rw-r--r-- | todolist/formatter.go | 4 | ||||
| -rw-r--r-- | todolist/parser.go | 16 | ||||
| -rw-r--r-- | todolist/parser_test.go | 24 |
5 files changed, 71 insertions, 7 deletions
@@ -97,6 +97,10 @@ func usage() { yellow.Println("\ttodo e 33 due none") fmt.Println("\tEdits the todo with 33 and removes the due date\n") + blueBold.Println("\nExpanding existing todos") + yellow.Println("\ttodo ex 39 +final: read physics due mon, do literature report due fri") + fmt.Println("\tRemoves the todo with id 39, and adds following two todos\n") + blueBold.Println("\nDeleting") yellow.Println("\ttodo d 33") fmt.Println("\tDeletes a todo with id 33\n") @@ -125,6 +129,8 @@ func routeInput(command string, input string) { app.ArchiveCompleted() case "e", "edit": app.EditTodoDue(input) + case "ex", "expand": + app.ExpandTodo(input) case "init": app.InitializeRepo() case "web": diff --git a/todolist/app.go b/todolist/app.go index f223a0a..1ab6b20 100644 --- a/todolist/app.go +++ b/todolist/app.go @@ -4,6 +4,7 @@ import ( "fmt" "regexp" "strconv" + "strings" "time" ) @@ -102,6 +103,33 @@ func (a *App) EditTodoDue(input string) { fmt.Println("Todo due date updated.") } +func (a *App) ExpandTodo(input string) { + a.Load() + id, _ := a.getId(input) + parser := &Parser{} + if id == -1 { + return + } + + commonProject := parser.ExpandProject(input) + todos := strings.LastIndex(input, ":") + if commonProject == "" || len(input) <= todos+1 || todos == -1 { + fmt.Println("I'm expecting a format like \"todolist ex <project>: <todo1>, <todo2>, ...\"") + return + } + + newTodos := strings.Split(input[todos+1:], ",") + + for _, todo := range newTodos { + args := []string{"add ", commonProject, " ", todo} + a.AddTodo(strings.Join(args, "")) + } + + a.TodoList.Delete(id) + a.Save() + fmt.Println("Todo expanded.") +} + func (a *App) ArchiveCompleted() { a.Load() for _, todo := range a.TodoList.Todos() { diff --git a/todolist/formatter.go b/todolist/formatter.go index db4aa4b..43d9b1e 100644 --- a/todolist/formatter.go +++ b/todolist/formatter.go @@ -103,8 +103,8 @@ func (f *Formatter) formatSubject(subject string) string { magenta := color.New(color.FgMagenta).SprintFunc() splitted := strings.Split(subject, " ") - projectRegex, _ := regexp.Compile(`\+\w+`) - contextRegex, _ := regexp.Compile(`\@\w+`) + projectRegex, _ := regexp.Compile(`\+[\p{L}\d_]+`) + contextRegex, _ := regexp.Compile(`\@[\p{L}\d_]+`) coloredWords := []string{} diff --git a/todolist/parser.go b/todolist/parser.go index 62d864d..6cf1967 100644 --- a/todolist/parser.go +++ b/todolist/parser.go @@ -39,13 +39,25 @@ func (p *Parser) Subject(input string) string { } } +func (p *Parser) ExpandProject(input string) string { + r, _ := regexp.Compile(`(ex|expand) +\d+ +\+[\p{L}\d_]+:`) + pattern := r.FindString(input) + if len(pattern) == 0 { + return "" + } + + newProject := pattern[0 : len(pattern)-1] + project := strings.Split(newProject, " ") + return project[len(project)-1] +} + func (p *Parser) Projects(input string) []string { - r, _ := regexp.Compile(`\+\w+`) + r, _ := regexp.Compile(`\+[\p{L}\d_]+`) return p.matchWords(input, r) } func (p *Parser) Contexts(input string) []string { - r, err := regexp.Compile(`\@\w+`) + r, err := regexp.Compile(`\@[\p{L}\d_]+`) if err != nil { fmt.Println("regex error", err) } diff --git a/todolist/parser_test.go b/todolist/parser_test.go index 83c0602..791958c 100644 --- a/todolist/parser_test.go +++ b/todolist/parser_test.go @@ -26,11 +26,26 @@ func TestParseSubjectWithDue(t *testing.T) { } } +func TestParseExpandProjects(t *testing.T) { + assert := assert.New(t) + parser := &Parser{} + correctFormat := parser.ExpandProject("ex 113 +meeting: figures, slides, coffee, suger") + assert.Equal("+meeting", correctFormat) + wrongFormat1 := parser.ExpandProject("ex 114 +meeting figures, slides, coffee, suger") + assert.Equal("", wrongFormat1) + wrongFormat2 := parser.ExpandProject("ex 115 meeting: figures, slides, coffee, suger") + assert.Equal("", wrongFormat2) + wrongFormat3 := parser.ExpandProject("ex 116 meeting figures, slides, coffee, suger") + assert.Equal("", wrongFormat3) + wrongFormat4 := parser.ExpandProject("ex 117 +重要な會議: 図, コーヒー, 砂糖") + assert.Equal("+重要な會議", wrongFormat4) +} + func TestParseProjects(t *testing.T) { parser := &Parser{} - todo := parser.ParseNewTodo("do this thing +proj1 +proj2 due tomorrow") - if len(todo.Projects) != 2 { - t.Error("Expected Projects length to be 2") + todo := parser.ParseNewTodo("do this thing +proj1 +proj2 +專案3 due tomorrow") + if len(todo.Projects) != 3 { + t.Error("Expected Projects length to be 3") } if todo.Projects[0] != "proj1" { t.Error("todo.Projects[0] should equal 'proj1' but got", todo.Projects[0]) @@ -38,6 +53,9 @@ func TestParseProjects(t *testing.T) { if todo.Projects[1] != "proj2" { t.Error("todo.Projects[1] should equal 'proj2' but got", todo.Projects[1]) } + if todo.Projects[2] != "專案3" { + t.Error("todo.Projects[2] should equal '專案3' but got", todo.Projects[2]) + } } func TestParseContexts(t *testing.T) { |
