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