13c702964c0287059a75eaec98cd71de51f4f19c

Author
Ilia Burtsev <paillechat@gmail.com>
Committer
GitHub <noreply@github.com>
Date

Message

fix(async): ensure `git_prompt_status` can be registered (#13134)

Diff

This diff is truncated to protect this page.

  1diff --git a/lib/git.zsh b/lib/git.zsh
  2index a1b4d15874bb41e5f85605510efc5e5f1ecdcfe6..f4d4229cbd70b249568a8706a9a09859732b4a99 100644
  3--- a/lib/git.zsh
  4+++ b/lib/git.zsh
  5@@ -39,6 +39,105 @@ function _omz_git_prompt_info() {
  6   echo "${ZSH_THEME_GIT_PROMPT_PREFIX}${ref:gs/%/%%}${upstream:gs/%/%%}$(parse_git_dirty)${ZSH_THEME_GIT_PROMPT_SUFFIX}"
  7 }
  8 
  9+function _omz_git_prompt_status() {
 10+  [[ "$(__git_prompt_git config --get oh-my-zsh.hide-status 2>/dev/null)" = 1 ]] && return
 11+
 12+  # Maps a git status prefix to an internal constant
 13+  # This cannot use the prompt constants, as they may be empty
 14+  local -A prefix_constant_map
 15+  prefix_constant_map=(
 16+    '\?\? '     'UNTRACKED'
 17+    'A  '       'ADDED'
 18+    'M  '       'MODIFIED'
 19+    'MM '       'MODIFIED'
 20+    ' M '       'MODIFIED'
 21+    'AM '       'MODIFIED'
 22+    ' T '       'MODIFIED'
 23+    'R  '       'RENAMED'
 24+    ' D '       'DELETED'
 25+    'D  '       'DELETED'
 26+    'UU '       'UNMERGED'
 27+    'ahead'     'AHEAD'
 28+    'behind'    'BEHIND'
 29+    'diverged'  'DIVERGED'
 30+    'stashed'   'STASHED'
 31+  )
 32+
 33+  # Maps the internal constant to the prompt theme
 34+  local -A constant_prompt_map
 35+  constant_prompt_map=(
 36+    'UNTRACKED' "$ZSH_THEME_GIT_PROMPT_UNTRACKED"
 37+    'ADDED'     "$ZSH_THEME_GIT_PROMPT_ADDED"
 38+    'MODIFIED'  "$ZSH_THEME_GIT_PROMPT_MODIFIED"
 39+    'RENAMED'   "$ZSH_THEME_GIT_PROMPT_RENAMED"
 40+    'DELETED'   "$ZSH_THEME_GIT_PROMPT_DELETED"
 41+    'UNMERGED'  "$ZSH_THEME_GIT_PROMPT_UNMERGED"
 42+    'AHEAD'     "$ZSH_THEME_GIT_PROMPT_AHEAD"
 43+    'BEHIND'    "$ZSH_THEME_GIT_PROMPT_BEHIND"
 44+    'DIVERGED'  "$ZSH_THEME_GIT_PROMPT_DIVERGED"
 45+    'STASHED'   "$ZSH_THEME_GIT_PROMPT_STASHED"
 46+  )
 47+
 48+  # The order that the prompt displays should be added to the prompt
 49+  local status_constants
 50+  status_constants=(
 51+    UNTRACKED ADDED MODIFIED RENAMED DELETED
 52+    STASHED UNMERGED AHEAD BEHIND DIVERGED
 53+  )
 54+
 55+  local status_text
 56+  status_text="$(__git_prompt_git status --porcelain -b 2> /dev/null)"
 57+
 58+  # Don't continue on a catastrophic failure
 59+  if [[ $? -eq 128 ]]; then
 60+    return 1
 61+  fi
 62+
 63+  # A lookup table of each git status encountered
 64+  local -A statuses_seen
 65+
 66+  if __git_prompt_git rev-parse --verify refs/stash &>/dev/null; then
 67+    statuses_seen[STASHED]=1
 68+  fi
 69+
 70+  local status_lines
 71+  status_lines=("${(@f)${status_text}}")
 72+
 73+  # If the tracking line exists, get and parse it
 74+  if [[ "$status_lines[1]" =~ "^## [^ ]+ \[(.*)\]" ]]; then
 75+    local branch_statuses
 76+    branch_statuses=("${(@s/,/)match}")
 77+    for branch_status in $branch_statuses; do
 78+      if [[ ! $branch_status =~ "(behind|diverged|ahead) ([0-9]+)?" ]]; then
 79+        continue
 80+      fi
 81+      local last_parsed_status=$prefix_constant_map[$match[1]]
 82+      statuses_seen[$last_parsed_status]=$match[2]
 83+    done
 84+  fi
 85+
 86+  # For each status prefix, do a regex comparison
 87+  for status_prefix in ${(k)prefix_constant_map}; do
 88+    local status_constant="${prefix_constant_map[$status_prefix]}"
 89+    local status_regex=$'(^|\n)'"$status_prefix"
 90+
 91+    if [[ "$status_text" =~ $status_regex ]]; then
 92+      statuses_seen[$status_constant]=1
 93+    fi
 94+  done
 95+
 96+  # Display the seen statuses in the order specified
 97+  local status_prompt
 98+  for status_constant in $status_constants; do
 99+    if (( ${+statuses_seen[$status_constant]} )); then
100+      local next_display=$constant_prompt_map[$status_constant]
101+      status_prompt="$next_display$status_prompt"
102+    fi
103+  done
104+