139 lines
		
	
	
		
			2.7 KiB
		
	
	
	
		
			Bash
		
	
	
	
	
	
			
		
		
	
	
			139 lines
		
	
	
		
			2.7 KiB
		
	
	
	
		
			Bash
		
	
	
	
	
	
| # 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 &!
 | |
| }
 |