diff --git a/.tmuxrc b/.tmuxrc new file mode 100644 index 0000000..83b36fb --- /dev/null +++ b/.tmuxrc @@ -0,0 +1,4 @@ +rename-window dev +neww -n build +neww -n run +select-window -t 0:0 diff --git a/cmd/list.go b/cmd/list.go index 2f045ec..e80fbf9 100644 --- a/cmd/list.go +++ b/cmd/list.go @@ -1,6 +1,5 @@ /* Copyright © 2022 Brian Buller - */ package cmd @@ -74,6 +73,7 @@ func opListTimers(cmd *cobra.Command, args []string) error { } filter := util.BuildFilterFromArgs(args) list = list.Filter(filter) + list.Sort(timertxt.SortFinishDateAsc) dayTotals := make(map[string]time.Duration) for _, v := range list.GetTimerSlice() { diff --git a/cmd/time.go b/cmd/time.go index 954a457..375875f 100644 --- a/cmd/time.go +++ b/cmd/time.go @@ -1,6 +1,5 @@ /* Copyright © 2022 Brian Buller - */ package cmd @@ -10,6 +9,7 @@ import ( "git.bullercodeworks.com/brian/gime/cli" "git.bullercodeworks.com/brian/gime/util" + "git.bullercodeworks.com/brian/go-timertxt" "github.com/spf13/cobra" ) @@ -22,25 +22,58 @@ var timeCmd = &cobra.Command{ func init() { rootCmd.AddCommand(timeCmd) + + // Local Flags + timeCmd.Flags().BoolP("all", "a", false, "Include done.txt timers") + timeCmd.Flags().BoolP("done", "d", false, "Only done.txt timers") } func opShowTimers(cmd *cobra.Command, args []string) error { var err error + var includeArchive bool + var onlyArchive bool + if onlyArchive, err = cmd.Flags().GetBool("done"); err != nil { + return err + } else if includeArchive, err = cmd.Flags().GetBool("all"); err != nil { + return err + } + p := cli.Program{} err = p.Initialize() if err != nil { return err } - if err := p.LoadTimerList(); err != nil { - return err + if !onlyArchive { + if err := p.LoadTimerList(); err != nil { + return err + } } - list := p.GetFilteredTimerList(args) + if includeArchive || onlyArchive { + if err := p.LoadDoneList(); err != nil { + return err + } + } + list := timertxt.NewTimerList() + if !onlyArchive { + list = p.TimerList + if includeArchive { + for _, tmr := range p.DoneList.GetTimerSlice() { + list.AddTimer(tmr) + } + } + } else { + list = p.DoneList + } + filter := util.BuildFilterFromArgs(args) + list = list.Filter(filter) + list.Sort(timertxt.SortFinishDateAsc) + var isActive bool var total time.Duration for _, v := range list.GetTimerSlice() { - dur := v.FinishDate.Sub(v.StartDate) + dur := util.Round(v.FinishDate.Sub(v.StartDate)) if v.FinishDate.IsZero() { - dur = time.Now().Sub(v.StartDate) + dur = util.Round(time.Now().Sub(v.StartDate)) isActive = true } total += dur diff --git a/ui/widdle_addtagtotimers.go b/ui/widdle_addtagtotimers.go index 4b13ce4..16a00ca 100644 --- a/ui/widdle_addtagtotimers.go +++ b/ui/widdle_addtagtotimers.go @@ -11,6 +11,7 @@ import ( */ type PromptForTagWiddle struct { active bool + visible bool x, y, w, h int origKey, origVal string @@ -36,8 +37,8 @@ func NewPromptForTagWiddle(x, y, w, h int, key, val string) *PromptForTagWiddle origKey: key, origVal: val, keyInput: keyInp, valInput: widdles.NewToggleField("Value", val, 0, 0, 0, 0), - cancelButton: widdles.NewButton("Cancel", 0, 0, 0, 0), - doneButton: widdles.NewButton("Done", 0, 0, 0, 0), + cancelButton: widdles.NewButton("Cancel"), + doneButton: widdles.NewButton("Done"), } } @@ -86,9 +87,11 @@ func (w *PromptForTagWiddle) View(style wandle.Style) { wandle.Print(w.x+1, w.y+w.h-2, style, w.msg) } -func (w *PromptForTagWiddle) IsActive() bool { return w.active } -func (w *PromptForTagWiddle) SetActive(b bool) { w.active = b } -func (w *PromptForTagWiddle) Focusable() bool { return true } +func (w *PromptForTagWiddle) SetVisible(v bool) { w.visible = v } +func (w *PromptForTagWiddle) IsVisible() bool { return w.visible } +func (w *PromptForTagWiddle) IsActive() bool { return w.active } +func (w *PromptForTagWiddle) SetActive(b bool) { w.active = b } +func (w *PromptForTagWiddle) Focusable() bool { return true } func (w *PromptForTagWiddle) SetX(x int) { w.x = x w.Measure() diff --git a/util/helpers.go b/util/helpers.go index 61112c1..ecda574 100644 --- a/util/helpers.go +++ b/util/helpers.go @@ -102,9 +102,11 @@ func DurationToDecimal(dur time.Duration) float64 { mins := dur.Minutes() - (dur.Hours() * 60) return dur.Hours() + (mins / 60) } + func AddDurations(dur1, dur2 time.Duration) time.Duration { return time.Duration(int64(dur1) + int64(dur2)) } + func SubDurations(dur1, dur2 time.Duration) time.Duration { return time.Duration(int64(dur1) - int64(dur2)) } @@ -359,10 +361,12 @@ func BuildFilterFromArgs(args []string) func(*timertxt.Timer) bool { end := time.Now() var contextFilters []string var projectFilters []string + var tagFilters []string var allFilters []func(timertxt.Timer) bool if len(args) > 0 { contextFilters, args = GetContextsFromSlice(args) projectFilters, args = GetProjectsFromSlice(args) + tagFilters, args = GetAdditionalTagsFromSlice(args) } if len(args) > 0 { var err error @@ -394,22 +398,33 @@ func BuildFilterFromArgs(args []string) func(*timertxt.Timer) bool { allFilters = append(allFilters, func(t timertxt.Timer) bool { for _, v := range contextFilters { v = strings.TrimPrefix(v, "@") - if !t.HasContext(v) { - return false + if t.HasContext(v) { + return true } } - return true + return false }) } if len(projectFilters) > 0 { allFilters = append(allFilters, func(t timertxt.Timer) bool { for _, v := range projectFilters { v = strings.TrimPrefix(v, "+") - if !t.HasProject(v) { - return false + if t.HasProject(v) { + return true } } - return true + return false + }) + } + if len(tagFilters) > 0 { + allFilters = append(allFilters, func(t timertxt.Timer) bool { + for _, v := range tagFilters { + pts := strings.Split(v, ":") + if len(pts) == 2 && t.HasTag(pts[0]) && t.GetTag(pts[0]) == pts[1] { + return true + } + } + return false }) } doFilters := func(t *timertxt.Timer) bool { @@ -441,6 +456,7 @@ func StringSliceContains(sl []string, val string) bool { } return false } + func AppendStringIfDistinct(sl []string, val string) []string { if !StringSliceContains(sl, val) { return append(sl, val)