diff --git a/README.md b/README.md index 53fe7384..5ab37632 100644 --- a/README.md +++ b/README.md @@ -66,6 +66,19 @@ Set `SCM_CHECK` to 'true' (the default value) to **turn on** version control che **NOTE:** It is possible for themes to ignore the `SCM_CHECK` flag and query specific version control information directly. For example, themes that use functions like `git_prompt_vars` skip the `SCM_CHECK` flag to retrieve and display git prompt information. If you turned version control checking off and you still see version control information within your prompt, then functions like `git_prompt_vars` are most likely the reason why. +### Git repository info in the prompt +Bash it can show some information about Git repositories in the shell prompt: the current branch, tag or commit you are at, how many commits the local branch is ahead or behind from the remote branch, and if you have changes stashed. + +Additionally, you can view the status of your working copy and get the count of staged, unstaged and untracked files. This feature is controlled through the flag `SCM_GIT_SHOW_DETAILS` as follows: + +Set `SCM_GIT_SHOW_DETAILS` to 'true' (the default value) to **show** the working copy details in your prompt: + +* `export SCM_GIT_SHOW_DETAILS=true` + +Set `SCM_GIT_SHOW_DETAILS` to 'false' to **don't show** it: + +* `export SCM_GIT_SHOW_DETAILS=false` + ## Help out I think everyone has their own custom scripts accumulated over time. And so, following in the footsteps of oh-my-zsh, bash it is a framework for easily customizing your bash shell. Everyone's got a custom toolbox, so let's start making them even better, **as a community!** diff --git a/themes/base.theme.bash b/themes/base.theme.bash index 8b63189e..584fb9ce 100644 --- a/themes/base.theme.bash +++ b/themes/base.theme.bash @@ -8,9 +8,20 @@ SCM_THEME_PROMPT_DIRTY=' ✗' SCM_THEME_PROMPT_CLEAN=' ✓' SCM_THEME_PROMPT_PREFIX=' |' SCM_THEME_PROMPT_SUFFIX='|' +SCM_THEME_BRANCH_PREFIX='' +SCM_THEME_TAG_PREFIX='tag:' +SCM_THEME_COMMIT_PREFIX='commit:' +SCM_THEME_REMOTE_PREFIX='' + +SCM_GIT_SHOW_DETAILS=${SCM_GIT_SHOW_DETAILS:=true} SCM_GIT='git' SCM_GIT_CHAR='±' +SCM_GIT_AHEAD_CHAR="↑" +SCM_GIT_BEHIND_CHAR="↓" +SCM_GIT_UNTRACKED_CHAR="?:" +SCM_GIT_UNSTAGED_CHAR="U:" +SCM_GIT_STAGED_CHAR="S:" SCM_HG='hg' SCM_HG_CHAR='☿' @@ -34,7 +45,6 @@ RBFU_THEME_PROMPT_PREFIX=' |' RBFU_THEME_PROMPT_SUFFIX='|' function scm { - if [[ "$SCM_CHECK" = false ]]; then SCM=$SCM_NONE elif [[ -f .git/HEAD ]]; then SCM=$SCM_GIT elif which git &> /dev/null && [[ -n "$(git symbolic-ref HEAD 2> /dev/null)" ]]; then SCM=$SCM_GIT @@ -75,60 +85,65 @@ function scm_prompt_info { } function git_prompt_vars { - SCM_GIT_AHEAD='' - SCM_GIT_BEHIND='' - SCM_GIT_STASH='' - SCM_GIT_UNTRACKED='' - SCM_GIT_UNSTAGED='' - SCM_GIT_STAGED='' + local details='' + SCM_STATE=${GIT_THEME_PROMPT_CLEAN:-$SCM_THEME_PROMPT_CLEAN} if [[ "$(git config --get bash-it.hide-status)" != "1" ]]; then local status="$(git status -b --porcelain 2> /dev/null || git status --porcelain 2> /dev/null)" if [[ -n "${status}" ]] && [[ "${status}" != "\n" ]] && [[ -n "$(grep -v ^# <<< "${status}")" ]]; then - local untracked_count="$(egrep -c '^\?\? .+' <<< "${status}")" - local unstaged_count="$(egrep -c '^.[^ ?#] .+' <<< "${status}")" - local staged_count="$(egrep -c '^[^ ?#]. .+' <<< "${status}")" - [[ "${untracked_count}" -gt 0 ]] && SCM_GIT_UNTRACKED="${SCM_GIT_UNTRACKED_CHAR}${untracked_count}" - [[ "${unstaged_count}" -gt 0 ]] && SCM_GIT_UNSTAGED="${SCM_GIT_UNSTAGED_CHAR}${unstaged_count}" - [[ "${staged_count}" -gt 0 ]] && SCM_GIT_STAGED="${SCM_GIT_STAGED_CHAR}${staged_count}" SCM_DIRTY=1 + if [[ "${SCM_GIT_SHOW_DETAILS}" = "true" ]]; then + local untracked_count="$(egrep -c '^\?\? .+' <<< "${status}")" + local unstaged_count="$(egrep -c '^.[^ ?#] .+' <<< "${status}")" + local staged_count="$(egrep -c '^[^ ?#]. .+' <<< "${status}")" + [[ "${staged_count}" -gt 0 ]] && details+=" ${SCM_GIT_STAGED_CHAR}${staged_count}" && SCM_DIRTY=3 + [[ "${unstaged_count}" -gt 0 ]] && details+=" ${SCM_GIT_UNSTAGED_CHAR}${unstaged_count}" && SCM_DIRTY=2 + [[ "${untracked_count}" -gt 0 ]] && details+=" ${SCM_GIT_UNTRACKED_CHAR}${untracked_count}" && SCM_DIRTY=1 + fi SCM_STATE=${GIT_THEME_PROMPT_DIRTY:-$SCM_THEME_PROMPT_DIRTY} - else - SCM_DIRTY=0 - SCM_STATE=${GIT_THEME_PROMPT_CLEAN:-$SCM_THEME_PROMPT_CLEAN} fi - else - SCM_DIRTY=0 - SCM_STATE=${GIT_THEME_PROMPT_CLEAN:-$SCM_THEME_PROMPT_CLEAN} fi - SCM_PREFIX=${GIT_THEME_PROMPT_PREFIX:-$SCM_THEME_PROMPT_PREFIX} - SCM_SUFFIX=${GIT_THEME_PROMPT_SUFFIX:-$SCM_THEME_PROMPT_SUFFIX} local ref=$(git symbolic-ref -q HEAD 2> /dev/null) if [[ -n "$ref" ]]; then - SCM_BRANCH=${ref#refs/heads/} - SCM_IS_BRANCH=1 - SCM_IS_TAG=0 + SCM_BRANCH=${SCM_THEME_BRANCH_PREFIX}${ref#refs/heads/} else - SCM_BRANCH=$(git describe --tags --exact-match 2> /dev/null) - SCM_IS_TAG=1 - SCM_IS_BRANCH=0 + ref=$(git describe --tags --exact-match 2> /dev/null) + if [[ -n "$ref" ]]; then + SCM_BRANCH=${SCM_THEME_TAG_PREFIX}${ref} + else + local commit_re='(^remotes/)?(.+-g[a-zA-Z0-9]+)$' + local remote_re='^remotes/(.+)$' + ref=$(git describe --tags --all --always 2> /dev/null) + if [[ "$ref" =~ ${commit_re} ]]; then + SCM_BRANCH=${SCM_THEME_COMMIT_PREFIX}${BASH_REMATCH[2]} + elif [[ "$ref" =~ ${remote_re} ]]; then + SCM_BRANCH=${SCM_THEME_REMOTE_PREFIX}${BASH_REMATCH[1]} + fi + fi fi - SCM_CHANGE=$(git rev-parse HEAD 2>/dev/null) + local ahead_re='.+ahead ([0-9]+).+' local behind_re='.+behind ([0-9]+).+' - [[ "${status}" =~ ${ahead_re} ]] && SCM_GIT_AHEAD="${SCM_GIT_AHEAD_CHAR}${BASH_REMATCH[1]}" - [[ "${status}" =~ ${behind_re} ]] && SCM_GIT_BEHIND="${SCM_GIT_BEHIND_CHAR}${BASH_REMATCH[1]}" + [[ "${status}" =~ ${ahead_re} ]] && SCM_BRANCH+=" ${SCM_GIT_AHEAD_CHAR}${BASH_REMATCH[1]}" + [[ "${status}" =~ ${behind_re} ]] && SCM_BRANCH+=" ${SCM_GIT_BEHIND_CHAR}${BASH_REMATCH[1]}" + local stash_count="$(git stash list 2> /dev/null | wc -l | tr -d ' ')" - [[ "${stash_count}" -gt 0 ]] && SCM_GIT_STASH="{${stash_count}}" + [[ "${stash_count}" -gt 0 ]] && SCM_BRANCH+=" {${stash_count}}" + + SCM_BRANCH+=${details} + + SCM_PREFIX=${GIT_THEME_PROMPT_PREFIX:-$SCM_THEME_PROMPT_PREFIX} + SCM_SUFFIX=${GIT_THEME_PROMPT_SUFFIX:-$SCM_THEME_PROMPT_SUFFIX} + SCM_CHANGE=$(git rev-parse HEAD 2>/dev/null) } function svn_prompt_vars { if [[ -n $(svn status 2> /dev/null) ]]; then SCM_DIRTY=1 - SCM_STATE=${SVN_THEME_PROMPT_DIRTY:-$SCM_THEME_PROMPT_DIRTY} + SCM_STATE=${SVN_THEME_PROMPT_DIRTY:-$SCM_THEME_PROMPT_DIRTY} else SCM_DIRTY=0 - SCM_STATE=${SVN_THEME_PROMPT_CLEAN:-$SCM_THEME_PROMPT_CLEAN} + SCM_STATE=${SVN_THEME_PROMPT_CLEAN:-$SCM_THEME_PROMPT_CLEAN} fi SCM_PREFIX=${SVN_THEME_PROMPT_PREFIX:-$SCM_THEME_PROMPT_PREFIX} SCM_SUFFIX=${SVN_THEME_PROMPT_SUFFIX:-$SCM_THEME_PROMPT_SUFFIX} diff --git a/themes/powerline-plain/powerline-plain.theme.bash b/themes/powerline-plain/powerline-plain.theme.bash index 63606658..dbe0f7c2 100644 --- a/themes/powerline-plain/powerline-plain.theme.bash +++ b/themes/powerline-plain/powerline-plain.theme.bash @@ -9,17 +9,6 @@ VIRTUALENV_THEME_PROMPT_COLOR=35 SCM_NONE_CHAR="" SCM_GIT_CHAR="⎇ " -SCM_GIT_BEHIND_CHAR="↓" -SCM_GIT_AHEAD_CHAR="↑" -SCM_GIT_UNTRACKED_CHAR="?:" -SCM_GIT_UNSTAGED_CHAR="U:" -SCM_GIT_STAGED_CHAR="S:" - -if [[ -z "$THEME_SCM_TAG_PREFIX" ]]; then - SCM_TAG_PREFIX="tag > " -else - SCM_TAG_PREFIX="$THEME_SCM_TAG_PREFIX" -fi SCM_THEME_PROMPT_CLEAN="" SCM_THEME_PROMPT_DIRTY="" @@ -74,29 +63,17 @@ function powerline_scm_prompt { scm_prompt_vars if [[ "${SCM_NONE_CHAR}" != "${SCM_CHAR}" ]]; then - if [[ "${SCM_DIRTY}" -eq 1 ]]; then - if [[ -n "${SCM_GIT_STAGED}" ]]; then - SCM_PROMPT="$(set_rgb_color ${SCM_THEME_PROMPT_STAGED_COLOR} ${SCM_THEME_PROMPT_COLOR})" - elif [[ -n "${SCM_GIT_UNSTAGED}" ]]; then - SCM_PROMPT="$(set_rgb_color ${SCM_THEME_PROMPT_UNSTAGED_COLOR} ${SCM_THEME_PROMPT_COLOR})" - else - SCM_PROMPT="$(set_rgb_color ${SCM_THEME_PROMPT_DIRTY_COLOR} ${SCM_THEME_PROMPT_COLOR})" - fi + if [[ "${SCM_DIRTY}" -eq 3 ]]; then + SCM_PROMPT="$(set_rgb_color ${SCM_THEME_PROMPT_STAGED_COLOR} ${SCM_THEME_PROMPT_COLOR})" + elif [[ "${SCM_DIRTY}" -eq 2 ]]; then + SCM_PROMPT="$(set_rgb_color ${SCM_THEME_PROMPT_UNSTAGED_COLOR} ${SCM_THEME_PROMPT_COLOR})" + elif [[ "${SCM_DIRTY}" -eq 1 ]]; then + SCM_PROMPT="$(set_rgb_color ${SCM_THEME_PROMPT_DIRTY_COLOR} ${SCM_THEME_PROMPT_COLOR})" else SCM_PROMPT="$(set_rgb_color ${SCM_THEME_PROMPT_CLEAN_COLOR} ${SCM_THEME_PROMPT_COLOR})" fi if [[ "${SCM_GIT_CHAR}" == "${SCM_CHAR}" ]]; then - local tag="" - if [[ $SCM_IS_TAG -eq "1" ]]; then - tag=$SCM_TAG_PREFIX - fi - SCM_PROMPT+=" ${SCM_CHAR}${tag}${SCM_BRANCH}${SCM_STATE} " - [[ -n "${SCM_GIT_AHEAD}" ]] && SCM_PROMPT+="${SCM_GIT_AHEAD} " - [[ -n "${SCM_GIT_BEHIND}" ]] && SCM_PROMPT+="${SCM_GIT_BEHIND} " - [[ -n "${SCM_GIT_STAGED}" ]] && SCM_PROMPT+="${SCM_GIT_STAGED} " - [[ -n "${SCM_GIT_UNSTAGED}" ]] && SCM_PROMPT+="${SCM_GIT_UNSTAGED} " - [[ -n "${SCM_GIT_UNTRACKED}" ]] && SCM_PROMPT+="${SCM_GIT_UNTRACKED} " - [[ -n "${SCM_GIT_STASH}" ]] && SCM_PROMPT+="${SCM_GIT_STASH} " + SCM_PROMPT+=" ${SCM_CHAR}${SCM_BRANCH}${SCM_STATE} " fi SCM_PROMPT="${SCM_PROMPT}${normal}" else diff --git a/themes/powerline/powerline.theme.bash b/themes/powerline/powerline.theme.bash index bf7e33b3..1bc4eca9 100644 --- a/themes/powerline/powerline.theme.bash +++ b/themes/powerline/powerline.theme.bash @@ -11,17 +11,6 @@ VIRTUALENV_THEME_PROMPT_COLOR=35 SCM_NONE_CHAR="" SCM_GIT_CHAR=" " -SCM_GIT_BEHIND_CHAR="↓" -SCM_GIT_AHEAD_CHAR="↑" -SCM_GIT_UNTRACKED_CHAR="?:" -SCM_GIT_UNSTAGED_CHAR="U:" -SCM_GIT_STAGED_CHAR="S:" - -if [[ -z "$THEME_SCM_TAG_PREFIX" ]]; then - SCM_TAG_PREFIX="tag > " -else - SCM_TAG_PREFIX="$THEME_SCM_TAG_PREFIX" -fi SCM_THEME_PROMPT_CLEAN="" SCM_THEME_PROMPT_DIRTY="" @@ -78,31 +67,19 @@ function powerline_scm_prompt { scm_prompt_vars if [[ "${SCM_NONE_CHAR}" != "${SCM_CHAR}" ]]; then - if [[ "${SCM_DIRTY}" -eq 1 ]]; then - if [[ -n "${SCM_GIT_STAGED}" ]]; then - SCM_PROMPT="$(set_rgb_color ${SCM_THEME_PROMPT_STAGED_COLOR} ${SCM_THEME_PROMPT_COLOR})" - elif [[ -n "${SCM_GIT_UNSTAGED}" ]]; then - SCM_PROMPT="$(set_rgb_color ${SCM_THEME_PROMPT_UNSTAGED_COLOR} ${SCM_THEME_PROMPT_COLOR})" - else - SCM_PROMPT="$(set_rgb_color ${SCM_THEME_PROMPT_DIRTY_COLOR} ${SCM_THEME_PROMPT_COLOR})" - fi + if [[ "${SCM_DIRTY}" -eq 3 ]]; then + SCM_PROMPT="$(set_rgb_color ${SCM_THEME_PROMPT_STAGED_COLOR} ${SCM_THEME_PROMPT_COLOR})" + elif [[ "${SCM_DIRTY}" -eq 2 ]]; then + SCM_PROMPT="$(set_rgb_color ${SCM_THEME_PROMPT_UNSTAGED_COLOR} ${SCM_THEME_PROMPT_COLOR})" + elif [[ "${SCM_DIRTY}" -eq 1 ]]; then + SCM_PROMPT="$(set_rgb_color ${SCM_THEME_PROMPT_DIRTY_COLOR} ${SCM_THEME_PROMPT_COLOR})" else SCM_PROMPT="$(set_rgb_color ${SCM_THEME_PROMPT_CLEAN_COLOR} ${SCM_THEME_PROMPT_COLOR})" fi if [[ "${SCM_GIT_CHAR}" == "${SCM_CHAR}" ]]; then - local tag="" - if [[ $SCM_IS_TAG -eq "1" ]]; then - tag=$SCM_TAG_PREFIX - fi - SCM_PROMPT+=" ${SCM_CHAR}${tag}${SCM_BRANCH}${SCM_STATE} " - [[ -n "${SCM_GIT_AHEAD}" ]] && SCM_PROMPT+="${SCM_GIT_AHEAD} " - [[ -n "${SCM_GIT_BEHIND}" ]] && SCM_PROMPT+="${SCM_GIT_BEHIND} " - [[ -n "${SCM_GIT_STAGED}" ]] && SCM_PROMPT+="${SCM_GIT_STAGED} " - [[ -n "${SCM_GIT_UNSTAGED}" ]] && SCM_PROMPT+="${SCM_GIT_UNSTAGED} " - [[ -n "${SCM_GIT_UNTRACKED}" ]] && SCM_PROMPT+="${SCM_GIT_UNTRACKED} " - [[ -n "${SCM_GIT_STASH}" ]] && SCM_PROMPT+="${SCM_GIT_STASH} " + SCM_PROMPT+=" ${SCM_CHAR}${SCM_BRANCH}${SCM_STATE}" fi - SCM_PROMPT="$(set_rgb_color ${LAST_THEME_COLOR} ${SCM_THEME_PROMPT_COLOR})${THEME_PROMPT_SEPARATOR}${normal}${SCM_PROMPT}${normal}" + SCM_PROMPT="$(set_rgb_color ${LAST_THEME_COLOR} ${SCM_THEME_PROMPT_COLOR})${THEME_PROMPT_SEPARATOR}${normal}${SCM_PROMPT} ${normal}" LAST_THEME_COLOR=${SCM_THEME_PROMPT_COLOR} else SCM_PROMPT=""