Home » Questions » Computers [ Ask a new question ]

how to format the path in a zsh prompt?

how to format the path in a zsh prompt?

I would love to have a readable colored path. For example, instead of simply using %~ to return ~/path/to/foo I would like to format it to ~$RED/$NOCOLORpath$RED/$NOCOLORto$RED/$NOCOLORfoo to highlight the path separators.

Asked by: Guest | Views: 347
Total answers/comments: 2
bert [Entry]

"zsh

Try this:

setopt PROMPT_SUBST
PROMPT='%{$(pwd|grep --color=always /)%${#PWD}G%} %(!.%F{red}.%F{cyan})%n%f@%F{yellow}%m%f%(!.%F{red}.)%#%f '

Here's a breakdown of the prompt:

PROMPT_SUBST turns on command substitution in the prompt (and parameter expansion and arithmetic expansion)
%{...%} - an escape sequence
$(pwd|grep --color=always /) - print the current directory and highlight the / - the color will depend on the $GREP_COLORS environment variable (or its default value) - bold red is the default
%${#PWD}G - use the length in characters of the name of the current directory as a glitch value. This makes the shell consider this the length of the preceding character sequence ( after the ""%{"" ) instead of the actual length of the string which includes ANSI escape sequences. This keeps the shell from being confused about the position of the cursor relative to the end of the prompt.
- - - - - - - this is the end of the part that answers your question - - - - - - -
%(!.%F{red}.%F{cyan}) - if this is a privileged shell (root) set the foreground color to red, otherwise cyan
%n - output the username
%f - reset the foreground color to the default
@ - a literal at sign
%F{yellow} - make the foreground color yellow
%m - output the hostname
%f - reset the foreground color to the default
%(!.%F{red}.) - if this is a privileged shell (root) set the foreground color to red
%# - output a # for a privileged shell or % for an unprivileged one
%f - reset the foreground color to the default

I put the path first in this prompt for emphasis, since the question concerns the path.

Here is a version for zsh that changes the slash color depending on whether you are root (privileged) by manipulating the $GREP_COLORS variable:

setopt PROMPT_SUBST
PROMPT='%{$(pwd|([[ $EUID == 0 ]] && GREP_COLORS=""mt=01;31"" grep --color=always /|| GREP_COLORS=""mt=01;34"" grep --color=always /))%${#PWD}G%} %(!.%F{red}.%F{cyan})%n%f@%F{yellow}%m%f%(!.%F{red}.)%#%f '

Bash

You can do a similar prompt in Bash. In this example, I've put the user and hostname first and the color of the slashes also changes when the UID is 0. Warning: this overwrites Bash's $PS1 prompt variable. That shouldn't be a problem unless you're doing something special or you expect the behavior to change when you set that variable directly and this is in effect. Also, this uses a variable called ""usercolor"" which may collide with something else, although this whole thing could be put in a function and the variable declared local.

PROMPT_COMMAND='usercolor=""\[\033[0;36m\]"";[[ $EUID == 0 ]] && usercolor=""\[\033[1;31m\]"";PS1=""$(pwd)"";PS1=""$usercolor\u\[\033[0m\]@\[\033[0;33m\]\h\[\033[0m\]:${PS1//\//$usercolor/\[\033[0m\]}$usercolor\\$\[\033[0m\] ""'

I took advantage of the fact that Bash doesn't have zsh's ""glitch"" feature to use parameter expansion substitution to conditionally color the slashes (instead of using grep)."
bert [Entry]

"A pure zsh solution:

PROMPT='%n@%m: %{$PR_BOLD_RED%}${${(%):-%~}//\//${PR_BOLD_RED}/%f}%f '

${(%):-%~} is the current path.
${xxxxx//\//${PR_BOLD_RED}/%f} replaces every / in xxxxx by a bold red colored one
and of course PROMPT_SUBST has to be on.

I had be using double quotes in my tests, which does not allow substitution. Everything works fine with single quotes."