bash-git_prompt 3.09 KB
Newer Older
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
USE_GIT_PROMPT=1
export USE_GIT_PROMPT

git_prompt_toggle() {
  if [[ $USE_GIT_PROMPT == 1 ]]; then
    USE_GIT_PROMPT=0
  else
    USE_GIT_PROMPT=1
  fi
  export USE_GIT_PROMPT
}

_show_git_status() {
  # Get the current git branch and colorize to indicate branch state
  # branch_name+ indicates there are stash(es)
  # branch_name? indicates there are untracked files
  # branch_name! indicates your branches have diverged
  local unknown untracked stash clean ahead behind staged dirty diverged
  unknown='0;34'      # blue
  untracked='0;32'    # green
  stash='0;32'        # green
  clean='0;32'        # green
  ahead='0;33'        # yellow
  behind='0;33'       # yellow
  staged='0;96'       # cyan
  dirty='0;31'        # red
  diverged='0;31'     # red

  if [[ $TERM = *256color ]]; then
    unknown='38;5;20'     # dark blue
    untracked='38;5;76'   # mid lime-green
    stash='38;5;76'       # mid lime-green
    clean='38;5;82'       # brighter green
    ahead='38;5;226'      # bright yellow
    behind='38;5;142'     # darker yellow-orange
    staged='38;5;214'     # orangey yellow
    dirty='38;5;202'      # orange
    diverged='38;5;196'   # red
  fi

  branch=$(git rev-parse --abbrev-ref HEAD 2>/dev/null)
  if [[ -n "$branch" ]]; then
    if [[ "$branch" == 'HEAD' ]]; then
      branch=$(git rev-parse --short HEAD 2>/dev/null)
    fi
    git_status=$(git status 2> /dev/null)
    # If nothing changes the color, we can spot unhandled cases.
    color=$unknown
    if [[ $git_status =~ 'Untracked files' ]]; then
      color=$untracked
      branch="${branch}?"
    fi
    if git stash show &>/dev/null; then
      color=$stash
      branch="${branch}+"
    fi
    if [[ $git_status =~ 'working directory clean' ]]; then
      color=$clean
    fi
    if [[ $git_status =~ 'Your branch is ahead' ]]; then
      color=$ahead
      branch="${branch}>"
    fi
    if [[ $git_status =~ 'Your branch is behind' ]]; then
      color=$behind
      branch="${branch}<"
    fi
    if [[ $git_status =~ 'Changes to be committed' ]]; then
      color=$staged
    fi
    if [[ $git_status =~ 'Changed but not updated' ||
          $git_status =~ 'Changes not staged'      ||
          $git_status =~ 'Unmerged paths' ]]; then
      color=$dirty
    fi
    if [[ $git_status =~ 'Your branch'.+diverged ]]; then
      color=$diverged
      branch="${branch}!"
    fi
    printf "\[\033[%sm\]%s\[\033[0m\]" "$color" "$branch"
  fi
  return 0
}

_show_last_exit_status() {
  # Display the exit status of the last run command
  exit_status=$?
  if [[ "$exit_status" -ne 0 ]]; then
    echo "Exit $exit_status"
  fi
}

_build_prompt() {
  local git_status prompt_dir
  if [[ $USE_GIT_PROMPT != 0 ]]; then
    git_status=$(_show_git_status)
    if [[ -n "$git_status" ]]; then
      git_status=":${git_status}"
    fi
  fi
  prompt_dir=$(basename "${PWD}")

  # Set xterm title
  echo -ne "\033]0;${HOSTNAME}\007"
  if [[ -n "$STY" ]]; then
    # If in a screen session...
    # Set xterm title
    echo -ne "\033_${HOSTNAME}\033\0134"
  fi
  PS1="\h [${prompt_dir}${git_status}]\\\$ "
  return 0
}

PROMPT_COMMAND="_show_last_exit_status; _build_prompt;"