From 6df47c3dcdb6d58a5c6a7dc660a0e185efc8254f Mon Sep 17 00:00:00 2001 From: Daryl Manning Date: Sat, 31 Aug 2024 01:06:13 +0800 Subject: [PATCH] Feature: Log and ask dynamically adapt to terminal size. --- go.mod | 1 + go.sum | 2 ++ harsh.go | 36 +++++++++++++++++++++++++----------- 3 files changed, 28 insertions(+), 11 deletions(-) diff --git a/go.mod b/go.mod index 07e7977..a3c5d67 100644 --- a/go.mod +++ b/go.mod @@ -14,4 +14,5 @@ require ( github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e // indirect github.com/xrash/smetrics v0.0.0-20240521201337-686a1a2994c1 // indirect golang.org/x/sys v0.24.0 // indirect + golang.org/x/term v0.23.0 // indirect ) diff --git a/go.sum b/go.sum index 8761ef7..b26e8d7 100644 --- a/go.sum +++ b/go.sum @@ -24,5 +24,7 @@ golang.org/x/exp v0.0.0-20220909182711-5c715a9e8561 h1:MDc5xs78ZrZr3HMQugiXOAkSZ golang.org/x/exp v0.0.0-20220909182711-5c715a9e8561/go.mod h1:cyybsKvd6eL0RnXn6p/Grxp8F5bW7iYuBgsNCOHpMYE= golang.org/x/sys v0.24.0 h1:Twjiwq9dn6R1fQcyiK+wQyHWfaz/BJB+YIpzU/Cv3Xg= golang.org/x/sys v0.24.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/term v0.23.0 h1:F6D4vR+EHoL9/sWAWgAR1H2DcHr4PareCbAaCo1RpuU= +golang.org/x/term v0.23.0/go.mod h1:DgV24QBUrK6jhZXl+20l6UWznPlwAHm1Q1mGHtydmSk= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/harsh.go b/harsh.go index 892a7ad..c29f886 100755 --- a/harsh.go +++ b/harsh.go @@ -16,6 +16,7 @@ import ( "cloud.google.com/go/civil" "github.com/gookit/color" "github.com/urfave/cli/v2" + "golang.org/x/term" ) var configDir string @@ -60,6 +61,7 @@ type Entries map[DailyHabit]Outcome type Harsh struct { Habits []*Habit MaxHabitNameLength int + CountBack int Entries *Entries } @@ -68,7 +70,7 @@ func main() { Name: "Harsh", Usage: "habit tracking for geeks", Description: "A simple, minimalist CLI for tracking and understanding habits.", - Version: "0.10.1", + Version: "0.10.3", Flags: []cli.Flag{ &cli.BoolFlag{ Name: "no-color", @@ -127,7 +129,7 @@ func main() { harsh := newHarsh() to := civil.DateOf(time.Now()) - from := to.AddDays(-100) + from := to.AddDays(-harsh.CountBack) consistency := map[string][]string{} undone := harsh.getTodos(to, 0) @@ -141,7 +143,7 @@ func main() { heading := "" for _, habit := range harsh.Habits { - consistency[habit.Name] = append(consistency[habit.Name], harsh.buildGraph(habit)) + consistency[habit.Name] = append(consistency[habit.Name], harsh.buildGraph(habit, false)) if heading != habit.Heading { color.Bold.Printf(habit.Heading + "\n") heading = habit.Heading @@ -237,7 +239,7 @@ func main() { } to := civil.DateOf(time.Now()) - from := to.AddDays(-100) + from := to.AddDays(-harsh.CountBack) consistency := map[string][]string{} sparkline, calline := harsh.buildSpark(from, to) @@ -248,13 +250,12 @@ func main() { fmt.Print(strings.Join(calline, "")) fmt.Printf("\n") - consistency[check.Name] = append(consistency[check.Name], harsh.buildGraph(&check)) + consistency[check.Name] = append(consistency[check.Name], harsh.buildGraph(&check, false)) fmt.Printf("%*v", harsh.MaxHabitNameLength, check.Name+" ") fmt.Print(strings.Join(consistency[check.Name], "")) fmt.Printf("\n") - fmt.Println(habit_fragment) return nil }, }, @@ -279,15 +280,24 @@ func newHarsh() *Harsh { to := civil.DateOf(time.Now()) from := to.AddDays(-365 * 5) entries.firstRecords(from, to, habits) + width, _, err := term.GetSize(int(os.Stdout.Fd())) + if err != nil { + log.Fatal(err) + } + countBack := 100 + if width < 100+maxHabitNameLength { + // Remove 2 for the habitName and graph padding + countBack = width - maxHabitNameLength - 2 + } - return &Harsh{habits, maxHabitNameLength, entries} + return &Harsh{habits, maxHabitNameLength, countBack, entries} } // Ask function prompts func (h *Harsh) askHabits() { to := civil.DateOf(time.Now()) - from := to.AddDays(-60) + from := to.AddDays(-h.CountBack - 40) // Goes back 8 days to check unresolved entries checkBackDays := 10 @@ -319,7 +329,7 @@ func (h *Harsh) askHabits() { } for { fmt.Printf("%*v", h.MaxHabitNameLength, habit.Name+" ") - fmt.Print(h.buildGraph(habit)) + fmt.Print(h.buildGraph(habit, true)) fmt.Printf(" [y/n/s/⏎] ") reader := bufio.NewReader(os.Stdin) @@ -451,12 +461,16 @@ func (h *Harsh) buildSpark(from civil.Date, to civil.Date) ([]string, []string) return sparkline, calline } -func (h *Harsh) buildGraph(habit *Habit) string { +func (h *Harsh) buildGraph(habit *Habit, ask bool) string { var graphDay string var consistency []string - from := civil.DateOf(time.Now()).AddDays(-100) to := civil.DateOf(time.Now()) + from := to.AddDays(-h.CountBack) + if ask { + from = to.AddDays(-h.CountBack + 12) + } + for d := from; !d.After(to); d = d.AddDays(1) { if outcome, ok := (*h.Entries)[DailyHabit{Day: d, Habit: habit.Name}]; ok { switch {