From 232a4e3f321631699546678c598148aacac1d65e Mon Sep 17 00:00:00 2001 From: Dimitri Sokolyuk Date: Tue, 11 Apr 2017 12:48:36 +0200 Subject: kiss --- main.go | 132 ++++++++++++++++++++++------------------------------------------ 1 file changed, 45 insertions(+), 87 deletions(-) diff --git a/main.go b/main.go index 2ad9538..028bf79 100644 --- a/main.go +++ b/main.go @@ -7,7 +7,6 @@ import ( "log" "os" "os/signal" - "strings" "time" ) @@ -18,29 +17,39 @@ type Opt struct { Day time.Duration Runs int run int - do chan do -} - -type do struct { - s string - d time.Duration } type stateFn func(context.Context) stateFn +func display(ctx context.Context, s string) { + ticker := time.NewTicker(time.Second) + defer ticker.Stop() + defer fmt.Printf("\r%s done\x1b[K\n", s) + dl, _ := ctx.Deadline() + for range ticker.C { + left := time.Until(dl) + left -= left % time.Second + if left < 0 { + left = 0 + } + fmt.Printf("\r%s %s left\x1b[K", s, left) + select { + case <-ctx.Done(): + return + default: + } + } +} + func (o *Opt) doWork(ctx context.Context) stateFn { - timer := time.NewTimer(o.Work) - defer timer.Stop() - o.do <- do{"work", o.Work} + ctx, cancel := context.WithTimeout(ctx, o.Work) + defer cancel() select { case <-ctx.Done(): return nil - case <-timer.C: - return o.doBreak + default: + display(ctx, "work") } -} - -func (o *Opt) doBreak(_ context.Context) stateFn { if o.run++; o.run%o.Runs == 0 { return o.longBreak } @@ -48,67 +57,34 @@ func (o *Opt) doBreak(_ context.Context) stateFn { } func (o *Opt) shortBreak(ctx context.Context) stateFn { - timer := time.NewTimer(o.Short) - defer timer.Stop() - o.do <- do{"short", o.Short} + ctx, cancel := context.WithTimeout(ctx, o.Short) + defer cancel() select { case <-ctx.Done(): return nil - case <-timer.C: - return o.doWork + default: + display(ctx, "short break") } + return o.doWork } func (o *Opt) longBreak(ctx context.Context) stateFn { - timer := time.NewTimer(o.Long) - defer timer.Stop() - o.do <- do{"long", o.Long} + ctx, cancel := context.WithTimeout(ctx, o.Long) + defer cancel() select { case <-ctx.Done(): return nil - case <-timer.C: - return o.doWork + default: + display(ctx, "long break") } + return o.doWork } -func notifier(ctx context.Context) chan do { - c := make(chan do) - go func() { - defer close(c) - for v := range c { - select { - case <-ctx.Done(): - return - default: - count(ctx, v.s, v.d) - } - } - }() - return c -} +const timeBase = time.Minute -func atInterrupt(cancel context.CancelFunc) { - c := make(chan os.Signal, 1) - signal.Notify(c, os.Interrupt) - go func() { - <-c - cancel() - }() -} - -func (o *Opt) pomodoro() { +func main() { defer func(t time.Time) { log.Printf("total %v", time.Since(t)) }(time.Now()) - ctx, cancel := context.WithTimeout(context.Background(), o.Day) - defer cancel() - atInterrupt(cancel) - o.do = notifier(ctx) - for s := o.doWork; s != nil; s = s(ctx) { - } -} -const timeBase = time.Second - -func main() { var o Opt flag.DurationVar(&o.Work, "work", 25*timeBase, "work time") flag.DurationVar(&o.Short, "short", 5*timeBase, "short break") @@ -116,34 +92,16 @@ func main() { flag.DurationVar(&o.Day, "day", 600*timeBase, "work day") flag.IntVar(&o.Runs, "runs", 4, "work runs") flag.Parse() - o.pomodoro() -} -func progress(current, max time.Duration) string { - if current > max { - current = max - } - width := time.Duration(40) - n := width * current / max - done := strings.Repeat("*", int(n)) - left := strings.Repeat(".", int(width-n)) - return fmt.Sprintf("%3d%% |%v%v| %6s/%-6s", - 100*current/max, done, left, - current-current%time.Second, max-max%time.Second) -} + ctx, cancel := context.WithTimeout(context.Background(), o.Day) -func count(ctx context.Context, s string, d time.Duration) { - ctx, _ = context.WithTimeout(ctx, d) - start := time.Now() - defer fmt.Print("\n") - ticker := time.NewTicker(time.Second) - defer ticker.Stop() - for t := range ticker.C { - fmt.Printf("\r%-16s %v", s, progress(t.Sub(start), d)) - select { - case <-ctx.Done(): - return - default: - } + sig := make(chan os.Signal, 1) + signal.Notify(sig, os.Interrupt) + go func() { + <-sig + cancel() + }() + + for s := o.doWork; s != nil; s = s(ctx) { } } -- cgit v1.2.3