Zsh & custom prompt

I love seeing same shell prompt on all my working machines, it’s like bringing little piece of home everywhere I go (alongside my favourite wallpaper). Here’re my .(ba|z)shrc files (I’m lately sticking with z, because it has some nice features).

First problem I ran into when source‘ing my .bashrc on freshly installed fedora - __git_ps1 not found error. ‘Fixed’ that (not sure, whether did it optimally) using

source /usr/share/git-core/contrib/completion/git-prompt.sh

Decided to look into zshell about all good things that coming my way from Mac users among friendly developers. After getting some history lesson (#10-12 especially) it was suprisingly to find out that zshell and bash came to be at pretty match same time 23 years ago.

Installing and switching for zhell is either simple, considering amount of different manuals in the net and also such cool thing as oh-my-zsh

Customizing your prompt

Customizing prompt basically means firstly deciding what info to show, and secondly - how to do that. For different possible escape sequence in zshell & tcsh, check out this blogpost. Don’t forget bash as well.

As for the second part, there’re a lot of preinstalled themes you can check out in a list, by running

prompt -l

and preview one of those using ‘-p’ flag or even set using ‘-s’ There’re tons of those, and some of them look really neat.

####And for how to switch prompt from bash-y like into zhell-y one?

So, colors went from




And overall prompt line from this


turned into

PS1="$LIGHT_GREEN%n@%m%{$reset_color%}:$LIGHT_BLUE%~$LIGHT_RED$git_st%{$reset_color%}$ "

For right prompt (you got that for free in zshell, without any laggy solutions) I decided to show ruby & node.js version that are currently being used.

node_folder() {
  if [ "$(print -l *.js(.N) 2>&1 | wc -w)" != "0" ] || [[ -f package.json  ||  -f Gruntfile.json ||  -f grunt.js ||  -f bower.json ]] ; then 
    ref="[node `node -v`]"
  echo $ref

ruby_folder() {
  if [ "$(print -l *.rb(.N) 2>&1 | wc -w)" != "0" ] || [[ -f Gemfile  ||  -f Gemfile.lock ||  -f config.ru ]] ; then 
    xef="[ruby `~/.rvm/bin/rvm-prompt`]"
  echo $xef
source ~/.nvm/nvm.sh
source /usr/share/git-core/contrib/completion/git-prompt.sh 
PS1="$LIGHT_GREEN%n@%m%{$reset_color%}:$LIGHT_BLUE%~$LIGHT_RED$git_st%{$reset_color%}$ "

autoload -U promptinit

This code basically uses output of node -v & ~/.rvm/bin/rvm-prompt to get current versions of thos and display them in the right prompt. But it does that only for folders which contains: for ruby – any *.rb, Gemfile, Gemfile.lock, config.ru; for node – any *.js, package.json, Gruntfile.json, grunt.js, bower.json files. Direct match was done via regular bash -f primary expression, and for pattern match I went with wc tool mixing up different solutions I saw around the web to supress zshell ls standard behaviour (it raises ‘no matches found:…’) when there’s nothing matching pattern.

After all this, my prompt looks something like this Screenshot of my prompt

Unless for tricky interpolation differences between "" & '' I’d never read about lots of bash stuff in single night I mostly forgot by now just to write my single implementation of __git_ps1()

In case you ran in issue with your prompt not being recomputed and this or this solution doesn’t help you out, be sure to checkout whether you have magic string setopt prompt_subst in your file.

prompt_subst is not set by default. It allows variable substitution to take place in the prompt, so I can just change the contents of certain variables without recreating the prompt every time.

Possible handy reading links:

Be sure to customize your prompt. It get’s you to know your tool and makes you feel good.