-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathprompt.zsh
146 lines (121 loc) · 4.49 KB
/
prompt.zsh
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
##########
# Colors #
###########
# autoload docs: http://zsh.sourceforge.net/Doc/Release/Shell-Builtin-Commands.html
# colors provides `$fg_bold` etc: http://zsh.sourceforge.net/Doc/Release/User-Contributions.html#Other-Functions
autoload -Uz colors && colors
prompt_color() {
[[ -n "$1" ]] && print "%{$fg_bold[$2]%}$1%{$reset_color%}"
}
prompt_gray() { print "$(prompt_color "$1" grey)" }
prompt_yellow() { print "$(prompt_color "$1" yellow)" }
prompt_green() { print "$(prompt_color "$1" green)" }
prompt_red() { print "$(prompt_color "$1" red)" }
prompt_cyan() { print "$(prompt_color "$1" cyan)" }
prompt_blue() { print "$(prompt_color "$1" blue)" }
prompt_magenta(){ print "$(prompt_color "$1" magenta)" }
prompt_spaced() { [[ -n "$1" ]] && print " $@" }
prompt() { [[ -n "$1" ]] && print "$@" }
###########################################
# Helper functions: path and Ruby version #
###########################################
# %2~ means "show the last two components of the path, and show the home
# directory as ~".
#
# Examples:
#
# ~/foo/bar is shown as "foo/bar"
# ~/foo is shown as ~/foo (not /Users/gabe/foo)
prompt_shortened_path() { print "$(prompt_blue "%2~")" }
prompt_ruby_version() {
local version=$(rbenv version-name)
prompt_magenta "$version"
}
#######################
# GIT (branch, vcs) #
#######################
#
# vcs_info docs: http://zsh.sourceforge.net/Doc/Release/User-Contributions.html#Version-Control-Information
autoload -Uz vcs_info
zstyle ':vcs_info:*' enable git
zstyle ':vcs_info:git*' formats $(prompt_yellow "%b")
zstyle ':vcs_info:git*' actionformats $(prompt_red "%b|%a")
prompt_git_status_symbol(){
local letter
# http://www.fileformat.info/info/unicode/char/2714/index.htm
local checkmark="\u2714"
# http://www.fileformat.info/info/unicode/char/2718/index.htm
local x_mark="\u2718"
case $(prompt_git_status) in
changed) letter=$(prompt_red $x_mark);;
staged) letter=$(prompt_yellow "S");;
untracked) letter=$(prompt_cyan "UT");;
unchanged) letter=$(prompt_green $checkmark);;
esac
prompt_spaced "$letter"
}
# Is this branch ahead/behind its remote tracking branch?
prompt_git_relative_branch_status_symbol(){
local arrow;
# Sources:
# http://www.fileformat.info/info/unicode/char/21e3/index.htm
# http://www.fileformat.info/info/unicode/char/21e1/index.htm
local downwards_arrow="\u21e3"
local upwards_arrow="\u21e1"
case $(prompt_git_relative_branch_status) in
behind) arrow=$(prompt_cyan $downwards_arrow);;
ahead) arrow=$(prompt_cyan $upwards_arrow);;
esac
print -n "$arrow"
}
prompt_git_status() {
local git_status="$(cat "/tmp/git-status-$$")"
if print "$git_status" | grep -qF "Changes not staged" ; then
print "changed"
elif print "$git_status" | grep -qF "Changes to be committed"; then
print "staged"
elif print "$git_status" | grep -qF "Untracked files"; then
print "untracked"
elif print "$git_status" | grep -qF "working directory clean"; then
print "unchanged"
fi
}
prompt_git_relative_branch_status(){
local git_status="$(cat "/tmp/git-status-$$")"
if print "$git_status" | grep -qF "Your branch is behind"; then
print "behind"
elif print "$git_status" | grep -qF "Your branch is ahead"; then
print "ahead"
fi
}
prompt_git_branch() {
# vcs_info_msg_0_ is set by the `zstyle vcs_info` directives
local colored_branch_name="$vcs_info_msg_0_"
prompt "$colored_branch_name"
}
# This shows everything about the current git branch:
# * branch name
# * check mark/x mark/letter etc depending on whether branch is dirty, clean,
# has staged changes, etc
# * Up arrow if local branch is ahead of remote branch, or down arrow if local
# branch is behind remote branch
prompt_full_git_status(){
if [[ -n "$vcs_info_msg_0_" ]]; then
prompt_spaced "($(prompt_git_branch))" $(prompt_git_status_symbol) $(prompt_git_relative_branch_status_symbol)
fi
}
# `precmd` is a magic function that's run right before the prompt is evaluated
# on each line.
# Here, it's used to capture the git status to show in the prompt.
function precmd {
vcs_info
git status 2> /dev/null >! "/tmp/git-status-$$"
}
###########################
# Actually set the PROMPT #
###########################
# prompt_subst allows `$(function)` inside the PROMPT
# Escape the `$()` like `\$()` so it's not immediately evaluated when this file
# is sourced but is evaluated every time we need the prompt.
setopt prompt_subst
export PROMPT="\$(prompt_ruby_version) \$(prompt_shortened_path)\$(prompt_full_git_status) "