Site icon Golang Libraries, Apps, Golang Jobs and Go Tutorials

A Golang-based tool for glamorous shell scripts

A tool for glamorous shell scripts. Leverage the power of Bubbles and Lip Gloss in your scripts and aliases without writing any Golang code!

The above example is running from a single shell script (source).

Tutorial

Gum provides highly configurable, ready-to-use utilities to help you write useful shell scripts and dotfiles aliases with 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/sh.

#!/bin/sh

Ask for the commit type with gum choose:

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

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

Prompt for an (optional) scope for the commit:

gum input --placeholder "scope"

Prompt 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 (CTRL+D to finish)"

Prompt for a confirmation before committing:

gum confirm exits with status 0 if confirmed and status 1 if cancelled.

gum confirm "Commit changes?" && git commit -m "$SUMMARY" -m "$DESCRIPTION"

Putting it all together…

#!/bin/sh
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.
test -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 (CTRL+D to finish)")

# Commit these changes
gum confirm "Commit changes?" && git commit -m "$SUMMARY" -m "$DESCRIPTION"

Installation

Use a package manager:

# macOS or Linux
brew install gum

# Arch Linux (btw)
pacman -S gum

# Nix
nix-env -iA nixpkgs.gum

# Debian/Ubuntu
echo 'deb [trusted=yes] https://repo.charm.sh/apt/ /' | sudo tee /etc/apt/sources.list.d/charm.list
sudo apt update && sudo apt install gum

# Fedora
echo '[charm]
name=Charm
baseurl=https://repo.charm.sh/yum/
enabled=1
gpgcheck=0' | sudo tee /etc/yum.repos.d/charm.repo
sudo yum install gum

Or download it:

Or just install it with go:

go install github.com/charmbracelet/gum@latest

Customization

gum is designed to be embedded in scripts and supports all sorts of use cases. 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 each command’s customization and configuration options.

For example, let’s use an input and change the cursor color, prompt color, prompt indicator, placeholder text, width, and pre-populate the value:

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

You can also use ENVIRONMENT_VARIABLES to customize gum by default, this is useful to keep a consistent theme for all your gum commands.

export GUM_INPUT_CURSOR_FOREGROUND="#FF0"
export GUM_INPUT_PROMPT_FOREGROUND="#0FF"
export GUM_INPUT_PLACEHOLDER="What's up?"
export GUM_INPUT_PROMPT="* "
export GUM_INPUT_WIDTH=80

# Uses values configured through environment variables above but can still be
# overridden with flags.
gum input

Interaction

Input

Prompt for input with a simple command.

gum input > answer.text

Prompt for sensitive input with the --password flag.

gum input --password > password.text

Write

Prompt for some multi-line text.

Note: CTRL+D and esc are used to complete text entry. CTRL+C will cancel.

gum write > story.text

Filter

Use fuzzy matching to filter a list of values:

echo Strawberry >> flavors.text
echo Banana >> flavors.text
echo Cherry >> flavors.text
cat flavors.text | gum filter > selection.text

Choose

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 select multiple items with the --limit flag, which determines the maximum of items that can be chosen.

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

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

Exit mobile version