fix: satisfy all linters

This commit is contained in:
Maas Lalani 2022-08-04 18:45:19 -04:00
parent 2d5ef98037
commit 1479184f3f
31 changed files with 137 additions and 115 deletions

View file

@ -7,8 +7,7 @@
// //
// Let's pick from a list of gum flavors: // Let's pick from a list of gum flavors:
// //
// $ gum choose "Strawberry" "Banana" "Cherry" // $ gum choose "Strawberry" "Banana" "Cherry"
//
package choose package choose
import ( import (

View file

@ -9,10 +9,11 @@ import (
"github.com/alecthomas/kong" "github.com/alecthomas/kong"
"github.com/charmbracelet/bubbles/paginator" "github.com/charmbracelet/bubbles/paginator"
tea "github.com/charmbracelet/bubbletea" tea "github.com/charmbracelet/bubbletea"
"github.com/charmbracelet/lipgloss"
"github.com/charmbracelet/gum/internal/exit" "github.com/charmbracelet/gum/internal/exit"
"github.com/charmbracelet/gum/internal/stdin" "github.com/charmbracelet/gum/internal/stdin"
"github.com/charmbracelet/gum/style" "github.com/charmbracelet/gum/style"
"github.com/charmbracelet/lipgloss"
) )
var ( var (
@ -31,9 +32,9 @@ func (o Options) Run() error {
o.Options = strings.Split(strings.TrimSpace(input), "\n") o.Options = strings.Split(strings.TrimSpace(input), "\n")
} }
var items []item var items = make([]item, len(o.Options))
for _, option := range o.Options { for i, option := range o.Options {
items = append(items, item{text: option, selected: false}) items[i] = item{text: option, selected: false}
} }
// We don't need to display prefixes if we are only picking one option. // 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(), selectedItemStyle: o.SelectedItemStyle.ToLipgloss(),
}, tea.WithOutput(os.Stderr)).StartReturningModel() }, tea.WithOutput(os.Stderr)).StartReturningModel()
if err != nil {
return fmt.Errorf("failed to start tea program: %w", err)
}
m := tm.(model) m := tm.(model)
if m.aborted { if m.aborted {
return exit.ErrAborted return exit.ErrAborted
@ -95,10 +100,11 @@ func (o Options) Run() error {
fmt.Println(strings.TrimSuffix(s.String(), "\n")) fmt.Println(strings.TrimSuffix(s.String(), "\n"))
return err return nil
} }
// BeforeReset hook. Used to unclutter style flags. // BeforeReset hook. Used to unclutter style flags.
func (o Options) BeforeReset(ctx *kong.Context) error { func (o Options) BeforeReset(ctx *kong.Context) error {
return style.HideFlags(ctx) style.HideFlags(ctx)
return nil
} }

View file

@ -3,7 +3,6 @@ package choose
import "github.com/charmbracelet/gum/style" import "github.com/charmbracelet/gum/style"
// Options is the customization options for the choose command. // Options is the customization options for the choose command.
// nolint:staticcheck
type Options struct { type Options struct {
Options []string `arg:"" optional:"" help:"Options to choose from."` Options []string `arg:"" optional:"" help:"Options to choose from."`

View file

@ -21,7 +21,10 @@ func (b Bash) Run(ctx *kong.Context) error {
writePostscript(buf, ctx.Model.Name) writePostscript(buf, ctx.Model.Name)
_, err := fmt.Fprint(ctx.Stdout, buf.String()) _, 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 // ShellCompDirective is a bit map representing the different behaviors the shell

View file

@ -24,7 +24,10 @@ complete -c gum -f
node := ctx.Model.Node node := ctx.Model.Node
f.gen(&buf, node) f.gen(&buf, node)
_, err := fmt.Fprint(ctx.Stdout, buf.String()) _, 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) { func (f Fish) gen(buf io.StringWriter, cmd *kong.Node) {

View file

@ -22,7 +22,10 @@ func (z Zsh) Run(ctx *kong.Context) error {
fmt.Fprintf(&out, format, ctx.Model.Name) fmt.Fprintf(&out, format, ctx.Model.Name)
z.gen(&out, ctx.Model.Node) z.gen(&out, ctx.Model.Node)
_, err := fmt.Fprint(ctx.Stdout, out.String()) _, 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) { func (z Zsh) writeFlag(buf io.StringWriter, f *kong.Flag) {

View file

@ -1,10 +1,12 @@
package confirm package confirm
import ( import (
"fmt"
"os" "os"
"github.com/alecthomas/kong" "github.com/alecthomas/kong"
tea "github.com/charmbracelet/bubbletea" tea "github.com/charmbracelet/bubbletea"
"github.com/charmbracelet/gum/style" "github.com/charmbracelet/gum/style"
) )
@ -22,7 +24,7 @@ func (o Options) Run() error {
}, tea.WithOutput(os.Stderr)).StartReturningModel() }, tea.WithOutput(os.Stderr)).StartReturningModel()
if err != nil { if err != nil {
return err return fmt.Errorf("unable to run confirm: %w", err)
} }
if m.(model).confirmation { if m.(model).confirmation {
@ -36,5 +38,6 @@ func (o Options) Run() error {
// BeforeReset hook. Used to unclutter style flags. // BeforeReset hook. Used to unclutter style flags.
func (o Options) BeforeReset(ctx *kong.Context) error { func (o Options) BeforeReset(ctx *kong.Context) error {
return style.HideFlags(ctx) style.HideFlags(ctx)
return nil
} }

View file

@ -7,8 +7,7 @@
// //
// I.e. confirm if the user wants to delete a file // 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 package confirm
import ( import (

View file

@ -3,13 +3,14 @@ package confirm
import "github.com/charmbracelet/gum/style" import "github.com/charmbracelet/gum/style"
// Options is the customization options for the confirm command. // Options is the customization options for the confirm command.
// nolint:staticcheck
type Options struct { type Options struct {
Affirmative string `help:"The title of the affirmative action" default:"Yes"` Affirmative string `help:"The title of the affirmative action" default:"Yes"`
Negative string `help:"The title of the negative action" default:"No"` Negative string `help:"The title of the negative action" default:"No"`
Default bool `help:"Default confirmation action" default:"true"` Default bool `help:"Default confirmation action" default:"true"`
Prompt string `arg:"" help:"Prompt to display." default:"Are you sure?"` 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_"` 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_"` //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_"` 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_"`
} }

View file

@ -9,6 +9,7 @@ import (
"github.com/charmbracelet/bubbles/textinput" "github.com/charmbracelet/bubbles/textinput"
"github.com/charmbracelet/bubbles/viewport" "github.com/charmbracelet/bubbles/viewport"
tea "github.com/charmbracelet/bubbletea" tea "github.com/charmbracelet/bubbletea"
"github.com/charmbracelet/gum/internal/exit" "github.com/charmbracelet/gum/internal/exit"
"github.com/charmbracelet/gum/internal/files" "github.com/charmbracelet/gum/internal/files"
"github.com/charmbracelet/gum/internal/stdin" "github.com/charmbracelet/gum/internal/stdin"
@ -53,6 +54,9 @@ func (o Options) Run() error {
}, options...) }, options...)
tm, err := p.StartReturningModel() tm, err := p.StartReturningModel()
if err != nil {
return fmt.Errorf("unable to run filter: %w", err)
}
m := tm.(model) m := tm.(model)
if m.aborted { if m.aborted {
@ -62,10 +66,11 @@ func (o Options) Run() error {
fmt.Println(m.matches[m.selected].Str) fmt.Println(m.matches[m.selected].Str)
} }
return err return nil
} }
// BeforeReset hook. Used to unclutter style flags. // BeforeReset hook. Used to unclutter style flags.
func (o Options) BeforeReset(ctx *kong.Context) error { func (o Options) BeforeReset(ctx *kong.Context) error {
return style.HideFlags(ctx) style.HideFlags(ctx)
return nil
} }

View file

@ -7,8 +7,7 @@
// //
// I.e. let's pick from a list of gum flavors: // I.e. let's pick from a list of gum flavors:
// //
// $ cat flavors.text | gum filter // $ cat flavors.text | gum filter
//
package filter package filter
import ( import (
@ -136,6 +135,7 @@ func (m model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
} }
func matchAll(options []string) []fuzzy.Match { func matchAll(options []string) []fuzzy.Match {
//nolint:prealloc
var matches []fuzzy.Match var matches []fuzzy.Match
for _, option := range options { for _, option := range options {
matches = append(matches, fuzzy.Match{Str: option}) matches = append(matches, fuzzy.Match{Str: option})

View file

@ -3,7 +3,6 @@ package filter
import "github.com/charmbracelet/gum/style" import "github.com/charmbracelet/gum/style"
// Options is the customization options for the filter command. // Options is the customization options for the filter command.
// nolint:staticcheck
type Options struct { type Options struct {
Indicator string `help:"Character for selection" default:"•" env:"GUM_FILTER_INDICATOR"` Indicator string `help:"Character for selection" default:"•" env:"GUM_FILTER_INDICATOR"`
IndicatorStyle style.Styles `embed:"" prefix:"indicator." set:"defaultForeground=212" envprefix:"GUM_FILTER_INDICATOR_"` IndicatorStyle style.Styles `embed:"" prefix:"indicator." set:"defaultForeground=212" envprefix:"GUM_FILTER_INDICATOR_"`

View file

@ -2,13 +2,12 @@
// //
// It supports the following types: // It supports the following types:
// //
// 1. Markdown // 1. Markdown
// 2. Code // 2. Code
// 3. Emoji // 3. Emoji
// 4. Template // 4. Template
// //
// For more information, see the format/README.md file. // For more information, see the format/README.md file.
//
package format package format
import ( import (

View file

@ -15,9 +15,13 @@ var code Func = func(input string) (string, error) {
glamour.WithWordWrap(0), glamour.WithWordWrap(0),
) )
if err != nil { 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) { var emoji Func = func(input string) (string, error) {
@ -25,9 +29,13 @@ var emoji Func = func(input string) (string, error) {
glamour.WithEmoji(), glamour.WithEmoji(),
) )
if err != nil { 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) { var markdown Func = func(input string) (string, error) {
@ -36,16 +44,20 @@ var markdown Func = func(input string) (string, error) {
glamour.WithWordWrap(0), glamour.WithWordWrap(0),
) )
if err != nil { 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) { var template Func = func(input string) (string, error) {
f := termenv.TemplateFuncs(termenv.ColorProfile()) f := termenv.TemplateFuncs(termenv.ColorProfile())
t, err := tpl.New("tpl").Funcs(f).Parse(input) t, err := tpl.New("tpl").Funcs(f).Parse(input)
if err != nil { if err != nil {
return "", err return "", fmt.Errorf("unable to parse template: %w", err)
} }
var buf bytes.Buffer var buf bytes.Buffer

4
go.sum
View file

@ -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/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 h1:Mv+mAeH1Q+n9Fr+oyamOlAkUNPWPlA8PPGR0QAaYuPk=
github.com/aymerick/douceur v0.2.0/go.mod h1:wlT5vV2O3h55X9m7iVYN0TBM0NH/MmbLnd30/FjWUq4= 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 h1:iQZnv9OkOx/jhBSVNn5bIhH3PdJgVk82dVCIVJg9jik=
github.com/charmbracelet/bubbles v0.13.1-0.20220804185250-84eacf535a81/go.mod h1:bbeTiXwPww4M031aGi8UK2HT9RDWoiNibae+1yCMtcc= 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= github.com/charmbracelet/bubbletea v0.21.0/go.mod h1:GgmJMec61d08zXsOhqRC/AiOx4K4pmz+VIcRIm1FKr4=

17
gum.go
View file

@ -2,6 +2,7 @@ package main
import ( import (
"github.com/alecthomas/kong" "github.com/alecthomas/kong"
"github.com/charmbracelet/gum/choose" "github.com/charmbracelet/gum/choose"
"github.com/charmbracelet/gum/completion" "github.com/charmbracelet/gum/completion"
"github.com/charmbracelet/gum/confirm" "github.com/charmbracelet/gum/confirm"
@ -35,7 +36,7 @@ type Gum struct {
// //
// Let's pick from a list of gum flavors: // 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"` 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 // 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"` 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: // 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"` 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 // It can be used to prompt the user for some input. The text the user
// entered will be sent to stdout. // 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"` 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 // 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. // 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, // We can simply prepend a spinner to this task to show it to the user,
// while performing the task / command in the background. // 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. // 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: // Let's make some text glamorous using bash:
// //
// $ gum style \ // $ gum style \
// --foreground 212 --border double --align center \ // --foreground 212 --border double --align center \
// --width 50 --margin 2 --padding "2 4" \ // --width 50 --margin 2 --padding "2 4" \
// "Bubble Gum (1¢)" "So sweet and so fresh\!" // "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 // 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. // (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"` Write write.Options `cmd:"" help:"Prompt for long-form text"`
} }

View file

@ -7,6 +7,7 @@ import (
"github.com/alecthomas/kong" "github.com/alecthomas/kong"
"github.com/charmbracelet/bubbles/textinput" "github.com/charmbracelet/bubbles/textinput"
tea "github.com/charmbracelet/bubbletea" tea "github.com/charmbracelet/bubbletea"
"github.com/charmbracelet/gum/internal/exit" "github.com/charmbracelet/gum/internal/exit"
"github.com/charmbracelet/gum/internal/stdin" "github.com/charmbracelet/gum/internal/stdin"
"github.com/charmbracelet/gum/style" "github.com/charmbracelet/gum/style"
@ -40,6 +41,9 @@ func (o Options) Run() error {
aborted: false, aborted: false,
}, tea.WithOutput(os.Stderr)) }, tea.WithOutput(os.Stderr))
tm, err := p.StartReturningModel() tm, err := p.StartReturningModel()
if err != nil {
return fmt.Errorf("failed to run input: %w", err)
}
m := tm.(model) m := tm.(model)
if m.aborted { if m.aborted {
@ -47,10 +51,11 @@ func (o Options) Run() error {
} }
fmt.Println(m.textinput.Value()) fmt.Println(m.textinput.Value())
return err return nil
} }
// BeforeReset hook. Used to unclutter style flags. // BeforeReset hook. Used to unclutter style flags.
func (o Options) BeforeReset(ctx *kong.Context) error { func (o Options) BeforeReset(ctx *kong.Context) error {
return style.HideFlags(ctx) style.HideFlags(ctx)
return nil
} }

View file

@ -4,8 +4,7 @@
// It can be used to prompt the user for some input. The text the user entered // It can be used to prompt the user for some input. The text the user entered
// will be sent to stdout. // 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 package input
import ( 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) { func (m model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
switch msg := msg.(type) { switch msg := msg.(type) {
case tea.KeyMsg: case tea.KeyMsg:
switch msg.Type { switch msg.String() {
case tea.KeyEscape, tea.KeyCtrlC: case "ctrl+c", "esc":
m.aborted = true m.aborted = true
fallthrough return m, tea.Quit
case tea.KeyEnter: case "enter":
return m, tea.Quit return m, tea.Quit
} }
} }

View file

@ -3,7 +3,6 @@ package input
import "github.com/charmbracelet/gum/style" import "github.com/charmbracelet/gum/style"
// Options are the customization options for the input. // Options are the customization options for the input.
// nolint:staticcheck
type Options struct { type Options struct {
Placeholder string `help:"Placeholder value" default:"Type something..." env:"GUM_INPUT_PLACEHOLDER"` Placeholder string `help:"Placeholder value" default:"Type something..." env:"GUM_INPUT_PLACEHOLDER"`
Prompt string `help:"Prompt to display" default:"> " env:"GUM_INPUT_PROMPT"` Prompt string `help:"Prompt to display" default:"> " env:"GUM_INPUT_PROMPT"`

View file

@ -2,7 +2,7 @@ package stdin
import ( import (
"bufio" "bufio"
"errors" "fmt"
"io" "io"
"os" "os"
"strings" "strings"
@ -12,7 +12,7 @@ import (
func Read() (string, error) { func Read() (string, error) {
stat, err := os.Stdin.Stat() stat, err := os.Stdin.Stat()
if err != nil { 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 { if stat.Mode()&os.ModeNamedPipe == 0 && stat.Size() == 0 {
@ -29,7 +29,7 @@ func Read() (string, error) {
} }
_, err = b.WriteRune(r) _, err = b.WriteRune(r)
if err != nil { if err != nil {
return "", err return "", fmt.Errorf("failed to write rune: %w", err)
} }
} }

View file

@ -6,21 +6,21 @@
// wrap the variable in quotes to ensure the new lines are part of a single // wrap the variable in quotes to ensure the new lines are part of a single
// argument. Otherwise, the command won't work as expected. // argument. Otherwise, the command won't work as expected.
// //
// $ gum join --horizontal "$BUBBLE_BOX" "$GUM_BOX" // $ gum join --horizontal "$BUBBLE_BOX" "$GUM_BOX"
//
// ╔══════════════════════╗╔═════════════╗
// ║ ║║ ║
// ║ Bubble ║║ Gum ║
// ║ ║║ ║
// ╚══════════════════════╝╚═════════════╝
// //
// ╔══════════════════════╗╔═════════════╗
// ║ ║║ ║
// ║ Bubble ║║ Gum ║
// ║ ║║ ║
// ╚══════════════════════╝╚═════════════╝
package join package join
import ( import (
"fmt" "fmt"
"github.com/charmbracelet/gum/internal/decode"
"github.com/charmbracelet/lipgloss" "github.com/charmbracelet/lipgloss"
"github.com/charmbracelet/gum/internal/decode"
) )
// Run is the command-line interface for the joining strings through lipgloss. // Run is the command-line interface for the joining strings through lipgloss.

View file

@ -7,11 +7,14 @@ import (
"runtime/debug" "runtime/debug"
"github.com/alecthomas/kong" "github.com/alecthomas/kong"
"github.com/charmbracelet/gum/internal/exit"
"github.com/charmbracelet/lipgloss" "github.com/charmbracelet/lipgloss"
"github.com/muesli/termenv" "github.com/muesli/termenv"
"github.com/charmbracelet/gum/internal/exit"
) )
const shaLen = 7
var ( var (
// Version contains the application version number. It's set via ldflags // Version contains the application version number. It's set via ldflags
// when building. // when building.
@ -35,8 +38,8 @@ func main() {
} }
} }
version := fmt.Sprintf("gum version %s", Version) version := fmt.Sprintf("gum version %s", Version)
if len(CommitSHA) >= 7 { if len(CommitSHA) >= shaLen {
version += " (" + CommitSHA[:7] + ")" version += " (" + CommitSHA[:shaLen] + ")"
} }
gum := &Gum{} gum := &Gum{}

View file

@ -7,6 +7,7 @@ import (
"github.com/alecthomas/kong" "github.com/alecthomas/kong"
"github.com/charmbracelet/bubbles/spinner" "github.com/charmbracelet/bubbles/spinner"
tea "github.com/charmbracelet/bubbletea" tea "github.com/charmbracelet/bubbletea"
"github.com/charmbracelet/gum/internal/exit" "github.com/charmbracelet/gum/internal/exit"
"github.com/charmbracelet/gum/style" "github.com/charmbracelet/gum/style"
) )
@ -27,7 +28,7 @@ func (o Options) Run() error {
m = mm.(model) m = mm.(model)
if err != nil { if err != nil {
return err return fmt.Errorf("failed to run spin: %w", err)
} }
if o.ShowOutput { if o.ShowOutput {
@ -45,5 +46,6 @@ func (o Options) Run() error {
// BeforeReset hook. Used to unclutter style flags. // BeforeReset hook. Used to unclutter style flags.
func (o Options) BeforeReset(ctx *kong.Context) error { func (o Options) BeforeReset(ctx *kong.Context) error {
return style.HideFlags(ctx) style.HideFlags(ctx)
return nil
} }

View file

@ -3,7 +3,6 @@ package spin
import "github.com/charmbracelet/gum/style" import "github.com/charmbracelet/gum/style"
// Options is the customization options for the spin command. // Options is the customization options for the spin command.
// nolint:staticcheck
type Options struct { type Options struct {
Command []string `arg:"" help:"Command to run"` Command []string `arg:"" help:"Command to run"`

View file

@ -9,10 +9,9 @@
// We can simply prepend a spinner to this task to show it to the user, while // We can simply prepend a spinner to this task to show it to the user, while
// performing the task / command in the background. // 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. // The spinner will automatically exit when the task is complete.
//
package spin package spin
import ( import (

View file

@ -3,24 +3,6 @@
// //
// It allows you to use Lip Gloss to style text without needing to use Go. All // It allows you to use Lip Gloss to style text without needing to use Go. All
// of the styling options are available as flags. // 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 package style
import ( import (
@ -40,10 +22,10 @@ func (o Options) Run() error {
// HideFlags hides the flags from the usage output. This is used in conjunction // HideFlags hides the flags from the usage output. This is used in conjunction
// with BeforeReset hook. // with BeforeReset hook.
func HideFlags(ctx *kong.Context) error { func HideFlags(ctx *kong.Context) {
n := ctx.Selected() n := ctx.Selected()
if n == nil { if n == nil {
return nil return
} }
for _, f := range n.Flags { for _, f := range n.Flags {
if g := f.Group; g != nil && g.Key == groupName { if g := f.Group; g != nil && g.Key == groupName {
@ -52,5 +34,4 @@ func HideFlags(ctx *kong.Context) error {
} }
} }
} }
return nil
} }

View file

@ -1,8 +1,9 @@
package style package style
import ( import (
"github.com/charmbracelet/gum/internal/decode"
"github.com/charmbracelet/lipgloss" "github.com/charmbracelet/lipgloss"
"github.com/charmbracelet/gum/internal/decode"
) )
// ToLipgloss takes a Styles flag set and returns the corresponding // ToLipgloss takes a Styles flag set and returns the corresponding

View file

@ -5,6 +5,8 @@ import (
"strings" "strings"
) )
const minTokens = 1
const halfTokens = 2
const maxTokens = 4 const maxTokens = 4
// parsePadding parses 1 - 4 integers from a string and returns them in a top, // 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 ints[i] = parsed
} }
if len(tokens) == 1 { if len(tokens) == minTokens {
return ints[0], ints[0], ints[0], ints[0] 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] return ints[0], ints[1], ints[0], ints[1]
} }

View file

@ -7,6 +7,7 @@ import (
"github.com/alecthomas/kong" "github.com/alecthomas/kong"
"github.com/charmbracelet/bubbles/textarea" "github.com/charmbracelet/bubbles/textarea"
tea "github.com/charmbracelet/bubbletea" tea "github.com/charmbracelet/bubbletea"
"github.com/charmbracelet/gum/internal/exit" "github.com/charmbracelet/gum/internal/exit"
"github.com/charmbracelet/gum/internal/stdin" "github.com/charmbracelet/gum/internal/stdin"
"github.com/charmbracelet/gum/style" "github.com/charmbracelet/gum/style"
@ -48,16 +49,20 @@ func (o Options) Run() error {
p := tea.NewProgram(model{textarea: a}, tea.WithOutput(os.Stderr)) p := tea.NewProgram(model{textarea: a}, tea.WithOutput(os.Stderr))
tm, err := p.StartReturningModel() tm, err := p.StartReturningModel()
if err != nil {
return fmt.Errorf("failed to run write: %w", err)
}
m := tm.(model) m := tm.(model)
if m.aborted { if m.aborted {
return exit.ErrAborted return exit.ErrAborted
} }
fmt.Println(m.textarea.Value()) fmt.Println(m.textarea.Value())
return err return nil
} }
// BeforeReset hook. Used to unclutter style flags. // BeforeReset hook. Used to unclutter style flags.
func (o Options) BeforeReset(ctx *kong.Context) error { func (o Options) BeforeReset(ctx *kong.Context) error {
return style.HideFlags(ctx) style.HideFlags(ctx)
return nil
} }

View file

@ -3,7 +3,6 @@ package write
import "github.com/charmbracelet/gum/style" import "github.com/charmbracelet/gum/style"
// Options are the customization options for the textarea. // Options are the customization options for the textarea.
// nolint:staticcheck
type Options struct { type Options struct {
Width int `help:"Text area width" default:"50" env:"GUM_WRITE_WIDTH"` Width int `help:"Text area width" default:"50" env:"GUM_WRITE_WIDTH"`
Height int `help:"Text area height" default:"5" env:"GUM_WRITE_HEIGHT"` Height int `help:"Text area height" default:"5" env:"GUM_WRITE_HEIGHT"`

View file

@ -1,11 +1,10 @@
// Package write provides a shell script interface for the text area bubble. // Package write provides a shell script interface for the text area bubble.
// https://github.com/charmbracelet/bubbles/tree/master/textarea // https://github.com/charmbracelet/bubbles/tree/master/textarea
// //
// It can be used to ask the user to write some long form of text // It can be used to ask the user to write some long form of text (multi-line)
// (multi-line) input. The text the user entered will be sent to stdout. // input. The text the user entered will be sent to stdout.
//
// $ gum write > output.text
// //
// $ gum write > output.text
package write package write
import ( import (
@ -29,11 +28,12 @@ func (m model) View() string {
func (m model) Update(msg tea.Msg) (tea.Model, tea.Cmd) { func (m model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
switch msg := msg.(type) { switch msg := msg.(type) {
case tea.KeyMsg: case tea.KeyMsg:
switch msg.Type { switch msg.String() {
case tea.KeyCtrlC: case "ctrl+c":
m.aborted = true m.aborted = true
fallthrough m.quitting = true
case tea.KeyEscape, tea.KeyCtrlD: return m, tea.Quit
case "esc", "ctrl+d":
m.quitting = true m.quitting = true
return m, tea.Quit return m, tea.Quit
} }