diff --git a/spin/command.go b/spin/command.go new file mode 100644 index 0000000..5e5ef8d --- /dev/null +++ b/spin/command.go @@ -0,0 +1,22 @@ +package spin + +import ( + "github.com/charmbracelet/bubbles/spinner" + tea "github.com/charmbracelet/bubbletea" + "github.com/charmbracelet/lipgloss" +) + +// Run provides a shell script interface for the spinner bubble. +// https://github.com/charmbracelet/bubbles/spinner +func (o Options) Run() { + s := spinner.New() + s.Style = lipgloss.NewStyle().Foreground(lipgloss.Color(o.Color)) + s.Spinner = spinnerMap[o.Spinner] + m := model{ + spinner: s, + title: o.Title, + command: o.Command, + } + p := tea.NewProgram(m) + _ = p.Start() +} diff --git a/spin/options.go b/spin/options.go new file mode 100644 index 0000000..fc4dc95 --- /dev/null +++ b/spin/options.go @@ -0,0 +1,10 @@ +package spin + +// Options is the customization options for the spin command. +type Options struct { + Command []string `arg:"" help:"Command to run"` + + Color string `help:"Spinner color" default:"#FF06B7"` + Title string `help:"Text to display to user while spinning" default:"Loading..."` + Spinner string `help:"Spinner type" type:"spinner" enum:"line,dot,minidot,jump,pulse,points,globe,moon,monkey,meter,hamburger" default:"dot"` +} diff --git a/spin/spin.go b/spin/spin.go new file mode 100644 index 0000000..212c938 --- /dev/null +++ b/spin/spin.go @@ -0,0 +1,51 @@ +package spin + +import ( + "os/exec" + + "github.com/charmbracelet/bubbles/spinner" + tea "github.com/charmbracelet/bubbletea" +) + +type model struct { + spinner spinner.Model + title string + command []string +} + +type finishCommandMsg struct{ output string } + +func commandStart(command []string) tea.Cmd { + return func() tea.Msg { + var args []string + if len(command) > 1 { + args = command[1:] + } + out, _ := exec.Command(command[0], args...).Output() + return finishCommandMsg{output: string(out)} + } +} + +func (m model) Init() tea.Cmd { + return tea.Batch( + m.spinner.Tick, + commandStart(m.command), + ) +} +func (m model) View() string { return m.spinner.View() + " " + m.title } + +func (m model) Update(msg tea.Msg) (tea.Model, tea.Cmd) { + var cmd tea.Cmd + switch msg := msg.(type) { + case finishCommandMsg: + return m, tea.Quit + case tea.KeyMsg: + switch msg.String() { + case "ctrl+c": + return m, tea.Quit + } + } + + m.spinner, cmd = m.spinner.Update(msg) + return m, cmd +} diff --git a/spin/spinners.go b/spin/spinners.go new file mode 100644 index 0000000..a8e235e --- /dev/null +++ b/spin/spinners.go @@ -0,0 +1,17 @@ +package spin + +import "github.com/charmbracelet/bubbles/spinner" + +var spinnerMap = map[string]spinner.Spinner{ + "line": spinner.Line, + "dot": spinner.Dot, + "minidot": spinner.MiniDot, + "jump": spinner.Jump, + "pulse": spinner.Pulse, + "points": spinner.Points, + "globe": spinner.Globe, + "moon": spinner.Moon, + "monkey": spinner.Monkey, + "meter": spinner.Meter, + "hamburger": spinner.Hamburger, +}