-
Notifications
You must be signed in to change notification settings - Fork 8
/
prompt_framework
208 lines (184 loc) · 5.75 KB
/
prompt_framework
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
#!/bin/env zsh
# For my own and others sanity
# git:
# %b => current branch
# %a => current action (rebase/merge)
# %c => current changed files
# %u => current staged files
# prompt:
# %F => color dict
# %f => reset color
# %~ => current path
# %* => time
# %n => username
# %m => shortname host
# %1 => vcs branch and vcs
# %2 => vcs dirty
# %3 => vcs action
# %4 => cmd execution time
# %(?..) => prompt conditional - %(condition.true.false)
# terminal codes:
# \e7 => save cursor position
# \e[2A => move cursor 2 lines up
# \e[1G => go to position 1 in terminal
# \e8 => restore cursor position
# \e[K => clears everything after the cursor on the current line
# \e[2K => clear everything on the current line
### Shared Functions ###
prompt_clean_zstyles() {
# zstyle ':vcs_info:*' debug true
zstyle ':vcs_info:*' enable ALL
zstyle ':vcs_info:*' max-exports 3
zstyle ':vcs_info:*' use-simple true
zstyle ':vcs_info:*:*' formats "%s/%b" "%c%u"
zstyle ':vcs_info:*:*' actionformats "%s/%b" "%c%u" "%a"
zstyle ':vcs_info:git:*' formats "%b" "%c%u"
zstyle ':vcs_info:git:*' actionformats "%b" "%c%u" "%a"
# Additional hooks
zstyle ':vcs_info:git*+post-backend:*' hooks git-arrows
zstyle ':vcs_info:git*+set-message:*' hooks git-untracked
# Additional clean specific styles
# Set other defaults
zstyle ':vcs_info:*' get-revision true
zstyle ':vcs_info:*' check-for-changes true
zstyle ':vcs_info:*' unstagedstr '*'
zstyle ':vcs_info:*' stagedstr '+'
zstyle ':vcs_info:*:clean:*' check-for-untracked true
zstyle ':vcs_info:*:clean:*' check-head true
zstyle ':vcs_info:*:clean:*' untrackedstr '.'
zstyle ':vcs_info:*:clean:*' headbehindstr '⇣'
zstyle ':vcs_info:*:clean:*' headaheadstr '⇡'
zstyle ':clean:normal:*' prompt-symbol '❯'
zstyle ':clean:root:*' prompt-symbol '#'
}
### VCS Hooks ###
+vi-git-untracked() {
if [[ $1 -eq 0 ]] && \
zstyle -T ":vcs_info:${vcs}:clean:untracked" check-for-untracked && \
[[ $($vcs rev-parse --is-inside-work-tree 2> /dev/null) == 'true' ]] && \
$vcs status --porcelain | grep '??' &> /dev/null
then
# This will show the marker if there are any untracked files in repo.
# If instead you want to show the marker only if there are untracked
# files in $PWD, use:
#[[ -n $(git ls-files --others --exclude-standard) ]] ; then
local sym
zstyle -s ":vcs_info:${vcs}:clean:untracked" untrackedstr sym
hook_com[unstaged]+=$sym
fi
}
+vi-git-arrows() {
if zstyle -T ":vcs_info:${vcs}:clean:arrows" check-head
then
local arrows=$($vcs rev-list --left-right --count HEAD...@'{u}' 2> /dev/null)
local rev=("${(@z)arrows}")
local left=$rev[1] right=$rev[2]
local behind_arrow ahead_arrow
zstyle -s ":vcs_info:${vcs}:clean:arrows" headbehindstr behind_arrow
zstyle -s ":vcs_info:${vcs}:clean:arrows" headaheadstr ahead_arrow
unset arrows
if (( right > 0 ))
then
(( right > 1 )) && arrows+=$right
arrows+=$behind_arrow
fi
if (( left > 0 ))
then
(( left > 1 )) && arrows+=$left
arrows+=$ahead_arrow
fi
hook_com[action]+=$arrows
fi
}
### Prompt Hooks ###
prompt_clean_add_hooks() {
autoload -Uz add-zsh-hook
autoload -Uz vcs_info
add-zsh-hook chpwd prompt_clean_chpwd
add-zsh-hook precmd prompt_clean_precmd
add-zsh-hook preexec prompt_clean_preexec
}
prompt_clean_preexec() {
typeset -g cmd_timestamp=$EPOCHSECONDS
}
prompt_clean_precmd() {
psvar[4]=`prompt_clean_check_cmd_exec_time`
unset cmd_timestamp
vcs_info
psvar[1]=$vcs_info_msg_0_
psvar[2]=$vcs_info_msg_1_
psvar[3]=$vcs_info_msg_2_
psvar[5]=`prompt_clean_pwd`
}
prompt_clean_chpwd() {
((
git rev-parse --is-inside-work-tree &> /dev/null &&
git fetch &> /dev/null &&
prompt_clean_reprint
) &)
}
### Helpers ###
prompt_clean_reprint() {
## Removed for bug will re-add TODO
# vcs_info
# psvar[1]=$vcs_info_msg_0_
# psvar[2]=$vcs_info_msg_1_
# psvar[3]=$vcs_info_msg_2_
# psvar[5]=`prompt_clean_pwd`
#
# local l=`echo $PROMPT | wc -l`
# print -n "\e7"
# for (( i = 1 ; i < $l ; i++ ))
# do
# print -n "\e[1F\e[K"
# done
# print -Pn "\e[1G$PROMPT\e8"
}
prompt_clean_pwd() {
local num tmp p q
if [[ -v prompt_clean_pwd_length ]]; then
num=$prompt_clean_pwd_length
else
num=1
fi
p="${PWD#$HOME}"
if [[ $PWD != $p ]]; then
printf '~'
fi
local -a dirlist
dirlist=(${(ps:/:)p})
if [[ $num -ne 0 && ${#dirlist[@]} -gt $num ]]; then
for q in ${dirlist:0:(-$num)}; do
printf "/${q:0:1}"
done
for q in ${dirlist:(-$num)}; do
printf "/$q"
done
else
printf "$p"
fi
}
prompt_clean_check_cmd_exec_time() {
integer elapsed
(( elapsed = EPOCHSECONDS - ${cmd_timestamp:-$EPOCHSECONDS} ))
if (( elapsed > ${CMD_MAX_EXEC_TIME:-5} ))
then
print `prompt_clean_human_time_to_var $elapsed`
fi
}
# turns seconds into human readable time
# 165392 => 1d 21h 56m 32s
# https://github.com/sindresorhus/pretty-time-zsh
prompt_clean_human_time_to_var() {
local human total_seconds=$1
local days=$(( total_seconds / 60 / 60 / 24 ))
local hours=$(( total_seconds / 60 / 60 % 24 ))
local minutes=$(( total_seconds / 60 % 60 ))
local seconds=$(( total_seconds % 60 ))
(( days > 0 )) && human+="${days}d "
(( hours > 0 )) && human+="${hours}h "
(( minutes > 0 )) && human+="${minutes}m "
human+="${seconds}s"
# store human readable time in variable as specified by caller
print "${human}"
}