-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathpatatetoy_common.sh
259 lines (240 loc) · 7.72 KB
/
patatetoy_common.sh
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
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
# vim ft=bash
# This file define common function for zsh & bash prompt
#
# It define for prompts:
# - symbol/colors values
# - git & time functions
# - behaviors
#
# Git functions are extracted from:
# Bring a light and modified version of git-prompt.sh functions from Shawn O. Pearce <[email protected]>
# https://github.com/git/git/blob/master/contrib/completion/git-prompt.sh
# Config
export PATATETOY_CMD_MAX_EXEC_TIME=${PATATETOY_CMD_MAX_EXEC_TIME:-5}
export PATATETOY_FORCE_DISPLAY_USERNAME=${PATATETOY_FORCE_DISPLAY_USERNAME:-0}
export PATATETOY_GIT_PULL=${PATATETOY_GIT_PULL:-1}
export PATATETOY_GIT_STASH_CHECK=${PATATETOY_GIT_STASH_CHECK:-1}
export PATATETOY_GIT_UNTRACKED_DIRTY=${PATATETOY_GIT_UNTRACKED_DIRTY:-1}
# Symbols
export PATATETOY_GIT_DIRTY_SYMBOL=${PATATETOY_GIT_DIRTY_SYMBOL:-'✗'}
export PATATETOY_GIT_DOWN_ARROW=${PATATETOY_GIT_DOWN_ARROW:-⬇}
export PATATETOY_GIT_STASH_SYMBOL=${PATATETOY_GIT_STASH_SYMBOL:-"ⵢ"}
export PATATETOY_GIT_UP_ARROW=${PATATETOY_GIT_UP_ARROW:-⬆}
export PATATETOY_PROMPT_SYMBOL=${PATATETOY_PROMPT_SYMBOL:-❯}
export PATATETOY_ROOT_SYMBOL=${PATATATETOY_ROOT_SYMBOL:-"✦"}
# Colors
export PATATETOY_CURSOR_COLOR_KO=${PATATETOY_CURSOR_COLOR_KO:-red}
export PATATETOY_CURSOR_COLOR_OK=${PATATETOY_CURSOR_COLOR_OK:-yellow}
export PATATETOY_GIT_ARROW_COLOR=${PATATETOY_GIT_ARROW_COLOR:-yellow}
export PATATETOY_GIT_BRANCH_COLOR=${PATATETOY_GIT_BRANCH_COLOR:-darkgrey}
export PATATETOY_GIT_DIRTY_SYMBOL_COLOR=${PATATETOY_GIT_DIRTY_SYMBOL_COLOR:-darkgrey}
export PATATETOY_GIT_STASH_SYMBOL_COLOR=${PATATETOY_GIT_STASH_SYMBOL_COLOR:-cyan}
export PATATETOY_PATH_COLOR=${PATATETOY_PATH_COLOR:-blue}
export PATATETOY_ROOT_SYMBOL_COLOR=${PATATETOY_ROOT_SYMBOL_COLOR:-red}
export PATATETOY_USERNAME_COLOR=${PATATETOY_USERNAME_COLOR:-green}
export PATATETOY_VIRTUALENV_COLOR=${PATATETOY_VIRTUALENV_COLOR:-darkgrey}
# Helper function to read the first line of a file into a variable.
# __git_eread requires 2 arguments, the file path and the name of the
# variable, in that order.
# shellcheck disable=SC2162
__git_eread() {
test -r "$1" && IFS=$'\r\n' read "$2" <"$1"
}
# see if a cherry-pick or revert is in progress, if the user has committed a
# conflict resolution with 'git commit' in the middle of a sequence of picks or
# reverts then CHERRY_PICK_HEAD/REVERT_HEAD will not exist so we have to read
# the todo file.
__git_sequencer_status() {
local todo
if test -f "$g/CHERRY_PICK_HEAD"; then
r="|CHERRY-PICKING"
return 0
elif test -f "$g/REVERT_HEAD"; then
r="|REVERTING"
return 0
elif __git_eread "$g/sequencer/todo" todo; then
case "$todo" in
p[\ \ ] | pick[\ \ ]*)
r="|CHERRY-PICKING"
return 0
;;
revert[\ \ ]*)
r="|REVERTING"
return 0
;;
esac
fi
return 1
}
# Get git repo informations
#
# Exported vars:
# - patatetoy_vcs_legacy - don't use the '--count' option available in recent versions of git-rev-list
# - patatetoy_git_stash - contain stash symbol if some stash exists
# - patatetoy_git_branch - contain the name of the current branch
# - patatetoy_git_action - contain action such as REBASE/CHERRY-PICK
# - patatetoy_git_inside_worktree - if in git repo
#
_patatetoy_vcs_info() {
export patatetoy_vcs_legacy
export patatetoy_git_stash
export patatetoy_git_branch
export patatetoy_git_action
export patatetoy_git_inside_worktree
# preserve exit status
local exit=$?
[ -z "${ZSH_VERSION-}" ] || [[ -o PROMPT_SUBST ]]
[ -z "${BASH_VERSION-}" ] || shopt -q promptvars
local repo_info rev_parse_exit_code
local short_sha
repo_info="$(git rev-parse --git-dir --is-inside-git-dir \
--is-bare-repository --is-inside-work-tree \
--short HEAD 2>/dev/null)"
rev_parse_exit_code="$?"
if [ -z "$repo_info" ]; then
return $exit
fi
if [ "$rev_parse_exit_code" = "0" ]; then
short_sha="${repo_info##*$'\n'}"
repo_info="${repo_info%$'\n'*}"
fi
patatetoy_git_inside_worktree="${repo_info##*$'\n'}"
repo_info="${repo_info%$'\n'*}"
repo_info="${repo_info%$'\n'*}"
g="${repo_info%$'\n'*}"
# Stash
if [[ "$PATATETOY_GIT_STASH_CHECK" == "1" && $(git stash list 2>/dev/null | tail -n1) != "" ]]; then
patatetoy_git_stash=$PATATETOY_GIT_STASH_SYMBOL
fi
# Branch / Action
local r=""
local b=""
local step=""
local total=""
if [ -d "$g/rebase-merge" ]; then
__git_eread "$g/rebase-merge/head-name" b
__git_eread "$g/rebase-merge/msgnum" step
__git_eread "$g/rebase-merge/end" total
if [ -f "$g/rebase-merge/interactive" ]; then
r="|REBASE-i"
else
r="|REBASE-m"
fi
else
if [ -d "$g/rebase-apply" ]; then
__git_eread "$g/rebase-apply/next" step
__git_eread "$g/rebase-apply/last" total
if [ -f "$g/rebase-apply/rebasing" ]; then
__git_eread "$g/rebase-apply/head-name" b
r="|REBASE"
elif [ -f "$g/rebase-apply/applying" ]; then
r="|AM"
else
r="|AM/REBASE"
fi
elif [ -f "$g/MERGE_HEAD" ]; then
r="|MERGING"
elif __git_sequencer_status; then
:
elif [ -f "$g/BISECT_LOG" ]; then
r="|BISECTING"
fi
if [ -n "$b" ]; then
:
elif [ -h "$g/HEAD" ]; then
# symlink symbolic ref
b="$(git symbolic-ref HEAD 2>/dev/null)"
else
local head=""
if ! __git_eread "$g/HEAD" head; then
return $exit
fi
# is it a symbolic ref?
b="${head#ref: }"
if [ "$head" = "$b" ]; then
b="$(
case "${GIT_PS1_DESCRIBE_STYLE-}" in
contains)
git describe --contains HEAD
;;
branch)
git describe --contains --all HEAD
;;
tag)
git describe --tags HEAD
;;
describe)
git describe HEAD
;;
*)
git describe --tags --exact-match HEAD
;;
esac 2>/dev/null
)" ||
b="$short_sha..."
b="($b)"
fi
fi
fi
if [ -n "$step" ] && [ -n "$total" ]; then
r="$r $step/$total "
fi
b=${b##refs/heads/}
patatetoy_git_branch="${b}"
patatetoy_git_action="${r}"
}
# Detect changes with upstreams
#
# Exported vars:
# - patatetoy_git_upstream - git arrow symbols
#
_patatetoy_vcs_upstream() {
export patatetoy_git_upstream=
local count
local p
# Find how many commits we are ahead/behind our upstream
count=$(git rev-list --count --left-right "@{u}"...HEAD 2>/dev/null)
case "$count" in
"") # no upstream
p="" ;;
"0 0") # equal to upstream
p="" ;;
"0 "*) # ahead of upstream
p=$PATATETOY_GIT_UP_ARROW ;;
*" 0") # behind upstream
p=$PATATETOY_GIT_DOWN_ARROW ;;
*) # diverged from upstream
p=${PATATETOY_GIT_DOWN_ARROW}${PATATETOY_GIT_UP_ARROW} ;;
esac
patatetoy_git_upstream="$p"
}
# Check if repo is dirty
# Return check command code
_patatetoy_vcs_dirty() {
if [[ "$PATATETOY_GIT_UNTRACKED_DIRTY" == "0" ]]; then
command git diff --no-ext-diff --quiet --exit-code
else
test -z "$(command git status --porcelain --ignore-submodules -unormal)"
fi
return $?
}
# Calculate elapsed time in human readable format
# Exported vars:
# - patatetoy_cmd_human_time - elapsed time in seconds, minutes, hours...
#
_patatetoy_cmd_exec_time() {
local elapsed=$1
export patatetoy_human_exec_time
if [[ $elapsed -gt $PATATETOY_CMD_MAX_EXEC_TIME ]]; then
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"
patatetoy_human_exec_time="${human}"
fi
}