My custom ZSH prompt

Some time ago, I posted my bash prompt. Since I am mostly using ZSH these days, I ported my prompt to ZSH and added some extras. After the old prompt was pretty popular I publish the new one in case somebody is interested.

“physos” prompt theme:

preview of the physos ZSH prompt theme

A preview of the physos zsh prompt theme

“physosvcs” prompt theme:

A preview of the physos VCS ZSH prompt theme

A preview of the physos zsh prompt theme with version control support

Both themes are based on the prompt theming included with ZSH. I got most of the syntax from the ZSH manpages (mainly zshcontrib(1) for the theming and VCS informations and zshmisc(1) for the prompt formatting)

Install Instructions

To install my prompt:

  1. download the prompt files:
    Archive of the physos and physosvcs ZSH prompt themes
  2. copy or link the prompt_physos*_setup files to /usr/share/zsh/[ZSH version here]/functions/
  3. Test it with:
    % autoload -U promptinit
    % prompt -p physos  # This gives you a preview of the prompt
    % prompt -h physos  # This gives you the help page
  4. Since the -s option of the prompt tool is not working yet, add the following lines to your .zshrc :

    autoload -Uz vcs_info

    if you want to use the VCS version of the prompt and

    setopt prompt_subst
    autoload -U promptinit
    promptinit
    prompt physos green white blue black

Code

I will highlight the significant parts. I learned most of the syntax from looking into other prompt_*_setup files, and the man pages.

Show the prompt_physos_setup code

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
# physos ZSH prompt theme by <rainer@physos.com>
# 
#
prompt_physos_help () {
  cat <<'EOH'
 
General Look
 
  [user@host][12:34]
  [~/] %                                                                                                                      
Options
 
  You can change the colours of the theme.
 
  % prompt physos [<colour1> [<colour2> [<colour3> [<colour4> ]]]]
 
                 colour1 : [user@host] 
                 colour2 : [24:00] (time)
                 colour3 : [~/dir/] (pwd)
		 colour4 : command
 
  The defaults are green, white, blue, black respectively and
  work best with a white background.
 
  Note:
    The default "white" for the time relies on your terminal
    foreground colour with ID 8 to be configured as "grey".
 
Example
 
  prompt physos red magenta blue
 
EOH
}
 
prompt_physos_setup () {
 
#Initialization
 
  local -A pc
 
  pc['user']=${1:-'green'}
  pc['time']=${2:-'white'}
  pc['pwd']=${3:-'blue'}
  pc['com']=${4:-'black'}
 
 
# %F{$pc['colour']} to allow for colour configuration
  PROMPT="%F{$pc['user']}[%n@%m]%F{$pc['time']}[%T]%f$prompt_newline%F{$pc['pwd']}[%~/] %# %F{$pc['com']}"
 
# Use %_ to show why you are in a continued prompt
  PROMPT2="%F{$pc['pwd']}%_> %F{$pc['com']}"
 
}
 
prompt_physos_setup "$@"

The prompt_physos_help() function is called when you execute prompt -h physos. Simple enough.

The prompt_physos_setup() function is responsible for doing all the real work.

40
41
42
43
44
45
  local -A pc
 
  pc['user']=${1:-'green'}
  pc['time']=${2:-'white'}
  pc['pwd']=${3:-'blue'}
  pc['com']=${4:-'black'}

Here I initialize and fill an array to make color switching a bit less cumbersome in the final prompt. ${1:-'green'} reads the first argument given when the prompt is called and defaults to 'green' if no argument is given.

49
  PROMPT="%F{$pc['user']}[%n@%m]%F{$pc['time']}[%T]%f$prompt_newline%F{$pc['pwd']}[%~/] %# %F{$pc['com']}"

The prompt. Let us have a look at an uncolored version:

  PROMPT="[%n@%m][%T]$prompt_newline[%~/] %# "

The “%” is the escape character in the prompt. You can find all special prompt
commands in the zshmisc(1) manpage.

