aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDimitri Sokolyuk <demon@dim13.org>2017-04-11 12:48:36 +0200
committerDimitri Sokolyuk <demon@dim13.org>2017-04-11 12:48:36 +0200
commit232a4e3f321631699546678c598148aacac1d65e (patch)
tree821faf30ad295817715a2397a0d7158ae63c16cc
parent7b530f5e52b12bb9beb241909bdc65838dc5a0b7 (diff)
kiss
-rw-r--r--main.go132
1 files 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) {
}
}