From 7190822247b09d0ddee3757e30a2eed003a947a4 Mon Sep 17 00:00:00 2001 From: Maas Lalani Date: Tue, 12 Jul 2022 22:12:02 -0400 Subject: [PATCH] refactor(kong): Implement `Run(...) error` interface Instead of needing to run the commands manually in main.go, we can implement the `Run(...) error` method to satisfy the command interface so that `kong` can Run our commands for us. --- choose/command.go | 15 ++++++++------ filter/command.go | 6 ++++-- go.sum | 2 -- gum.go | 18 ++++++++-------- input/command.go | 19 ++++++++++++----- join/command.go | 3 ++- main.go | 50 ++++++++------------------------------------- progress/command.go | 4 ++-- spin/command.go | 4 ++-- style/command.go | 3 ++- style/style.go | 2 +- write/command.go | 11 ++++++++-- 12 files changed, 62 insertions(+), 75 deletions(-) diff --git a/choose/command.go b/choose/command.go index fc17092..eea7c2e 100644 --- a/choose/command.go +++ b/choose/command.go @@ -3,15 +3,22 @@ package choose import ( "fmt" "os" + "strings" "github.com/charmbracelet/bubbles/list" tea "github.com/charmbracelet/bubbletea" + "github.com/charmbracelet/gum/internal/stdin" "github.com/mattn/go-runewidth" ) // Run provides a shell script interface for choosing between different through // options. -func (o Options) Run() { +func (o Options) Run() error { + if len(o.Options) == 0 { + input, _ := stdin.Read() + o.Options = strings.Split(input, "\n") + } + items := []list.Item{} for _, option := range o.Options { if option == "" { @@ -37,10 +44,6 @@ func (o Options) Run() { l.SetShowPagination(!o.HidePagination) m, err := tea.NewProgram(model{list: l}, tea.WithOutput(os.Stderr)).StartReturningModel() - - if err != nil { - fmt.Println("Error running program:", err) - os.Exit(1) - } fmt.Println(m.(model).choice) + return err } diff --git a/filter/command.go b/filter/command.go index 2a6b463..9bc0452 100644 --- a/filter/command.go +++ b/filter/command.go @@ -13,7 +13,7 @@ import ( // Run provides a shell script interface for filtering through options, powered // by the textinput bubble. -func (o Options) Run() { +func (o Options) Run() error { i := textinput.New() i.Focus() @@ -40,10 +40,12 @@ func (o Options) Run() { textStyle: o.TextStyle.ToLipgloss(), }, tea.WithOutput(os.Stderr)) - tm, _ := p.StartReturningModel() + tm, err := p.StartReturningModel() m := tm.(model) if len(m.matches) > m.selected && m.selected >= 0 { fmt.Println(m.matches[m.selected].Str) } + + return err } diff --git a/go.sum b/go.sum index cf64799..15c3153 100644 --- a/go.sum +++ b/go.sum @@ -4,8 +4,6 @@ github.com/alecthomas/repr v0.0.0-20210801044451-80ca428c5142 h1:8Uy0oSf5co/NZXj github.com/alecthomas/repr v0.0.0-20210801044451-80ca428c5142/go.mod h1:2kn6fqh/zIyPLmm3ugklbEi5hg5wS435eygvNfaDQL8= github.com/atotto/clipboard v0.1.4 h1:EH0zSVneZPSuFR11BlR9YppQTVDbh5+16AmcJi4g1z4= github.com/atotto/clipboard v0.1.4/go.mod h1:ZY9tmq7sm5xIbd9bOK4onWV4S6X0u6GY7Vn0Yu86PYI= -github.com/charmbracelet/bubbles v0.13.0 h1:zP/ROH3wJEBqZWKIsD50ZKKlx3ydLInq3LdD/Nrlb8w= -github.com/charmbracelet/bubbles v0.13.0/go.mod h1:bbeTiXwPww4M031aGi8UK2HT9RDWoiNibae+1yCMtcc= github.com/charmbracelet/bubbles v0.13.1-0.20220708023448-746ec595c3d1 h1:2iHkYbnXv+7i5pp/dIJa/IhM+hE6EckujhOQWLzGMP4= github.com/charmbracelet/bubbles v0.13.1-0.20220708023448-746ec595c3d1/go.mod h1:bbeTiXwPww4M031aGi8UK2HT9RDWoiNibae+1yCMtcc= github.com/charmbracelet/bubbletea v0.21.0/go.mod h1:GgmJMec61d08zXsOhqRC/AiOx4K4pmz+VIcRIm1FKr4= diff --git a/gum.go b/gum.go index 3d5abdd..f624742 100644 --- a/gum.go +++ b/gum.go @@ -11,7 +11,7 @@ import ( "github.com/charmbracelet/gum/write" ) -// Gum is the command-line interface for Soda Gum. +// Gum is the command-line interface for Gum. type Gum struct { // Input provides a shell script interface for the text input bubble. // https://github.com/charmbracelet/bubbles/tree/master/textinput @@ -21,7 +21,7 @@ type Gum struct { // // $ gum input --placeholder "What's your favorite gum?" > answer.text // - Input input.Options `cmd:"" help:"Prompt for input."` + Input input.Options `cmd:"" help:"Prompt for some input"` // Write provides a shell script interface for the text area bubble. // https://github.com/charmbracelet/bubbles/tree/master/textarea @@ -31,7 +31,7 @@ type Gum struct { // // $ gum write > output.text // - Write write.Options `cmd:"" help:"Prompt for multi-line input."` + Write write.Options `cmd:"" help:"Prompt for long-form text"` // Filter provides a fuzzy searching text input to allow filtering a list of // options to select one option. @@ -44,7 +44,7 @@ type Gum struct { // // $ cat flavors.text | gum filter // - Filter filter.Options `cmd:"" help:"Filter options through fuzzy search."` + Filter filter.Options `cmd:"" help:"Filter items from a list"` // Choose provides an interface to choose one option from a given list of // options. The options can be provided as (new-line separated) stdin or a @@ -57,7 +57,7 @@ type Gum struct { // // $ gum choose "Strawberry" "Banana" "Cherry" // - Choose choose.Options `cmd:"" help:"Choose from a list of options."` + Choose choose.Options `cmd:"" help:"Choose an option from a list of choices"` // Spin provides a shell script interface for the spinner bubble. // https://github.com/charmbracelet/bubbles/tree/master/spinner @@ -74,7 +74,7 @@ type Gum struct { // $ gum spin -t "Taking a nap..." -- sleep 5 // // The spinner will automatically exit when the task is complete. - Spin spin.Options `cmd:"" help:"Show spinner while executing a command."` + Spin spin.Options `cmd:"" help:"Display spinner while running a command"` // Progress provides a shell script interface for the progress bubble. // https://github.com/charmbracelet/bubbles/tree/master/progress @@ -82,7 +82,7 @@ type Gum struct { // It's useful for indicating that something is happening in the background // that will end after some set time. // - Progress progress.Options `cmd:"" help:"Show a progress bar for some amount of time."` + Progress progress.Options `cmd:"" help:"Display a progress bar for a certain time"` // Style provides a shell script interface for Lip Gloss. // https://github.com/charmbracelet/lipgloss @@ -107,7 +107,7 @@ type Gum struct { // ║ ║ // ╚══════════════════════════════════════════════════╝ // - Style style.Options `cmd:"" help:"Style some text."` + Style style.Options `cmd:"" help:"Apply coloring, borders, spacing to text"` // Join provides a shell script interface for the lipgloss JoinHorizontal // and JoinVertical commands. It allows you to join multi-line text to @@ -125,5 +125,5 @@ type Gum struct { // ║ ║║ ║ // ╚══════════════════════╝╚═════════════╝ // - Join join.Options `cmd:"" help:"Join text horizontally or vertically."` + Join join.Options `cmd:"" help:"Join text vertically or horizontally"` } diff --git a/input/command.go b/input/command.go index 213d6a6..3581b5b 100644 --- a/input/command.go +++ b/input/command.go @@ -6,15 +6,23 @@ import ( "github.com/charmbracelet/bubbles/textinput" tea "github.com/charmbracelet/bubbletea" + "github.com/charmbracelet/gum/internal/stdin" ) // Run provides a shell script interface for the text input bubble. // https://github.com/charmbracelet/bubbles/textinput -func (o Options) Run() { - i := textinput.New() - i.Focus() +func (o Options) Run() error { + in, _ := stdin.Read() - i.SetValue(o.Value) + i := textinput.New() + + if in != "" && o.Value == "" { + i.SetValue(in) + } else { + i.SetValue(o.Value) + } + + i.Focus() i.Prompt = o.Prompt i.Placeholder = o.Placeholder i.Width = o.Width @@ -22,6 +30,7 @@ func (o Options) Run() { i.CursorStyle = o.CursorStyle.ToLipgloss() p := tea.NewProgram(model{i}, tea.WithOutput(os.Stderr)) - m, _ := p.StartReturningModel() + m, err := p.StartReturningModel() fmt.Println(m.(model).textinput.Value()) + return err } diff --git a/join/command.go b/join/command.go index 047083b..d828456 100644 --- a/join/command.go +++ b/join/command.go @@ -8,10 +8,11 @@ import ( ) // Run is the command-line interface for the joining strings through lipgloss. -func (o Options) Run() { +func (o Options) Run() error { join := lipgloss.JoinHorizontal if o.Vertical { join = lipgloss.JoinVertical } fmt.Println(join(decode.Align[o.Align], o.Text...)) + return nil } diff --git a/main.go b/main.go index f83b68f..862a268 100644 --- a/main.go +++ b/main.go @@ -1,10 +1,7 @@ package main import ( - "strings" - "github.com/alecthomas/kong" - "github.com/charmbracelet/gum/internal/stdin" "github.com/charmbracelet/lipgloss" "github.com/muesli/termenv" ) @@ -12,47 +9,16 @@ import ( func main() { lipgloss.SetColorProfile(termenv.ANSI256) gum := &Gum{} - ctx := kong.Parse(gum, + ctx := kong.Parse( + gum, kong.Name("gum"), kong.Description("Tasty Bubble Gum for your shell."), kong.UsageOnError(), - kong.Vars{ - "defaultBackground": "", - "defaultForeground": "", - }, + kong.ConfigureHelp(kong.HelpOptions{ + Compact: true, + Summary: false, + }), + kong.Vars{"defaultBackground": "", "defaultForeground": ""}, ) - switch ctx.Command() { - case "input": - v, _ := stdin.Read() - if v != "" { - gum.Input.Value = v - } - gum.Input.Run() - case "write": - v, _ := stdin.Read() - if v != "" { - gum.Write.Value = v - } - gum.Write.Run() - case "filter": - gum.Filter.Run() - case "choose": - input, _ := stdin.Read() - gum.Choose.Options = strings.Split(input, "\n") - gum.Choose.Run() - case "choose ": - gum.Choose.Run() - case "spin ": - gum.Spin.Run() - case "progress": - gum.Progress.Run() - case "style": - input, _ := stdin.Read() - gum.Style.Text = []string{input} - gum.Style.Run() - case "style ": - gum.Style.Run() - case "join ": - gum.Join.Run() - } + ctx.Run() } diff --git a/progress/command.go b/progress/command.go index 468b8ad..310cbd1 100644 --- a/progress/command.go +++ b/progress/command.go @@ -8,7 +8,7 @@ import ( ) // Run runs the progress command. -func (o Options) Run() { +func (o Options) Run() error { p := progress.New( progress.WithGradient(o.ColorStart, o.ColorEnd), progress.WithSpringOptions(o.Frequency, o.Damping), @@ -18,5 +18,5 @@ func (o Options) Run() { interval: o.Interval, increment: o.Increment, } - _ = tea.NewProgram(m, tea.WithOutput(os.Stderr)).Start() + return tea.NewProgram(m, tea.WithOutput(os.Stderr)).Start() } diff --git a/spin/command.go b/spin/command.go index 7d9e315..b752b1c 100644 --- a/spin/command.go +++ b/spin/command.go @@ -7,7 +7,7 @@ import ( // Run provides a shell script interface for the spinner bubble. // https://github.com/charmbracelet/bubbles/spinner -func (o Options) Run() { +func (o Options) Run() error { s := spinner.New() s.Style = o.SpinnerStyle.ToLipgloss() s.Spinner = spinnerMap[o.Spinner] @@ -17,5 +17,5 @@ func (o Options) Run() { command: o.Command, } p := tea.NewProgram(m) - _ = p.Start() + return p.Start() } diff --git a/style/command.go b/style/command.go index 8f5744d..c299ae8 100644 --- a/style/command.go +++ b/style/command.go @@ -7,7 +7,8 @@ import ( // Run provides a shell script interface for the Lip Gloss styling. // https://github.com/charmbracelet/lipgloss -func (o Options) Run() { +func (o Options) Run() error { text := strings.Join(o.Text, "\n") fmt.Println(o.Style.ToLipgloss().Render(text)) + return nil } diff --git a/style/style.go b/style/style.go index 2da1887..1f283ea 100644 --- a/style/style.go +++ b/style/style.go @@ -10,7 +10,7 @@ import ( type Styles struct { // Colors Background string `help:"Background color of the ${name=element}" default:"${defaultBackground}" hidden:""` - Foreground string `help:"Foreground color of the ${name=element}" default:"${defaultForeground}"` + Foreground string `help:"color of the ${name=element}" default:"${defaultForeground}"` // Border Border string `help:"Border style to apply" enum:"none,hidden,normal,rounded,thick,double" default:"none" hidden:""` diff --git a/write/command.go b/write/command.go index 8647177..01bbb4a 100644 --- a/write/command.go +++ b/write/command.go @@ -6,11 +6,17 @@ import ( "github.com/charmbracelet/bubbles/textarea" tea "github.com/charmbracelet/bubbletea" + "github.com/charmbracelet/gum/internal/stdin" ) // Run provides a shell script interface for the text area bubble. // https://github.com/charmbracelet/bubbles/textarea -func (o Options) Run() { +func (o Options) Run() error { + in, _ := stdin.Read() + if in != "" && o.Value == "" { + o.Value = in + } + a := textarea.New() a.Focus() @@ -37,6 +43,7 @@ func (o Options) Run() { a.SetValue(o.Value) p := tea.NewProgram(model{textarea: a}, tea.WithOutput(os.Stderr)) - m, _ := p.StartReturningModel() + m, err := p.StartReturningModel() fmt.Println(m.(model).textarea.Value()) + return err }