Commit 142d83d

Karn Wong <[email protected]>
2024-06-10 16:51:41
add stopwatch
1 parent e5797c0
Changed files (2)
cmd/misc/stopwatch.go
@@ -0,0 +1,111 @@
+// from <https://github.com/charmbracelet/bubbletea/blob/master/examples/stopwatch/main.go>
+package misc
+
+import (
+	"fmt"
+	"os"
+	"time"
+
+	"github.com/charmbracelet/bubbles/help"
+	"github.com/charmbracelet/bubbles/key"
+	"github.com/spf13/cobra"
+
+	"github.com/charmbracelet/bubbles/stopwatch"
+	tea "github.com/charmbracelet/bubbletea"
+)
+
+type model struct {
+	stopwatch stopwatch.Model
+	keymap    keymap
+	help      help.Model
+	quitting  bool
+}
+
+type keymap struct {
+	start key.Binding
+	stop  key.Binding
+	reset key.Binding
+	quit  key.Binding
+}
+
+func (m model) Init() tea.Cmd {
+	return m.stopwatch.Init()
+}
+
+func (m model) View() string {
+	// Note: you could further customize the time output by getting the
+	// duration from m.stopwatch.Elapsed(), which returns a time.Duration, and
+	// skip m.stopwatch.View() altogether.
+	s := m.stopwatch.View() + "\n"
+	if !m.quitting {
+		s = "Elapsed: " + s
+		s += m.helpView()
+	}
+	return s
+}
+
+func (m model) helpView() string {
+	return "\n" + m.help.ShortHelpView([]key.Binding{
+		m.keymap.start,
+		m.keymap.stop,
+		m.keymap.reset,
+		m.keymap.quit,
+	})
+}
+
+func (m model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
+	switch msg := msg.(type) {
+	case tea.KeyMsg:
+		switch {
+		case key.Matches(msg, m.keymap.quit):
+			m.quitting = true
+			return m, tea.Quit
+		case key.Matches(msg, m.keymap.reset):
+			return m, m.stopwatch.Reset()
+		case key.Matches(msg, m.keymap.start, m.keymap.stop):
+			m.keymap.stop.SetEnabled(!m.stopwatch.Running())
+			m.keymap.start.SetEnabled(m.stopwatch.Running())
+			return m, m.stopwatch.Toggle()
+		}
+	}
+	var cmd tea.Cmd
+	m.stopwatch, cmd = m.stopwatch.Update(msg)
+	return m, cmd
+}
+
+// main
+var StopwatchCmd = &cobra.Command{
+	Use:   "stopwatch",
+	Short: "Create a stopwatch",
+	Run: func(cmd *cobra.Command, args []string) {
+		m := model{
+			stopwatch: stopwatch.NewWithInterval(time.Millisecond),
+			keymap: keymap{
+				start: key.NewBinding(
+					key.WithKeys("s"),
+					key.WithHelp("s", "start"),
+				),
+				stop: key.NewBinding(
+					key.WithKeys("s"),
+					key.WithHelp("s", "stop"),
+				),
+				reset: key.NewBinding(
+					key.WithKeys("r"),
+					key.WithHelp("r", "reset"),
+				),
+				quit: key.NewBinding(
+					key.WithKeys("ctrl+c", "q"),
+					key.WithHelp("q", "quit"),
+				),
+			},
+			help: help.New(),
+		}
+
+		m.keymap.start.SetEnabled(false)
+
+		if _, err := tea.NewProgram(m).Run(); err != nil {
+			fmt.Println("Oh no, it didn't work:", err)
+			os.Exit(1)
+		}
+	},
+}
cmd/root.go
@@ -29,4 +29,5 @@ func init() {
 	rootCmd.AddCommand(generate.Cmd)
 	rootCmd.AddCommand(misc.ShouldIDeployTodayCmd)
 	rootCmd.AddCommand(misc.TimerCmd)
+	rootCmd.AddCommand(misc.StopwatchCmd)
 }