Skip to content

Instantly share code, notes, and snippets.

@kigster
Last active August 23, 2026 18:25
Show Gist options
  • Select an option

  • Save kigster/ee667e080423c24c2a92d2de53cd9a48 to your computer and use it in GitHub Desktop.

Select an option

Save kigster/ee667e080423c24c2a92d2de53cd9a48 to your computer and use it in GitHub Desktop.
A ZSH script that interactively lets you choose one of the prompt presets, and (if supported) palettes. Based on http://starship.rs/
#!/usr/bin/env zsh
# © 2026 Konstantin Gredeskoul, MIT License.
# starship ZSH preset chooser and palette helper script, interactive.
#
# WHY this script?
#
# Starship povides one of the best prompts I've ever seen, it's super fast, colorful and
# very customizable. Once you install it from https://starship.rs it will also install
# a couple of presets. Some presets (such as catppuccin) have multiple palletes to choose
# from.
#
# This simple ZSH script lets you choose the preset, and if the preset contains multiple
# palletes, it also lets you choose the pallete. Using a simple text menu. This makes
# using Startship and it's presents trivial.
#
# USAGE:
# We recommend you install this script as in your `$PATH` and make it executable.
# Then once you have the system prompt type: `which-starship` and go through the menu.
#
# INSTALLATION:
# 1. startship prompt
# If `starship` binary is not in your `$PATH`, this script will run the
# installer for you.
#
# 2. To install this script, run the following command:
# curl -fsSL https://bit.ly/get-which-starship -o /usr/local/bin/which-starship
# chmod 755 /usr/local/bin/which-starship
# which-starship # and follow the menu
#
# KEYBOARD MAPING:
# Use arrows to move up/down the menu, use spacebar or ENTER to select.
#
ho=$'\e[1;33m' hi=$'\e[1;32m' dim=$'\e[38;5;245m' rst=$'\e[0m' clr=$'\e[2K'
function menu_select() {
emulate -L zsh
setopt local_options no_ksh_arrays no_nomatch
local title=$1; shift
local -a opts=("$@")
local n=$#opts
(( n )) || return 1
local sel=1 key seq i redraw=0 tty saved_tty
local mark_on='⏺' mark_off='⊙'
# ⊙ is an East-Asian "ambiguous width" glyph, so it can render two cells wide
# while ⏺ renders one. Rather than trust the glyph width, the label is placed
# at an absolute column (\e[6G) so the two states always line up.
local col=$'\e[6G'
# Everything the user sees goes to stderr, so $(menu_select ...) captures
# only the chosen value. Input comes straight from the tty, so the function
# still works with its stdin or stdout redirected.
exec {tty}</dev/tty || return 1
# Put the terminal into cbreak mode EXPLICITLY rather than relying on
# `read -k` to do it. Note: -icanon -echo, NOT `stty raw` — raw also clears
# opost/onlcr (newlines would staircase) and isig (Ctrl-C would stop working).
saved_tty=$(stty -g <&$tty) || return 1
stty -icanon -echo min 1 time 0 <&$tty
print -u2 -r -- "${ho}${title}${rst} ${dim}— ↑/↓ · enter to pick · q to cancel${rst}"
tput civis >&2 # hide the cursor
{
while true; do
(( redraw )) && print -u2 -n $'\e['${n}'A'
redraw=1
for (( i = 1; i <= n; i++ )); do
if (( i == sel )); then
print -u2 -r -- "${clr} ${hi}${mark_on}${col}${opts[i]}${rst}"
else
print -u2 -r -- "${clr} ${dim}${mark_off}${col}${opts[i]}${rst}"
fi
done
read -u $tty -k 1 key || return 130
case $key in
$'\e')
# Arrows arrive as ESC [ A in normal cursor-key mode and as
# ESC O A when the terminal is in application cursor-key mode
# (DECCKM) — tmux, some ssh sessions, and ZLE widgets set this.
# A bare Esc times out and cancels.
read -u $tty -k 2 -t 0.1 seq || { print -u2; return 130 }
case $seq in
'[A'|'OA') (( sel = sel > 1 ? sel - 1 : n )) ;; # up
'[B'|'OB') (( sel = sel < n ? sel + 1 : 1 )) ;; # down
'[H'|'OH') sel=1 ;; # home
'[F'|'OF') sel=$n ;; # end
esac ;;
k) (( sel = sel > 1 ? sel - 1 : n )) ;;
j) (( sel = sel < n ? sel + 1 : 1 )) ;;
g) sel=1 ;;
G) sel=$n ;;
q) print -u2; return 130 ;;
$'\n'|$'\r') break ;;
esac
done
} always {
stty "$saved_tty" <&$tty # restore canonical mode + echo
tput cnorm >&2 # put the cursor back
exec {tty}<&-
}
# Collapse the menu down to a single confirmation line.
print -u2 -n $'\e['${n}'A'
for (( i = 1; i <= n; i++ )); do print -u2 -n "${clr}"$'\e[1B'; done
print -u2 -n $'\e['${n}'A'
print -u2 -r -- "${clr} ${hi}${mark_on}${col}${opts[sel]}${rst}"
print -r -- $opts[sel]
}
function install-starship() {
if ! command -v starship >/dev/null; then
echo "starship command is not in the PATH, installing..."
curl -sS https://starship.rs/install.sh | sh -s -- -y
hash -r
fi
if [[ -f ~/.bashrc ]] && ! grep -q "starship init bash" ~/.bashrc; then
echo "installing starship hook into your ~/.bashrc..."
echo 'eval "$(starship init bash)"' >> ~/.bashrc
fi
if [[ -f ~/.zshrc ]] && ! grep -q "starship init zsh" ~/.zshrc; then
echo "installing starship hook into your ~/.zshrc..."
echo 'eval "$(starship init zsh)"' >> ~/.zshrc
fi
}
# ---------------------------------------------------------------------------
# Pick a starship and go with it.
# ---------------------------------------------------------------------------
function which-starship() {
install-starship
local -a presets=(${(f)"$(starship preset --list)"})
(( $#presets )) || { print -u2 "no presets found — is starship installed?"; return 1 }
local choice palette
choice=$(menu_select "Choose a preset" $presets) || return
if [[ ${choice} == "catppuccin-powerline" ]]; then
echo
echo "This preset comes with several color palettes:"
local -a palettes=(
mocha
latte
macchiato
frappe
)
palette=$(menu_select "Choose a Pallete" $palettes) || return
palette="catppuccin_$palette"
fi
starship preset "$choice" -o "${XDG_CONFIG_HOME:-$HOME/.config}/starship.toml" --force
if [[ -n ${palette} ]]; then
starship config palette ${palette}
print -r -- "installed palette: $palette"
fi
}
function usage() {
print -u2 -r -- "
${hi}DESCRIPTION${dim}
Starship povides one of the best prompts I've ever seen, it's super fast, colorful and
very customizable. Once you install it from https://starship.rs it will also install
a couple of presets. Some presets (such as catppuccin) have multiple palletes to choose
from.
This simple ZSH script lets you choose the preset, and if the preset contains multiple
palletes, it also lets you choose the pallete. Using a simple text menu. This makes
using Startship and it's presents trivial.
${hi}USAGE:${dim}
We recommend that you install this script somewhere in your '\$PATH' and
make it executable. Then just type: ${ho}which-starship${dim} and go through the
menus to select the prompt.
${hi}INSTALLATION:${dim}
1. To install this script, run the following command:
${ho}curl -fsSL https://bit.ly/get-which-starship -o /usr/local/bin/which-starship
chmod 755 /usr/local/bin/which-starship
which-starship ${dim}# and follow the menu
2. NOTE: If starship binary is not in your '\$PATH', this script will run the
starship installer for you.
${hi}KEYBOARD MAPING:${dim}
Use arrows to move up/down the menu, use spacebar or ENTER to select.
${hi}Enjoy!
-- @kigster (https://kig.re)
${dim}
"
}
if [[ "$0" == "${(%):-%x}" ]]; then
if [[ $1 =~ "-h" || $1 =~ "--help" ]]; then
usage
else
which-starship
fi
fi
@kigster

kigster commented Aug 23, 2026

Copy link
Copy Markdown
Author

The entire installation is trivial:

curl -fsSL https://bit.ly/get-which-starship -o /usr/local/bin/which-starship
chmod 755 /usr/local/bin/which-starship
which-starship

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment