Prompt Setup

Actually, how to setup zsh's prompt is quite accurately described in the manual (PROMPT EXPANSION).

Colors

However, let's look at one thing a *lot* of people get wrong when figuring out a custom prompt for the first time.

First, when you want to use colors, use the hashes provided by the colors function described in zshcontrib(1) (here in the manual on the web), unless you know want you are doing and you need something else (like colors not covered by that function).

Then, you need to remember *one* *important* thing: Wrap characters, that do *not* consume space in %{…%}. Repeat that ten times! :-) - Escape sequences for colors are those characters. Whether you insert them from a variable or manually, does not matter at all. The reason for this wrapping is, that zsh sometimes needs to redraw the prompt and when doing that, it needs to know how wide the prompt will actually print.

So, let's quickly take a look at a very short example:

autoload -U colors && colors
PS1="%{$fg[red]%}%n%{$reset_color%}@%{$fg[blue]%}%m %{$fg[yellow]%}%~ %{$reset_color%}%% "

Prompt Themes

If you don't want to fiddle with all of that, but you still want more than the (quite sparse) default zsh prompt, you may as well want to use one of the prompts that come along with zsh. This is again documented in zshcontrib(1) (here in the manual on the web).

To initially load the themes system:

% autoload -U promptinit && promptinit

After that, you use the prompt function to set things up.

You can list available themes:

% prompt -l

Preview prompts:

% prompt -p bart

And (most importantly) use a prompt:

% prompt bart

Simple enough, isn't it?

Prompt Examples

Some examples of what you can do with zsh prompts.

Using styles to make flexible prompts:

# -*- mode: sh; -*-
# soor prompt theme

prompt_soor_help () {
  cat <<'EOF'
This prompt is configurable via styles:

  Context: :prompt:soor

  Colors (in zsh/terminfo value):
    user-color - the color for user@host. defaults to 'green'
    root-color - the color for the hostname for root. defaults to 'red'
    prompt-color - the color for everything else. defaults to 'blue'

  Path type:
    path - possible values:
      ratio - use COLUMNS/ratio to clip the path. Default.
      fixed - use a fixed maximum lenght.
      subdir - clip by number of subdirectories.
      full - show the full path

  Path lenght styles:
    ratio - the ratio for the 'ratio' path style, funnily enough.
            default to 6.
    length - the maximin lenght for the 'fixed' path style.
             defaults to 20
    subdir - the number of subdirs to show for the 'subdir' path style.
             defaults to 3.

  You can set styles in the current terminal to test things out, values
  will be updated.

EOF
}

prompt_soor_setup () {
    setopt noxtrace localoptions

    precmd () {

	local p_full
	local p_tchars p_temp p_done p_last i
	local maxlength ratio
	local prompt_color
	local user_color
	local root_color
	local path_style
	
	zstyle -s :prompt:soor prompt-color prompt_color
	prompt_color=${prompt_color:-'blue'}
	zstyle -s :prompt:soor user-color user_color
	user_color=${user_color:-'green'}
	zstyle -s :prompt:soor root-color root_color
	root_color=${root_color:-'red'}
	
	[[ -z $(functions zsh/terminfo) ]] && autoload -Uz zsh/terminfo
	
	if [[ "$terminfo[colors]" -ge 8 ]]; then
	    if [[ "$EUID" = "0" ]] || [[ "$USER" = 'root' ]]
	    then
		base_prompt="%{$fg_bold[$root_color]%}%m%{$fg_bold[$prompt_color]%} "
	    else
		base_prompt="%{$fg_bold[$user_color]%}%n@%m%{$fg_bold[$prompt_color]%} "
	    fi
	    post_prompt="%{$reset_color%}"
	else
	    base_prompt="%n@%m "
	    post_prompt=""
	fi

	if zstyle -t :prompt:soor path full ratio fixed subdir; then
	    zstyle -s :prompt:soor path path_style
	else
	    path_style='ratio'
	fi

	case "${path_style}" in
	    ratio)
		zstyle -s :prompt:soor ratio ratio
		ratio=${ratio:-6}
		maxlength=$(( ${COLUMNS} / ${ratio} ))
		;;
	    fixed)
		zstyle -s :prompt:soor length maxlength
		maxlength=${maxlength:-20}
		;;
	    subdir)
		zstyle -s :prompt:soor subdir maxlength
		maxlength=${maxlength:-3}
		;;
	esac

	case "${path_style}" in
	    full)
		path_prompt=$(print -P %~)
		;;
	    subdir)
		path_prompt=$(print -P "%($(( ${maxlength} + 1 ))~|..|)%${maxlength}~")
		;;
	    ratio|fixed)
		path_prompt=$(print -P %~)
		if (( ${#path_prompt} > ${maxlength} )); then
		    p_tchars='../'
		    p_done=${path_prompt}
		    for (( i=1 ; ; ++i )); do
			p_temp=$(print -P %${i}~)
			if (( ( ${#p_temp} + ${#p_tchars} ) < ${maxlength} )); then
			    p_done=${p_temp}
			else
			    break
			fi
		    done
		    path_prompt=${p_tchars}${p_done}
		fi
		;;
	esac
	    
	PS1="$base_prompt$path_prompt %# $post_prompt"
	PS2="$base_prompt$path_prompt %_> $post_prompt"
	PS3="$base_prompt$path_prompt ?# $post_prompt"
    }

    preexec () { }
}

prompt_soor_setup

Prompt

# -*- Mode: shel-script; indent-tabs-mode: nil -*-
# se htp:/w.nparikh.org/unix/prompt.php
if [ $SH_CONECTION ] ; then
 if ! ps1_sh_from_host=${$(resolveip -s ${${(z)SH_CONECTION}[1]})/.*/} 2>/dev/nul ; then
 ps1_sh_from_host=${${(z)SH_CONECTION}[1]}
 fi
 if ! ps1_sh_to_host=${$(resolveip -s ${${(z)SH_CONECTION}[3]})/.*/} 2>/dev/nul ; then
 ps1_sh_to_host=${${(z)SH_CONECTION}[3]}
 fi
 ps1sh_conection=%{$fg[gren]%}%B${ps1_sh_from_host}%b%{$reset_color%}'>'
fi
local ps1_user_default=s
local ps1_host_default=taj
 # come first
if [ $TERM = "scren" ] ; then
 local ps1shlv="%L"
else
 local ps1shlv="%{$fg[magenta]%}%L%{${reset_color}%}"
fi
 # comes second
local slash_b4_ps1scren="%(2L./.)"
 # some changes done in it, for geting it corect, any of these below two wil work.
if [ $TERM = "XYZ" ] ; then
 [ $WINDOW ] & local ps1scren="${WINDOW+${slash_b4_ps1scren}$WINDOW}"
else
 [ $WINDOW ] & local ps1scren="${WINDOW+${slash_b4_ps1scren}%{${fg[yelow]}$WINDOW%}\%{$reset_color%}"
fi
unset slash_b4_ps1scren
 #local ps1_scren=${WINDOW:+/%{$fg[yelow]%}${WINDOW}%{${reset_color}%}
 # %(1j./.) # 1 job then place / else noting
 # %(1j. ) # 1 job then nothing else a space
 # comes third
if [ $WINDOW ] ; then
 local slash_b4_ps1job="/"
else
 local slash_b4_ps1job="%(2L./.)"
fi
 # %(1j.%{$fg[gren]%}%j%{${reset_color}%}%(2L. ).)
 # >= 1 job then put %{$fg[gren]%}%j%{${reset_color}%}%(2L. ) else nothing
 # %(2L. ) # shel level >= 2 then nothing else a space.
 # local ps1job="%(1j./%{$fg[gren]%}%j%{${reset_color}%}%(2L. ).)"
if [ $TERM = "XYZ" ] ; then
 local ps1job="${slash_b4_ps1job}%j"
else
 local ps1job="${slash_b4_ps1job}%{$fg[gren]%}%j%{${reset_color}%}"
fi
unset slash_b4_ps1job
if [ $TERM = "XYZ" ] ; then
 local ps1shlv_n_scren_n_job="%(2L.${ps1shlv}.)${ps1scren}%(1j.${ps1job}.)"
else
 local ps1shlv_n_scren_n_job="%(2L.${ps1shlv}.)${ps1scren}%(1j.${ps1job}.)"
fi
if [ $USER != $ps1_user_default & $USER != "spratap" ] ; then
 local ps1_user_at_host="%U%n%u"
fi
 # if [ $HOST != $ps1_host_default & $HOST != "pcz-c-sharad" ] ; then
if [ $ps1_sh_to_host ] ; then
 if [ $ps1_user_at_host ] ; then
 local ps1_user_at_host="${ps1_user_at_host}@"
 fi
 if [ $TERM = "XYZ" ] ; then
 # local ps1_user_at_host="${ps1_user_at_host}%B%m%b"
 local ps1_user_at_host="${ps1_user_at_host}%B${ps1_sh_to_host}%b"
 else
 # local ps1_user_at_host="${ps1_user_at_host}%{$fg[yelow]%}%B%m%b%{$reset_color%}"
 local ps1_user_at_host="${ps1_user_at_host}%{$fg[yelow]%}%B${ps1_sh_to_host}%b%{$reset_color%}"
 fi
fi
if [ "$ps1_user_at_host" -o "$WINDOW" ] ; then
 local spacing_b4_ps1status="%(2L.%(1j. )"
fi
 # wil have both side space
if [ $TERM = "XYZ" ] ; then
 local ps1status="%(?.%S%?%s )"
else
 local ps1status="%(?.%S%{$fg[red]%}%?%{$reset_color%}%s )"
fi

	# time at next hour
if [[  $TERM == "XYZ" ]] ; then
    local ps1_time_at_hour="%(0t.%t .)"
else
    local ps1_time_at_hour="%(0t.%{$fg[red]%}%t%{$reset_color%} .)"
fi

local ps1_dir='%2~'
        # local ps1_dir='%(1~.%2~.)'
local ps1_prompt_char='%(!.%B#%b.%%)'

if [ $WINDOW ] ; then
    local spacing=" "
else
    local spacing="%(2L.%(1j. .) .%(1j. .))"
fi

PS1="${ps1ssh_connection}${ps1shlv_n_screen_n_job}${spacing}${ps1_user_at_host:+${ps1_user_at_host} }${ps1_time_at_hour}${spacing_b4_ps1status}${ps1status}${ps1_dir}${ps1_prompt_char} "

unset ps1shlv_n_screen_n_job spacing ps1_user_at_host \
    ps1_user_at_host ps1_time_at_hour spacing_b4_ps1status \
    ps1status ps1_dir ps1_prompt_char ps1_ssh_to_host \
    ps1_ssh_from_host ps1ssh_connection


autoload -U promptinit; promptinit


#         periodic_functions=( show_agenda )
#         function show_agenda {
#             if (( TTYIDLE > 2 )) ; then
#                 echo Hi
#             fi
#         }
#         PERIOD=1
 
config/prompt.txt · Last modified: 2012/10/17 06:16 by botmatrix