.github/workflows | ||
choose | ||
completion | ||
examples | ||
filter | ||
format | ||
input | ||
internal | ||
join | ||
man | ||
spin | ||
style | ||
write | ||
.gitignore | ||
.goreleaser.yml | ||
Dockerfile | ||
go.mod | ||
go.sum | ||
gum.go | ||
LICENSE | ||
main.go | ||
README.md |
Gum
A tool for building glamorous shell scripts.
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
orfile.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"
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?"
Interaction
Input
Prompt your users for input with a simple command.
gum input > answer.text
Write
Prompt your users to write some multi-line text.
gum write > story.text
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
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
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
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!'
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"
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
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
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
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
We’d love to hear your thoughts on this project. Feel free to drop us a note!
License
Part of Charm.
Charm热爱开源 • Charm loves open source