Skip to content

About

Catppuccin theme for Oh My Zsh with configurable flavors, path display, and git indicators

Resources

Stars

0 stars

Watchers

0 watching

Forks

Repository files navigation

omzppuccin

A zsh prompt with a configurator built in. Five layouts, five palettes, and an interactive menu that rebuilds your real prompt as you arrow through it.

It needs zsh and git, and nothing else — no framework, no plugin, no binary. Git status comes from one git status --porcelain=v2 call rather than the four processes oh-my-zsh's helpers spend, so a prompt in a repository costs about 15 ms instead of 73, and a prompt outside one costs half a millisecond instead of the same 73.

Install

git clone https://github.com/eishexac/omzppuccin.git ~/omzppuccin

Then pick whichever line matches how you load things.

Oh My Zsh — as a theme:

ln -s ~/omzppuccin/omzppuccin.zsh-theme ~/.oh-my-zsh/custom/themes/omzppuccin.zsh-theme
ZSH_THEME="omzppuccin"

ZSH_THEME="catppuccin" still works — the old filename is kept as a shim, since the project shipped under it. Switch when convenient.

zinit / antidote / zplug / sheldon — as a plugin:

zinit light eishexac/omzppuccin
antidote bundle eishexac/omzppuccin

Plain zsh, no framework:

fpath+=(~/omzppuccin)
autoload -Uz promptinit && promptinit
prompt omzppuccin

Or just source it:

source ~/omzppuccin/omzppuccin.zsh

All four load the same implementation. The prompt and the omzppuccin command are deliberately one thing: the configurator previews by expanding the live PROMPT in your shell, which a separate process could not do.

omzp is an alias for omzppuccin, with the same completions.

Fonts

No font is required. One optional setting needs one: omzppuccin symbol context draws an icon of the machine you're on, and those live in the Nerd Fonts private-use area.

brew install --cask font-sauce-code-pro-nerd-font   # macOS

Everything else is ordinary Unicode, but coverage varies more than you'd expect. Checking Source Code Pro's Nerd Font build, which is a typical programming font:

in a programming font example
Box drawing essentially always ╰──╼ └──╼ ┗━━╸ ╔═╗
Latin-1 always » $ #
Dingbats often missing ➜ ✔ ✗ ✘ ➤

So the tail presets arc, parrot, short and heavy are the safe ones, and guillemet is safest of all. The default ➜ ✔ ✗ markers are dingbats and are frequently supplied by system fallback rather than by your terminal font — which works fine, and is why every glyph carries a %N{…%} width hint: a fallback face can have a different advance width, and without the hint zsh would lose track of the cursor column.

Over SSH the font that matters is the one on the machine you're typing at. Terminal emulators render text locally, so a remote box needs no fonts at all.

Settings were CATPPUCCIN_*

They're OMZP_* now, since the palettes are no longer all Catppuccin. The old names still work — anything set under one is copied across at load, and an explicit OMZP_* wins over its CATPPUCCIN_* counterpart. omzppuccin save writes the new names.

Changing settings

omzppuccin on its own opens a configurator. Arrow keys move and change; the preview at the top is your real prompt, rebuilt on every keystroke:

  ╔═╗╔╦╗╔═╗╔═╗╔═╗╦ ╦╔═╗╔═╗╦╔╗╔
  ║ ║║║║╔═╝╠═╝╠═╝║ ║║  ║  ║║║║
  ╚═╝╩ ╩╚═╝╩  ╩  ╚═╝╚═╝╚═╝╩╝╚╝

    ➜ hexac ~/coding/hexac/omzppuccin git:(main) ✗
    ╰──╼

  › style        line  elbow  bare  rail  ledge
    flavor       mocha
    tail         arc
    tail-color   auto
    …

  ↑↓ move   ←→ change   e edit   s save   d defaults   q done
Key
↑ ↓ move between settings
← → change the selected one
e edit a text field (sep, badge-text)
s save to ~/.zshrc
d back to defaults
q done

Changes apply to the running shell the moment you make them, and last only for that shell until you press s. omzppuccin status prints the settings instead of opening the menu, and is what you get in a script or a pipeline.

Three commands draw options instead of listing them, so you choose by looking:

omzppuccin styles     # every style, rendered with your settings
omzppuccin flavors    # every flavor, rendered with your settings
omzppuccin tails      # every tail preset, side by side

omzppuccin preview draws a configuration without applying it — after a command that worked and after one that exited 127, so you can see both halves of the exit-status coloring:

omzppuccin preview OMZP_STYLE=rail OMZP_FLAVOR=latte

Previews inherit the real session, so an SSH shell previews red anchors and a root shell previews yellow ones. What you see is what you get.

It also reconfigures the prompt in the running shell — no restart, no editing files to try something out:

omzppuccin flavor latte     # applies to the next prompt drawn
omzppuccin flavor celestial
omzppuccin badge off
omzppuccin host ssh
omzppuccin path truncated
omzppuccin help             # every command

Changes last as long as the shell. To keep them:

omzppuccin save             # writes to ~/.zshrc

save writes only the settings that differ from the defaults, into a managed block placed above whatever line loads the prompt — source $ZSH/oh-my-zsh.sh, a zinit/antidote line, promptinit, or a plain source of the file itself. The settings are read as the prompt loads, so anything below that line would be too late. It backs the file up to ~/.zshrc.omzppuccin.bak first. Anything inside the block is replaced on the next save; the rest of your .zshrc is left alone.

Command Values
flavor mocha | macchiato | frappe | latte | celestial | cyberpunk
style line | elbow | bare | rail | ledge
tail preset name or any string
tail-color auto | palette color name | #rrggbb
prompt-char auto | off | any string, plus an optional root variant
prompt-char-color auto | status | session | role name | #rrggbb
symbol arrow | context | none
gap 1–4
badge on | off
badge-text any string
badge-color #rrggbb | auto
host never | ssh | always
sep any string, plus an optional root variant
path short | full | truncated
path-dim on | off
git classic | bare
user on | off
time on | off
blank-line auto | on | off
exit-code off | inline | right
exec-time seconds
tails styles flavors — (draw the options)
preview KEY=VALUE …
menu status logo —
save optional file path
reset —

Tab-completion is available for every command and value.

Styles

line is the original prompt and stays the default. Everything below is opt-in, and every setting added alongside these styles is off until you turn it on.

omzppuccin style elbow
Style Shape
line ➜ [ssh] user directory git:(main) ✔
elbow context row, then a corner and stem ending in the tail
bare context row, then the tail alone — a blank line separates the blocks
rail a background-colored cell at column 0 on both rows
ledge one line, with the identity right-aligned instead of leading

The framed styles exist to solve one problem: when you scroll back through a few thousand lines of output, you need to find where each command started. A frame is an anchor, and an anchor is worth its columns.

Under rail the anchor is a background-colored space rather than a glyph, so there is nothing to render at the wrong width and nothing a program's own output can imitate. Its color is a free channel — grey on a local shell, red over SSH, yellow as root — which is the whole job of the [ssh] badge at no cost in columns. elbow colors its stem the same way.

Under every style but line, the icon and the [ssh] badge lead the context row — the same place the icon sits today, next to what it describes. The tail below is structural, and is drawn in two colors: the stem recedes with the rest of the frame, and the tip takes the tail color. Exit status stays with the icon, so the two marks never compete over the same channel.

Tails

The corner and stem drawn under elbow; bare draws the tip alone. Run omzppuccin tails to see each one rendered as a real prompt.

