agnoster.zsh-theme 6.09 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
prompt_hg() {
131
  (( $+commands[hg] )) || return
Eddie Monge's avatar
Eddie Monge committed
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
  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)
152
      if `hg st | grep -q "^\?"`; then
Eddie Monge's avatar
Eddie Monge committed
153
154
        prompt_segment red black
        st='±'
Mark Mendoza's avatar
Mark Mendoza committed
155
      elif `hg st | grep -q "^[MA]"`; then
Eddie Monge's avatar
Eddie Monge committed
156
157
158
159
160
161
162
163
        prompt_segment yellow black
        st='±'
      else
        prompt_segment green black
      fi
      echo -n "☿ $rev@$branch" $st
    fi
  fi
164
165
}

166
167
168
# Dir: current working directory
prompt_dir() {
  prompt_segment blue black '%~'
Isaac Wolkerstorfer's avatar
Isaac Wolkerstorfer committed
169
170
}

171
172
173
# Virtualenv: current working virtualenv
prompt_virtualenv() {
  local virtualenv_path="$VIRTUAL_ENV"
174
  if [[ -n $virtualenv_path && -n $VIRTUAL_ENV_DISABLE_PROMPT ]]; then
175
176
177
178
    prompt_segment blue black "(`basename $virtualenv_path`)"
  fi
}

179
180
181
182
183
# Status:
# - was there an error
# - am I root
# - are there background jobs?
prompt_status() {
Isaac Wolkerstorfer's avatar
Isaac Wolkerstorfer committed
184
185
  local symbols
  symbols=()
186
  [[ $RETVAL -ne 0 ]] && symbols+="%{%F{red}%}✘"
Isaac Wolkerstorfer's avatar
Isaac Wolkerstorfer committed
187
  [[ $UID -eq 0 ]] && symbols+="%{%F{yellow}%}⚡"
188
189
190
  [[ $(jobs -l | wc -l) -gt 0 ]] && symbols+="%{%F{cyan}%}⚙"

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

Isaac Wolkerstorfer's avatar
Isaac Wolkerstorfer committed
193
## Main prompt
194
build_prompt() {
Isaac Wolkerstorfer's avatar
Isaac Wolkerstorfer committed
195
196
  RETVAL=$?
  prompt_status
197
  prompt_virtualenv
198
  prompt_context
Isaac Wolkerstorfer's avatar
Isaac Wolkerstorfer committed
199
200
  prompt_dir
  prompt_git
201
  prompt_hg
202
  prompt_end
Isaac Wolkerstorfer's avatar
Isaac Wolkerstorfer committed
203
}
Isaac Wolkerstorfer's avatar
Isaac Wolkerstorfer committed
204

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