Go to file
2022-07-25 16:24:06 -04:00
.github/workflows feat(ci): add ci build and goreleaser 2022-07-08 13:21:53 -04:00
choose feat: autocompletion 2022-07-25 13:03:18 -04:00
completion feat: add fish completion script generator 2022-07-25 16:24:06 -04:00
examples docs: show how to embed gum in python and ruby scripts 2022-07-21 17:49:47 -04:00
filter feat: autocompletion 2022-07-25 13:03:18 -04:00
format fix(format): don't word wrap markdown 2022-07-21 16:56:22 -04:00
input feat: autocompletion 2022-07-25 13:03:18 -04:00
internal fix: ignore node_modules by default 2022-07-07 22:39:28 -04:00
join refactor: add package comments describing behavior 2022-07-13 09:55:36 -04:00
man feat: generate man pages 2022-07-18 12:03:47 -04:00
spin feat: autocompletion 2022-07-25 13:03:18 -04:00
style feat: autocompletion 2022-07-25 13:03:18 -04:00
write feat: autocompletion 2022-07-25 13:03:18 -04:00
.gitignore feat: generate man pages 2022-07-18 12:03:47 -04:00
.goreleaser.yml feat(ci): add ci build and goreleaser 2022-07-08 13:21:53 -04:00
Dockerfile feat: add Dockerfile 2022-07-08 13:37:13 -04:00
go.mod feat: generate man pages 2022-07-18 12:03:47 -04:00
go.sum feat: add fish completion script generator 2022-07-25 16:24:06 -04:00
gum.go feat: implement zsh & bash completion scripts 2022-07-25 14:36:21 -04:00
LICENSE Initial commit 2022-07-06 12:05:45 -04:00
main.go refactor(variables): place on new lines 2022-07-21 11:27:36 -04:00
README.md docs: update tag line and description 2022-07-25 12:44:40 -04:00

Gum

Gum Image

Latest Release GoDoc Build Status

A tool for building glamorous shell scripts.

Shell running the ./demo.sh script

Tutorial

Gum provides highly configurable, ready-to-use utilities to help you write useful bash scripts in just a few lines of code.

Let's build a simple script to help you write Conventional Commits for your dotfiles.

Start with a #!/bin/bash.

#!/bin/bash

Ask the user for the commit type with gum choose:

gum choose "fix" "feat" "docs" "style" "refactor" "test" "chore" "revert"

Note: this command itself will print to stdout which is not all that useful. To make use of the command later on you should save the stdout to a $VARIABLE or file.txt.

Prompt for an (optional) scope for the commit:

gum input --placeholder "scope"

Prompt the user for a commit message:

gum input --placeholder "Summary of this change"

Prompt for a detailed (multi-line) explanation of the changes:

gum write --placeholder "Details of this change"

Putting it all together...

#!/bin/bash
TYPE=$(gum choose "fix" "feat" "docs" "style" "refactor" "test" "chore" "revert")
SCOPE=$(gum input --placeholder "scope")

# Since the scope is optional, wrap it in parentheses if it has a value.
[[ -n "$SCOPE" ]] && SCOPE="($SCOPE)"

# Pre-populate the input with the type(scope): so that the user may change it
SUMMARY=$(gum input --value "$TYPE$SCOPE: " --placeholder "Summary of this change")
DESCRIPTION=$(gum write --placeholder "Details of this change")

# Commit these changes
git commit -m "$SUMMARY" -m "$DESCRIPTION"
Running the ./examples/commit.sh script to commit to git

Installation

Use a package manager:

# macOS or Linux
brew tap charmbracelet/tap && brew install charmbracelet/tap/gum

# Arch Linux (btw)
pacman -S gum

# Nix
nix-env -iA nixpkgs.gum

Or download it:

  • Packages are available in Debian and RPM formats
  • Binaries are available for Linux, macOS, and Windows

Or just install it with go:

go install github.com/charmbracelet/gum@latest

Customization

gum is designed to be embedded in scripts and different use cases. All components are configurable and customizable to fit your theme and use case.

You can customize with --flags. See gum <command> --help for a full view of all the command's customization and configuration options.

For example, let's customize the cursor color, prompt color, prompt indicator, placeholder text, width, and pre-populate the value of the input:

gum input --cursor.foreground "#FF0" --prompt.foreground "#0FF" --prompt "* " \
    --placeholder "What's up?" --width 80 --value "Not much, hby?"
Gum input displaying most customization options

Interaction

Input

Prompt your users for input with a simple command.

gum input > answer.text
Shell running gum input typing Not much, you?

Write

Prompt your users to write some multi-line text.

