forked from geerlingguy/dotfiles
-
Notifications
You must be signed in to change notification settings - Fork 2
/
.prompt_command
190 lines (160 loc) · 4.79 KB
/
.prompt_command
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
#!/usr/bin/env bash
# vim: set noexpandtab:
# configure bash prompt with git info
# forked from https://github.com/twolfson/sexy-bash-prompt (MIT)
# afirth 2018
# set -ux
source .prompt_colors
PROMPT_COMMAND=prompt_command
# Define the prompt
function prompt_command() {
retval=$?
history -a
# exit status, time, user, host, directory
PS1="\[$txtrst\]$(prompt_get_exit_status) [\t] \u@\h \w\[$txtrst\]"
# git info
if prompt_is_on_git; then
PS1="${PS1} \[$txtcyn\]$(prompt_get_git_info)\[$txtylw\]$(prompt_get_git_progress)"
fi
# new line, prompt, and clear format
PS1="${PS1} \n\[$txtrst\]\[$txtcyn\]\$ \[$txtrst\]"
export PS1
}
# Set up symbols
prompt_synced_symbol="👌"
prompt_dirty_synced_symbol="*"
prompt_unpushed_symbol="△"
prompt_dirty_unpushed_symbol="▲"
prompt_unpulled_symbol="▽"
prompt_dirty_unpulled_symbol="▼"
prompt_unpushed_unpulled_symbol="⬡"
prompt_dirty_unpushed_unpulled_symbol="⬢"
function prompt_get_git_branch() {
# On branches, this will return the branch name
# On non-branches, (no branch)
ref=$(git symbolic-ref HEAD --short 2> /dev/null)
if [[ "$ref" != "" ]]; then
echo "$ref"
else
echo "(no branch)"
fi
}
function prompt_get_exit_status() {
if [[ $retval -eq 0 ]]; then
echo -n "✓"
else
echo -n "❌($retval)"
fi
}
function prompt_get_git_progress() {
# Detect in-progress actions (e.g. merge, rebase)
# https://github.com/git/git/blob/v1.9-rc2/wt-status.c#L1199-L1241
git_dir="$(git rev-parse --git-dir)"
# git merge
if [[ -f "$git_dir/MERGE_HEAD" ]]; then
echo " [merge]"
elif [[ -d "$git_dir/rebase-apply" ]]; then
# git am
if [[ -f "$git_dir/rebase-apply/applying" ]]; then
echo " [am]"
# git rebase
else
echo " [rebase]"
fi
elif [[ -d "$git_dir/rebase-merge" ]]; then
# git rebase --interactive/--merge
echo " [rebase]"
elif [[ -f "$git_dir/CHERRY_PICK_HEAD" ]]; then
# git cherry-pick
echo " [cherry-pick]"
fi
if [[ -f "$git_dir/BISECT_LOG" ]]; then
# git bisect
echo " [bisect]"
fi
if [[ -f "$git_dir/REVERT_HEAD" ]]; then
# git revert --no-commit
echo " [revert]"
fi
}
prompt_is_branch1_behind_branch2 () {
# Unsynced commit
# Find the first log (if any) that is in branch1 but not branch2
first_log="$(git log $1..$2 -1 2> /dev/null)"
# Exit with 0 if there is a first log, 1 if there is not
[[ -n "$first_log" ]]
}
prompt_branch_exists () {
# List remote branches | # Find our branch and exit with 0 or 1 if found/not found
git branch --remote 2> /dev/null | grep --quiet "$1"
}
prompt_parse_git_ahead () {
# Grab the local and remote branch
branch="$(prompt_get_git_branch)"
remote="$(git config --get "branch.${branch}.remote" || echo -n "origin")"
remote_branch="$remote/$branch"
# If the remote branch is behind the local branch
# or it has not been merged into origin (remote branch doesn't exist)
if (prompt_is_branch1_behind_branch2 "$remote_branch" "$branch" ||
! prompt_branch_exists "$remote_branch"); then
# echo our character
echo 1
fi
}
prompt_parse_git_behind () {
# Grab the branch
branch="$(prompt_get_git_branch)"
remote="$(git config --get "branch.${branch}.remote" || echo -n "origin")"
remote_branch="$remote/$branch"
# If the local branch is behind the remote branch
if prompt_is_branch1_behind_branch2 "$branch" "$remote_branch"; then
# echo our character
echo 1
fi
}
function prompt_parse_git_dirty() {
# If the git status has *any* changes (e.g. dirty), echo our character
if [[ -n "$(git status --porcelain 2> /dev/null)" ]]; then
echo 1
fi
}
function prompt_is_on_git() {
git rev-parse &> /dev/null
}
function prompt_get_git_status() {
# Grab the git dirty and git behind
dirty_branch="$(prompt_parse_git_dirty)"
branch_ahead="$(prompt_parse_git_ahead)"
branch_behind="$(prompt_parse_git_behind)"
# Iterate through all the cases and if it matches, then echo
if [[ "$dirty_branch" == 1 && "$branch_ahead" == 1 && "$branch_behind" == 1 ]]; then
echo "$prompt_dirty_unpushed_unpulled_symbol"
elif [[ "$branch_ahead" == 1 && "$branch_behind" == 1 ]]; then
echo "$prompt_unpushed_unpulled_symbol"
elif [[ "$dirty_branch" == 1 && "$branch_ahead" == 1 ]]; then
echo "$prompt_dirty_unpushed_symbol"
elif [[ "$branch_ahead" == 1 ]]; then
echo "$prompt_unpushed_symbol"
elif [[ "$dirty_branch" == 1 && "$branch_behind" == 1 ]]; then
echo "$prompt_dirty_unpulled_symbol"
elif [[ "$branch_behind" == 1 ]]; then
echo "$prompt_unpulled_symbol"
elif [[ "$dirty_branch" == 1 ]]; then
echo "$prompt_dirty_synced_symbol"
else # clean
echo "$prompt_synced_symbol"
fi
}
prompt_get_git_info () {
# Grab the branch
branch="$(prompt_get_git_branch)"
# If there are any branches
if [[ "$branch" != "" ]]; then
# Echo the branch
output="$branch"
# Add on the git status
output="$output$(prompt_get_git_status)"
# Echo our output
echo "$output"
fi
}