]> git.rmz.io Git - dotfiles.git/blob - zsh/lib/prompt.zsh
zsh/aliases: add aliases for worktree
[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]A\ * ]] && (( added++ , modified++ )) # intend-to-add
66 [[ "$line" == 1\ [.MARCT]M\ * ]] && (( modified++ ))
67 [[ "$line" == 1\ [.MARCT]D\ * ]] && (( deleted_wt++ ))
68 [[ "$line" == \?\ * ]] && (( untracked++ ))
69
70 # merge conflicts
71 [[ "$line" == u\ (AA|DD|U?|?U)\ * ]] && (( unmerged++ ))
72 fi
73 done < <(${(z)status_cmd} 2> /dev/null)
74
75 local git_status=" %{$fg_bold[green]%}"
76
77 # Format branch and commit
78 git_status+="$head%{$fg_no_bold[yellow]%}(${oid[1,8]})"
79
80 # Format upstream
81 local upstream_str
82 (( ahead > 0 )) && upstream_str+="%{$fg[blue]%} >$ahead"
83 (( behind > 0 )) && upstream_str+="%{$fg[blue]%} <$behind"
84 git_status+="$upstream_str"
85
86 # Format push
87 push_ab=( $(git rev-list --left-right --count @...@{push} 2>/dev/null) )
88 if (( $? == 0 )); then
89 (( push_ab[1] > 0 )) && git_status+="%{$fg_bold[blue]%} ⮝$push_ab[1]"
90 (( push_ab[2] > 0 )) && git_status+="%{$fg_bold[blue]%} ⮟$push_ab[2]"
91 fi
92
93 # Format stashed
94 stashed=$(git stash list | wc -l)
95 if (( stashed > 0 )) then
96 stashed_str+="%{$fg_bold[cyan]%} ⋎$stashed%{$reset_color%}"
97 fi
98 git_status+="$stashed_str"
99
100 # Format index
101 local index_str
102 (( updated > 0 )) && index_str+="%{$fg[green]%} *$updated"
103 (( added > 0 )) && index_str+="%{$fg[green]%} +$added"
104 (( deleted > 0 )) && index_str+="%{$fg[green]%} -$deleted"
105 (( renamed > 0 )) && index_str+="%{$fg[green]%} ≈$renamed"
106 git_status+="$index_str"
107
108 # Format working tree
109 local wt_str
110 (( modified > 0 )) && wt_str+="%{$fg[red]%} *$modified"
111 (( deleted_wt > 0 )) && wt_str+="%{$fg[red]%} -$deleted_wt"
112 (( untracked > 0 )) && wt_str+="%{$fg[red]%} +$untracked"
113 (( unmerged > 0 )) && wt_str+="%{$fg[magenta]%} ♒$unmerged"
114 git_status+="$wt_str"
115
116 git_status+="%{$reset_color%}"
117
118 echo $git_status
119 }
120
121 function virtualenv_prompt() {
122 if [[ -z $VIRTUAL_ENV ]] then
123 echo ""
124 else
125 echo "(${VIRTUAL_ENV##*/}) "
126 fi
127 }
128
129 function print_if_fits() {
130 local zero length
131
132 zero='%([BSUbfksu]|([FB]|){*})'
133 length=${#${(S%%)1//$~zero/}}
134 echo "%-$length(l.$1.)"
135 }