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
shells `pop`. Powered by [Bubbles](https://github.com/charmbracelet/bubbles)
and [Lip Gloss](https://github.com/charmbracelet/lipgloss)
Gum is a command-line tool (`gum`) that gives you the power of
[Bubbles](https://github.com/charmbracelet/bubbles) and
[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
@ -12,7 +16,7 @@ and [Lip Gloss](https://github.com/charmbracelet/lipgloss)
Prompt your users for input with a simple command.
```bash
pop input > answer.text
gum input > answer.text
```
#### Search
@ -20,19 +24,20 @@ pop input > answer.text
Allow your users to filter through a list of options by fuzzy searching.
```bash
echo Strawberry >> flavors.text
echo Banana >> flavors.text
echo Cherry >> flavors.text
echo Grape >> flavors.text
echo Lime >> flavors.text
echo Orange >> flavors.text
cat flavors.text | pop search > selection.text
cat flavors.text | gum search > selection.text
```
#### 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
pop loading --time 5s
gum progress --increment 0.1 --interval 1s
```
#### Spinners
@ -42,11 +47,11 @@ run while showing the spinner, the spinner will automatically stop after the
command exits.
```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.
```bash
pop style \
--foreground "#FF06B7" --border "double" \
--margin 2 --padding "2 4" --width 50 \
"And oh gosh, how delicious the fabulous frizzy frobscottle was!
gum style \
--foreground "#FF06B7" --border "double" --align "center" \
--width 50 --margin 2 --padding "2 4" \
"Bubble Gum (1¢)" "So sweet and so fresh\!"
```
Result:
```
╔══════════════════════════════════════════════════╗
║ ║
║ ║
║ And oh gosh, how delicious the fabulous ║
║ frizzy frobscottle was! ║
║ ║
║ ║
╚══════════════════════════════════════════════════╝
╔══════════════════════════════════════════════════╗
║ ║
║ ║
║ Bubble Gum (1¢) ║
║ So sweet and so fresh! ║
║ ║
║ ║
╚══════════════════════════════════════════════════╝
```
## Feedback

View file

@ -1,40 +1,40 @@
#!/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..."
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
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
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
Grape
Lime
Orange
POPS)
FLAVORS)
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 \
"Well, it was nice meeting you, $(pop style --foreground 212 "$NAME"). Hope to see you soon!"\
"Don't forget to drink some $(pop style --foreground 212 $POP) soda pop."
gum style --width 50 --padding "1 5" --margin "1 2" --border double --border-foreground 212 \
"Well, it was nice meeting you, $(gum style --foreground 212 "$NAME"). Hope to see you soon!"\
"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 (
github.com/alecthomas/kong v0.6.1
@ -11,16 +11,3 @@ require (
github.com/muesli/termenv v0.11.1-0.20220212125758-44cd13922739
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.22.0 h1:E1BTNSE3iIrq0G0X6TjGAmrQ32cGCbFDPcIuImikrUc=
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/lipgloss v0.5.0 h1:lulQHuVeodSgDez+3rGiuxlPVXSnhth442DATR2/8t8=
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/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=
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/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=

View file

@ -1,22 +1,23 @@
package main
import (
"github.com/charmbracelet/sodapop/input"
"github.com/charmbracelet/sodapop/search"
"github.com/charmbracelet/sodapop/spin"
"github.com/charmbracelet/sodapop/style"
"github.com/charmbracelet/sodapop/write"
"github.com/charmbracelet/gum/input"
"github.com/charmbracelet/gum/progress"
"github.com/charmbracelet/gum/search"
"github.com/charmbracelet/gum/spin"
"github.com/charmbracelet/gum/style"
"github.com/charmbracelet/gum/write"
)
// Pop is the command-line interface for Soda Pop.
type Pop struct {
// Gum is the command-line interface for Soda Gum.
type Gum struct {
// Input provides a shell script interface for the text input bubble.
// https://github.com/charmbracelet/bubbles/textinput
//
// It can be used to prompt the user for some input. The text the user
// 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."`
@ -26,7 +27,7 @@ type Pop 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.
//
// $ pop write > output.text
// $ gum write > output.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
// 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."`
@ -55,11 +56,19 @@ type Pop struct {
// We can simply prepend a spinner to this task to show it to the user,
// 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.
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.
// https://github.com/charmbracelet/lipgloss
//
@ -68,27 +77,20 @@ type Pop struct {
//
// Let's make some text glamorous using bash:
//
// $ pop style \
// --foreground "#FF06B7" --border "double" \
// --margin 2 --padding "2 4" --width 50 \
// "And oh gosh, how delicious the fabulous frizzy frobscottle" \
// "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."
// $ gum style \
// --foreground "#FF06B7" --border "double" --align "center" \
// --width 50 --margin 2 --padding "2 4" \
// "Bubble Gum (1¢)" "So sweet and so fresh\!"
//
//
// ╔══════════════════════════════════════════════════╗
// ║ ║
// ║ ║
// ║ And oh gosh, how delicious the fabulous ║
// ║ frizzy frobscottle 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. ║
// ║ ║
// ║ ║
// ╚══════════════════════════════════════════════════╝
// ╔══════════════════════════════════════════════════╗
// ║ ║
// ║ ║
// ║ Bubble Gum (1¢) ║
// ║ So sweet and so fresh! ║
// ║ ║
// ║ ║
// ╚══════════════════════════════════════════════════╝
//
Style style.Options `cmd:"" help:"Style some text."`
}

26
main.go
View file

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

View file

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