%n
The username from $USERNAME
%m
Hostname up to the first “.” or with %2m up to the second “.”, and so on.
%T
The time in 24-hour format (15:00). “%*” gives you 24h+seconds (15:00:00)
$prompt_newline
The stout alternative to “\n” in other prompts.
%~
shows $PWD and replaces $HOME with “~”

one alternative is %/ which does no replacement. Both can be truncated on both ends.
%#
resolves to “#” for a privleged user (i.e. root) and “%” for nurmal user.

When you add colour handling everything looks a bit confusing, but it works.

%F{colour}
Switch to a named colour
%f
Switch off any colour
52
  PROMPT2="%F{$pc['pwd']}%_> %F{$pc['com']}"

The “continuation prompt”

%_
shows why the prompt was continued. For example an uncomplete loop.
continue prompt demo

prompt continuation demo

Version Control

Show the prompt_physosvcs_setup code

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
# physos ZSH prompt theme by <rainer@physos.com>
# 
#
prompt_physosvcs_help () {
  cat <<'EOH'
 
General Look
 
  [user@host][12:34]
  [~/] %                               [vcs|branch-revision]                                                                                       
Options
 
  You can change the colours of the theme.
 
  % prompt physosvcs [<colour1> [<colour2> [<colour3> [<colour4> ]]]]
 
                 colour1 : [user@host] 
                 colour2 : [24:00] (time)
                 colour3 : [~/dir/] (pwd)
		 colour4 : command
 
  The defaults are green, white, blue, black respectively and
  work best with a white background.
 
  Note:
    The default "white" for the time relies on your terminal
    foreground colour with ID 8 to be configured as "grey".
 
  Note:
    The VCS display uses colour3.
 
Example
 
  prompt physosvcs red magenta blue
 
EOH
}
 
prompt_physosvcs_setup () {
 
#Initialization
 
  local -A pc
 
  pc['user']=${1:-'green'}
  pc['time']=${2:-'white'}
  pc['pwd']=${3:-'blue'}
  pc['com']=${4:-'black'}
 
 
# zstyle setup of the vcs_info display
# Information in "man zshcontrib"
 
# check for changes in the git repository
# 
# can be slow, comment it out if you encounter delays
  zstyle ':vcs_info:git:*' check-for-changes true
 
# Format when some action is going on in 
# your repository (rebranch,merge conflict, ...)
#
  zstyle ':vcs_info:*' actionformats \
    "%F{$pc['pwd']}[%s|%b|%a]%F{$pc['com']}"
  zstyle ':vcs_info:*' actionformats \
    "%F{$pc['pwd']}%c %u [%s|%b|%a]%F{$pc['com']}"
# Default format: [git|master]  
  zstyle ':vcs_info:*' formats       \
    "%F{$pc['pwd']}[%s|%b]%F{$pc['com']}"
  zstyle ':vcs_info:git:*' formats       \
    "%F{$pc['pwd']}%c %u [%s|%b]%F{$pc['com']}"
 
# Different branch formats
# [svn|www-1173739]
  zstyle ':vcs_info:*' branchformat '%b-%r'
 
# Used VCS use 
# %  vcs_info_printsys 
# for supported systems 
  zstyle ':vcs_info:*' enable git cvs svn
 
# get vcs_info to collect informations
  precmd(){ 
 
    vcs_info
 
  }
# %F{$pc['colour']} to allow for color configuration
  PROMPT="%F{$pc['user']}[%n@%m]%F{$pc['time']}[%T]%f$prompt_newline%F{$pc['pwd']}[%~/] %# %F{$pc['com']}"
 
# Use %_ to show why you are in a continued prompt
  PROMPT2="%F{$pc['pwd']}%_> %F{$pc['com']}"
 
# Print the VCS info
  RPROMPT='${vcs_info_msg_0_}'
}
 
prompt_physosvcs_setup "$@"

