diff --git a/choose/choose.go b/choose/choose.go index ac0c935..30ed74b 100644 --- a/choose/choose.go +++ b/choose/choose.go @@ -7,8 +7,7 @@ // // Let's pick from a list of gum flavors: // -// $ gum choose "Strawberry" "Banana" "Cherry" -// +// $ gum choose "Strawberry" "Banana" "Cherry" package choose import ( diff --git a/choose/command.go b/choose/command.go index 01654d6..7e95ad2 100644 --- a/choose/command.go +++ b/choose/command.go @@ -9,10 +9,11 @@ import ( "github.com/alecthomas/kong" "github.com/charmbracelet/bubbles/paginator" tea "github.com/charmbracelet/bubbletea" + "github.com/charmbracelet/lipgloss" + "github.com/charmbracelet/gum/internal/exit" "github.com/charmbracelet/gum/internal/stdin" "github.com/charmbracelet/gum/style" - "github.com/charmbracelet/lipgloss" ) var ( @@ -31,9 +32,9 @@ func (o Options) Run() error { o.Options = strings.Split(strings.TrimSpace(input), "\n") } - var items []item - for _, option := range o.Options { - items = append(items, item{text: option, selected: false}) + var items = make([]item, len(o.Options)) + for i, option := range o.Options { + items[i] = item{text: option, selected: false} } // We don't need to display prefixes if we are only picking one option. @@ -79,6 +80,10 @@ func (o Options) Run() error { selectedItemStyle: o.SelectedItemStyle.ToLipgloss(), }, tea.WithOutput(os.Stderr)).StartReturningModel() + if err != nil { + return fmt.Errorf("failed to start tea program: %w", err) + } + m := tm.(model) if m.aborted { return exit.ErrAborted @@ -95,10 +100,11 @@ func (o Options) Run() error { fmt.Println(strings.TrimSuffix(s.String(), "\n")) - return err + return nil } // BeforeReset hook. Used to unclutter style flags. func (o Options) BeforeReset(ctx *kong.Context) error { - return style.HideFlags(ctx) + style.HideFlags(ctx) + return nil } diff --git a/choose/options.go b/choose/options.go index 17b3a51..04a5cdd 100644 --- a/choose/options.go +++ b/choose/options.go @@ -3,7 +3,6 @@ package choose import "github.com/charmbracelet/gum/style" // Options is the customization options for the choose command. -// nolint:staticcheck type Options struct { Options []string `arg:"" optional:"" help:"Options to choose from."` diff --git a/completion/bash.go b/completion/bash.go index b4f1aed..3064ec1 100644 --- a/completion/bash.go +++ b/completion/bash.go @@ -21,7 +21,10 @@ func (b Bash) Run(ctx *kong.Context) error { writePostscript(buf, ctx.Model.Name) _, err := fmt.Fprint(ctx.Stdout, buf.String()) - return err + if err != nil { + return fmt.Errorf("unable to generate bash completion: %v", err) + } + return nil } // ShellCompDirective is a bit map representing the different behaviors the shell diff --git a/completion/fish.go b/completion/fish.go index 362f0fe..8335356 100644 --- a/completion/fish.go +++ b/completion/fish.go @@ -24,7 +24,10 @@ complete -c gum -f node := ctx.Model.Node f.gen(&buf, node) _, err := fmt.Fprint(ctx.Stdout, buf.String()) - return err + if err != nil { + return fmt.Errorf("unable to generate fish completion: %w", err) + } + return nil } func (f Fish) gen(buf io.StringWriter, cmd *kong.Node) { diff --git a/completion/zsh.go b/completion/zsh.go index 0e7c40f..5981c72 100644 --- a/completion/zsh.go +++ b/completion/zsh.go @@ -22,7 +22,10 @@ func (z Zsh) Run(ctx *kong.Context) error { fmt.Fprintf(&out, format, ctx.Model.Name) z.gen(&out, ctx.Model.Node) _, err := fmt.Fprint(ctx.Stdout, out.String()) - return err + if err != nil { + return fmt.Errorf("unable to generate zsh completion: %w", err) + } + return nil } func (z Zsh) writeFlag(buf io.StringWriter, f *kong.Flag) { diff --git a/confirm/command.go b/confirm/command.go index 231d1ac..39bf2d6 100644 --- a/confirm/command.go +++ b/confirm/command.go @@ -1,10 +1,12 @@ package confirm import ( + "fmt" "os" "github.com/alecthomas/kong" tea "github.com/charmbracelet/bubbletea" + "github.com/charmbracelet/gum/style" ) @@ -22,7 +24,7 @@ func (o Options) Run() error { }, tea.WithOutput(os.Stderr)).StartReturningModel() if err != nil { - return err + return fmt.Errorf("unable to run confirm: %w", err) } if m.(model).confirmation { @@ -36,5 +38,6 @@ func (o Options) Run() error { // BeforeReset hook. Used to unclutter style flags. func (o Options) BeforeReset(ctx *kong.Context) error { - return style.HideFlags(ctx) + style.HideFlags(ctx) + return nil } diff --git a/confirm/confirm.go b/confirm/confirm.go index abb3f75..128f4a3 100644 --- a/confirm/confirm.go +++ b/confirm/confirm.go @@ -7,8 +7,7 @@ // // I.e. confirm if the user wants to delete a file // -// $ gum confirm "Are you sure?" && rm file.txt -// +// $ gum confirm "Are you sure?" && rm file.txt package confirm import ( diff --git a/confirm/options.go b/confirm/options.go index 53e67f4..cca2785 100644 --- a/confirm/options.go +++ b/confirm/options.go @@ -3,13 +3,14 @@ package confirm import "github.com/charmbracelet/gum/style" // Options is the customization options for the confirm command. -// nolint:staticcheck type Options struct { - Affirmative string `help:"The title of the affirmative action" default:"Yes"` - Negative string `help:"The title of the negative action" default:"No"` - Default bool `help:"Default confirmation action" default:"true"` - Prompt string `arg:"" help:"Prompt to display." default:"Are you sure?"` - PromptStyle style.Styles `embed:"" prefix:"prompt." help:"The style of the prompt" set:"defaultMargin=1 0 0 0" envprefix:"GUM_CONFIRM_PROMPT_"` - SelectedStyle style.Styles `embed:"" prefix:"selected." help:"The style of the selected action" set:"defaultBackground=212" set:"defaultForeground=230" set:"defaultPadding=0 3" set:"defaultMargin=1 1" envprefix:"GUM_CONFIRM_SELECTED_"` + Affirmative string `help:"The title of the affirmative action" default:"Yes"` + Negative string `help:"The title of the negative action" default:"No"` + Default bool `help:"Default confirmation action" default:"true"` + Prompt string `arg:"" help:"Prompt to display." default:"Are you sure?"` + PromptStyle style.Styles `embed:"" prefix:"prompt." help:"The style of the prompt" set:"defaultMargin=1 0 0 0" envprefix:"GUM_CONFIRM_PROMPT_"` + //nolint:staticcheck + SelectedStyle style.Styles `embed:"" prefix:"selected." help:"The style of the selected action" set:"defaultBackground=212" set:"defaultForeground=230" set:"defaultPadding=0 3" set:"defaultMargin=1 1" envprefix:"GUM_CONFIRM_SELECTED_"` + //nolint:staticcheck UnselectedStyle style.Styles `embed:"" prefix:"unselected." help:"The style of the unselected action" set:"defaultBackground=235" set:"defaultForeground=254" set:"defaultPadding=0 3" set:"defaultMargin=1 1" envprefix:"GUM_CONFIRM_UNSELECTED_"` } diff --git a/filter/command.go b/filter/command.go index 239b839..746c504 100644 --- a/filter/command.go +++ b/filter/command.go @@ -9,6 +9,7 @@ import ( "github.com/charmbracelet/bubbles/textinput" "github.com/charmbracelet/bubbles/viewport" tea "github.com/charmbracelet/bubbletea" + "github.com/charmbracelet/gum/internal/exit" "github.com/charmbracelet/gum/internal/files" "github.com/charmbracelet/gum/internal/stdin" @@ -53,6 +54,9 @@ func (o Options) Run() error { }, options...) tm, err := p.StartReturningModel() + if err != nil { + return fmt.Errorf("unable to run filter: %w", err) + } m := tm.(model) if m.aborted { @@ -62,10 +66,11 @@ func (o Options) Run() error { fmt.Println(m.matches[m.selected].Str) } - return err + return nil } // BeforeReset hook. Used to unclutter style flags. func (o Options) BeforeReset(ctx *kong.Context) error { - return style.HideFlags(ctx) + style.HideFlags(ctx) + return nil } diff --git a/filter/filter.go b/filter/filter.go index fc6e73e..b5a8953 100644 --- a/filter/filter.go +++ b/filter/filter.go @@ -7,8 +7,7 @@ // // I.e. let's pick from a list of gum flavors: // -// $ cat flavors.text | gum filter -// +// $ cat flavors.text | gum filter package filter import ( @@ -136,6 +135,7 @@ func (m model) Update(msg tea.Msg) (tea.Model, tea.Cmd) { } func matchAll(options []string) []fuzzy.Match { + //nolint:prealloc var matches []fuzzy.Match for _, option := range options { matches = append(matches, fuzzy.Match{Str: option}) diff --git a/filter/options.go b/filter/options.go index 7dc5963..0bd79d9 100644 --- a/filter/options.go +++ b/filter/options.go @@ -3,7 +3,6 @@ package filter import "github.com/charmbracelet/gum/style" // Options is the customization options for the filter command. -// nolint:staticcheck type Options struct { Indicator string `help:"Character for selection" default:"•" env:"GUM_FILTER_INDICATOR"` IndicatorStyle style.Styles `embed:"" prefix:"indicator." set:"defaultForeground=212" envprefix:"GUM_FILTER_INDICATOR_"` diff --git a/format/command.go b/format/command.go index 1555f45..2c21078 100644 --- a/format/command.go +++ b/format/command.go @@ -2,13 +2,12 @@ // // It supports the following types: // -// 1. Markdown -// 2. Code -// 3. Emoji -// 4. Template +// 1. Markdown +// 2. Code +// 3. Emoji +// 4. Template // // For more information, see the format/README.md file. -// package format import ( diff --git a/format/formats.go b/format/formats.go index 648eefa..82d4e4d 100644 --- a/format/formats.go +++ b/format/formats.go @@ -15,9 +15,13 @@ var code Func = func(input string) (string, error) { glamour.WithWordWrap(0), ) if err != nil { - return "", err + return "", fmt.Errorf("unable to create renderer: %w", err) } - return renderer.Render(fmt.Sprintf("```\n%s\n```", input)) + output, err := renderer.Render(fmt.Sprintf("```\n%s\n```", input)) + if err != nil { + return "", fmt.Errorf("unable to render: %w", err) + } + return output, nil } var emoji Func = func(input string) (string, error) { @@ -25,9 +29,13 @@ var emoji Func = func(input string) (string, error) { glamour.WithEmoji(), ) if err != nil { - return "", err + return "", fmt.Errorf("unable to create renderer: %w", err) } - return renderer.Render(input) + output, err := renderer.Render(input) + if err != nil { + return "", fmt.Errorf("unable to render: %w", err) + } + return output, nil } var markdown Func = func(input string) (string, error) { @@ -36,16 +44,20 @@ var markdown Func = func(input string) (string, error) { glamour.WithWordWrap(0), ) if err != nil { - return "", err + return "", fmt.Errorf("unable to create renderer: %w", err) } - return renderer.Render(input) + output, err := renderer.Render(input) + if err != nil { + return "", fmt.Errorf("unable to render: %w", err) + } + return output, nil } var template Func = func(input string) (string, error) { f := termenv.TemplateFuncs(termenv.ColorProfile()) t, err := tpl.New("tpl").Funcs(f).Parse(input) if err != nil { - return "", err + return "", fmt.Errorf("unable to parse template: %w", err) } var buf bytes.Buffer diff --git a/go.sum b/go.sum index 9d7d3e8..b915067 100644 --- a/go.sum +++ b/go.sum @@ -11,10 +11,6 @@ github.com/atotto/clipboard v0.1.4 h1:EH0zSVneZPSuFR11BlR9YppQTVDbh5+16AmcJi4g1z github.com/atotto/clipboard v0.1.4/go.mod h1:ZY9tmq7sm5xIbd9bOK4onWV4S6X0u6GY7Vn0Yu86PYI= github.com/aymerick/douceur v0.2.0 h1:Mv+mAeH1Q+n9Fr+oyamOlAkUNPWPlA8PPGR0QAaYuPk= github.com/aymerick/douceur v0.2.0/go.mod h1:wlT5vV2O3h55X9m7iVYN0TBM0NH/MmbLnd30/FjWUq4= -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/bubbles v0.13.1-0.20220731172002-8f6516082803 h1:+XxHUDsn8N5dvaLgAiCK04B+xe+gKW0pDG39T476ztM= -github.com/charmbracelet/bubbles v0.13.1-0.20220731172002-8f6516082803/go.mod h1:bbeTiXwPww4M031aGi8UK2HT9RDWoiNibae+1yCMtcc= github.com/charmbracelet/bubbles v0.13.1-0.20220804185250-84eacf535a81 h1:iQZnv9OkOx/jhBSVNn5bIhH3PdJgVk82dVCIVJg9jik= github.com/charmbracelet/bubbles v0.13.1-0.20220804185250-84eacf535a81/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 f7c2823..b7233c3 100644 --- a/gum.go +++ b/gum.go @@ -2,6 +2,7 @@ package main import ( "github.com/alecthomas/kong" + "github.com/charmbracelet/gum/choose" "github.com/charmbracelet/gum/completion" "github.com/charmbracelet/gum/confirm" @@ -35,7 +36,7 @@ type Gum struct { // // Let's pick from a list of gum flavors: // - // $ gum choose "Strawberry" "Banana" "Cherry" + // $ gum choose "Strawberry" "Banana" "Cherry" // Choose choose.Options `cmd:"" help:"Choose an option from a list of choices"` @@ -49,7 +50,7 @@ type Gum struct { // // I.e. confirm if the user wants to delete a file // - // $ gum confirm "Are you sure?" && rm file.txt + // $ gum confirm "Are you sure?" && rm file.txt // Confirm confirm.Options `cmd:"" help:"Ask a user to confirm an action"` @@ -62,7 +63,7 @@ type Gum struct { // // I.e. let's pick from a list of gum flavors: // - // $ cat flavors.text | gum filter + // $ cat flavors.text | gum filter // Filter filter.Options `cmd:"" help:"Filter items from a list"` @@ -77,7 +78,7 @@ type Gum struct { // It can be used to prompt the user for some input. The text the user // entered will be sent to stdout. // - // $ gum input --placeholder "What's your favorite gum?" > answer.text + // $ gum input --placeholder "What's your favorite gum?" > answer.text // Input input.Options `cmd:"" help:"Prompt for some input"` @@ -89,7 +90,7 @@ type Gum struct { // Note: We wrap the variable in quotes to ensure the new lines are part of a // single argument. Otherwise, the command won't work as expected. // - // $ gum join --horizontal "$BUBBLE_BOX" "$GUM_BOX" + // $ gum join --horizontal "$BUBBLE_BOX" "$GUM_BOX" // // ╔══════════════════════╗╔═════════════╗ // ║ ║║ ║ @@ -110,7 +111,7 @@ type Gum struct { // We can simply prepend a spinner to this task to show it to the user, // while performing the task / command in the background. // - // $ gum spin -t "Taking a nap..." -- sleep 5 + // $ gum spin -t "Taking a nap..." -- sleep 5 // // The spinner will automatically exit when the task is complete. // @@ -124,7 +125,7 @@ type Gum struct { // // Let's make some text glamorous using bash: // - // $ gum style \ + // $ gum style \ // --foreground 212 --border double --align center \ // --width 50 --margin 2 --padding "2 4" \ // "Bubble Gum (1¢)" "So sweet and so fresh\!" @@ -147,7 +148,7 @@ type Gum struct { // It can be used to ask the user to write some long form of text // (multi-line) input. The text the user entered will be sent to stdout. // - // $ gum write > output.text + // $ gum write > output.text // Write write.Options `cmd:"" help:"Prompt for long-form text"` } diff --git a/input/command.go b/input/command.go index d6ad5db..5cf8319 100644 --- a/input/command.go +++ b/input/command.go @@ -7,6 +7,7 @@ import ( "github.com/alecthomas/kong" "github.com/charmbracelet/bubbles/textinput" tea "github.com/charmbracelet/bubbletea" + "github.com/charmbracelet/gum/internal/exit" "github.com/charmbracelet/gum/internal/stdin" "github.com/charmbracelet/gum/style" @@ -40,6 +41,9 @@ func (o Options) Run() error { aborted: false, }, tea.WithOutput(os.Stderr)) tm, err := p.StartReturningModel() + if err != nil { + return fmt.Errorf("failed to run input: %w", err) + } m := tm.(model) if m.aborted { @@ -47,10 +51,11 @@ func (o Options) Run() error { } fmt.Println(m.textinput.Value()) - return err + return nil } // BeforeReset hook. Used to unclutter style flags. func (o Options) BeforeReset(ctx *kong.Context) error { - return style.HideFlags(ctx) + style.HideFlags(ctx) + return nil } diff --git a/input/input.go b/input/input.go index 6886148..c868b22 100644 --- a/input/input.go +++ b/input/input.go @@ -4,8 +4,7 @@ // It can be used to prompt the user for some input. The text the user entered // will be sent to stdout. // -// $ gum input --placeholder "What's your favorite gum?" > answer.text -// +// $ gum input --placeholder "What's your favorite gum?" > answer.text package input import ( @@ -23,11 +22,11 @@ func (m model) View() string { return m.textinput.View() } func (m model) Update(msg tea.Msg) (tea.Model, tea.Cmd) { switch msg := msg.(type) { case tea.KeyMsg: - switch msg.Type { - case tea.KeyEscape, tea.KeyCtrlC: + switch msg.String() { + case "ctrl+c", "esc": m.aborted = true - fallthrough - case tea.KeyEnter: + return m, tea.Quit + case "enter": return m, tea.Quit } } diff --git a/input/options.go b/input/options.go index cd2c491..f32d7c5 100644 --- a/input/options.go +++ b/input/options.go @@ -3,7 +3,6 @@ package input import "github.com/charmbracelet/gum/style" // Options are the customization options for the input. -// nolint:staticcheck type Options struct { Placeholder string `help:"Placeholder value" default:"Type something..." env:"GUM_INPUT_PLACEHOLDER"` Prompt string `help:"Prompt to display" default:"> " env:"GUM_INPUT_PROMPT"` diff --git a/internal/stdin/stdin.go b/internal/stdin/stdin.go index 9a20cdd..b495f1d 100644 --- a/internal/stdin/stdin.go +++ b/internal/stdin/stdin.go @@ -2,7 +2,7 @@ package stdin import ( "bufio" - "errors" + "fmt" "io" "os" "strings" @@ -12,7 +12,7 @@ import ( func Read() (string, error) { stat, err := os.Stdin.Stat() if err != nil { - return "", errors.New("failed to get stdin stat") + return "", fmt.Errorf("failed to stat stdin: %w", err) } if stat.Mode()&os.ModeNamedPipe == 0 && stat.Size() == 0 { @@ -29,7 +29,7 @@ func Read() (string, error) { } _, err = b.WriteRune(r) if err != nil { - return "", err + return "", fmt.Errorf("failed to write rune: %w", err) } } diff --git a/join/command.go b/join/command.go index 69eb078..9563ec7 100644 --- a/join/command.go +++ b/join/command.go @@ -6,21 +6,21 @@ // wrap the variable in quotes to ensure the new lines are part of a single // argument. Otherwise, the command won't work as expected. // -// $ gum join --horizontal "$BUBBLE_BOX" "$GUM_BOX" -// -// ╔══════════════════════╗╔═════════════╗ -// ║ ║║ ║ -// ║ Bubble ║║ Gum ║ -// ║ ║║ ║ -// ╚══════════════════════╝╚═════════════╝ +// $ gum join --horizontal "$BUBBLE_BOX" "$GUM_BOX" // +// ╔══════════════════════╗╔═════════════╗ +// ║ ║║ ║ +// ║ Bubble ║║ Gum ║ +// ║ ║║ ║ +// ╚══════════════════════╝╚═════════════╝ package join import ( "fmt" - "github.com/charmbracelet/gum/internal/decode" "github.com/charmbracelet/lipgloss" + + "github.com/charmbracelet/gum/internal/decode" ) // Run is the command-line interface for the joining strings through lipgloss. diff --git a/main.go b/main.go index 09de900..fbd8155 100644 --- a/main.go +++ b/main.go @@ -7,11 +7,14 @@ import ( "runtime/debug" "github.com/alecthomas/kong" - "github.com/charmbracelet/gum/internal/exit" "github.com/charmbracelet/lipgloss" "github.com/muesli/termenv" + + "github.com/charmbracelet/gum/internal/exit" ) +const shaLen = 7 + var ( // Version contains the application version number. It's set via ldflags // when building. @@ -35,8 +38,8 @@ func main() { } } version := fmt.Sprintf("gum version %s", Version) - if len(CommitSHA) >= 7 { - version += " (" + CommitSHA[:7] + ")" + if len(CommitSHA) >= shaLen { + version += " (" + CommitSHA[:shaLen] + ")" } gum := &Gum{} diff --git a/spin/command.go b/spin/command.go index 181b7f6..a60d1cc 100644 --- a/spin/command.go +++ b/spin/command.go @@ -7,6 +7,7 @@ import ( "github.com/alecthomas/kong" "github.com/charmbracelet/bubbles/spinner" tea "github.com/charmbracelet/bubbletea" + "github.com/charmbracelet/gum/internal/exit" "github.com/charmbracelet/gum/style" ) @@ -27,7 +28,7 @@ func (o Options) Run() error { m = mm.(model) if err != nil { - return err + return fmt.Errorf("failed to run spin: %w", err) } if o.ShowOutput { @@ -45,5 +46,6 @@ func (o Options) Run() error { // BeforeReset hook. Used to unclutter style flags. func (o Options) BeforeReset(ctx *kong.Context) error { - return style.HideFlags(ctx) + style.HideFlags(ctx) + return nil } diff --git a/spin/options.go b/spin/options.go index ea86625..3bf8bad 100644 --- a/spin/options.go +++ b/spin/options.go @@ -3,7 +3,6 @@ package spin import "github.com/charmbracelet/gum/style" // Options is the customization options for the spin command. -// nolint:staticcheck type Options struct { Command []string `arg:"" help:"Command to run"` diff --git a/spin/spin.go b/spin/spin.go index 6a357a2..c589855 100644 --- a/spin/spin.go +++ b/spin/spin.go @@ -9,10 +9,9 @@ // We can simply prepend a spinner to this task to show it to the user, while // performing the task / command in the background. // -// $ gum spin -t "Taking a nap..." -- sleep 5 +// $ gum spin -t "Taking a nap..." -- sleep 5 // // The spinner will automatically exit when the task is complete. -// package spin import ( diff --git a/style/command.go b/style/command.go index 2027d70..a8045ac 100644 --- a/style/command.go +++ b/style/command.go @@ -3,24 +3,6 @@ // // It allows you to use Lip Gloss to style text without needing to use Go. All // of the styling options are available as flags. -// -// Let's make some text glamorous using bash: -// -// $ gum style \ -// --foreground 212 --border double --align center \ -// --width 50 --margin 2 --padding "2 4" \ -// "Bubble Gum (1¢)" "So sweet and so fresh\!" -// -// -// ╔══════════════════════════════════════════════════╗ -// ║ ║ -// ║ ║ -// ║ Bubble Gum (1¢) ║ -// ║ So sweet and so fresh! ║ -// ║ ║ -// ║ ║ -// ╚══════════════════════════════════════════════════╝ -// package style import ( @@ -40,10 +22,10 @@ func (o Options) Run() error { // HideFlags hides the flags from the usage output. This is used in conjunction // with BeforeReset hook. -func HideFlags(ctx *kong.Context) error { +func HideFlags(ctx *kong.Context) { n := ctx.Selected() if n == nil { - return nil + return } for _, f := range n.Flags { if g := f.Group; g != nil && g.Key == groupName { @@ -52,5 +34,4 @@ func HideFlags(ctx *kong.Context) error { } } } - return nil } diff --git a/style/lipgloss.go b/style/lipgloss.go index d8d641a..391b55f 100644 --- a/style/lipgloss.go +++ b/style/lipgloss.go @@ -1,8 +1,9 @@ package style import ( - "github.com/charmbracelet/gum/internal/decode" "github.com/charmbracelet/lipgloss" + + "github.com/charmbracelet/gum/internal/decode" ) // ToLipgloss takes a Styles flag set and returns the corresponding diff --git a/style/spacing.go b/style/spacing.go index a1eb3f6..6b3fe26 100644 --- a/style/spacing.go +++ b/style/spacing.go @@ -5,6 +5,8 @@ import ( "strings" ) +const minTokens = 1 +const halfTokens = 2 const maxTokens = 4 // parsePadding parses 1 - 4 integers from a string and returns them in a top, @@ -27,11 +29,11 @@ func parsePadding(s string) (int, int, int, int) { ints[i] = parsed } - if len(tokens) == 1 { + if len(tokens) == minTokens { return ints[0], ints[0], ints[0], ints[0] } - if len(tokens) == 2 { + if len(tokens) == halfTokens { return ints[0], ints[1], ints[0], ints[1] } diff --git a/write/command.go b/write/command.go index dc4facb..e0bb933 100644 --- a/write/command.go +++ b/write/command.go @@ -7,6 +7,7 @@ import ( "github.com/alecthomas/kong" "github.com/charmbracelet/bubbles/textarea" tea "github.com/charmbracelet/bubbletea" + "github.com/charmbracelet/gum/internal/exit" "github.com/charmbracelet/gum/internal/stdin" "github.com/charmbracelet/gum/style" @@ -48,16 +49,20 @@ func (o Options) Run() error { p := tea.NewProgram(model{textarea: a}, tea.WithOutput(os.Stderr)) tm, err := p.StartReturningModel() + if err != nil { + return fmt.Errorf("failed to run write: %w", err) + } m := tm.(model) if m.aborted { return exit.ErrAborted } fmt.Println(m.textarea.Value()) - return err + return nil } // BeforeReset hook. Used to unclutter style flags. func (o Options) BeforeReset(ctx *kong.Context) error { - return style.HideFlags(ctx) + style.HideFlags(ctx) + return nil } diff --git a/write/options.go b/write/options.go index 1144a80..53ef1c9 100644 --- a/write/options.go +++ b/write/options.go @@ -3,7 +3,6 @@ package write import "github.com/charmbracelet/gum/style" // Options are the customization options for the textarea. -// nolint:staticcheck type Options struct { Width int `help:"Text area width" default:"50" env:"GUM_WRITE_WIDTH"` Height int `help:"Text area height" default:"5" env:"GUM_WRITE_HEIGHT"` diff --git a/write/write.go b/write/write.go index b756542..41aa988 100644 --- a/write/write.go +++ b/write/write.go @@ -1,11 +1,10 @@ // Package write provides a shell script interface for the text area bubble. // https://github.com/charmbracelet/bubbles/tree/master/textarea // -// It can be used to ask the user to write some long form of text -// (multi-line) input. The text the user entered will be sent to stdout. -// -// $ gum write > output.text +// It can be used to ask the user to write some long form of text (multi-line) +// input. The text the user entered will be sent to stdout. // +// $ gum write > output.text package write import ( @@ -29,11 +28,12 @@ func (m model) View() string { func (m model) Update(msg tea.Msg) (tea.Model, tea.Cmd) { switch msg := msg.(type) { case tea.KeyMsg: - switch msg.Type { - case tea.KeyCtrlC: + switch msg.String() { + case "ctrl+c": m.aborted = true - fallthrough - case tea.KeyEscape, tea.KeyCtrlD: + m.quitting = true + return m, tea.Quit + case "esc", "ctrl+d": m.quitting = true return m, tea.Quit }