aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--todo.go6
-rw-r--r--todolist/app.go28
-rw-r--r--todolist/formatter.go4
-rw-r--r--todolist/parser.go16
-rw-r--r--todolist/parser_test.go24
5 files changed, 71 insertions, 7 deletions
diff --git a/todo.go b/todo.go
index 36e5bf7..2a45f28 100644
--- a/todo.go
+++ b/todo.go
@@ -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) {