agnoster.zsh-theme 6.74 KB
Newer Older
1
2
# vim:ft=zsh ts=2 sw=2 sts=2
#
Isaac Wolkerstorfer's avatar
Isaac Wolkerstorfer committed
3
# agnoster's Theme - https://gist.github.com/3712874
4
5
6
7
8
# A Powerline-inspired theme for ZSH
#
# # README
#
# In order for this theme to render correctly, you will need a
9
# [Powerline-patched font](https://github.com/Lokaltog/powerline-fonts).
10
11
12
# Make sure you have a recent version: the code points that Powerline
# uses changed in 2012, and older versions will display incorrectly,
# in confusing ways.
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
#
# In addition, I recommend the
# [Solarized theme](https://github.com/altercation/solarized/) and, if you're
# using it on Mac OS X, [iTerm 2](http://www.iterm2.com/) over Terminal.app -
# it has significantly better color fidelity.
#
# # Goals
#
# The aim of this theme is to only show you *relevant* information. Like most
# prompts, it will only show git information when in a git working directory.
# However, it goes a step further: everything from the current user and
# hostname to whether the last call exited with an error to whether background
# jobs are running in this shell will all be displayed automatically when
# appropriate.

Isaac Wolkerstorfer's avatar
Isaac Wolkerstorfer committed
28
29
### Segment drawing
# A few utility functions to make it easy and re-usable to draw segmented prompts
Isaac Wolkerstorfer's avatar
Isaac Wolkerstorfer committed
30

31
CURRENT_BG='NONE'
32

33
34
# Special Powerline characters

35
36
37
38
() {
  local LC_ALL="" LC_CTYPE="en_US.UTF-8"
  # NOTE: This segment separator character is correct.  In 2012, Powerline changed
  # the code points they use for their special characters. This is the new code point.
39
  # If this is not working for you, you probably have an old version of the
40
41
42
43
44
45
  # Powerline-patched fonts installed. Download and install the new version.
  # Do not submit PRs to change this unless you have reviewed the Powerline code point
  # history and have new information.
  # This is defined using a Unicode escape sequence so it is unambiguously readable, regardless of
  # what font the user is viewing this source code in. Do not replace the
  # escape sequence with a single literal character.
46
47
  # Do not change this! Do not make it '\u2b80'; that is the old, wrong code point.
  SEGMENT_SEPARATOR=$'\ue0b0'
48
}
49
50
51
52
53
54
55
56
57
58

# Begin a segment
# Takes two arguments, background and foreground. Both can be omitted,
# rendering default background/foreground.
prompt_segment() {
  local bg fg
  [[ -n $1 ]] && bg="%K{$1}" || bg="%k"
  [[ -n $2 ]] && fg="%F{$2}" || fg="%f"
  if [[ $CURRENT_BG != 'NONE' && $1 != $CURRENT_BG ]]; then
    echo -n " %{$bg%F{$CURRENT_BG}%}$SEGMENT_SEPARATOR%{$fg%} "
Isaac Wolkerstorfer's avatar
Isaac Wolkerstorfer committed
59
  else
60
    echo -n "%{$bg%}%{$fg%} "
Isaac Wolkerstorfer's avatar
Isaac Wolkerstorfer committed
61
  fi
62
63
  CURRENT_BG=$1
  [[ -n $3 ]] && echo -n $3
Isaac Wolkerstorfer's avatar
Isaac Wolkerstorfer committed
64
}
Isaac Wolkerstorfer's avatar
Isaac Wolkerstorfer committed
65

66
67
# End the prompt, closing any open segments
prompt_end() {
Isaac Wolkerstorfer's avatar
Isaac Wolkerstorfer committed
68
69
70
71
72
73
74
  if [[ -n $CURRENT_BG ]]; then
    echo -n " %{%k%F{$CURRENT_BG}%}$SEGMENT_SEPARATOR"
  else
    echo -n "%{%k%}"
  fi
  echo -n "%{%f%}"
  CURRENT_BG=''
Isaac Wolkerstorfer's avatar
Isaac Wolkerstorfer committed
75
76
}

Isaac Wolkerstorfer's avatar
Isaac Wolkerstorfer committed
77
78
79
### Prompt components
# Each component will draw itself, and hide itself if no information needs to be shown

80
81
# Context: user@hostname (who am I and where am I)
prompt_context() {
82
83
  if [[ "$USER" != "$DEFAULT_USER" || -n "$SSH_CLIENT" ]]; then
    prompt_segment black default "%(!.%{%F{yellow}%}.)$USER@%m"
Isaac Wolkerstorfer's avatar
Isaac Wolkerstorfer committed
84
85
86
  fi
}

