]> git.rmz.io Git - dotfiles.git/blob - zsh/lib/prompt.zsh
zsh: only print pacman updates if checkupdates exists
[dotfiles.git] / zsh / lib / prompt.zsh
1 # Setup the prompt with pretty colors
2 setopt prompt_subst
3 autoload colors; colors;
4
5 hostcolor=cyan
6 [[ $(hostname) == "tardis" ]] && hostcolor=red
7
8 precmd() {
9 PROMPT='%T $(virtualenv_prompt)%n@%{$fg[$hostcolor]%}%m$(jobs_prompt)%-0>..>$(git_prompt_status)%>>
10 %(?..%{$fg_bold[white]%}%?)%{$reset_color%}$(vi_prompt_info)%{%(!.$fg[red]❰.$fg[green]❱)%1G%} '
11 RPROMPT='%{$fg[green]%}%~%{$reset_color%}'
12 }
13
14 jobs_prompt() {
15 printf '%s' "%(1j. $fg_bold[white]↵%{$fg_bold[red]%}%j.)%{$reset_color%}"
16 }
17
18 vi_prompt_info() {
19 local vicmd="$fg_bold[green]❰$reset_color%1G"
20 local viins="$fg_bold[blue]❱$reset_color%1G"
21 local map=${KEYMAP:-viins}
22 printf '%s' "%{${${map/vicmd/$vicmd}/(main|viins)/$viins}%}"
23 }
24
25 function zle-line-init zle-line-finish zle-keymap-select {
26 zle reset-prompt
27 zle -R
28 }
29
30 # zle -N zle-line-init
31 # zle -N zle-line-finish
32 zle -N zle-keymap-select
33
34 # reset zle on resize
35 TRAPWINCH() {
36 zle && { zle reset-prompt; zle -R }
37 }
38
39 # Get the status of the working tree
40 git_prompt_status() {
41 if ! git rev-parse --is-inside-work-tree &>/dev/null; then
42 return
43 fi
44 local oid head ahead behind
45 local added deleted modified renamed unmerged untracked dirty
46 # Use porcelain status for easy parsing.
47 local status_cmd="git status --porcelain=v2 -b"
48
49 # Get current status.
50 while IFS=$'\n' read line; do
51 if [[ "$line" == \#\ * ]]; then
52 [[ "$line" =~ '# branch.oid ([0-9a-f]+)' ]] && oid=$match[1]
53 [[ "$line" =~ '# branch.head (.*)' ]] && head=$match[1]
54 [[ "$line" =~ '# branch.ab \+([0-9]+) -([0-9]+)' ]] && ahead=$match[1] && behind=$match[2]
55 else
56 # Count added, deleted, modified, renamed, unmerged, untracked, dirty.
57 # T (type change) is undocumented, see http://git.io/FnpMGw.
58 # index
59 [[ "$line" == 1\ M[.MTD]\ * ]] && (( updated++ ))
60 [[ "$line" == 1\ [AC][.MTD]\ * ]] && (( added++ ))
61 [[ "$line" == 1\ D[.MT]\ * ]] && (( deleted++ ))
62 [[ "$line" == 2\ R[.MTD]\ * ]] && (( renamed++ ))
63
64 # work tree
65 [[ "$line" == 1\ [.MARCT]M\ * ]] && (( modified++ ))
66 [[ "$line" == 1\ [.MARCT]D\ * ]] && (( deleted_wt++ ))
67 [[ "$line" == \?\ * ]] && (( untracked++ ))
68
69 # merge conflicts
70 [[ "$line" == u\ (AA|DD|U?|?U)\ * ]] && (( unmerged++ ))
71 fi
72 done < <(${(z)status_cmd} 2> /dev/null)
73
74 local git_status=" %{$fg_bold[green]%}"
75
76 # Format branch and commit
77 git_status+="$head%{$fg_no_bold[yellow]%}(${oid[1,8]})"
78
79 # Format upstream
80 local upstream_str
81 (( ahead > 0 )) && upstream_str+="%{$fg[blue]%} >$ahead"
82 (( behind > 0 )) && upstream_str+="%{$fg[blue]%} <$behind"
83 git_status+="$upstream_str"
84
85 # Format push
86 push_ab=( $(git rev-list --left-right --count @...@{push} 2>/dev/null) )
87 if (( $? == 0 )); then
88 (( push_ab[1] > 0 )) && git_status+="%{$fg_bold[blue]%} ⮝$push_ab[1]"
89 (( push_ab[2] > 0 )) && git_status+="%{$fg_bold[blue]%} ⮟$push_ab[2]"
90 fi
91
92 # Format stashed
93 stashed=$(git stash list | wc -l)
94 if (( stashed > 0 )) then
95 stashed_str+="%{$fg_bold[cyan]%} ⋎$stashed%{$reset_color%}"
96 fi
97 git_status+="$stashed_str"
98
99 # Format index
100 local index_str
101 (( updated > 0 )) && index_str+="%{$fg[green]%} *$updated"
102 (( added > 0 )) && index_str+="%{$fg[green]%} +$added"
103 (( deleted > 0 )) && index_str+="%{$fg[green]%} -$deleted"
104 (( renamed > 0 )) && index_str+="%{$fg[green]%} ≈$renamed"
105 git_status+="$index_str"
106
107 # Format working tree
108 local wt_str
109 (( modified > 0 )) && wt_str+="%{$fg[red]%} *$modified"
110 (( deleted_wt > 0 )) && wt_str+="%{$fg[red]%} -$deleted_wt"
111 (( untracked > 0 )) && wt_str+="%{$fg[red]%} +$untracked"
112 (( unmerged > 0 )) && wt_str+="%{$fg[magenta]%} ♒$unmerged"
113 git_status+="$wt_str"
114
115 git_status+="%{$reset_color%}"
116
117 echo $git_status
118 }
119
120 function virtualenv_prompt() {
121 if [[ -z $VIRTUAL_ENV ]] then
122 echo ""
123 else
124 echo "(${VIRTUAL_ENV##*/}) "
125 fi
126 }
127
128 function print_if_fits() {
129 local zero length
130
131 zero='%([BSUbfksu]|([FB]|){*})'
132 length=${#${(S%%)1//$~zero/}}
133 echo "%-$length(l.$1.)"
134 }