├── screenshot.png ├── README.md ├── LICENSE.md └── theme.bash /screenshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/diesire/git_bash_windows_powerline/HEAD/screenshot.png -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Git bash for windows powerline theme 2 | 3 | Light & simple powerline theme for Git bash for windows 4 | 5 | ![ScreenShot](screenshot.png) 6 | 7 | 8 | ## Install: 9 | 10 | I recommend the following: 11 | 12 | ```bash 13 | cd $HOME 14 | mkdir -p .bash/themes/git_bash_windows_powerline 15 | git clone https://github.com/diesire/git_bash_windows_powerline.git .bash/themes/git_bash_windows_powerline 16 | ``` 17 | 18 | then add the following to your .bashrc: 19 | 20 | ```bash 21 | # Theme 22 | THEME=$HOME/.bash/themes/git_bash_windows_powerline/theme.bash 23 | if [ -f $THEME ]; then 24 | . $THEME 25 | fi 26 | unset THEME 27 | ``` 28 | 29 | ## Requisites 30 | 31 | * In order for this theme to render correctly, you will need a 32 | [Powerline-patched font](https://github.com/powerline/fonts). 33 | 34 | ## License 35 | 36 | MIT 37 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017 Pablo Escalada 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /theme.bash: -------------------------------------------------------------------------------- 1 | # Git bash for windows powerline theme 2 | # 3 | # Licensed under MIT 4 | # Based on https://github.com/Bash-it/bash-it and https://github.com/Bash-it/bash-it/tree/master/themes/powerline 5 | # Some ideas from https://github.com/speedenator/agnoster-bash 6 | # Git code based on https://github.com/joeytwiddle/git-aware-prompt/blob/master/prompt.sh 7 | # More info about color codes in https://en.wikipedia.org/wiki/ANSI_escape_code 8 | 9 | 10 | PROMPT_CHAR=${POWERLINE_PROMPT_CHAR:=""} 11 | POWERLINE_LEFT_SEPARATOR=" " 12 | POWERLINE_PROMPT="last_status user_info cwd scm" 13 | 14 | USER_INFO_SSH_CHAR=" " 15 | USER_INFO_PROMPT_COLOR="C B" 16 | 17 | SCM_GIT_CHAR=" " 18 | SCM_PROMPT_CLEAN="" 19 | SCM_PROMPT_DIRTY="*" 20 | SCM_PROMPT_AHEAD="↑" 21 | SCM_PROMPT_BEHIND="↓" 22 | SCM_PROMPT_CLEAN_COLOR="G Bl" 23 | SCM_PROMPT_DIRTY_COLOR="R Bl" 24 | SCM_PROMPT_AHEAD_COLOR="" 25 | SCM_PROMPT_BEHIND_COLOR="" 26 | SCM_PROMPT_STAGED_COLOR="Y Bl" 27 | SCM_PROMPT_UNSTAGED_COLOR="R Bl" 28 | SCM_PROMPT_COLOR=${SCM_PROMPT_CLEAN_COLOR} 29 | 30 | CWD_PROMPT_COLOR="B C" 31 | 32 | STATUS_PROMPT_COLOR="Bl R B" 33 | STATUS_PROMPT_ERROR="✘" 34 | STATUS_PROMPT_ERROR_COLOR="Bl R B" 35 | STATUS_PROMPT_ROOT="⚡" 36 | STATUS_PROMPT_ROOT_COLOR="Bl Y B" 37 | STATUS_PROMPT_JOBS="●" 38 | STATUS_PROMPT_JOBS_COLOR="Bl Y B" 39 | 40 | function __color { 41 | local bg 42 | local fg 43 | local mod 44 | case $1 in 45 | 'Bl') bg=40;; 46 | 'R') bg=41;; 47 | 'G') bg=42;; 48 | 'Y') bg=43;; 49 | 'B') bg=44;; 50 | 'M') bg=45;; 51 | 'C') bg=46;; 52 | 'W') bg=47;; 53 | *) bg=49;; 54 | esac 55 | 56 | case $2 in 57 | 'Bl') fg=30;; 58 | 'R') fg=31;; 59 | 'G') fg=32;; 60 | 'Y') fg=33;; 61 | 'B') fg=34;; 62 | 'M') fg=35;; 63 | 'C') fg=36;; 64 | 'W') fg=37;; 65 | *) fg=39;; 66 | esac 67 | 68 | case $3 in 69 | 'B') mod=1;; 70 | *) mod=0;; 71 | esac 72 | 73 | # Control codes enclosed in \[\] to not polute PS1 74 | # See http://unix.stackexchange.com/questions/71007/how-to-customize-ps1-properly 75 | echo "\[\e[${mod};${fg};${bg}m\]" 76 | } 77 | 78 | function __powerline_user_info_prompt { 79 | local user_info="" 80 | local color=${USER_INFO_PROMPT_COLOR} 81 | if [[ -n "${SSH_CLIENT}" ]]; then 82 | user_info="${USER_INFO_SSH_CHAR}\u@\h" 83 | else 84 | user_info="\u@\h" 85 | fi 86 | [[ -n "${user_info}" ]] && echo "${user_info}|${color}" 87 | } 88 | 89 | function __powerline_cwd_prompt { 90 | echo "\w|${CWD_PROMPT_COLOR}" 91 | } 92 | 93 | function __powerline_scm_prompt { 94 | git_local_branch="" 95 | git_branch="" 96 | git_dirty="" 97 | git_dirty_count="" 98 | git_ahead_count="" 99 | git_ahead="" 100 | git_behind_count="" 101 | git_behind="" 102 | 103 | find_git_branch() { 104 | # Based on: http://stackoverflow.com/a/13003854/170413 105 | git_local_branch=$(git rev-parse --abbrev-ref HEAD 2> /dev/null) 106 | 107 | if [[ -n "$git_local_branch" ]]; then 108 | if [[ "$git_local_branch" == "HEAD" ]]; then 109 | # Branc detached Could show the hash here 110 | git_branch=$(git rev-parse --short HEAD 2>/dev/null) 111 | else 112 | git_branch=$git_local_branch 113 | fi 114 | else 115 | git_branch="" 116 | return 1 117 | fi 118 | } 119 | 120 | find_git_dirty() { 121 | # All dirty files (modified and untracked) 122 | local status_count=$(git status --porcelain 2> /dev/null | wc -l) 123 | 124 | if [[ "$status_count" != 0 ]]; then 125 | git_dirty=true 126 | git_dirty_count="$status_count" 127 | else 128 | git_dirty='' 129 | git_dirty_count='' 130 | fi 131 | } 132 | 133 | find_git_ahead_behind() { 134 | if [[ -n "$git_local_branch" ]] && [[ "$git_branch" != "HEAD" ]]; then 135 | local upstream_branch=$(git rev-parse --abbrev-ref "@{upstream}" 2> /dev/null) 136 | # If we get back what we put in, then that means the upstream branch was not found. (This was observed on git 1.7.10.4 on Ubuntu) 137 | [[ "$upstream_branch" = "@{upstream}" ]] && upstream_branch='' 138 | # If the branch is not tracking a specific remote branch, then assume we are tracking origin/[this_branch_name] 139 | [[ -z "$upstream_branch" ]] && upstream_branch="origin/$git_local_branch" 140 | if [[ -n "$upstream_branch" ]]; then 141 | git_ahead_count=$(git rev-list --left-right ${git_local_branch}...${upstream_branch} 2> /dev/null | grep -c '^<') 142 | git_behind_count=$(git rev-list --left-right ${git_local_branch}...${upstream_branch} 2> /dev/null | grep -c '^>') 143 | if [[ "$git_ahead_count" = 0 ]]; then 144 | git_ahead_count='' 145 | else 146 | git_ahead=true 147 | fi 148 | if [[ "$git_behind_count" = 0 ]]; then 149 | git_behind_count='' 150 | else 151 | git_behind=true 152 | fi 153 | fi 154 | fi 155 | } 156 | 157 | 158 | local color 159 | local scm_info 160 | 161 | find_git_branch && find_git_dirty && find_git_ahead_behind 162 | 163 | #not in Git repo 164 | [[ -z "$git_branch" ]] && return 165 | 166 | scm_info="${SCM_GIT_CHAR}${git_branch}" 167 | [[ -n "$git_dirty" ]] && color=${SCM_PROMPT_DIRTY_COLOR} || color=${SCM_PROMPT_CLEAN_COLOR} 168 | [[ -n "$git_behind" ]] && scm_info+="${SCM_PROMPT_BEHIND}${git_behind_count}" 169 | [[ -n "$git_ahead" ]] && scm_info+="${SCM_PROMPT_AHEAD}${git_ahead_count}" 170 | 171 | [[ -n "${scm_info}" ]] && echo "${scm_info}|${color}" 172 | } 173 | 174 | function __powerline_left_segment { 175 | local OLD_IFS="${IFS}"; IFS="|" 176 | local params=( $1 ) 177 | IFS="${OLD_IFS}" 178 | local separator_char="${POWERLINE_LEFT_SEPARATOR}" 179 | local separator="" 180 | local styles=( ${params[1]} ) 181 | 182 | if [[ "${SEGMENTS_AT_LEFT}" -gt 0 ]]; then 183 | styles[1]=${LAST_SEGMENT_COLOR} 184 | styles[2]="" 185 | separator="$(__color ${styles[@]})${separator_char}" 186 | fi 187 | 188 | styles=( ${params[1]} ) 189 | LEFT_PROMPT+="${separator}$(__color ${styles[@]})${params[0]}" 190 | 191 | #Save last background for next segment 192 | LAST_SEGMENT_COLOR=${styles[0]} 193 | (( SEGMENTS_AT_LEFT += 1 )) 194 | } 195 | 196 | function __powerline_last_status_prompt { 197 | local symbols=() 198 | [[ $last_status -ne 0 ]] && symbols+="$(__color ${STATUS_PROMPT_ERROR_COLOR})${STATUS_PROMPT_ERROR}" 199 | [[ $UID -eq 0 ]] && symbols+="$(__color ${STATUS_PROMPT_ROOT_COLOR})${STATUS_PROMPT_ROOT}" 200 | [[ $(jobs -l | wc -l) -gt 0 ]] && symbols+="$(__color ${STATUS_PROMPT_JOBS_COLOR})${STATUS_PROMPT_JOBS}" 201 | 202 | [[ -n "$symbols" ]] && echo "$symbols|${STATUS_PROMPT_COLOR}" 203 | } 204 | 205 | function __powerline_prompt_command { 206 | local last_status="$?" ## always the first 207 | local separator_char="${POWERLINE_PROMPT_CHAR}" 208 | 209 | LEFT_PROMPT="" 210 | SEGMENTS_AT_LEFT=0 211 | LAST_SEGMENT_COLOR="" 212 | 213 | ## left prompt ## 214 | for segment in $POWERLINE_PROMPT; do 215 | local info="$(__powerline_${segment}_prompt)" 216 | [[ -n "${info}" ]] && __powerline_left_segment "${info}" 217 | done 218 | 219 | [[ -n "${LEFT_PROMPT}" ]] && LEFT_PROMPT+="$(__color - ${LAST_SEGMENT_COLOR})${separator_char}$(__color)" 220 | PS1="${LEFT_PROMPT} " 221 | 222 | ## cleanup ## 223 | unset LAST_SEGMENT_COLOR \ 224 | LEFT_PROMPT \ 225 | SEGMENTS_AT_LEFT 226 | } 227 | 228 | function safe_append_prompt_command { 229 | local prompt_re 230 | 231 | # Set OS dependent exact match regular expression 232 | if [[ ${OSTYPE} == darwin* ]]; then 233 | # macOS 234 | prompt_re="[[:<:]]${1}[[:>:]]" 235 | else 236 | # Linux, FreeBSD, etc. 237 | prompt_re="\<${1}\>" 238 | fi 239 | 240 | if [[ ${PROMPT_COMMAND} =~ ${prompt_re} ]]; then 241 | return 242 | elif [[ -z ${PROMPT_COMMAND} ]]; then 243 | PROMPT_COMMAND="${1}" 244 | else 245 | PROMPT_COMMAND="${1};${PROMPT_COMMAND}" 246 | fi 247 | } 248 | 249 | safe_append_prompt_command __powerline_prompt_command 250 | 251 | __color_matrix() { 252 | local buffer 253 | 254 | declare -A colors=([0]=black [1]=red [2]=green [3]=yellow [4]=blue [5]=purple [6]=cyan [7]=white) 255 | declare -A mods=([0]='' [1]=B [4]=U [5]=k [7]=N) 256 | 257 | # Print foreground color names 258 | echo -ne " " 259 | for fgi in "${!colors[@]}"; do 260 | local fg=`printf "%10s" "${colors[$fgi]}"` 261 | #print color names 262 | echo -ne "\e[m$fg " 263 | done 264 | echo 265 | 266 | # Print modificators 267 | echo -ne " " 268 | for fgi in "${!colors[@]}"; do 269 | for modi in "${!mods[@]}"; do 270 | local mod=`printf "%1s" "${mods[$modi]}"` 271 | buffer="${buffer}$mod " 272 | done 273 | # echo -ne "\e[m " 274 | buffer="${buffer} " 275 | done 276 | echo -e "$buffer\e[m" 277 | buffer="" 278 | 279 | # Print color matrix 280 | for bgi in "${!colors[@]}"; do 281 | local bgn=$((bgi + 40)) 282 | local bg=`printf "%6s" "${colors[$bgi]}"` 283 | 284 | #print color names 285 | echo -ne "\e[m$bg " 286 | 287 | for fgi in "${!colors[@]}"; do 288 | local fgn=$((fgi + 30)) 289 | local fg=`printf "%7s" "${colors[$fgi]}"` 290 | 291 | for modi in "${!mods[@]}"; do 292 | buffer="${buffer}\e[${modi};${bgn};${fgn}m " 293 | done 294 | # echo -ne "\e[m " 295 | buffer="${buffer}\e[m " 296 | done 297 | echo -e "$buffer\e[m" 298 | buffer="" 299 | done 300 | } 301 | 302 | __character_map () { 303 | echo "powerline: ±●➦★⚡★ ✗✘✓✓✔✕✖✗← ↑ → ↓" 304 | echo "other: ☺☻👨⚙⚒⚠⌛" 305 | } 306 | --------------------------------------------------------------------------------