87
88
# Git: branch/detached head, dirty status
prompt_git() {
89
90
91
92
93
94

  local PL_BRANCH_CHAR
  () {
    local LC_ALL="" LC_CTYPE="en_US.UTF-8"
    PL_BRANCH_CHAR=$'\ue0a0'         # 
  }
95
96
97
  local ref dirty mode repo_path
  repo_path=$(git rev-parse --git-dir 2>/dev/null)

Isaac Wolkerstorfer's avatar
Isaac Wolkerstorfer committed
98
  if $(git rev-parse --is-inside-work-tree >/dev/null 2>&1); then
99
    dirty=$(parse_git_dirty)
100
    ref=$(git symbolic-ref HEAD 2> /dev/null) || ref="➦ $(git rev-parse --short HEAD 2> /dev/null)"
Isaac Wolkerstorfer's avatar
Isaac Wolkerstorfer committed
101
    if [[ -n $dirty ]]; then
102
      prompt_segment yellow black
Isaac Wolkerstorfer's avatar
Isaac Wolkerstorfer committed
103
    else
104
      prompt_segment green black
Isaac Wolkerstorfer's avatar
Isaac Wolkerstorfer committed
105
    fi
106

107
108
109
110
111
112
113
114
    if [[ -e "${repo_path}/BISECT_LOG" ]]; then
      mode=" <B>"
    elif [[ -e "${repo_path}/MERGE_HEAD" ]]; then
      mode=" >M<"
    elif [[ -e "${repo_path}/rebase" || -e "${repo_path}/rebase-apply" || -e "${repo_path}/rebase-merge" || -e "${repo_path}/../.dotest" ]]; then
      mode=" >R>"
    fi

115
116
117
118
119
120
121
    setopt promptsubst
    autoload -Uz vcs_info

    zstyle ':vcs_info:*' enable git
    zstyle ':vcs_info:*' get-revision true
    zstyle ':vcs_info:*' check-for-changes true
    zstyle ':vcs_info:*' stagedstr '✚'
122
    zstyle ':vcs_info:*' unstagedstr '●'
123
    zstyle ':vcs_info:*' formats ' %u%c'
124
    zstyle ':vcs_info:*' actionformats ' %u%c'
125
    vcs_info
126
    echo -n "${ref/refs\/heads\//$PL_BRANCH_CHAR }${vcs_info_msg_0_%% }${mode}"
Isaac Wolkerstorfer's avatar
Isaac Wolkerstorfer committed
127
128
129
  fi
}

130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
prompt_bzr() {
    if (bzr status >/dev/null 2>&1); then
        status_mod=`bzr status | head -n1 | grep "modified" | wc -m`
        status_all=`bzr status | head -n1 | wc -m`
        revision=`bzr log | head -n2 | tail -n1 | sed 's/^revno: //'`
        if [[ $status_mod -gt 0 ]] ; then
            prompt_segment yellow black
            echo -n "bzr@"$revision "✚ "
        else
            if [[ $status_all -gt 0 ]] ; then
                prompt_segment yellow black
                echo -n "bzr@"$revision

            else
                prompt_segment green black
                echo -n "bzr@"$revision
            fi
        fi
    fi
}

151
prompt_hg() {
152
  (( $+commands[hg] )) || return
Eddie Monge's avatar
Eddie Monge committed
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
  local rev status
  if $(hg id >/dev/null 2>&1); then
    if $(hg prompt >/dev/null 2>&1); then
      if [[ $(hg prompt "{status|unknown}") = "?" ]]; then
        # if files are not added
        prompt_segment red white
        st='±'
      elif [[ -n $(hg prompt "{status|modified}") ]]; then
        # if any modification
        prompt_segment yellow black
        st='±'
      else
        # if working copy is clean
        prompt_segment green black
      fi
      echo -n $(hg prompt "☿ {rev}@{branch}") $st
    else
      st=""
      rev=$(hg id -n 2>/dev/null | sed 's/[^-0-9]//g')
      branch=$(hg id -b 2>/dev/null)
173
      if `hg st | grep -q "^\?"`; then
Eddie Monge's avatar
Eddie Monge committed
174
175
        prompt_segment red black
        st='±'
Mark Mendoza's avatar
Mark Mendoza committed
176
      elif `hg st | grep -q "^[MA]"`; then
Eddie Monge's avatar
Eddie Monge committed
177
178
179
180
181
182
183
184
        prompt_segment yellow black
        st='±'
      else
        prompt_segment green black
      fi
      echo -n "☿ $rev@$branch" $st
    fi
  fi
185
186
}

187
188
189
# Dir: current working directory
prompt_dir() {
  prompt_segment blue black '%~'
Isaac Wolkerstorfer's avatar
Isaac Wolkerstorfer committed
190
191
}

192
193
194
# Virtualenv: current working virtualenv
prompt_virtualenv() {
  local virtualenv_path="$VIRTUAL_ENV"
195
  if [[ -n $virtualenv_path && -n $VIRTUAL_ENV_DISABLE_PROMPT ]]; then
196
197
198
199
    prompt_segment blue black "(`basename $virtualenv_path`)"
  fi
}

200
201
202
203
204
# Status:
# - was there an error
# - am I root
# - are there background jobs?
prompt_status() {
Isaac Wolkerstorfer's avatar
Isaac Wolkerstorfer committed
205
206
  local symbols
  symbols=()
207
  [[ $RETVAL -ne 0 ]] && symbols+="%{%F{red}%}✘"
Isaac Wolkerstorfer's avatar
Isaac Wolkerstorfer committed
208
  [[ $UID -eq 0 ]] && symbols+="%{%F{yellow}%}⚡"
209
210
211
  [[ $(jobs -l | wc -l) -gt 0 ]] && symbols+="%{%F{cyan}%}⚙"

  [[ -n "$symbols" ]] && prompt_segment black default "$symbols"
Isaac Wolkerstorfer's avatar
Isaac Wolkerstorfer committed
212
213
}

Isaac Wolkerstorfer's avatar
Isaac Wolkerstorfer committed
214
## Main prompt
215
build_prompt() {
Isaac Wolkerstorfer's avatar
Isaac Wolkerstorfer committed
216
217
  RETVAL=$?
  prompt_status
218
  prompt_virtualenv
219
  prompt_context
Isaac Wolkerstorfer's avatar
Isaac Wolkerstorfer committed
220
221
  prompt_dir
  prompt_git
222
  prompt_bzr
223
  prompt_hg
224
  prompt_end
Isaac Wolkerstorfer's avatar
Isaac Wolkerstorfer committed
225
}
Isaac Wolkerstorfer's avatar
Isaac Wolkerstorfer committed
226

227
PROMPT='%{%f%b%k%}$(build_prompt) '