The physosvcs prompt uses the vcs_info() function included with current ZSH versions (zshcontrib(1)).

Here are the important changes:

79
80
81
82
83
  precmd(){ 
 
    vcs_info
 
  }
91
  RPROMPT='${vcs_info_msg_0_}'

First I load the vcs_info() function and in the second part I print the output of the function. Easy, isn’t it? The output ends up in $RPROMPT which is printed by ZSH on the right side of the terminal and automatically hidden when my commands become to long.

ZSH git prompt

The output is assembled and formatted using zstyle commands.

51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
# zstyle setup of the vcs_info display
# Information in "man zshcontrib"
 
# check for changes in the git repository
# 
# can be slow, comment it out if you encounter delays
  zstyle ':vcs_info:git:*' check-for-changes true
 
# Format when some action is going on in 
# your repository (rebranch,merge conflict, ...)
#
  zstyle ':vcs_info:*' actionformats \
    "%F{$pc['pwd']}[%s|%b|%a]%F{$pc['com']}"
  zstyle ':vcs_info:*' actionformats \
    "%F{$pc['pwd']}%c %u [%s|%b|%a]%F{$pc['com']}"
# Default format: [git|master]  
  zstyle ':vcs_info:*' formats       \
    "%F{$pc['pwd']}[%s|%b]%F{$pc['com']}"
  zstyle ':vcs_info:git:*' formats       \
    "%F{$pc['pwd']}%c %u [%s|%b]%F{$pc['com']}"
 
# Different branch formats
# [svn|www-1173739]
  zstyle ':vcs_info:*' branchformat '%b-%r'
 
# Used VCS use 
# %  vcs_info_printsys 
# for supported systems 
  zstyle ':vcs_info:*' enable git cvs svn
  zstyle ':vcs_info:git:*' check-for-changes true

The first zstyle command allows to look for local changes to a git repository.

The second and third are defining the actual output.

  "[%s|%b|%a]"

This format is used when there is an action going on or needed (i.e. a merge)

  "[%s|%b]"

This format is used without an action.

git is a bit special since vcs_info() can show staged (%c) and unstaged (%u) changes.

%s
the VCS in use in the curent directory
%b
Information about the current branch (revision, branch, etc.; see below)
%a
the action

The %b from the general format can be configured in more detail in the branchformat lines.

74
  zstyle ':vcs_info:*' branchformat '%b-%r'
%b
the branch name
%r
the current revision number

As is said in the comments, more information about the zstyle commands and complete placeholder lists can be found in the zshcontrib(1) manpage.

The final zstyle command is probably one you want to edit.

  zstyle ':vcs_info:*' enable git cvs svn

Here you can enable (or disable) the VCS systems you want to use. “vcs_info_printsys” on the commandline gives you a list of supported VCS. When I was writing this it gave me:

## list of supported version control backends:                                               
## disabled systems are prefixed by a hash sign (#)                                          
#bzr                                                                                         
#cdv                                                                                         
cvs                                                                                          
#darcs                                                                                       
git                                                                                          
#hg                                                                                          
#mtn                                                                                         
#p4                                                                                          
#svk                                                                                         
svn                                                                                          
#tla                                                                                         
## flavours (cannot be used in the enable or disable styles; they                            
## are enabled and disabled with their master [git-svn -> git])                              
## they *can* be used contexts: ':vcs_info:git-svn:*'.                                       
git-p4                                                                                       
git-svn

Feel free to activate the ones you use. If you have zstyle patches for your prefered VCS please send them my way.

2 Responses to “My custom ZSH prompt”

  1. Adam says:

    I’ve been using a prompt based on one I found at http://aperiodic.net/phil/prompt/ on Linux and OS X for some time. You might find something useful in there.

  2. rainer says:

    I used Phil’s prompt for inspiration. I decided on using some things which were not around when Phil wrote it or he decided against.

    I will add a link list with the sites I used, when I am back at the machine I left the bookmarks on without syncing them.