Preset Tail Notes
arc ╰──╼ the default
parrot └──╼ box-drawing throughout
short ╰─╼ one stem segment
heavy ┗━━╸ heavy weight end to end
angle ╰─ ❯ gapped, see below
head ╰─➤ flat-backed, so it butts cleanly
guillemet ╰─» Latin-1, present in every font
classic ╰─$ the shell's own character as a stem
tree `-> pure ASCII, after tree(1)
minimal ╰❯ no stem, so no seam

Box-drawing characters are designed to tile: they meet edge to edge at an exact vertical center in any font, which is why └──╼ looks solid. An ornament like ❯ is not, and butted against ─ the stem disappears into the chevron's open notch — so those presets carry their own gap instead.

Any string works too, and its last character becomes the tip:

omzppuccin tail '╰━━▶'
omzppuccin tail arc

Prompt character

OMZP_PROMPT_CHAR="auto"        # auto (default) | off | any string
OMZP_PROMPT_CHAR_ROOT=""       # counterpart when running as root
OMZP_PROMPT_CHAR_COLOR="auto"  # auto | status | session | role | #rrggbb

auto is $, and # when you're root — the way sh has done it since the seventies. It closes the input line under every style but line:

➜ hexac@htb-brcong4yib ~/coding/hexac/omzppuccin main ✔
╰──╼ $

bare has no frame to hang it from, so the character stands on its own there; if you turn it off, the tail's tip steps in so the input line is never blank.

prompt-char-color
auto plain text, and the error color the moment it becomes a #
status green or red, by how the last command ended
session the tail tip's color — accent, red over SSH, yellow as root
a role name accent, path, err… follows whichever palette you're on
#rrggbb pinned

auto tracks privilege, because that's the one signal the character itself already reflects — $ becomes #, and the color is what makes you notice. Both are left to zsh's %(!…), so they follow privilege as the prompt is drawn. sudo -i and su start a new shell anyway, but a privileged shell can drop itself by assigning to EUID, and this is the convention that exists to show that. A custom character stays resolved at build time, since one containing a . would split the ternary's delimiter. Everything else is spoken for: exit status belongs to the icon a row above, and the session to the tail's tip. status is there if you'd rather have the conventional green/red under your cursor anyway.

omzppuccin prompt-char '»' '#'   # your own, with a root counterpart
omzppuccin prompt-char off

Tail color

OMZP_TAIL_COLOR="auto"  # auto (default) | palette color name | #rrggbb

auto is sapphire on a local shell, red over SSH, yellow as root — so the tip doubles as the session indicator, and the [ssh] badge becomes optional.

Sapphire because it is the one cool tone the prompt does not already spend: green and red are the exit status, blue is the path, peach the branch, pink the user, mauve the host, teal the git:() wrapper, yellow a dirty tree. Any other palette name works — omzppuccin tail-color teal — and tracks the flavor when you switch it.

Configuration

Everything above is also settable directly. Add any of these to your ~/.zshrc below ZSH_THEME="omzppuccin" and above source $ZSH/oh-my-zsh.sh — the prompt reads them as it loads, so anything after that line is too late:

Flavor

OMZP_FLAVOR="mocha"  # mocha (default) | latte | frappe | macchiato | celestial | cyberpunk

Palettes are discovered from flavors/, so dropping a file in is the whole of adding one. omzppuccin flavors draws each one as a real prompt.

Palettes

The prompt never names a color. It names a role, and a palette decides which of its colors fills each one — so a palette with no rosewater and no mauve can still describe a prompt completely.

Role Role
text what you type dim what recedes
muted secondary labels frame the tail's stem
user username host hostname
path working directory branch the git branch
git the git:() wrapper stash the stash count
ok success warn a dirty tree
err failure accent the tail's tip
alt the root separator info spare, used by the wordmark

A Catppuccin flavor file lists its 26 colors and the theme maps those onto the roles, so the four flavor files are unchanged. A palette that isn't Catppuccin fills the roles itself:

# flavors/mine.zsh
_omzp_roles_native=true
_omzp_is_light=false

_omzp_text="#d5d8da"
_omzp_path="#26bbd9"
_omzp_accent="#ee64ac"
# …

_omzp_is_light matters: a light palette's dim needs one more step away from the background than a dark one's to stay readable. Declaring it means the rule applies to any light palette rather than being hardcoded for latte.

tail-color and badge-color take role names, so omzppuccin tail-color accent follows whichever palette you switch to. Catppuccin's own color names still work where they exist — sapphire resolves on a Catppuccin flavor and falls back to accent elsewhere.

Celestial

The JetBrains theme of the same name, a Horizon-family palette. Values read out of the plugin's own color scheme rather than sampled by eye:

text #d5d8da dim #6c6f93 user #e95678 host #ffb373
path #fab795 branch #d2d922 git #25b0bc stash #fac29a
ok #29d398 warn #f09483 err #f43e5c accent #ee64ac

Celestial is a warm theme — crimson, salmon, rose and peach outnumber everything else in its scheme by a wide margin, and cyan is the counterpoint rather than the lead. The roles follow that: the path takes peach, identity takes rose and orange, and cyan appears only in the git:() wrapper. Magenta takes accent because it's the one hue nothing else spends.

Style and tail

OMZP_STYLE="line"       # line (default) | elbow | bare | rail | ledge
OMZP_TAIL="icon"        # icon (default), a preset name, or any string
OMZP_BLANK_LINE="auto"  # auto (on under 'bare') | on | off

Path display

OMZP_PATH="short"    # short (default) | full | truncated
OMZP_PATH_DIM=false  # false (default) | true
Mode Example
short project
full ~/coding/hexac/project
truncated ~/cod…/hex…/project

PATH_DIM dims the parent directories so a long path reads as its last component without being shortened — which is what makes full comfortable to leave on.

The dim step is chosen per flavor rather than by one token name. Catppuccin's overlay ramp always moves away from base, so overlay0 recedes in every flavor, but not by the same amount: against mocha's near-black base it sits around 3:1, and against latte's near-white base it drops to roughly 2:1 and stops being readable. Latte therefore takes overlay2 instead.

Git segment

OMZP_GIT_STYLE="classic"  # classic (default) | bare

classic is git:(main ✔). bare drops the wrapper and lets the color mark the boundary, leaving main ✔ — two spaces and a hue change already read as a new segment.

Exit status

OMZP_EXIT_CODE="off"  # off (default) | inline | right

A red prompt symbol says something broke; ✘ 127 says it was a missing binary rather than a failed test. It's already sitting in $?.

Mode Where
off nowhere
inline beside the prompt icon
right right-aligned, next to the execution time

right reads best: both facts describe the command that just finished, so both recede to the same edge and leave the prompt itself alone.

➜ hexac@htb-brcong4yib ~/coding/hexac/omzppuccin main ✔      ✘ 127 3m12s
╰──╼ $

Nothing is printed when the last command succeeded — not even the space that would separate it from the time. The padding lives inside the %(?..) conditional, so it disappears along with the rest.

Separator

OMZP_SEP="@"        # "@" (default) — any string
OMZP_SEP_ROOT=""    # optional replacement when running as root
omzppuccin sep ' ☺ ' ' ☠ '

SSH badge

Remote sessions get a badge next to the prompt symbol, so you always know when you're on someone else's machine. It's on by default.

➜ [ssh] user directory git:(main) ✔
OMZP_SSH_BADGE=true          # true (default) | false
OMZP_SSH_BADGE_TEXT="[ssh]"  # any string
OMZP_SSH_BADGE_COLOR="#f38ba8"

A text badge is deliberate: it needs no special font, and a word reads at a glance in a way a glyph doesn't. OMZP_SHOW_HOST="ssh" pairs well with it, adding which machine you're on.

The session is detected from SSH_CONNECTION, SSH_CLIENT or SSH_TTY — the latter two catch shells where the first got dropped, such as after su or sudo -i.

Prompt icon

By default the prompt opens with ➜, colored green or red by the last command's exit status. Setting context swaps it for an icon of the machine you're on:

OMZP_PROMPT_ICON="arrow"  # arrow (default) | context
Context Nerd Font name Codepoint
SSH session nf-fa-server U+F233
macOS nf-fa-apple U+F179
Linux nf-fa-linux U+F17C
Windows (Cygwin/MSYS) nf-fa-windows U+F17A
Anything else ➜ U+279C

This mode needs a Nerd Font — without one the glyphs render as empty boxes. On macOS: brew install --cask font-sauce-code-pro-nerd-font. The glyphs above sit in the Font Awesome block, which is unchanged between Nerd Fonts v2 and v3. SSH takes precedence over the OS icon, and the exit-status coloring is the same as the arrow's.

Each icon is overridable — any string works, so you can swap in a distro logo, an ethernet port, or plain text:

OMZP_ICON_SSH=$'\U000f0200'   # nf-md-ethernet, a literal port (Nerd Fonts v3 only)
OMZP_ICON_MACOS=$'\uf8ff'     # Apple logo; renders on macOS even without a Nerd Font
OMZP_ICON_LINUX="[linux]"     # plain text works too

Username and hostname

OMZP_SHOW_USER=true    # true (default) | false
OMZP_SHOW_HOST="never" # never (default) | ssh | always
SHOW_HOST Behavior
never Hostname hidden
ssh Hostname shown only in SSH sessions
always Hostname always shown

Show time

OMZP_SHOW_TIME=true  # false by default

Command execution time

Long-running commands display their elapsed time on the right side of the prompt.

OMZP_EXEC_TIME_THRESHOLD=5  # seconds (default: 5)

Prompt

➜ [ssh] user directory git:(branch) ✔↑         5s
  • Green/red prompt symbol based on last command exit status, optionally an OS/SSH icon
  • [ssh] badge on remote sessions
  • Optional timestamp
  • Configurable username and hostname
  • Configurable path display
  • Git branch with clean/dirty indicator
  • Git ahead (↑) / behind (↓) remote indicators
  • Git stash count (≡)
  • Command execution time (right-aligned, for commands exceeding threshold)

Credits

The prompt began as catppuccin-zsh by JannoTjarks.

Palettes

Catppuccin — mocha, macchiato, frappé and latte are the Catppuccin palettes, by the Catppuccin org and its contributors, used under the MIT license.

Celestial — by Alex Adewole, from the JetBrains IDE theme of the same name. The values here were read out of the plugin's own color scheme rather than sampled from screenshots, so they are the theme's actual colors. Celestial belongs to the Horizon family; the palette is reproduced here for use in a terminal prompt, and all credit for the color work is theirs.

Neither project is affiliated with this one. If you are an author here and want a palette changed or removed, open an issue and it will be.

License

MIT

About

Catppuccin theme for Oh My Zsh with configurable flavors, path display, and git indicators

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages