autoload -Uz add-zle-hook-widget add-zsh-hook vcs_info readonly -gHA _prompt_newuser_formats=( start:chpwd $'\n%B%F{blue}%~%b%f/\n' start:left $'%(?,%F{green},%F{red}%v%k\n%B%S)%#%b%f%s ' start:right '%B%F{blue}%n%b%f%k@%F{magenta}%m%f' start:staged '%B%F{green}+%b%f' start:unstaged '%B%F{red}*%b%f' start:action '%B%F{red}%a%%b%f' start:branch '%B%F{cyan}%b%%b%f' start:repo '|%B%F{blue}%r%%b%f' cont:indent ' ' cont:left '' cont:right '%F{red}%^%f' ) readonly -ga sysexits=( USAGE DATAERR NOINPUT NOUSER NOHOST UNAVAILABLE SOFTWARE OSERR OSFILE CANTCREAT IOERR TEMPFAIL PROTOCOL NOPERM CONFIG ) prompt_newuser_help() { print -r -- \ "To customize your prompt, copy-paste any of the following to your .zshrc file and edit it in there: # Start prompt: zstyle ':prompt:*:start' left ${(q+)_prompt_newuser_formats[start:left]} zstyle ':prompt:*:start' right ${(q+)_prompt_newuser_formats[start:right]} # Prepended to left side of start prompt if we changed dirs: zstyle ':prompt:*:start' chpwd ${(q+)_prompt_newuser_formats[start:chpwd]} # Replaces right side of start prompt when in a repo: zstyle ':prompt:*:start' unstaged ${(q+)_prompt_newuser_formats[start:unstaged]} zstyle ':prompt:*:start' staged ${(q+)_prompt_newuser_formats[start:staged]} zstyle ':prompt:*:start' branch ${(q+)_prompt_newuser_formats[start:branch]} zstyle ':prompt:*:start' action ${(q+)_prompt_newuser_formats[start:action]} zstyle ':prompt:*:start' repo ${(q+)_prompt_newuser_formats[start:repo]} # Continuation prompt: zstyle ':prompt:*:cont' left ${(q+)_prompt_newuser_formats[cont:left]} zstyle ':prompt:*:cont' right ${(q+)_prompt_newuser_formats[cont:right]} # Used to indent left side of continuation prompt: zstyle ':prompt:*:cont' indent ${(q+)_prompt_newuser_formats[cont:indent]} For an explanation of the % codes, see http://zsh.sourceforge.net/Doc/Release/Prompt-Expansion.html and the end of http://zsh.sourceforge.net/Doc/Release/User-Contributions.html#vcs_005finfo-Configuration" } prompt_newuser_format() { local ctx=$1 arg fmt out shift for arg; do zstyle -s :prompt:newuser:$ctx $arg fmt || fmt="$_prompt_newuser_formats[${ctx}:$arg]" out+="$fmt" done print -r -- "$out" } prompt_newuser_chpwd() { emulate -L zsh unset vcs_info_msg_0_ PS1="$( prompt_newuser_format start chpwd left )" } prompt_newuser_precmd() { local exitstatus=$? emulate -L zsh psvar[1]= case $exitstatus in <128-> ) psvar[1]="SIG$signals[exitstatus-127] " ;| <64-78> ) psvar[1]="EX_$sysexits[exitstatus-63] " ;| <1-> ) psvar[1]+="($exitstatus)" esac if ! [[ -v vcs_info_msg_0_ ]]; then zstyle ':vcs_info:*' check-for-staged-changes yes vcs_info if [[ -n $vcs_info_msg_0_ ]]; then RPS1="$vcs_info_msg_0_" else RPS1="$( prompt_newuser_format start right )" fi fi } prompt_newuser_line-init() { emulate -L zsh case $CONTEXT in start ) local -i fd=-1 exec {fd}< <( zstyle ':vcs_info:*' check-for-changes yes vcs_info print -rNC1 -- "$PWD" "${vcs_info_msg_0_}" ) zle -Fw "$fd" prompt_newuser_async ;; cont ) local fmt="$( prompt_newuser_format cont indent )" local -a indent=( '%('{1..$(( COLUMNS / ${(m)#fmt} ))}"_,$fmt,)" ) PS2="${(j::)indent}$( prompt_newuser_format cont left )" RPS2="$( prompt_newuser_format cont right )" ;; esac } prompt_newuser_async() { emulate -L zsh { zle -F "$1" [[ $2 != (|hup) ]] && return () { local pwd null IFS=$'\0' read -ru "$1" pwd vcs_info_msg_0_ null [[ $pwd == $PWD ]] } "$@" || return if [[ -n $vcs_info_msg_0_ ]]; then RPS1="$vcs_info_msg_0_" else RPS1="$( prompt_newuser_format start right )" fi zle .reset-prompt } always { exec {1}<&- } } prompt_newuser_line-finish() { emulate -L zsh PS1="$( prompt_newuser_format start left )" } prompt_newuser_setup() { prompt_opts=( cr percent sp ) zstyle -e ':vcs_info:*' formats ' reply=( "%u%c$( prompt_newuser_format start branch repo )" ) ' zstyle -e ':vcs_info:*' actionformats ' reply=( "%u%c$( prompt_newuser_format start action repo )" ) ' zstyle -e ':vcs_info:*' stagedstr ' reply=( "$( prompt_newuser_format start staged )" ) ' zstyle -e ':vcs_info:*' unstagedstr ' reply=( "$( prompt_newuser_format start unstaged )" ) ' PS4=$'# ?=%(?,%F{green},%B%F{red}%S)%?%b%f%s e=%e %F{green}%1N%f:%I %(1_,%F{yellow}%K{black}%_%f%k ,)' SPROMPT='Correct %B%F{red}%U%R%b%f%u to %B%F{green}%r%b%f? [%Sy%ses|%Sn%so|%Se%sdit|%Sa%sbort] ' PROMPT_EOL_MARK='%S%F{cyan}%#%s%f' zle_highlight=( isearch:fg=black,bg=yellow special:fg=cyan,bold region:bg=blue suffix:bg=blue paste:none ) zle -N prompt_newuser_async add-zsh-hook chpwd prompt_newuser_chpwd add-zsh-hook precmd prompt_newuser_precmd add-zle-hook-widget line-init prompt_newuser_line-init add-zle-hook-widget line-finish prompt_newuser_line-finish prompt_newuser_chpwd } prompt_newuser_setup "$@"