gum write > story.text
Shell running gum write typing a story

Filter

Allow your users to filter through a list of options by fuzzy searching.

echo Strawberry >> flavors.text
echo Banana >> flavors.text
echo Cherry >> flavors.text
cat flavors.text | gum filter > selection.text
Shell running gum filter on different bubble gum flavors

Choose

Ask your users to choose an option from a list of choices.

echo "Pick a card, any card..."
CARD=$(gum choose --height 15 {{A,K,Q,J},{10..2}}" "{♠,♥,♣,♦})
echo "Was your card the $CARD?"

You can also set a limit on the number of items to choose with the --limit flag.

echo "Pick your top 5 songs."
cat songs.txt | gum choose --limit 5

Or, allow any number of selections with the --no-limit flag.

echo "What do you need from the grocery store?"
cat foods.txt | gum choose --no-limit
Shell running gum choose with numbers and gum flavors

Spin

Display a spinner while taking some running action. We specify the command to run while showing the spinner, the spinner will automatically stop after the command exits.

gum spin --spinner dot --title "Buying Bubble Gum..." -- sleep 5
Shell running gum spin while sleeping for 5 seconds

Styling

Style

Pretty print any string with any layout with one command.

gum style \
	--foreground 212 --border-foreground 212 --border double \
	--align center --width 50 --margin "1 2" --padding "2 4" \
	'Bubble Gum (1¢)' 'So sweet and so fresh!'
Bubble Gum, So sweet and so fresh!

Layout

Join

Combine text vertically or horizontally with a single command, use this command with gum style to build layouts and pretty output.

Note: It's important to wrap the output of gum style in quotes to ensure new lines (\n) are part of a single argument passed to the join command.

I=$(gum style --padding "1 5" --border double --border-foreground 212 "I")
LOVE=$(gum style --padding "1 4" --border double --border-foreground 57 "LOVE")
BUBBLE=$(gum style --padding "1 8" --border double --border-foreground 255 "Bubble")
GUM=$(gum style --padding "1 5" --border double --border-foreground 240 "Gum")

I_LOVE=$(gum join "$I" "$LOVE")
BUBBLE_GUM=$(gum join "$BUBBLE" "$GUM")
gum join --align center --vertical "$I_LOVE" "$BUBBLE_GUM"
I LOVE Bubble Gum written out in four boxes with double borders around them.

Format

The format command allows you to take some text and stylize it. gum format can parse markdown, code, template strings, and emoji strings.

# Format some markdown
gum format -- "# Gum Formats" "- Markdown" "- Code" "- Template" "- Emoji"
echo "# Gum Formats\n- Markdown\n- Code\n- Template\n- Emoji" | gum format

# Syntax highlight some code
cat main.go | gum format -t code

# Render text any way you want with templates
echo '{{ Bold "Tasty" }} {{ Italic "Bubble" }} {{ Color "99" "0" " Gum " }}' \
    | gum format -t template

# Display your favorite emojis!
echo 'I :heart: Bubble Gum :candy:' | gum format -t emoji
Running gum format for different types of formats

Examples

See the examples directory for more real world use cases.

How to use gum in your daily workflows:

Write a commit message

Prompt for user input to write git commit messages with a short summary and longer details with gum input and gum write.

Bonus points if you use gum filter with the Conventional Commits Specification as a prefix for your commit message.

git commit -m "$(gum input --width 50 --placeholder "Summary of changes")" \
           -m "$(gum write --width 80 --placeholder "Details of changes")"

Open files in your $EDITOR

By default gum filter will display a list of all files (searched recursively) through your current directory, it has some sensible ignored defaults (.git, node_modules). You can use this to pick a file and open it in your $EDITOR.

$EDITOR $(gum filter)

Connect to a TMUX session

Pick from a running TMUX session and attach to it if not inside TMUX or switch your client to the session if already attached to a session.

SESSION=$(tmux list-sessions -F \#S | gum filter --placeholder "Pick session...")
tmux switch-client -t $SESSION || tmux attach -t $SESSION
Picking a tmux session with gum filter

Pick commit hash from history

Filter through your git history searching for commit messages and copy the commit hash of the selected commit.

git log --oneline | gum filter | cut -d' ' -f1 # | copy
Picking a commit with gum filter

Choose packages to uninstall

List all packages installed by your package manager (we'll use brew) and choose which packages to uninstall.

brew list | gum choose --no-limit | xargs brew uninstall

Feedback

Wed love to hear your thoughts on this project. Feel free to drop us a note!

License

MIT

Part of Charm.

The Charm logo

Charm热爱开源 • Charm loves open source