refactor: rename to gum

This commit is contained in:
Maas Lalani 2022-07-07 13:26:35 -04:00
parent 0b9efbda37
commit 9f4f9ecbf1
No known key found for this signature in database
GPG key ID: 5A6ED5CBF1A0A000
11 changed files with 183 additions and 102 deletions

View file

@ -1,10 +1,14 @@
# Soda Pop # Gum
Command line utilities to make your command-line `pop`. Tasty Bubble Gum for your shell.
Soda Pop provides utilities to help you create shell scripts make your user's Gum is a command-line tool (`gum`) that gives you the power of
shells `pop`. Powered by [Bubbles](https://github.com/charmbracelet/bubbles) [Bubbles](https://github.com/charmbracelet/bubbles) and
and [Lip Gloss](https://github.com/charmbracelet/lipgloss) [Lip Gloss](https://github.com/charmbracelet/lipgloss) without needing to write
any Go code.
Check out the [Example](./examples/demo.sh) script to see what you can do with
it.
## Interaction ## Interaction
@ -12,7 +16,7 @@ and [Lip Gloss](https://github.com/charmbracelet/lipgloss)
Prompt your users for input with a simple command. Prompt your users for input with a simple command.
```bash ```bash
pop input > answer.text gum input > answer.text
``` ```
#### Search #### Search
@ -20,19 +24,20 @@ pop input > answer.text
Allow your users to filter through a list of options by fuzzy searching. Allow your users to filter through a list of options by fuzzy searching.
```bash ```bash
echo Strawberry >> flavors.text
echo Banana >> flavors.text
echo Cherry >> flavors.text echo Cherry >> flavors.text
echo Grape >> flavors.text cat flavors.text | gum search > selection.text
echo Lime >> flavors.text
echo Orange >> flavors.text
cat flavors.text | pop search > selection.text
``` ```
#### Loading #### Loading
Display a progress bar while loading. Display a progress bar while loading. The following command will display a
progress bar and increment the progress by 10% every 1 second. Thus, taking 10
seconds to complete the progress bar.
```bash ```bash
pop loading --time 5s gum progress --increment 0.1 --interval 1s
``` ```
#### Spinners #### Spinners
@ -42,11 +47,11 @@ run while showing the spinner, the spinner will automatically stop after the
command exits. command exits.
```bash ```bash
pop spin --spinner dot --title "Buying Soda Pop..." -- sleep 5 gum spin --spinner dot --title "Buying Bubble Gum..." -- sleep 5
``` ```
``` ```
⣽ Buying Soda Pop... ⣽ Buying Bubble Gum...
``` ```
@ -55,23 +60,27 @@ pop spin --spinner dot --title "Buying Soda Pop..." -- sleep 5
Pretty print any string with any layout with one command. Pretty print any string with any layout with one command.
```bash ```bash
pop style \ gum style \
--foreground "#FF06B7" --border "double" \ --foreground "#FF06B7" --border "double" --align "center" \
--margin 2 --padding "2 4" --width 50 \ --width 50 --margin 2 --padding "2 4" \
"And oh gosh, how delicious the fabulous frizzy frobscottle was! "Bubble Gum (1¢)" "So sweet and so fresh\!"
``` ```
Result: Result:
``` ```
╔══════════════════════════════════════════════════╗
║ ║
║ ║ ╔══════════════════════════════════════════════════╗
║ And oh gosh, how delicious the fabulous ║ ║ ║
║ frizzy frobscottle was! ║ ║ ║
║ ║ ║ Bubble Gum (1¢) ║
║ ║ ║ So sweet and so fresh! ║
╚══════════════════════════════════════════════════╝ ║ ║
║ ║
╚══════════════════════════════════════════════════╝
``` ```
## Feedback ## Feedback

View file

@ -1,40 +1,40 @@
#!/bin/bash #!/bin/bash
go install github.com/charmbracelet/sodapop && mv $GOBIN/sodapop $GOBIN/pop go install github.com/charmbracelet/gum
echo "Hello, there! Welcome to $(pop style --foreground 212 'Soda Pop')" echo "Hello, there! Welcome to $(gum style --foreground 212 'Gum')."
NAME=$(pop input --placeholder "What is your name?") NAME=$(gum input --placeholder "What is your name?")
echo "Well, it is nice to meet you, $(pop style --foreground 212 "$NAME")." echo "Well, it is nice to meet you, $(gum style --foreground 212 "$NAME")."
COLOR=$(pop input --placeholder "What is your favorite color? (#HEX)") COLOR=$(gum input --placeholder "What is your favorite color? (#HEX)")
echo "Wait a moment, while I think of my favorite color..." echo "Wait a moment, while I think of my favorite color..."
pop spin --title "Thinking..." --color 212 -- sleep 3 gum spin --title "Thinking..." --color 212 -- sleep 3
echo "I like $(pop style --background $COLOR $COLOR), too. In fact, it's my $(pop style --background $COLOR 'favorite color!')" echo "I like $(gum style --background $COLOR $COLOR), too. In fact, it's my $(gum style --background $COLOR 'favorite color!')"
sleep 1 sleep 1
echo "Seems like we have a lot in common, $(pop style --foreground 212 "$NAME")." echo "Seems like we have a lot in common, $(gum style --foreground 212 "$NAME")."
sleep 1 sleep 1
echo "What's your favorite Soda Pop flavor?" echo "What's your favorite Gum flavor?"
POP=$(pop search --accent-color 212 << POPS GUM=$(gum search --accent-color 212 << FLAVORS
Cherry Cherry
Grape Grape
Lime Lime
Orange Orange
POPS) FLAVORS)
echo "One sec, while I finish my drink." echo "One sec, while I finish my drink."
pop spin --title "Drinking some $POP soda pop..." --color 212 -- sleep 5 gum spin --title "Chewing some $GUM bubble gum..." --color 212 -- sleep 5
pop style --width 50 --padding "1 5" --margin "1 2" --border double --border-foreground 212 \ gum style --width 50 --padding "1 5" --margin "1 2" --border double --border-foreground 212 \
"Well, it was nice meeting you, $(pop style --foreground 212 "$NAME"). Hope to see you soon!"\ "Well, it was nice meeting you, $(gum style --foreground 212 "$NAME"). Hope to see you soon!"\
"Don't forget to drink some $(pop style --foreground 212 $POP) soda pop." "Don't forget to chew some $(gum style --foreground 212 $GUM) bubble gum."

17
go.mod
View file

@ -1,6 +1,6 @@
module github.com/charmbracelet/sodapop module github.com/charmbracelet/gum
go 1.18 go 1.13
require ( require (
github.com/alecthomas/kong v0.6.1 github.com/alecthomas/kong v0.6.1
@ -11,16 +11,3 @@ require (
github.com/muesli/termenv v0.11.1-0.20220212125758-44cd13922739 github.com/muesli/termenv v0.11.1-0.20220212125758-44cd13922739
github.com/sahilm/fuzzy v0.1.0 github.com/sahilm/fuzzy v0.1.0
) )
require (
github.com/atotto/clipboard v0.1.4 // indirect
github.com/containerd/console v1.0.3 // indirect
github.com/lucasb-eyer/go-colorful v1.2.0 // indirect
github.com/mattn/go-isatty v0.0.14 // indirect
github.com/muesli/ansi v0.0.0-20211018074035-2e021307bc4b // indirect
github.com/muesli/cancelreader v0.2.1 // indirect
github.com/muesli/reflow v0.3.0 // indirect
github.com/rivo/uniseg v0.2.0 // indirect
golang.org/x/sys v0.0.0-20220209214540-3681064d5158 // indirect
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211 // indirect
)

2
go.sum
View file

@ -9,6 +9,7 @@ github.com/charmbracelet/bubbles v0.13.0/go.mod h1:bbeTiXwPww4M031aGi8UK2HT9RDWo
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=
github.com/charmbracelet/bubbletea v0.22.0 h1:E1BTNSE3iIrq0G0X6TjGAmrQ32cGCbFDPcIuImikrUc= github.com/charmbracelet/bubbletea v0.22.0 h1:E1BTNSE3iIrq0G0X6TjGAmrQ32cGCbFDPcIuImikrUc=
github.com/charmbracelet/bubbletea v0.22.0/go.mod h1:aoVIwlNlr5wbCB26KhxfrqAn0bMp4YpJcoOelbxApjs= github.com/charmbracelet/bubbletea v0.22.0/go.mod h1:aoVIwlNlr5wbCB26KhxfrqAn0bMp4YpJcoOelbxApjs=
github.com/charmbracelet/harmonica v0.2.0 h1:8NxJWRWg/bzKqqEaaeFNipOu77YR5t8aSwG4pgaUBiQ=
github.com/charmbracelet/harmonica v0.2.0/go.mod h1:KSri/1RMQOZLbw7AHqgcBycp8pgJnQMYYT8QZRqZ1Ao= github.com/charmbracelet/harmonica v0.2.0/go.mod h1:KSri/1RMQOZLbw7AHqgcBycp8pgJnQMYYT8QZRqZ1Ao=
github.com/charmbracelet/lipgloss v0.5.0 h1:lulQHuVeodSgDez+3rGiuxlPVXSnhth442DATR2/8t8= github.com/charmbracelet/lipgloss v0.5.0 h1:lulQHuVeodSgDez+3rGiuxlPVXSnhth442DATR2/8t8=
github.com/charmbracelet/lipgloss v0.5.0/go.mod h1:EZLha/HbzEt7cYqdFPovlqy5FZPj0xFhg5SaqxScmgs= github.com/charmbracelet/lipgloss v0.5.0/go.mod h1:EZLha/HbzEt7cYqdFPovlqy5FZPj0xFhg5SaqxScmgs=
@ -56,6 +57,7 @@ golang.org/x/sys v0.0.0-20220209214540-3681064d5158 h1:rm+CHSpPEEW2IsXUib1ThaHIj
golang.org/x/sys v0.0.0-20220209214540-3681064d5158/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220209214540-3681064d5158/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211 h1:JGgROgKl9N8DuW20oFS5gxc+lE67/N3FcwmBPMe7ArY= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211 h1:JGgROgKl9N8DuW20oFS5gxc+lE67/N3FcwmBPMe7ArY=
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=

View file

@ -1,22 +1,23 @@
package main package main
import ( import (
"github.com/charmbracelet/sodapop/input" "github.com/charmbracelet/gum/input"
"github.com/charmbracelet/sodapop/search" "github.com/charmbracelet/gum/progress"
"github.com/charmbracelet/sodapop/spin" "github.com/charmbracelet/gum/search"
"github.com/charmbracelet/sodapop/style" "github.com/charmbracelet/gum/spin"
"github.com/charmbracelet/sodapop/write" "github.com/charmbracelet/gum/style"
"github.com/charmbracelet/gum/write"
) )
// Pop is the command-line interface for Soda Pop. // Gum is the command-line interface for Soda Gum.
type Pop struct { type Gum struct {
// Input provides a shell script interface for the text input bubble. // Input provides a shell script interface for the text input bubble.
// https://github.com/charmbracelet/bubbles/textinput // https://github.com/charmbracelet/bubbles/textinput
// //
// 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.
// //
// $ pop input --placeholder "What's your favorite pop?" > answer.text // $ 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 input."`
@ -26,7 +27,7 @@ type Pop 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.
// //
// $ pop write > output.text // $ gum write > output.text
// //
Write write.Options `cmd:"" help:"Prompt for text"` Write write.Options `cmd:"" help:"Prompt for text"`
@ -37,9 +38,9 @@ type Pop struct {
// for the user to choose one, but the script (or user) can provide different // for the user to choose one, but the script (or user) can provide different
// new-line separated options to choose from. // new-line separated options to choose from.
// //
// I.e. let's pick from a list of soda pop flavors: // I.e. let's pick from a list of gum flavors:
// //
// $ cat flavors.text | pop search // $ cat flavors.text | gum search
// //
Search search.Options `cmd:"" help:"Fuzzy search options."` Search search.Options `cmd:"" help:"Fuzzy search options."`
@ -55,11 +56,19 @@ type Pop 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.
// //
// $ pop 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.
Spin spin.Options `cmd:"" help:"Show spinner while executing a command."` Spin spin.Options `cmd:"" help:"Show spinner while executing a command."`
// Progress provides a shell script interface for the progress bubble.
// https://github.com/charmbracelet/bubbles/progress
//
// 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."`
// Style provides a shell script interface for Lip Gloss. // Style provides a shell script interface for Lip Gloss.
// https://github.com/charmbracelet/lipgloss // https://github.com/charmbracelet/lipgloss
// //
@ -68,27 +77,20 @@ type Pop struct {
// //
// Let's make some text glamorous using bash: // Let's make some text glamorous using bash:
// //
// $ pop style \ // $ gum style \
// --foreground "#FF06B7" --border "double" \ // --foreground "#FF06B7" --border "double" --align "center" \
// --margin 2 --padding "2 4" --width 50 \ // --width 50 --margin 2 --padding "2 4" \
// "And oh gosh, how delicious the fabulous frizzy frobscottle" \ // "Bubble Gum (1¢)" "So sweet and so fresh\!"
// "was! It was sweet and refreshing. It tasted of vanilla and" \
// "cream, with just the faintest trace of raspberries on the" \
// "edge of the flavour. And the bubbles were wonderful."
// //
// //
// ╔══════════════════════════════════════════════════╗ // ╔══════════════════════════════════════════════════╗
// ║ ║ // ║ ║
// ║ ║ // ║ ║
// ║ And oh gosh, how delicious the fabulous ║ // ║ Bubble Gum (1¢) ║
// ║ frizzy frobscottle was It was sweet and ║ // ║ So sweet and so fresh! ║
// ║ refreshing. It tasted of vanilla and ║ // ║ ║
// ║ cream, with just the faintest trace of ║ // ║ ║
// ║ raspberries on the edge of the flavour. ║ // ╚══════════════════════════════════════════════════╝
// ║ And the bubbles were wonderful. ║
// ║ ║
// ║ ║
// ╚══════════════════════════════════════════════════╝
// //
Style style.Options `cmd:"" help:"Style some text."` Style style.Options `cmd:"" help:"Style some text."`
} }

26
main.go
View file

@ -2,17 +2,17 @@ package main
import ( import (
"github.com/alecthomas/kong" "github.com/alecthomas/kong"
"github.com/charmbracelet/gum/internal/stdin"
"github.com/charmbracelet/lipgloss" "github.com/charmbracelet/lipgloss"
"github.com/charmbracelet/sodapop/internal/stdin"
"github.com/muesli/termenv" "github.com/muesli/termenv"
) )
func main() { func main() {
lipgloss.SetColorProfile(termenv.ANSI256) lipgloss.SetColorProfile(termenv.ANSI256)
pop := &Pop{} gum := &Gum{}
ctx := kong.Parse(pop, ctx := kong.Parse(gum,
kong.Name("pop"), kong.Name("gum"),
kong.Description("Make your shell pop."), kong.Description("Tasty Bubble Gum for your shell."),
kong.UsageOnError(), kong.UsageOnError(),
kong.ConfigureHelp(kong.HelpOptions{ kong.ConfigureHelp(kong.HelpOptions{
Compact: true, Compact: true,
@ -20,19 +20,21 @@ func main() {
})) }))
switch ctx.Command() { switch ctx.Command() {
case "input": case "input":
pop.Input.Run() gum.Input.Run()
case "write": case "write":
pop.Write.Run() gum.Write.Run()
case "search": case "search":
pop.Search.Run() gum.Search.Run()
case "spin <command>": case "spin <command>":
pop.Spin.Run() gum.Spin.Run()
case "progress":
gum.Progress.Run()
case "style": case "style":
input, _ := stdin.Read() input, _ := stdin.Read()
pop.Style.Text = []string{input} gum.Style.Text = []string{input}
pop.Style.Run() gum.Style.Run()
case "style <text>": case "style <text>":
pop.Style.Run() gum.Style.Run()
case "layout": case "layout":
} }
} }

22
progress/command.go Normal file
View file

@ -0,0 +1,22 @@
package progress
import (
"os"
"github.com/charmbracelet/bubbles/progress"
tea "github.com/charmbracelet/bubbletea"
)
// Run runs the progress command.
func (o Options) Run() {
p := progress.New(
progress.WithDefaultGradient(),
progress.WithSpringOptions(o.Frequency, o.Damping),
)
m := model{
progress: p,
interval: o.Interval,
increment: o.Increment,
}
_ = tea.NewProgram(m, tea.WithOutput(os.Stderr)).Start()
}

11
progress/options.go Normal file
View file

@ -0,0 +1,11 @@
package progress
import "time"
// Options is the available options for the progress command.
type Options struct {
Damping float64 `help:"Damping of the spring animation." default:"0.9"`
Frequency float64 `help:"Frequency of the spring animation." default:"10.0"`
Increment float64 `help:"The percentage to increment the progress bar per tick." default:"0.1"`
Interval time.Duration `help:"The interval of time to wait before incrementing." default:"100ms"`
}

46
progress/progress.go Normal file
View file

@ -0,0 +1,46 @@
package progress
import (
"time"
"github.com/charmbracelet/bubbles/progress"
tea "github.com/charmbracelet/bubbletea"
)
type model struct {
interval time.Duration
progress progress.Model
increment float64
}
type tickMsg time.Time
func tickCmd(t time.Duration) tea.Cmd {
return tea.Tick(t, func(t time.Time) tea.Msg {
return tickMsg(t)
})
}
func (m model) Init() tea.Cmd { return tickCmd(m.interval) }
func (m model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
switch msg := msg.(type) {
case tea.KeyMsg:
switch msg.String() {
case "ctrl+c", "q":
return m, tea.Quit
}
case tickMsg:
if m.progress.Percent() >= 1 {
return m, tea.Quit
}
cmd := m.progress.IncrPercent(m.increment)
return m, tea.Batch(tickCmd(m.interval), cmd)
case progress.FrameMsg:
progressModel, cmd := m.progress.Update(msg)
m.progress = progressModel.(progress.Model)
return m, cmd
}
return m, nil
}
func (m model) View() string { return m.progress.View() }

View file

@ -7,9 +7,9 @@ import (
"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/log"
"github.com/charmbracelet/gum/internal/stdin"
"github.com/charmbracelet/lipgloss" "github.com/charmbracelet/lipgloss"
"github.com/charmbracelet/sodapop/internal/log"
"github.com/charmbracelet/sodapop/internal/stdin"
) )
// Run provides a shell script interface for the search bubble. // Run provides a shell script interface for the search bubble.

View file

@ -10,7 +10,7 @@ import (
// Run provides a shell script interface for the Lip Gloss styling. // Run provides a shell script interface for the Lip Gloss styling.
// https://github.com/charmbracelet/lipgloss // https://github.com/charmbracelet/lipgloss
func (o Options) Run() { func (o Options) Run() {
text := strings.Join(o.Text, " ") text := strings.Join(o.Text, "\n")
fmt.Println(lipgloss.NewStyle(). fmt.Println(lipgloss.NewStyle().
Foreground(lipgloss.Color(o.Foreground)). Foreground(lipgloss.Color(o.Foreground)).