The Z shell (zsh) offers advanced customization options for power users compared to bash or other shells. One of the most visible areas you can customize is your zsh prompt – the text, colors, and symbols that appear in your terminal before each command.
In this comprehensive 2600+ word guide, we‘ll cover:
- Components of the default zsh prompt and prompt syntax
- Customizing prompt content with expansion tags
- Adding colors, Git status, and other useful information
- Splitting your prompt into left and right sections
- Taking advantage of plugins and themes
- Formatting tips and best practices
- Saving your changes to your zshrc
Let‘s dive in and build the prompt of your dreams!
Anatomy of the Default Prompt
Understanding the default zsh prompt will help us customize it. In most installations, opening zsh shows something like:
user@hostname %
Where user
is your username, hostname
the system name, and %
indicates a regular user (vs root‘s #
).
This comes from the default prompt defined in zsh:
PROMPT=‘%n@%m %# ‘
Breaking this down:
%n
– Expansion tag for username%m
– Hostname up to the first.
character%#
– Prompt symbol (%
or#
)
Expansion tags like %n
dynamically print information when the prompt is rendered.
Now let‘s look at some other common tags:
Tag | Description | Example |
---|---|---|
%/ |
Base name of current working directory | projects |
%c |
Full cwd path | /home/user/projects |
%~ |
cwd relative to home folder | ~/projects |
%h |
Hostname up to 1st dot | mypc |
%H |
Full hostname | mypc.localdomain |
%t |
24-hour time | 23:59 |
%T |
12-hour time | 11:59pm |
%* |
Date | 2023-02-15 |
That covers some of the basic prompt syntax and tags, but many more are available for info like username, git details, exit status, etc. We‘ll use these later to build up a custom prompt.
First let‘s look at…
Customizing Prompt Content
The simple default prompt of username, hostname and prompt symbol leaves a lot to be desired. Let‘s start expanding that with some of the prompt tag covered earlier.
Showing our full path and time could be useful:
PROMPT=‘%n@%m:%~ %D{%t} %# ‘
Now when opening zsh we‘ll see something like:
user@mypc:/home/user/projects 23:59 %
The %~
tag prints our full cwd path relative to home, and %D{%t}
neatly formats the 24-hour %t
time.
We can build on this to include all kinds of contextual info:
PROMPT=‘%n@%m %1c %S [%D{%t}] %3b %# ‘
Breaking this down:
%n@%m
– Username and hostname%1c
– Full current working directory path%S
– Start standout mode (bold text)%D{%t}
– Time inside brackets%3b
– End standout mode after 3 characters%#
– Prompt symbol
For the current directory, using %1c
prints only the last folder name rather than the full path to keep things clean. The standout mode allows us to bold the time display.
With all those components, our prompt now looks like:
user@mypc projects [23:59] %
This gives us way more useful context than the default prompt!
Including Git Information
For developers or anyone using Git regularly, showing Git repo details in the prompt is extremely handy.
Some useful Git prompt expansion tags include:
%b
– Current branch name%c
– Short commit SHA hash%s
– Number of stashed changes%r
– Git repo root directory name
For example, we can update our prompt to this:
setopt prompt_subst
PROMPT=‘[%B%F{242}%~%f%b] %r (%b)%f:%c %D{%t} %# ‘
Breaking this down:
[
– Opening bracket%B%F{242}%~%f%b
– Current working dir in blue]
– Closing bracket%r
– Repo name(
%b
)
– Current Git branch in parentheses:
– Separator%c
– Full current working directory path- Rest same as before
Now when in a Git repo we‘ll see something like:
[myproject (main):] /home/user/projects 23:59 %
This shows we‘re on the main
branch within the myproject
repo. The color also helps the Git status stand out.
We could take this further with indicators for ahead/behind status, file changes status, etc. But this covers the basics of including useful Git details right in our prompt.
Expanding Right Prompt Content
So far everything has printed on one line before the cursor. But we can also split things into left and right prompt sections for more room.
The right prompt is configured by RPROMPT
, like so:
RPROMPT=‘%D{%Y-%m-%d}‘
This will simply print today‘s date on the right when we open zsh:
[myproject(main):] ~/projects 2023-02-15 %
Some other handy info for the right prompt:
- Current time
- Todo count from todo.txt
- Unread Gmail count via API call
- System load average
- Docker container details
- More Git stats likeahead/behind count
The left side shows shell context info, while the right works well for peripheral stats.
Now let‘s shift gears and explore…
Changing Prompt Colors and Formatting
So far our prompt contains good information, but the default white text on black background is a bit bland. Let‘s breathe some life into it with colors and text formatting.
Some useful formatting expansion tags are:
%K{color}
– Set background color%F{color}
– Set text color%B
– Start bold/bright mode%b
– End bold/standout mode
Where color
can be a name like red
, cyan
, etc. or an ANSI color code like 033
for yellow text.
Let‘s make our prompt red with bright white text:
PROMPT=‘%K{red}%F{white}%B%n@%m:%~ %D{%t}%b %# ‘
The %B
and %b
enable bold, which we wrap around the components we want to stand out.
This gives us:
user@mypc:/home/user/projects 23:11 %
The bold red/white prompt pops nicely against the terminal backgound.
We can also set different colors for each prompt section:
PROMPT=‘%K{240}%F{white}%B%n%b@%K{blue}%F{cyan}%B%m%b:%K{green}%F{black}%B%~%b %D{%t} %K{red}%F{yellow}%B%#%b ‘
Now the username, hostname, current directory, and prompt symbol each have their own color theme:
user@mypc:/home/user/projects 23:17 %
This distinguishes the individual components, while adding some visual appeal.
For a nice contrast against light IDE backgrounds, try an all-black prompt with white text. Or go crazy with your favorite color scheme!
When including Git status details, changing color based on repo state is also helpful:
PROMPT=‘%K{075}%F{white}%B$(git_prompt_info)%b%f ‘
Here git_prompt_info
will return repo details in a different color like red if there are uncommitted changes. This quickly flags the repo status when you glance at the prompt.
There are endless possibilities – the key is zsh provides fine-grained control to format prompts exactly how you like. Next let‘s look at…
Taking Advantage of Plugins and Frameworks
Manually customizing your prompt using expansion tags offers tons of flexibility. But for more preset options you can tap into prompt plugins and frameworks like:
-
Powerlevel10k – Popular zsh theme and framework with 10k+ stars on GitHub. Provides configuration wizard for installing a feature-packed prompt with icons, Git status, etc.
-
Spaceship ZSH – Modular zsh prompt with 3k+ stars on GitHub. Lean and fast with various info segments.
-
Starship – Fast cross-shell prompt written in Rust. Great performance and split section prompt model.
These "meta prompt frameworks" do the heavy lifting around color schemes, segment options, etc. allowing you to focus on tweaks and customization.
For example with Powerlevel10k, running p10k configure
launches an interactive wizard. You answer prompts about preferred style and features, and it handles installing the theme and assets.
So if you value convenience over control, leverage these prompt ecosystems for a more turnkey setup.
Moving forward let‘s go over…
Prompt Customization Tips and Best Practices
When pimping out your zsh prompt, keeping it clean and usable should balance aesthetics and fancy features. Here are some professional tips:
-
Separate sections clearly – Use spacing, brackets, or colors to delimit prompt segments like Git details, so status changes clearly stand out.
-
Consolidate where possible – To avoid prompt sprawl collapsing details (timezone, time, date) into one section saves space.
-
Be selective with icons – Icons can bring visual flair but also clutter. Choose intentional icons that are meaningful, not just decorative emoji.
-
Color code key details – Use color not just for beauty, but to highlight changes users should focus on like Git repo status.
-
Customize based on environment– Simplify prompts to minimalist details on production servers. Add more context-specific info locally like Python environment, cloud service namespaces, etc.
-
Keep responsive in terminal and logs – Avoid prompts that take up multiple lines and break text flow. Ensure prompts render properly when logged to files.
The end goal is balancing aesthetics with utility – your prompt should enrich your workflow rather than cause clutter and distraction.
Saving Your Changes in .zshrc
After all this tweaking and customizing, you definitely want your epic prompt to persist between sessions.
The solution is saving changes to your zsh config file.
Locate the hidden .zshrc
file in your home directory (likely ~/.zshrc
). Then open this file and add in any PROMPT=
, RPROMPT=
declarations or other lines changing prompt behavior.
For example, with our last prompt the contents would be:
PROMPT=‘%K{red}%F{white}%B%n@%m:%~ %D{%t}%b %# ‘
RPROMPT=‘%D{%Y-%m-%d}‘
Save and close the file, then run:
source ~/.zshrc
This reloads your zsh shell to apply the config changes, including prompt customizations.
Now whenever you open a new terminal or tab, you‘ll immediately see your awesome custom prompt without needing to change anything!
Conclusion and Additional Resources
I hope this 2600+ word guide has shown how deep yet user-friendly zsh prompt customization can be. With just a bit of knowledge of prompt expansion tags, you‘re free to include informative tidbits like the current directory, active Python version, Git status indicators, and more.
The formatting tags provide fine-grained control over color schemes and text formatting as well – you can build a prompt matching your personal sense of style. And splitting left/right prompt sections gives room to expand without cluttering one line.
To recap key points:
- Zsh offers many prompt expansion tags for dynamic context
- Tags like
%F{}
and%K{}
control text style and color - The right prompt configured via
RPROMPT
prints on the left - Changes can be saved to
~/.zshrc
for persistence
This should give you a framework for customizing prompts to your needs. But there‘s always more to explore! Here are some additional resources for tricking out your shell:
- Awesome Zsh Plugins – List of popular zsh plugins for all manner of features
- Pure Prompt – Minimal and fast prompt with excellent shell and tty support
- Powerlevel10k Customization – Additional details on tweaking Powerlevel10k themes
- /r/UnixPorn subreddit – Forum where users share their souped up Linux desktop rice configurations including terminal themes and prompts
Let me know if you have any other questions! I‘m always seeking feedback as well on prompt designs from UX and visual design perspectives.
Happy prompt customizing! Make your shell environment special.