How can I change the color of my prompt in zsh (different from normal text)?

Viewed 260791

To recognize better the start and the end of output on a commandline, I want to change the color of my prompt, so that it is visibly different from the programs output. As I use zsh, can anyone give me a hint?

12 Answers

Zsh comes with colored prompts builtin. Try

autoload -U promptinit && promptinit

and then prompt -l lists available prompts, -p fire previews the "fire" prompt, -s fire sets it.

When you are ready to add a prompt add something like this below the autoload line above:

prompt fade red

Here's an example of how to set a red prompt:

PS1=$'\e[0;31m$ \e[0m'

The magic is the \e[0;31m (turn on red foreground) and \e[0m (turn off character attributes). These are called escape sequences. Different escape sequences give you different results, from absolute cursor positioning, to color, to being able to change the title bar of your window, and so on.

For more on escape sequences, see the wikipedia entry on ANSI escape codes

The answer by Bryan Oakley above has a glitch as it has already been pointed out and the solution offered by Andrew Marshall though it does not carry the glitch, nevertheless it does not make it obvious for too much customization on the colors used.

As macOS Catalina asks for zsh to be the default shell from now on, I think several more people may want to customize their prompt and might be coming here for an answer. So, I thought I would try to give a broader summary and touch upon other very closely-related notions that allow more customization.

3-Digit Codes for Various Colors. First of all, here we can find 3-digit codes for various colors: https://unix.stackexchange.com/a/124409/194343. For example, 214 is some kind of orange color.

Foreground and Background. The other key information is that for Foreground and bacKground colors one can define what they want with F and K respectively. Source is zsh manual on visual effects: http://zsh.sourceforge.net/Doc/Release/Prompt-Expansion.html#Visual-effects

So, for example, the following two commands

autoload -U colors && colors
export PS1="%F{214}%K{000}%m%F{015}%K{000}:%F{039}%K{000}%~%F{015}%K{000}\$ "

present the hostname in orange with black background, followed by a colon in white with black background, followed by the current working directory in bright blue with black background, followed by the dollar sign in white with black background.

More related information is found below.

Prompt information on the right-hand side. For example, adding a timestamp. See https://superuser.com/a/1251045/290299. Of course, this can be color-coded, for example with some light blue/purple-ish color, like this:

RPROMPT="%F{111}%K{000}[%D{%f/%m/%y}|%@]"

Colors for ls. After reading the manual for ls, one for example can activate the colors for ls using the following two commands:

export CLICOLOR=1
export LSCOLORS=gafacadabaegedabagacad

Finally, as a last remark that I have not tested as I am happy with my configuration, another avenue might be for someone to install the port coreutils from MacPorts and then use gdircolors (source: https://unix.stackexchange.com/a/174596/194343). (I may edit this last part in the future as all the above are related pieces that make every-day life much more fun and easier to cope with.)

Try my favorite: put in

~/.zshrc

this line:

PROMPT='%F{240}%n%F{red}@%F{green}%m:%F{141}%d$ %F{reset}'

don't forget

source ~/.zshrc

to test the changes

you can change the colors/color codes, of course :-)

In order to not waste space in the terminal with special characters to pieces of information, you can differentiate information using multiple colors.

Eg. in order to get this desired effect:

Desired Outcome

You can do the following to your prompt:

PROMPT='%F{magenta}${PWD/#$HOME/~} %F{green}${vcs_info_msg_0_} %F{cyan}$%F{reset_color} '

The way it works is every time you set a color using $F{myColor} the color from that point onward will stick to that. It's important to add in %{reset_color} at the end so that the input text goes back to the original color (or you could set it to something else if you'd like).

To get a prompt with the color depending on the last command’s exit status, you could use this:

PS1='%(?.%F{green}.%F{red})%n@%m:%~%# %f'

Just add this line to your ~/.zshrc.

The documentation lists possible placeholders.

To complement all of the above answers another convenient trick is to place the coloured prompt settings into a zsh function. There you may define local variables to alias longer commands, e.g. rc=$reset_color or define your own colour variables. Don't forget to place it into your .zshrc file and call the function you have defined:

# Coloured prompt
autoload -U colors && colors
function myprompt {
  local rc=$reset_color
  export PS1="%F{cyan}%n%{$rc%}@%F{green}%m%{$rc%}:%F{magenta}%~%{$rc%}%# "
}
myprompt

Debian/Ubuntu/Raspberry Pi OS style bash prompt:

autoload -U colors && colors
PS1="%B%F{034}%n@%m%f%b:%B%F{019}%~ %#%f%b "

Screen shot

Not entirely sure if autoload -U colors && colors is necessary but I did need it when I was using $fg[...] instead of %F{...}.
In my example;

  • %F(%f) starts(stops) foreground color - I've used 256COLOR values but you could also use hex for example, I've used normal green %F{034} but %F{#00aa00} works too
  • %B(%b) starts(stops) bold
  • %n $USERNAME
  • %m short machine name
  • %~ logged in/working directory with ~ if in home directory
  • %# display % if normal user or # if su
Related