Customize your ZSH-Prompt for Git and SSH [Update 1]

12 Jun

The Z-Shell is one of the most powerfull shells I know. Why not customize it to your needs? Mine looks like this:


Here are some explanations of the prompt:

  1. This is the default Prompt. It contains the username (cyan), the current directory (magenta) and the number of the next history entry (repeat cd .env by typing !2090). The green arrow means that the last command ended with the return code 0
  2. We switched into an SVN repository. The first line contains the name of the repository (yellow), the current branch (green) and the commit number (blue).
  3. The second line is merle the same as in 1…
  4. … but it now only contains the path inside the repository (magenta).
  5. This is a git repository; the information is the same:repository name, branch name and commit id
  6. Changes are indicated as circles: untracked is red, changes is yellow, staged is green
  7. Outside a repository, the full pathname is shown
  8. If we are on a remote machine (detemined by checking SSH_CLIENT) the hostname is added (yellow)
  9. The state of the battery and the result of the last command (either :-) or :-( is shown on the right)

I have to give some credits. Important parts and ideas are explained in a open source press book (german) and two blog posts from Bart Trojanowski and Matija Šuklje.

So here is the code:

# customize prompts
autoload -U promptnl
autoload -Uz vcs_info
setopt prompt_subst #allow function calls in prompt
if [[ $UID != 0 ]]; then
if [[ -z "$SSH_CLIENT" ]]; then
        prompt_host=%{$fg_bold[white]%}@%{$reset_color$fg[yellow]%}$(hostname -s)
common_fmt_prompt_post="%{$fg[white]%}[%!]%{$fg_bold[white]%}%1(j. (%j%).)%{%(?.$fg_bold[green].$fg_bold[red])%}${prompt_arrow}%{$reset_color%} "
common_fmt_post="%{$reset_color%}"$'\nâ•š'"${common_fmt_prompt_pre}%S ${common_fmt_prompt_post}"
native_prompt="${common_fmt_prompt_pre}%~ ${common_fmt_prompt_post}"
zstyle ':vcs_info:*:prompt:*' check-for-changes true
zstyle ':vcs_info:*:prompt:*' stagedstr     "%{$fg_bold[green]●%}"
zstyle ':vcs_info:*:prompt:*' unstagedstr   "%{$fg_bold[yellow]●%}"
zstyle ':vcs_info:*:prompt:*' nvcsformats   "${native_prompt}"
zstyle ':vcs_info:*:prompt:*' branchformat  "%b"
zstyle ':vcs_info:*' enable git svn
zstyle ':vcs_info:*:prompt:*' get-revision 'true'
function precmd  {
        if [[ -n "$UPDATE_PROMPT" || -n "$UPDATE_PROMPT_ONCE" ]]; then
                if [[ -z $(git ls-files --other --exclude-standard -- $(git rev-parse --show-cdup 2>/dev/null) 2>/dev/null) ]] {
                } else {
                common_fmt_pre="â•”%{$fg[red]%}%s%{$fg[white]%}:%{$fg[yellow]%}%r%{$fg[white]%}[%{$fg_bold[green]%}%b%{$fg[white]%}:%{$fg[blue]%}%i%{$reset_color$fg[white]%}] %c%u$untracked%{$reset_color%}"
                zstyle ':vcs_info:*:prompt:*' actionformats "${common_fmt_pre} $fg[cyan](%a) ${common_fmt_post}"
                zstyle ':vcs_info:*:prompt:*' formats       "${common_fmt_pre} ${common_fmt_post}"
                vcs_info 'prompt'
faster() { UPDATE_PROMPT= }
slower() { UPDATE_PROMPT=1 }
function u {
setopt transient_rprompt #remove rprompt after enter
if type test >/dev/null && acpi -b 2>/dev/null | grep 'Battery 0' >/dev/null; then
        RPROMPT='[$(acpi -b | sed "s/.* \([0-9]\+\)%.*/\1/")%%] '"%(?.%{$fg_bold[green]%}:-%).%{$fg_bold[red]%}:-()%{$reset_color%}"
SPROMPT="zsh: correct %R to %r? ([Y]es/[No]/[E]dit/[A]bort) "


The lines 6-16 are workarounds, because %m and (!.⇒.→) did not work correctly with vcs_info (i.e. vcs_info stores different information in %m). The lines 18-29 define most of the left prompt. The function precmd is executed before each command and updates the variable parts of the prompt. The lines 48-55 are for slower environments like cygwin: typing faster does not update the prompt until you change your directory or type u, while slower restores the default behaviour. Line 57 defines the result of vcs_info_msg_0_ as your prompt (vcs_info constructs this string).

The Lines 59-64 define the right part of the prompt (item 9 in the screenshot). The battery state is only shown if a battery exists.

Take this as an idea what is possible with your prompt. If you add other cool features or find faster solutions, just drop me a line smiley

Update 1: Changed condition in line 33 so that the whole repository is scanned for new files.

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht.