Updated go-todotxt

This commit is contained in:
Brian Buller 2023-09-07 14:39:45 -05:00
parent c9813b1aaf
commit 4e4ef313f2
8 changed files with 243 additions and 239 deletions

View File

@ -13,7 +13,7 @@ import (
const (
ScreenIdMain = iota
ScreenIdTask
ScreenIdTodo
ScreenIdAbout
ScreenIdExit
)
@ -31,8 +31,8 @@ type AppState struct {
mode ResourceId
TaskList *todotxt.TaskList
DoneList *todotxt.TaskList
TodoList *todotxt.TodoList
DoneList *todotxt.TodoList
taskListLoaded bool
doneListLoaded bool
@ -55,7 +55,7 @@ func NewApp() *AppState {
app := &AppState{Name: AppName, Version: AppVersion}
app.initialize()
app.doVersionCheck()
if err := app.LoadTaskList(); err != nil {
if err := app.LoadTodoList(); err != nil {
if len(os.Args) > 1 && os.Args[1] != "--reinit" {
panic(err)
}
@ -69,7 +69,7 @@ func (a *AppState) run(parms []string) int {
a.mode = ResModeUI
a.uiManager = termboxScreen.NewManager()
a.uiManager.AddScreen(&MainScreen{})
a.uiManager.AddScreen(&TaskScreen{})
a.uiManager.AddScreen(&TodoScreen{})
a.uiManager.AddScreen(&AboutScreen{})
mainBundle := termboxScreen.Bundle{}
@ -91,16 +91,22 @@ func (a *AppState) run(parms []string) int {
return 1
}
func (a *AppState) filterList(list *todotxt.TaskList, filter string) *todotxt.TaskList {
return list.Filter(a.getFilterPredicate(filter))
func (a *AppState) filterList(list *todotxt.TodoList, filter string) *todotxt.TodoList {
return list
//TODO: Fix
//return list.Filter(a.getFilterPredicate(filter))
}
func (a *AppState) getFilteredList(filter string) *todotxt.TaskList {
return a.TaskList.Filter(a.getFilterPredicate(filter))
func (a *AppState) getFilteredList(filter string) *todotxt.TodoList {
return a.TodoList
// TODO: Fix
// return a.TodoList.Filter(a.getFilterPredicate(filter))
}
func (a *AppState) getFilteredDoneList(filter string) *todotxt.TaskList {
return a.DoneList.Filter(a.getFilterPredicate(filter))
func (a *AppState) getFilteredDoneList(filter string) *todotxt.TodoList {
return a.DoneList
// TODO: Fix
// return a.DoneList.Filter(a.getFilterPredicate(filter))
}
func (a *AppState) getTodoFile() string {
@ -118,7 +124,7 @@ func (a *AppState) addOperation(name string, desc []string, fn func([]string) in
a.OpFuncs[name] = fn
}
func (a *AppState) getTaskString(task todotxt.Task) string {
func (a *AppState) getTodoString(task todotxt.Todo) string {
var completed string
completed = " "
if task.Completed {
@ -127,7 +133,7 @@ func (a *AppState) getTaskString(task todotxt.Task) string {
return fmt.Sprintf("%d. [%s] %s", task.Id, completed, strings.TrimPrefix(task.String(), "x "))
}
func (a *AppState) getDoneTaskString(task todotxt.Task) string {
func (a *AppState) getDoneTodoString(task todotxt.Todo) string {
var completed string
completed = " "
if task.Completed {
@ -172,34 +178,34 @@ func (a *AppState) initialize() {
a.opI3Status,
)
a.addOperation("ls",
[]string{"ls - List Tasks"},
a.opListTasks,
[]string{"ls - List Todos"},
a.opListTodos,
)
a.addOperation("lsa",
[]string{"lsa - The same as 'ls -a'"},
func(args []string) int {
return a.opListTasks(append([]string{"-a"}, args...))
return a.opListTodos(append([]string{"-a"}, args...))
},
)
a.addOperation("add",
[]string{"add - Add a task"},
a.opAddTask,
a.opAddTodo,
)
a.addOperation("new",
[]string{"new - Same as 'add'"},
a.opAddTask,
a.opAddTodo,
)
a.addOperation("x",
[]string{"x - Toggle a task's complete flag on/off"},
a.opToggleTaskComplete,
a.opToggleTodoComplete,
)
a.addOperation("done",
[]string{"done - The same as 'x'"},
a.opToggleTaskComplete,
a.opToggleTodoComplete,
)
a.addOperation("archive",
[]string{"archive [id1 id2 ...] - Archive completed tasks"},
a.opArchiveTasks,
a.opArchiveTodos,
)
a.addOperation("--reinit",
[]string{"--reinit - Reset all Configuration Settings"},

6
go.mod
View File

@ -1,9 +1,11 @@
module git.bullercodeworks.com/brian/gask
go 1.16
go 1.20
replace git.bullercodeworks.com/brian/go-todotxt => /home/brbuller/Development/go/src/git.bullercodeworks.com/brian/go-todotxt
require (
git.bullercodeworks.com/brian/go-todotxt v1.0.1
git.bullercodeworks.com/brian/go-todotxt v1.5.0
git.bullercodeworks.com/brian/termbox-screen v0.0.0-20190712162752-c91f70ac38c6
git.bullercodeworks.com/brian/termbox-util v0.0.0-20200220160819-dc6d6950ba00
git.bullercodeworks.com/brian/user-config v0.0.0-20170914134719-16e743ec93a2

View File

@ -80,10 +80,10 @@ func sliceIsValidTags(v []string) bool {
return true
}
func copyTaskList(t todotxt.TaskList) todotxt.TaskList {
re := todotxt.NewTaskList()
for _, v := range t {
re.AddTask(&v)
func copyTodoList(t todotxt.TodoList) todotxt.TodoList {
re := todotxt.NewTodoList()
for _, v := range t.Todos {
re.AddTodo(v)
}
return *re
}

View File

@ -18,7 +18,7 @@ func (a *AppState) diskListChanged() bool {
if err != nil {
return false
}
return curr.String() != a.TaskList.String()
return curr.String() != a.TodoList.String()
}
// diskDoneListChanged returns true if the task list in done.txt
@ -34,23 +34,23 @@ func (a *AppState) diskDoneListChanged() bool {
return curr.String() != a.DoneList.String()
}
func (a *AppState) addTask(taskString string) error {
func (a *AppState) addTodo(taskString string) error {
if a.diskListChanged() {
return a.e(ResStrListChanged)
}
t, err := todotxt.ParseTask(taskString)
t, err := todotxt.ParseTodo(taskString)
if err != nil {
return err
}
if t.CreatedDate.IsZero() {
t.CreatedDate = time.Now()
}
a.TaskList.AddTask(t)
a.TodoList.AddTodo(t)
return a.WriteList()
}
func (a *AppState) saveTask(t *todotxt.Task) error {
lt, err := a.TaskList.GetTask(t.Id)
func (a *AppState) saveTodo(t *todotxt.Todo) error {
lt, err := a.TodoList.GetTodo(t.Id)
if err != nil {
return err
}
@ -62,13 +62,13 @@ func (a *AppState) saveTask(t *todotxt.Task) error {
return a.WriteList()
}
func (a *AppState) toggleTaskComplete(id int) error {
func (a *AppState) toggleTodoComplete(id int) error {
if a.diskListChanged() {
return a.e(ResStrListChanged)
}
var task *todotxt.Task
var task *todotxt.Todo
var err error
if task, err = a.TaskList.GetTask(id); err != nil {
if task, err = a.TodoList.GetTodo(id); err != nil {
return err
}
if task.Completed {
@ -79,41 +79,41 @@ func (a *AppState) toggleTaskComplete(id int) error {
return a.WriteList()
}
func (a *AppState) archiveTask(id int) error {
func (a *AppState) archiveTodo(id int) error {
if a.diskListChanged() {
return a.e(ResStrListChanged)
}
var err error
var task *todotxt.Task
if task, err = a.TaskList.GetTask(id); err != nil {
var task *todotxt.Todo
if task, err = a.TodoList.GetTodo(id); err != nil {
return err
}
if err := a.TaskList.ArchiveTaskToFile(*task, a.getDoneFile()); err != nil {
if err := a.TodoList.ArchiveTodoToFile(*task, a.getDoneFile()); err != nil {
return err
}
a.TaskList.RemoveTask(*task)
a.TodoList.RemoveTodo(*task)
return a.WriteList()
}
func (a *AppState) unarchiveTask(id int) error {
func (a *AppState) unarchiveTodo(id int) error {
if a.diskListChanged() {
return a.e(ResStrListChanged)
}
var err error
var task *todotxt.Task
if task, err = a.DoneList.GetTask(id); err != nil {
var task *todotxt.Todo
if task, err = a.DoneList.GetTodo(id); err != nil {
return err
}
a.TaskList.AddTask(task)
a.TodoList.AddTodo(task)
if err = a.WriteList(); err != nil {
return err
}
a.DoneList.RemoveTask(*task)
a.DoneList.RemoveTodo(*task)
return a.WriteDoneList()
}
func (a *AppState) getFilterPredicate(filter string) func(todotxt.Task) bool {
var predicates []func(todotxt.Task) bool
func (a *AppState) getFilterPredicate(filter string) func(todotxt.Todo) bool {
var predicates []func(todotxt.Todo) bool
// If none of the 'filter' is in upper-case, do a case-insensitive filter
checkCase := true
if strings.ToLower(filter) == filter {
@ -122,16 +122,16 @@ func (a *AppState) getFilterPredicate(filter string) func(todotxt.Task) bool {
filterParts := strings.Split(filter, " ")
for _, part := range filterParts {
if part == ":x" {
predicates = append(predicates, func(t todotxt.Task) bool {
predicates = append(predicates, func(t todotxt.Todo) bool {
return t.Completed
})
} else if part == ":-x" || part == ":o" {
predicates = append(predicates, func(t todotxt.Task) bool {
predicates = append(predicates, func(t todotxt.Todo) bool {
return !t.Completed
})
}
if strings.HasPrefix(part, "@") {
predicates = append(predicates, func(t todotxt.Task) bool {
predicates = append(predicates, func(t todotxt.Todo) bool {
for _, v := range t.Contexts {
if "@"+v == part {
return true
@ -140,7 +140,7 @@ func (a *AppState) getFilterPredicate(filter string) func(todotxt.Task) bool {
return false
})
} else if strings.HasPrefix(part, "+") {
predicates = append(predicates, func(t todotxt.Task) bool {
predicates = append(predicates, func(t todotxt.Todo) bool {
for _, v := range t.Projects {
if "+"+v == part {
return true
@ -149,7 +149,7 @@ func (a *AppState) getFilterPredicate(filter string) func(todotxt.Task) bool {
return false
})
} else {
predicates = append(predicates, func(t todotxt.Task) bool {
predicates = append(predicates, func(t todotxt.Todo) bool {
val := t.Original
if !checkCase {
val = strings.ToLower(t.Original)
@ -158,7 +158,7 @@ func (a *AppState) getFilterPredicate(filter string) func(todotxt.Task) bool {
})
}
}
return func(t todotxt.Task) bool {
return func(t todotxt.Todo) bool {
for _, v := range predicates {
if v(t) {
return true
@ -168,29 +168,25 @@ func (a *AppState) getFilterPredicate(filter string) func(todotxt.Task) bool {
}
}
func (a *AppState) LoadTaskList() error {
var err error
var tl todotxt.TaskList
tl, err = todotxt.LoadFromFilename(a.getTodoFile())
a.TaskList = &tl
func (a *AppState) LoadTodoList() error {
tl, err := todotxt.LoadFromFilename(a.getTodoFile())
a.TodoList = tl
a.taskListLoaded = true
return err
}
func (a *AppState) LoadDoneList() error {
var err error
var tl todotxt.TaskList
tl, err = todotxt.LoadFromFilename(a.getDoneFile())
a.DoneList = &tl
tl, err := todotxt.LoadFromFilename(a.getDoneFile())
a.DoneList = tl
a.doneListLoaded = true
return err
}
func (a *AppState) WriteList() error {
if !a.taskListLoaded {
return a.e(ResStrTaskListNotLoaded)
return a.e(ResStrTodoListNotLoaded)
}
return a.TaskList.WriteToFilename(a.getTodoFile())
return a.TodoList.WriteToFilename(a.getTodoFile())
}
func (a *AppState) WriteDoneList() error {
@ -200,7 +196,7 @@ func (a *AppState) WriteDoneList() error {
return a.DoneList.WriteToFilename(a.getDoneFile())
}
func (a *AppState) AdvancedPrioritySort(t1, t2 *todotxt.Task) bool {
func (a *AppState) AdvancedPrioritySort(t1, t2 *todotxt.Todo) bool {
if t1.HasPriority() && t2.HasPriority() {
return t1.Priority < t2.Priority
} else if t1.HasPriority() && !t2.HasPriority() {
@ -212,8 +208,8 @@ func (a *AppState) AdvancedPrioritySort(t1, t2 *todotxt.Task) bool {
}
type customSort struct {
list todotxt.TaskList
by func(t1, t2 *todotxt.Task) bool
list []todotxt.Todo
by func(t1, t2 *todotxt.Todo) bool
}
func (c *customSort) Len() int {
@ -228,9 +224,9 @@ func (c *customSort) Less(l, r int) bool {
return c.by(&c.list[l], &c.list[r])
}
type By func(t1, t2 *todotxt.Task) bool
type By func(t1, t2 *todotxt.Todo) bool
func (by By) Sort(list []todotxt.Task) {
func (by By) Sort(list []todotxt.Todo) {
ts := &customSort{
list: list,
by: by,

View File

@ -34,10 +34,10 @@ func (t *Translator) getString(res ResourceId) (string, error) {
const (
ResStrListChanged ResourceId = iota
ResStrTaskListNotLoaded
ResStrTodoListNotLoaded
ResStrDoneListNotLoaded
ResStrInvalidRefreshRequest
ResStrErrLoadingTaskList
ResStrErrLoadingTodoList
ResStrErrLoadingDoneList
ResStrErrSavingList
@ -49,9 +49,9 @@ func (a *AppState) initLanguage() {
a.lang = NewTranslator()
// Strings that are the same regardless of mode
a.lang.addString((ResStrTaskListNotLoaded), "Task list hasn't been loaded")
a.lang.addString((ResStrTodoListNotLoaded), "Todo list hasn't been loaded")
a.lang.addString((ResStrDoneListNotLoaded), "Done list hasn't been loaded")
a.lang.addString((ResStrErrLoadingTaskList), "Error loading Task list")
a.lang.addString((ResStrErrLoadingTodoList), "Error loading Todo list")
a.lang.addString((ResStrErrLoadingDoneList), "Error loading Done list")
a.lang.addString((ResStrErrSavingList), "Error saving list")

View File

@ -33,8 +33,8 @@ type MainScreen struct {
currentList string
currentFilter string
activeList *todotxt.TaskList
displayList *todotxt.TaskList
activeList *todotxt.TodoList
displayList *todotxt.TodoList
undoQueue []string
redoQueue []string
@ -55,9 +55,9 @@ const (
MainBackspaceFilter
InputIDFilter = "filter"
InputIDAddTask = "add task"
InputIDAddTodo = "add task"
InputIDIncompleteArchive = "archive incomplete task? (y/n)"
InputIDUnArchiveTask = "move task to active list? (y/n)"
InputIDUnArchiveTodo = "move task to active list? (y/n)"
)
func (screen *MainScreen) Id() int { return ScreenIdMain }
@ -87,7 +87,7 @@ func (screen *MainScreen) refreshList(bundle termboxScreen.Bundle) error {
whichList := bundle.GetString(MainBundleListKey, MainBundleListTodo)
switch whichList {
case MainBundleListTodo:
return app.LoadTaskList()
return app.LoadTodoList()
case MainBundleListDone:
return app.LoadDoneList()
}
@ -96,27 +96,27 @@ func (screen *MainScreen) refreshList(bundle termboxScreen.Bundle) error {
func (screen *MainScreen) reloadList(bundle termboxScreen.Bundle) error {
// We add tasks to the display list using append because we want to persist task Ids
screen.displayList = todotxt.NewTaskList()
screen.displayList = todotxt.NewTodoList()
screen.currentList = bundle.GetString(MainBundleListKey, MainBundleListTodo)
switch screen.currentList {
case MainBundleListTodo:
screen.setActiveList(app.TaskList)
screen.setActiveList(app.TodoList)
if screen.currentFilter = bundle.GetString(MainBundleFilterKey, ""); screen.currentFilter != "" {
filteredList := app.filterList(screen.activeList, screen.currentFilter)
for _, av := range *screen.activeList {
for _, fv := range *filteredList {
for _, av := range screen.activeList.Todos {
for _, fv := range filteredList.Todos {
if av.String() == fv.String() {
(*screen.displayList) = append(*screen.displayList, av)
screen.displayList.AddTodo(av)
break
}
}
}
} else {
for _, av := range *screen.activeList {
(*screen.displayList) = append(*screen.displayList, av)
for _, av := range screen.activeList.Todos {
screen.displayList.AddTodo(av)
}
}
By(app.AdvancedPrioritySort).Sort(*screen.displayList)
//By(app.AdvancedPrioritySort).Sort(screen.displayList.Todos)
case MainBundleListDone:
if err := app.LoadDoneList(); err != nil {
return err
@ -124,22 +124,22 @@ func (screen *MainScreen) reloadList(bundle termboxScreen.Bundle) error {
screen.setActiveList(app.DoneList)
if screen.currentFilter = bundle.GetString(MainBundleFilterKey, ""); screen.currentFilter != "" {
filteredList := app.filterList(screen.activeList, screen.currentFilter)
for _, av := range *screen.activeList {
for _, fv := range *filteredList {
for _, av := range screen.activeList.Todos {
for _, fv := range filteredList.Todos {
if av.String() == fv.String() {
(*screen.displayList) = append(*screen.displayList, av)
screen.displayList.AddTodo(av)
break
}
}
}
} else {
for _, av := range *screen.activeList {
(*screen.displayList) = append(*screen.displayList, av)
for _, av := range screen.activeList.Todos {
screen.displayList.AddTodo(av)
}
}
}
if screen.cursor[screen.currentList] > len(*screen.displayList)-1 {
screen.cursor[screen.currentList] = len(*screen.displayList) - 1
if screen.cursor[screen.currentList] > len(screen.displayList.Todos)-1 {
screen.cursor[screen.currentList] = len(screen.displayList.Todos) - 1
}
return nil
}
@ -171,13 +171,13 @@ func (screen *MainScreen) HandleKeyEvent(event termbox.Event) int {
return screen.Id()
} else if event.Key == termbox.KeySpace {
return screen.toggleTaskComplete()
return screen.toggleTodoComplete()
} else if event.Ch == 'g' {
screen.cursor[screen.currentList] = 0
} else if event.Ch == 'G' {
screen.cursor[screen.currentList] = len(*screen.displayList) - 1
screen.cursor[screen.currentList] = len(screen.displayList.Todos) - 1
} else if event.Key == termbox.KeyCtrlR {
b := screen.buildBundle(screen.currentList, screen.currentFilter)
@ -188,8 +188,8 @@ func (screen *MainScreen) HandleKeyEvent(event termbox.Event) int {
// Jump forward half a screen
_, h := termbox.Size()
screen.cursor[screen.currentList] += (h / 2)
if screen.cursor[screen.currentList] >= len(*screen.displayList) {
screen.cursor[screen.currentList] = len(*screen.displayList) - 1
if screen.cursor[screen.currentList] >= len(screen.displayList.Todos) {
screen.cursor[screen.currentList] = len(screen.displayList.Todos) - 1
}
} else if event.Key == termbox.KeyCtrlB {
@ -204,10 +204,10 @@ func (screen *MainScreen) HandleKeyEvent(event termbox.Event) int {
return screen.toggleViewList()
} else if event.Ch == 'a' {
return screen.startAddNewTask()
return screen.startAddNewTodo()
} else if event.Ch == 'l' || event.Key == termbox.KeyEnter || event.Key == termbox.KeyArrowRight {
return screen.startEditTaskScreen()
return screen.startEditTodoScreen()
} else if event.Ch == 'j' || event.Key == termbox.KeyArrowDown {
screen.moveCursorDown()
@ -216,7 +216,7 @@ func (screen *MainScreen) HandleKeyEvent(event termbox.Event) int {
screen.moveCursorUp()
} else if event.Ch == 'G' {
screen.cursor[screen.currentList] = len(*screen.displayList) - 1
screen.cursor[screen.currentList] = len(screen.displayList.Todos) - 1
} else if event.Ch == 'g' {
screen.cursor[screen.currentList] = 0
@ -246,10 +246,10 @@ func (screen *MainScreen) handleInputKeyEvent(event termbox.Event) int {
screen.reloadList(screen.buildBundle(screen.currentList, filter))
return screen.Id()
}
case InputIDAddTask:
case InputIDAddTodo:
if event.Key == termbox.KeyEnter {
// Create the new item
err := app.addTask(screen.inputField.GetValue())
err := app.addTodo(screen.inputField.GetValue())
if err != nil {
screen.setErrorMessage(err.Error())
}
@ -266,7 +266,7 @@ func (screen *MainScreen) handleInputKeyEvent(event termbox.Event) int {
screen.inputField.SetValue("")
screen.reloadList(screen.buildBundle(screen.currentList, screen.currentFilter))
return screen.Id()
case InputIDUnArchiveTask:
case InputIDUnArchiveTodo:
if event.Ch == 'y' || event.Ch == 'Y' {
screen.inputField.SetID("")
screen.inputField.SetValue("")
@ -295,7 +295,7 @@ func (screen *MainScreen) handleInputKeyEvent(event termbox.Event) int {
return screen.Id()
}
func (screen *MainScreen) setActiveList(list *todotxt.TaskList) {
func (screen *MainScreen) setActiveList(list *todotxt.TodoList) {
screen.activeList = list
}
@ -317,13 +317,13 @@ func (screen *MainScreen) DrawScreen() {
}
screen.drawHeader()
topId := 0
for _, v := range *screen.displayList {
for _, v := range screen.displayList.Todos {
if v.Id > topId {
topId = v.Id
}
}
padCnt := fmt.Sprintf("%d", topId)
for k, v := range *screen.displayList {
for k, v := range screen.displayList.Todos {
pad := strings.Repeat(" ", len(padCnt)-len(fmt.Sprintf("%d", v.Id)))
useFg, useBg := DefaultFg, DefaultBg
if k == screen.cursor[screen.currentList] {
@ -331,7 +331,7 @@ func (screen *MainScreen) DrawScreen() {
}
lineY := k + 1 - displayOffset
if lineY > 0 && lineY < screen.viewPort.numberOfRows {
termboxUtil.DrawStringAtPoint(pad+app.getTaskString(v), 0, lineY, useFg, useBg)
termboxUtil.DrawStringAtPoint(pad+app.getTodoString(*v), 0, lineY, useFg, useBg)
}
}
screen.drawFooter()
@ -369,14 +369,14 @@ func (screen *MainScreen) drawFooter() {
func (screen *MainScreen) confirmArchiveItem() int {
if screen.currentList != MainBundleListTodo {
screen.inputField.SetID(InputIDUnArchiveTask)
screen.inputField.SetID(InputIDUnArchiveTodo)
return screen.Id()
}
// Find the task under the cursor
if screen.cursor[screen.currentList] < len(*screen.displayList) {
t := (*screen.displayList)[screen.cursor[screen.currentList]]
if screen.cursor[screen.currentList] < len(screen.displayList.Todos) {
t := (screen.displayList.Todos)[screen.cursor[screen.currentList]]
if !t.Completed {
// Task isn't completed, verify that the user wants to archive it
// Todo isn't completed, verify that the user wants to archive it
screen.inputField.SetID(InputIDIncompleteArchive)
} else {
return screen.archiveCurrentItem()
@ -387,13 +387,13 @@ func (screen *MainScreen) confirmArchiveItem() int {
func (screen *MainScreen) archiveCurrentItem() int {
if screen.currentList != MainBundleListTodo {
screen.setErrorMessage("Task is already archived")
screen.setErrorMessage("Todo is already archived")
return screen.Id()
}
// Find the task under the cursor
if len(*screen.displayList) > screen.cursor[screen.currentList] {
t := (*screen.displayList)[screen.cursor[screen.currentList]]
if err := app.archiveTask(t.Id); err != nil {
if len(screen.displayList.Todos) > screen.cursor[screen.currentList] {
t := (screen.displayList.Todos)[screen.cursor[screen.currentList]]
if err := app.archiveTodo(t.Id); err != nil {
screen.setErrorMessage(err.Error())
return screen.Id()
}
@ -408,13 +408,13 @@ func (screen *MainScreen) archiveCurrentItem() int {
func (screen *MainScreen) unarchiveCurrentItem() int {
if screen.currentList == MainBundleListTodo {
screen.setErrorMessage("Task is not archived")
screen.setErrorMessage("Todo is not archived")
return screen.Id()
}
// Find the task under the cursor
if len(*screen.displayList) > screen.cursor[screen.currentList] {
t := (*screen.displayList)[screen.cursor[screen.currentList]]
if err := app.unarchiveTask(t.Id); err != nil {
if len(screen.displayList.Todos) > screen.cursor[screen.currentList] {
t := (screen.displayList.Todos)[screen.cursor[screen.currentList]]
if err := app.unarchiveTodo(t.Id); err != nil {
screen.setErrorMessage(err.Error())
return screen.Id()
}
@ -427,18 +427,18 @@ func (screen *MainScreen) unarchiveCurrentItem() int {
return screen.Id()
}
func (screen *MainScreen) startEditTaskScreen() int {
func (screen *MainScreen) startEditTodoScreen() int {
// Find the task under the cursor
if len(*screen.displayList) > screen.cursor[screen.currentList] {
t := (*screen.displayList)[screen.cursor[screen.currentList]]
if len(screen.displayList.Todos) > screen.cursor[screen.currentList] {
t := (screen.displayList.Todos)[screen.cursor[screen.currentList]]
// Load the task screen with this task
b := termboxScreen.Bundle{}
b.SetValue(TaskBundleTaskIdKey, t.Id)
if err := app.uiManager.InitializeScreen(ScreenIdTask, b); err != nil {
b.SetValue(TodoBundleTodoIdKey, t.Id)
if err := app.uiManager.InitializeScreen(ScreenIdTodo, b); err != nil {
screen.setErrorMessage(err.Error())
return screen.Id()
}
return ScreenIdTask
return ScreenIdTodo
}
return screen.Id()
}
@ -463,21 +463,21 @@ func (screen *MainScreen) toggleViewList() int {
return screen.Id()
}
func (screen *MainScreen) startAddNewTask() int {
screen.inputField.SetID(InputIDAddTask)
func (screen *MainScreen) startAddNewTodo() int {
screen.inputField.SetID(InputIDAddTodo)
return screen.Id()
}
func (screen *MainScreen) toggleTaskComplete() int {
func (screen *MainScreen) toggleTodoComplete() int {
if screen.currentList == MainBundleListDone {
screen.setErrorMessage("Task is archived, unable to modify.")
screen.setErrorMessage("Todo is archived, unable to modify.")
return screen.Id()
}
// Find the task under the cursor
if len(*screen.displayList) > screen.cursor[screen.currentList] {
t := (*screen.displayList)[screen.cursor[screen.currentList]]
err := app.toggleTaskComplete(t.Id)
if len(screen.displayList.Todos) > screen.cursor[screen.currentList] {
t := (screen.displayList.Todos)[screen.cursor[screen.currentList]]
err := app.toggleTodoComplete(t.Id)
if err != nil {
screen.setErrorMessage(err.Error())
return screen.Id()
@ -489,8 +489,8 @@ func (screen *MainScreen) toggleTaskComplete() int {
func (screen *MainScreen) moveCursorDown() bool {
screen.cursor[screen.currentList]++
if screen.cursor[screen.currentList] >= len(*screen.displayList) {
screen.cursor[screen.currentList] = len(*screen.displayList) - 1
if screen.cursor[screen.currentList] >= len(screen.displayList.Todos) {
screen.cursor[screen.currentList] = len(screen.displayList.Todos) - 1
return false
}
return true
@ -536,7 +536,7 @@ func (screen *MainScreen) setMessageWithTimeout(msg string, timeout time.Duratio
}
func (screen *MainScreen) clearMessage() {
screen.message = fmt.Sprintf("%d Total Tasks", len(*screen.activeList))
screen.message = fmt.Sprintf("%d Total Todos", len(screen.activeList.Todos))
screen.messageTimeout = -1
screen.messageColorBg = DefaultBg
screen.messageColorFg = DefaultFg

View File

@ -13,41 +13,41 @@ import (
)
const (
FieldTaskTodo = iota
FieldTaskPriority
FieldTaskProjects
FieldTaskContexts
FieldTaskTags
FieldTaskError
FieldTodoTodo = iota
FieldTodoPriority
FieldTodoProjects
FieldTodoContexts
FieldTodoTags
FieldTodoError
TaskBundleTaskIdKey = "taskscreen.taskid"
TodoBundleTodoIdKey = "todoscreen.todoid"
)
type TaskScreen struct {
type TodoScreen struct {
message *Message
cursor int
currentTaskId int
displayTask *todotxt.Task
currentTodoId int
displayTodo *todotxt.Todo
fieldLabels map[int]string
editing bool
inputField *termboxUtil.InputField
}
func (screen *TaskScreen) GetFieldValue(fld int) string {
func (screen *TodoScreen) GetFieldValue(fld int) string {
switch fld {
case FieldTaskTodo:
return screen.displayTask.Todo
case FieldTaskPriority:
return screen.displayTask.Priority
case FieldTaskProjects:
return strings.Join(screen.displayTask.Projects, ",")
case FieldTaskContexts:
return strings.Join(screen.displayTask.Contexts, ",")
case FieldTaskTags:
case FieldTodoTodo:
return screen.displayTodo.Todo
case FieldTodoPriority:
return screen.displayTodo.Priority
case FieldTodoProjects:
return strings.Join(screen.displayTodo.Projects, ",")
case FieldTodoContexts:
return strings.Join(screen.displayTodo.Contexts, ",")
case FieldTodoTags:
var ret []string
for k, v := range screen.displayTask.AdditionalTags {
for k, v := range screen.displayTodo.AdditionalTags {
ret = append(ret, k+":"+v)
}
return strings.Join(ret, ",")
@ -55,35 +55,35 @@ func (screen *TaskScreen) GetFieldValue(fld int) string {
return ""
}
func (screen *TaskScreen) Id() int { return ScreenIdTask }
func (screen *TodoScreen) Id() int { return ScreenIdTodo }
func (screen *TaskScreen) Initialize(bundle termboxScreen.Bundle) error {
func (screen *TodoScreen) Initialize(bundle termboxScreen.Bundle) error {
screen.fieldLabels = make(map[int]string)
screen.fieldLabels[FieldTaskTodo] = "Todo"
screen.fieldLabels[FieldTaskPriority] = "Priority"
screen.fieldLabels[FieldTaskProjects] = "Projects"
screen.fieldLabels[FieldTaskContexts] = "Contexts"
screen.fieldLabels[FieldTaskTags] = "Tags"
screen.fieldLabels[FieldTodoTodo] = "Todo"
screen.fieldLabels[FieldTodoPriority] = "Priority"
screen.fieldLabels[FieldTodoProjects] = "Projects"
screen.fieldLabels[FieldTodoContexts] = "Contexts"
screen.fieldLabels[FieldTodoTags] = "Tags"
var err error
width, height := termbox.Size()
screen.inputField = termboxUtil.CreateInputField(2, (height - 3), width, 1, DefaultFg, DefaultBg)
screen.message = NewMessage("", DefaultFg, DefaultBg, time.Second*2)
if bundle != nil {
screen.currentTaskId = bundle.GetInt(TaskBundleTaskIdKey, -1)
screen.currentTodoId = bundle.GetInt(TodoBundleTodoIdKey, -1)
}
if screen.currentTaskId == -1 {
return errors.New("Task Screen Initialization Failed")
if screen.currentTodoId == -1 {
return errors.New("Todo Screen Initialization Failed")
}
if screen.displayTask, err = app.TaskList.GetTask(screen.currentTaskId); err != nil {
if screen.displayTodo, err = app.TodoList.GetTodo(screen.currentTodoId); err != nil {
return err
}
screen.cursor = FieldTaskTodo
screen.cursor = FieldTodoTodo
return nil
}
func (screen *TaskScreen) ResizeScreen() { screen.Initialize(nil) }
func (screen *TodoScreen) ResizeScreen() { screen.Initialize(nil) }
func (screen *TaskScreen) HandleKeyEvent(event termbox.Event) int {
func (screen *TodoScreen) HandleKeyEvent(event termbox.Event) int {
if screen.editing {
return screen.handleEditingKeyEvent(event)
}
@ -108,43 +108,43 @@ func (screen *TaskScreen) HandleKeyEvent(event termbox.Event) int {
}
return screen.Id()
}
func (screen *TaskScreen) HandleNoneEvent(event termbox.Event) int { return screen.Id() }
func (screen *TodoScreen) HandleNoneEvent(event termbox.Event) int { return screen.Id() }
func (screen *TaskScreen) DrawScreen() {
func (screen *TodoScreen) DrawScreen() {
screen.drawHeader()
yPos := 1
if screen.cursor == FieldTaskTodo {
termboxUtil.DrawStringAtPoint(screen.displayTask.Todo, 0, yPos, CursorBg, CursorFg)
if screen.cursor == FieldTodoTodo {
termboxUtil.DrawStringAtPoint(screen.displayTodo.Todo, 0, yPos, CursorBg, CursorFg)
} else {
termboxUtil.DrawStringAtPoint(screen.displayTask.Todo, 0, yPos, DefaultFg, DefaultBg)
termboxUtil.DrawStringAtPoint(screen.displayTodo.Todo, 0, yPos, DefaultFg, DefaultBg)
}
yPos++
if screen.cursor == FieldTaskPriority {
termboxUtil.DrawStringAtPoint(fmt.Sprintf("Priority: %s", screen.displayTask.Priority), 0, yPos, CursorBg, CursorFg)
if screen.cursor == FieldTodoPriority {
termboxUtil.DrawStringAtPoint(fmt.Sprintf("Priority: %s", screen.displayTodo.Priority), 0, yPos, CursorBg, CursorFg)
} else {
termboxUtil.DrawStringAtPoint(fmt.Sprintf("Priority: %s", screen.displayTask.Priority), 0, yPos, DefaultFg, DefaultBg)
termboxUtil.DrawStringAtPoint(fmt.Sprintf("Priority: %s", screen.displayTodo.Priority), 0, yPos, DefaultFg, DefaultBg)
}
yPos++
if screen.cursor == FieldTaskProjects {
termboxUtil.DrawStringAtPoint(fmt.Sprintf("Projects: %s", screen.displayTask.Projects), 0, yPos, CursorBg, CursorFg)
if screen.cursor == FieldTodoProjects {
termboxUtil.DrawStringAtPoint(fmt.Sprintf("Projects: %s", screen.displayTodo.Projects), 0, yPos, CursorBg, CursorFg)
} else {
termboxUtil.DrawStringAtPoint(fmt.Sprintf("Projects: %s", screen.displayTask.Projects), 0, yPos, DefaultFg, DefaultBg)
termboxUtil.DrawStringAtPoint(fmt.Sprintf("Projects: %s", screen.displayTodo.Projects), 0, yPos, DefaultFg, DefaultBg)
}
yPos++
if screen.cursor == FieldTaskContexts {
termboxUtil.DrawStringAtPoint(fmt.Sprintf("Contexts: %s", screen.displayTask.Contexts), 0, yPos, CursorBg, CursorFg)
if screen.cursor == FieldTodoContexts {
termboxUtil.DrawStringAtPoint(fmt.Sprintf("Contexts: %s", screen.displayTodo.Contexts), 0, yPos, CursorBg, CursorFg)
} else {
termboxUtil.DrawStringAtPoint(fmt.Sprintf("Contexts: %s", screen.displayTask.Contexts), 0, yPos, DefaultFg, DefaultBg)
termboxUtil.DrawStringAtPoint(fmt.Sprintf("Contexts: %s", screen.displayTodo.Contexts), 0, yPos, DefaultFg, DefaultBg)
}
yPos++
if screen.cursor == FieldTaskTags {
if screen.cursor == FieldTodoTags {
termboxUtil.DrawStringAtPoint("Additional Tags: ", 0, yPos, CursorBg, CursorFg)
} else {
termboxUtil.DrawStringAtPoint("Additional Tags: ", 0, yPos, DefaultFg, DefaultBg)
}
yPos++
for k, v := range screen.displayTask.AdditionalTags {
for k, v := range screen.displayTodo.AdditionalTags {
termboxUtil.DrawStringAtPoint(fmt.Sprintf("%s: %s", k, v), 0, yPos, DefaultFg, DefaultBg)
yPos++
}
@ -159,60 +159,60 @@ func (screen *TaskScreen) DrawScreen() {
screen.drawFooter()
}
func (screen *TaskScreen) handleEditingKeyEvent(event termbox.Event) int {
func (screen *TodoScreen) handleEditingKeyEvent(event termbox.Event) int {
if event.Key == termbox.KeyEnter {
var needsSave bool
// Save the change
switch screen.cursor {
case FieldTaskTodo:
//screen.displayTask.Todo = screen.inputField.GetValue()
if screen.inputField.GetValue() != screen.displayTask.Todo {
screen.displayTask.Todo = screen.inputField.GetValue()
case FieldTodoTodo:
//screen.displayTodo.Todo = screen.inputField.GetValue()
if screen.inputField.GetValue() != screen.displayTodo.Todo {
screen.displayTodo.Todo = screen.inputField.GetValue()
needsSave = true
}
case FieldTaskPriority:
case FieldTodoPriority:
val := screen.inputField.GetValue()
if len(val) > 0 {
val = string(val[0])
}
if val != screen.displayTask.Priority {
screen.displayTask.Priority = val
if val != screen.displayTodo.Priority {
screen.displayTodo.Priority = val
needsSave = true
}
case FieldTaskProjects:
case FieldTodoProjects:
projects := splitFields(screen.inputField.GetValue())
if !isCombination(projects, screen.displayTask.Projects) {
if !isCombination(projects, screen.displayTodo.Projects) {
needsSave = true
screen.displayTask.Projects = []string{}
screen.displayTodo.Projects = []string{}
for _, v := range projects {
screen.displayTask.Projects = append(screen.displayTask.Projects, v)
screen.displayTodo.Projects = append(screen.displayTodo.Projects, v)
}
}
case FieldTaskContexts:
case FieldTodoContexts:
contexts := splitFields(screen.inputField.GetValue())
if !isCombination(contexts, screen.displayTask.Contexts) {
if !isCombination(contexts, screen.displayTodo.Contexts) {
needsSave = true
screen.displayTask.Contexts = []string{}
screen.displayTodo.Contexts = []string{}
for _, v := range contexts {
screen.displayTask.Contexts = append(screen.displayTask.Contexts, v)
screen.displayTodo.Contexts = append(screen.displayTodo.Contexts, v)
}
}
case FieldTaskTags:
case FieldTodoTags:
tagsSlice := splitFields(screen.inputField.GetValue())
if !sliceIsValidTags(tagsSlice) {
screen.message.Set("Tags should be in format <key>:<val>")
return screen.Id()
}
if !isCombination(tagsSlice, tagsToSlice(screen.displayTask.AdditionalTags)) {
if !isCombination(tagsSlice, tagsToSlice(screen.displayTodo.AdditionalTags)) {
needsSave = true
screen.displayTask.AdditionalTags = make(map[string]string)
screen.displayTodo.AdditionalTags = make(map[string]string)
for k, v := range sliceToTags(tagsSlice) {
screen.displayTask.AdditionalTags[k] = v
screen.displayTodo.AdditionalTags[k] = v
}
}
}
if needsSave {
if err := app.saveTask(screen.displayTask); err != nil {
if err := app.saveTodo(screen.displayTodo); err != nil {
screen.message.SetError(err.Error())
}
}
@ -226,32 +226,32 @@ func (screen *TaskScreen) handleEditingKeyEvent(event termbox.Event) int {
return screen.Id()
}
func (screen *TaskScreen) drawHeader() {
func (screen *TodoScreen) drawHeader() {
width, _ := termbox.Size()
headerString := screen.displayTask.Todo
headerString := screen.displayTodo.Todo
spaces := strings.Repeat(" ", ((width-len(headerString))/2)+1)
termboxUtil.DrawStringAtPoint(fmt.Sprintf("%s%s%s", spaces, headerString, spaces), 0, 0, TitleFg, TitleBg)
}
func (screen *TaskScreen) drawFooter() {
func (screen *TodoScreen) drawFooter() {
_, height := termbox.Size()
screen.message.DrawAt(0, height-1)
}
func (screen *TaskScreen) moveCursorDown() bool {
screen.cursor = (screen.cursor + 1) % FieldTaskError
func (screen *TodoScreen) moveCursorDown() bool {
screen.cursor = (screen.cursor + 1) % FieldTodoError
return true
}
func (screen *TaskScreen) moveCursorUp() bool {
func (screen *TodoScreen) moveCursorUp() bool {
if screen.cursor > 0 {
screen.cursor--
} else {
screen.cursor = FieldTaskError - 1
screen.cursor = FieldTodoError - 1
}
return true
}
func (screen *TaskScreen) editCurrentField() {
func (screen *TodoScreen) editCurrentField() {
}

View File

@ -13,11 +13,11 @@ func (a *AppState) opI3Status(args []string) int {
state := "Idle"
if len(args) > 0 {
filterString = strings.Join(args, " ")
a.TaskList = a.getFilteredList(filterString)
a.TodoList = a.getFilteredList(filterString)
}
total := len(*a.TaskList)
total := len(a.TodoList.Todos)
var incomplete int
for _, v := range *a.TaskList {
for _, v := range a.TodoList.Todos {
if !v.HasCompletedDate() {
incomplete++
if dateWithinNextDay(v.DueDate) {
@ -29,7 +29,7 @@ func (a *AppState) opI3Status(args []string) int {
warning := a.config.Get("i3status_warning")
if warning != "" {
t := a.getFilteredList(warning)
for _, v := range *t {
for _, v := range t.Todos {
if !v.HasCompletedDate() {
state = "Warning"
break
@ -41,7 +41,7 @@ func (a *AppState) opI3Status(args []string) int {
return 0
}
func (a *AppState) opListTasks(args []string) int {
func (a *AppState) opListTodos(args []string) int {
var lastIdx int
var filterString string
showAll := len(args) > 0 && args[0] == "-1"
@ -50,13 +50,13 @@ func (a *AppState) opListTasks(args []string) int {
}
if len(args) > 0 {
filterString = strings.Join(args, " ")
a.TaskList = a.getFilteredList(filterString)
a.TodoList = a.getFilteredList(filterString)
}
a.TaskList.Sort(todotxt.SORT_USEFULNESS_ASC)
a.TodoList.Sort(todotxt.SortPriorityAsc)
for _, v := range *a.TaskList {
fmt.Println(a.getTaskString(v))
for _, v := range a.TodoList.Todos {
fmt.Println(a.getTodoString(*v))
lastIdx++
}
if showAll {
@ -68,16 +68,16 @@ func (a *AppState) opListTasks(args []string) int {
if filterString != "" {
a.DoneList = a.getFilteredList(filterString)
}
for _, v := range *a.DoneList {
fmt.Println(a.getDoneTaskString(v))
for _, v := range a.DoneList.Todos {
fmt.Println(a.getDoneTodoString(*v))
}
}
return 0
}
func (a *AppState) opAddTask(args []string) int {
func (a *AppState) opAddTodo(args []string) int {
taskString := strings.Join(args, " ")
if err := a.addTask(taskString); err != nil {
if err := a.addTodo(taskString); err != nil {
fmt.Println("Error adding task")
fmt.Println(err.Error())
return 1
@ -85,7 +85,7 @@ func (a *AppState) opAddTask(args []string) int {
return 0
}
func (a *AppState) opToggleTaskComplete(args []string) int {
func (a *AppState) opToggleTodoComplete(args []string) int {
if len(args) == 0 {
fmt.Println("No id given")
return 1
@ -101,7 +101,7 @@ func (a *AppState) opToggleTaskComplete(args []string) int {
fmt.Printf("Invalid id given: %s\n", v)
return 1
}
if err := a.toggleTaskComplete(id); err != nil {
if err := a.toggleTodoComplete(id); err != nil {
fmt.Println(err.Error())
return 1
}
@ -113,34 +113,34 @@ func (a *AppState) opToggleTaskComplete(args []string) int {
return 0
}
func (a *AppState) opArchiveTasks(args []string) int {
func (a *AppState) opArchiveTodos(args []string) int {
if len(args) > 0 {
for _, v := range args {
var id int
var task *todotxt.Task
var task *todotxt.Todo
var err error
if id, err = strconv.Atoi(v); err != nil {
fmt.Printf("Invalid id given: %s\n", v)
return 1
}
if task, err = a.TaskList.GetTask(id); err != nil {
if task, err = a.TodoList.GetTodo(id); err != nil {
fmt.Printf("Error getting task %d\n", id)
return 1
}
if err = a.archiveTask(id); err != nil {
if err = a.archiveTodo(id); err != nil {
fmt.Printf("Error archiving task %d\n", id)
return 1
}
fmt.Println(a.getDoneTaskString(*task))
fmt.Println(a.getDoneTodoString(*task))
}
} else {
for _, v := range *a.TaskList {
for _, v := range a.TodoList.Todos {
if v.Completed {
if err := a.archiveTask(v.Id); err != nil {
if err := a.archiveTodo(v.Id); err != nil {
fmt.Printf("Error archiving task %d\n", v.Id)
return 1
}
fmt.Println(a.getDoneTaskString(v))
fmt.Println(a.getDoneTodoString(*v))
}
}
}