diff options
| author | Paul Buetow <paul@buetow.org> | 2026-04-08 22:05:11 +0300 |
|---|---|---|
| committer | Paul Buetow <paul@buetow.org> | 2026-04-08 22:05:11 +0300 |
| commit | 595075473a51b2709f1554f055df43a69369cddd (patch) | |
| tree | 9a0fb966535af4aa23c177991d92b8f6c36e1eed /internal/task/task.go | |
| parent | b6e10387a6a22f96e91542d487014b40e42c1dd0 (diff) | |
Task 9: extract SortTasks helpers
Diffstat (limited to 'internal/task/task.go')
| -rw-r--r-- | internal/task/task.go | 96 |
1 files changed, 0 insertions, 96 deletions
diff --git a/internal/task/task.go b/internal/task/task.go index 51d1451..42fbb30 100644 --- a/internal/task/task.go +++ b/internal/task/task.go @@ -8,10 +8,8 @@ import ( "io" "os" "os/exec" - "sort" "strconv" "strings" - "time" "github.com/google/shlex" ) @@ -393,97 +391,3 @@ func Edit(id int) error { } return EditCmd(id).Run() } - -// SortTasks orders tasks by start status, priority, due date, tag names and id. -// Started tasks are always placed before non-started ones. Tasks without a due -// date are placed after tasks with a due date. Overdue tasks are placed at the -// very top regardless of other properties. -// -// The sort order is: -// 1. Overdue tasks (oldest due date first) -// 2. Started tasks (not completed) -// 3. High priority tasks -// 4. Tasks with earlier due dates -// 5. Tasks sorted alphabetically by tags -// 6. Tasks sorted by ID (oldest first) -func SortTasks(tasks []Task) { - // Helper to join tags in a consistent order for comparison - joinTags := func(tags []string) string { - if len(tags) == 0 { - return "" - } - cpy := append([]string(nil), tags...) - sort.Strings(cpy) - return strings.Join(cpy, " ") - } - - // Convert priority to numeric value for comparison (higher = more important) - priVal := func(p string) int { - switch p { - case "H": - return 3 - case "M": - return 2 - case "L": - return 1 - default: - return 0 - } - } - - // Parse due date string into time.Time - parseDue := func(s string) (time.Time, bool) { - if s == "" { - return time.Time{}, false - } - t, err := time.Parse(DateFormat, s) - if err != nil { - return time.Time{}, false - } - return t, true - } - - // Check if a task is overdue - overdue := func(t Task) bool { - du, ok := parseDue(t.Due) - return ok && time.Now().After(du) - } - - sort.Slice(tasks, func(i, j int) bool { - ti, tj := tasks[i], tasks[j] - - if oi, oj := overdue(ti), overdue(tj); oi != oj { - return oi - } - - startedI := ti.Start != "" && ti.Status != "completed" - startedJ := tj.Start != "" && tj.Status != "completed" - if startedI != startedJ { - return startedI - } - - pi, pj := priVal(ti.Priority), priVal(tj.Priority) - if pi != pj { - return pi > pj - } - - di, iok := parseDue(ti.Due) - dj, jok := parseDue(tj.Due) - if iok && !jok { - return true - } - if !iok && jok { - return false - } - if iok && jok && !di.Equal(dj) { - return di.Before(dj) - } - - tgI, tgJ := joinTags(ti.Tags), joinTags(tj.Tags) - if tgI != tgJ { - return tgI < tgJ - } - - return ti.ID < tj.ID - }) -} |
