Now that Zsh is now the default shell on macOS, i figured it was a good time to install oh-my-zsh and give it another go. And obviously, i immediately wanted to customize my prompt. So i ended up going through the process of creating a custom Zsh theme..
I need a minimalist prompt with
Something like this:
--------------------------------------------------------------------------------
$ mysite.com (master) Sat 2, 15:39
and i ended up with this
code is here on Github
set the theme to random
1# ~/.zshrc
2ZSH_THEME="random"
every time you like a prompt, run echo $PROMPT
to get the prompt string value for the current theme and copy it. If you want to check the name of the theme, run echo -e ${ZSH_THEME}
I immediately liked af-magic when i came across it, it was similar to what i wanted so i based my custom theme on it
Themes are located in a themes
folder and must end with .zsh-theme
. The basename of the file is the name of the theme.
zsh_custom
└── themes
└── amnastic.zsh-theme
Then edit your .zshrc
to use that theme.
1ZSH_THEME="amnastic"
You can find all of these under the Login information heading when you man zshmisc
. Here’s a quick cheatsheet
%n - username
%m - short name of curent host
%M - name of curent host
%# - a `%` or a `#`, depending on whether the shell is running as root or not
%~ - relative path
%/ or %d - absolute path
%c or %C - Trailing component of the current working directory.
%t - time 12hr am/pm format
%T - time 24hr format
%w - day and date (day-dd)
%D - Date (default: yy-mm-dd)
%D{%f} - day of the month
%l or %y - The line (tty) the user is logged in on, without `/dev/' prefix.
You can check the value of any of these arguments with -P
to the print
command
1print -P %n # aamnah
2print -P %m # Serenity
3print -P %M # Serenity.local
4
5print -P %# # %
6print -P '%(!.#.$)' # $
7
8print -P %~ # ~/Documents
9print -P %c # Documents
10print -P %/ # /Users/aamnah/Documents
11
12print -P %t # 8:44PM
13print -P %T # 20:44
14print -P %w # Sat 2
15print -P %D # 20-05-02 yy-mm-dd
16print -P %W # 05/02/20 mm/dd/yy
17print -P %D{%f} # 2
18
19print -P %l # s001
You can have a prompt to the right with RPROMPT
or RPS1
1RPROMPT=' %{$gray%}%T%{$reset_color%}'
You can use 256-colors if supported, which they are on macOS Cataline (what i am on right now). You can create an if
block to set fallbacks. Use 256 color if available, or use these..
1#use extended color palette if available
2if [[ $terminfo[colors] -ge 256 ]]; then
3 turquoise="%F{81}"
4 orange="%F{166}"
5 purple="%F{135}"
6 hotpink="%F{161}"
7 limegreen="%F{118}"
8else
9 turquoise="%F{cyan}"
10 orange="%F{yellow}"
11 purple="%F{magenta}"
12 hotpink="%F{red}"
13 limegreen="%F{green}"
14fi
Colors are represented as %F{237}
or %F{red}
or $FG[237]
or $fg[red]
. All are valid formats. The reset for the color value can change based on the format you use
%F{237}
256 color number%F{red}
8 color name (black, red, green, yellow, blue, magenta, cyan, white)$FG[237]
(notice the $
sign instead of %
) 256 color number$fg[red]
(notice the $
and lower case fg
) 8 color name (black, red, green, yellow, blue, magenta, cyan, white)%{$fg_bold[blue]%}
bold variants%F
is Foreground color, $f
for resetting foreground color
%K
is bacKground color, %k
for resetting background color
$reset_color
is a Zsh variable that resets the color of output
You can use unicode for symbols
%E
Clear to end of line.
%U
(%u)
to Start (stop) underline mode.
You can check out how a color looks with:
1# change the value of 237 below to any one of 256-color
2print -P '%F{237} %m %f'
You can use $(git_prompt_info)
to show git branch and whether it is dirty or not. It’s a function that comes buit in with oh-my-zsh.
You can find all git functions in ~/.oh-my-zsh/lib/git.zsh
1$(git_prompt_info) # Outputs current branch info in prompt format
2$(parse_git_dirty) # Checks if working tree is dirty
3$(git_remote_status) # Gets the difference between the local and remote branches
4$(git_current_branch) # Outputs the name of the current branch
5$(git_commits_ahead) # Gets the number of commits ahead from remote
6$(git_commits_behind) # Gets the number of commits behind remote
7$(git_prompt_ahead) # Outputs if current branch is ahead of remote
8$(git_prompt_behind) # Outputs if current branch is behind remote
9$(git_prompt_remote) # Outputs if current branch exists on remote or not
10$(git_prompt_short_sha) # Formats prompt string for current git commit short SHA
11$(git_prompt_long_sha) # Formats prompt string for current git commit long SHA
12$(git_prompt_status) # Get the status of the working tree
13$(git_current_user_name) # Outputs the name of the current user
14$(git_current_user_email) # Outputs the email of the current user
15$(git_repo_name) # Output the name of the root directory of the git repository
git_prompt_info
can further be customized with plenty of ZSH_THEME_GIT_PROMPT_
variables that let you customize things like prefix and suffix and much more
1ZSH_THEME_GIT_PROMPT_PREFIX="$FG[075]($FG[078]"
2ZSH_THEME_GIT_PROMPT_CLEAN=""
3ZSH_THEME_GIT_PROMPT_DIRTY="$my_orange*%{$reset_color%}"
4ZSH_THEME_GIT_PROMPT_SUFFIX="$FG[075])%{$reset_color%}"
5
6ZSH_THEME_GIT_PROMPT_ADDED="%{$fg[cyan]%} ✈"
7ZSH_THEME_GIT_PROMPT_MODIFIED="%{$fg[yellow]%} ✭"
8ZSH_THEME_GIT_PROMPT_DELETED="%{$fg[red]%} ✗"
9ZSH_THEME_GIT_PROMPT_RENAMED="%{$fg[blue]%} ➦"
10ZSH_THEME_GIT_PROMPT_UNMERGED="%{$fg[magenta]%} ✂"
11ZSH_THEME_GIT_PROMPT_UNTRACKED="%{$fg[grey]%} ✱"
Here is a list of all the variables that you can use to customize $(git_prompt_info)
1ZSH_THEME_GIT_COMMITS_AHEAD_PREFIX
2ZSH_THEME_GIT_COMMITS_AHEAD_SUFFIX
3ZSH_THEME_GIT_COMMITS_BEHIND_PREFIX
4ZSH_THEME_GIT_COMMITS_BEHIND_SUFFIX
5ZSH_THEME_GIT_PROMPT_ADDED
6ZSH_THEME_GIT_PROMPT_AHEAD
7ZSH_THEME_GIT_PROMPT_AHEAD_REMOTE
8ZSH_THEME_GIT_PROMPT_AHEAD_REMOTE_COLOR
9ZSH_THEME_GIT_PROMPT_BEHIND
10ZSH_THEME_GIT_PROMPT_BEHIND_REMOTE
11ZSH_THEME_GIT_PROMPT_BEHIND_REMOTE_COLOR
12ZSH_THEME_GIT_PROMPT_CLEAN
13ZSH_THEME_GIT_PROMPT_DELETED
14ZSH_THEME_GIT_PROMPT_DIRTY
15ZSH_THEME_GIT_PROMPT_DIVERGED
16ZSH_THEME_GIT_PROMPT_DIVERGED_REMOTE
17ZSH_THEME_GIT_PROMPT_EQUAL_REMOTE
18ZSH_THEME_GIT_PROMPT_MODIFIED
19ZSH_THEME_GIT_PROMPT_PREFIX
20ZSH_THEME_GIT_PROMPT_REMOTE_EXISTS
21ZSH_THEME_GIT_PROMPT_REMOTE_MISSING
22ZSH_THEME_GIT_PROMPT_REMOTE_STATUS_DETAILED
23ZSH_THEME_GIT_PROMPT_REMOTE_STATUS_PREFIX
24ZSH_THEME_GIT_PROMPT_REMOTE_STATUS_SUFFIX
25ZSH_THEME_GIT_PROMPT_RENAMED
26ZSH_THEME_GIT_PROMPT_SHA_AFTER
27ZSH_THEME_GIT_PROMPT_SHA_BEFORE
28ZSH_THEME_GIT_PROMPT_STASHED
29ZSH_THEME_GIT_PROMPT_SUFFIX
30ZSH_THEME_GIT_PROMPT_UNMERGED
31ZSH_THEME_GIT_PROMPT_UNTRACKED
You need to set the prompt string with single quotes ' '
1PS1='%{$blue%}%c %{$purple%}%(!.#.») %{$reset_color%}'
above code will work just fine, whereas
1PS1="%{$blue%}%c %{$purple%}%(!.#.») %{$reset_color%}"
will show proper syntax highlighting in code editor, but will not update git when directory is changed. The double quotes make the variables in PROMPT to get evaluated when sourcing .zshrc
and that’s an issue.
That’s a big issue to be honest, because it applies for not just the theme, it applies for all files in the custom/
folder. This gave me a hard time after having copied over code from my .bash_aliases
. Some aliases there defined with double quotes made my git prompt stopped working again.
The following will cause issues
1## Recursively delete `.DS_Store` files
2alias cleanup="find . -type f -name '*.DS_Store' -ls -delete"
3
4## Kill all the tabs in Chrome to free up memory
5# [C] explained: http://www.commandlinefu.com/commands/view/402/exclude-grep-from-your-grepped-output-of-ps-alias-included-in-description
6alias chromekill="ps ux | grep '[C]hrome Helper --type=renderer' | grep -v extension-process | tr -s ' ' | cut -d ' ' -f2 | xargs kill"
Had to flip the single and double arrangement: single quote outside, double quote inside
1## Recursively delete `.DS_Store` files
2alias cleanup='find . -type f -name "*.DS_Store" -ls -delete'
3
4## Kill all the tabs in Chrome to free up memory
5# [C] explained: http://www.commandlinefu.com/commands/view/402/exclude-grep-from-your-grepped-output-of-ps-alias-included-in-description
6alias chromekill='ps ux | grep "[C]hrome Helper --type=renderer" | grep -v extension-process | tr -s " " | cut -d " " -f2 | xargs kill'