# Prompt # vim: ft=zsh autoload -U colors && colors nullexec() { "$@" &>/dev/null; } precmd.title() { printf '%b' "\e]2;$1\a" } precmd.svn() { if [[ -f .novcsprompt ]]; then return 0 fi if nullexec svn info; then while IFS= read -r line; do case $line in (M*|A*|D*) svn_unstaged=1;; (\!*) svn_missing=1;; (\?*) svn_untracked=1;; esac done < <( svn st ) (( svn_unstaged )) && { svn_st+='c' svn_st_col='red' } (( svn_missing )) && { svn_st+='m' svn_st_col='red' } (( svn_untracked )) && { svn_st+='f' svn_st_col='red' } svn_st_col=${svn_st_col:-"green"} svn_st=${svn_st:-"ok"} printf '%s' "(%F{cyan}svn%f:%F{$svn_st_col}$svn_st%f) " fi } precmd.is_git_repo() { declare _pwd=$PWD while [[ -n $_pwd ]]; do if [[ -r "$_pwd/.git/HEAD" ]]; then return 0 else _pwd=${_pwd%/*} fi done return 1 } precmd.git() { declare git_branch_info git_unstaged git_untracked git_status_short git_status_colour git_prompt_msg [[ -f .novcsprompt ]] && return 0 precmd.is_git_repo || return 0 declare line while IFS= read -r line; do [[ $line[1,2] == '##' ]] && git_branch_info=$line[4,-1] [[ $line[1,2] == '??' ]] && (( git_untracked++ )) [[ $line[1,2] =~ .[MD] ]] && (( git_unstaged++ )) [[ $line[1,2] =~ [MDARC]. ]] && (( git_staged++ )) done < <(git status --porcelain -bu 2>/dev/null) git_branch_name=${git_branch_info%%...*} [[ $git_branch_info =~ ahead\ ([0-9]+) ]] && git_ahead=$match[1] [[ $git_branch_info =~ behind\ ([0-9]+) ]] && git_behind=$match[1] git_status_colour='green' _c() { printf '%%F{%s}%s%%f' "$@" } (( git_ahead )) && git_status_short+=$(_c yellow a) (( git_behind )) && git_status_short+=$(_c yellow b) (( git_staged )) && git_status_short+=$(_c red s) (( git_unstaged )) && git_status_short+=$(_c red c) (( git_untracked )) && git_status_short+=$(_c red f) git_status_short=${git_status_short:-"ok"} git_prompt_msg="(%F{cyan}$git_branch_name%f[%F{$git_status_colour}${git_status_short}%f]) " printf '%s' $git_prompt_msg } rprompt() { { precmd.svn; precmd.git } > "$XDG_RUNTIME_DIR/zsh_rprompt_$$.tmp" kill -s USR1 $$ } TRAPUSR1() { prompt_async_data=$(<"$XDG_RUNTIME_DIR/zsh_rprompt_$$.tmp") draw_prompt zle && zle reset-prompt } draw_prompt() { prompt_custom=( "%F{$cmd_colour}$cmd_msg%f" "%F{$user_colour}$USER%f $HOST:${PWD//$HOME/~}" "$prompt_async_data%F{$user_colour}>%f" ) PROMPT=" $prompt_custom " } precmd() { declare last_exit_code=$? declare -g cmd_colour cmd_msg if (( last_exit_code )); then cmd_colour='red' cmd_msg='!' else cmd_colour='green' cmd_msg='.' fi if (( UID )); then user_colour='green' else user_colour='red' fi precmd.title "$USER@$HOST ${PWD//$HOME/~}" draw_prompt rprompt &! }