aboutsummaryrefslogtreecommitdiff
path: root/zsh/zshrc.d/prompt.zsh
diff options
context:
space:
mode:
Diffstat (limited to 'zsh/zshrc.d/prompt.zsh')
-rw-r--r--zsh/zshrc.d/prompt.zsh129
1 files changed, 66 insertions, 63 deletions
diff --git a/zsh/zshrc.d/prompt.zsh b/zsh/zshrc.d/prompt.zsh
index 48a3d5f9..e707f188 100644
--- a/zsh/zshrc.d/prompt.zsh
+++ b/zsh/zshrc.d/prompt.zsh
@@ -55,74 +55,77 @@ prompt() {
# Git prompt function
git)
- # Bail if we're not in a work tree--or, implicitly, if we don't
- # have git(1).
- local iswt
- iswt=$(git rev-parse --is-inside-work-tree 2>/dev/null)
- [[ $iswt = true ]] || return
-
- # Refresh index so e.g. git-diff-files(1) is accurate
- git update-index --refresh >/dev/null 2>&1
-
- # Find a local branch, remote branch, or tag (annotated or not), or
- # failing all of that just show the short commit ID, in that order
- # of preference; if none of that works, bail out
- local name
- name=$( {
- git symbolic-ref --quiet HEAD ||
- git describe --tags --exact-match HEAD ||
- git rev-parse --short HEAD
- } 2>/dev/null) || return
- name=${name##*/}
- [[ -n $name ]] || return
-
- # Check various files in .git to flag processes
- local proc
- [[ -d .git/rebase-merge || -d .git/rebase-apply ]] &&
- proc=${proc:+$proc,}'REBASE'
- [[ -f .git/MERGE_HEAD ]] &&
- proc=${proc:+$proc,}'MERGE'
- [[ -f .git/CHERRY_PICK_HEAD ]] &&
- proc=${proc:+$proc,}'PICK'
- [[ -f .git/REVERT_HEAD ]] &&
- proc=${proc:+$proc,}'REVERT'
- [[ -f .git/BISECT_LOG ]] &&
- proc=${proc:+$proc,}'BISECT'
-
- # Collect symbols representing repository state
- local state
-
- # Upstream HEAD has commits after local HEAD; we're "behind"
- local -i behind
- behind=$(git rev-list --count 'HEAD..@{u}' 2>/dev/null)
- ((behind)) && state=${state}'<'
-
- # Local HEAD has commits after upstream HEAD; we're "ahead"
- local -i ahead
- ahead=$(git rev-list --count '@{u}..HEAD' 2>/dev/null)
- ((ahead)) && state=${state}'>'
-
- # Tracked files are modified
- git diff-files --no-ext-diff --quiet ||
- state=${state}'!'
-
- # Changes are staged
- git diff-index --cached --no-ext-diff --quiet HEAD 2>/dev/null ||
- state=${state}'+'
-
- # There are some untracked and unignored files
- git ls-files --directory --error-unmatch --exclude-standard \
- --no-empty-directory --others -- ':/*' >/dev/null 2>&1 &&
- state=${state}'?'
- # There are stashed changes
- git rev-parse --quiet --verify refs/stash >/dev/null &&
- state=${state}'^'
+ # Wrap as compound command; we don't want to see output from any of
+ # these git(1) calls
+ {
+ # Bail if we're not in a work tree--or, implicitly, if we don't
+ # have git(1).
+ [[ -n $(git rev-parse --is-inside-work-tree) ]] ||
+ return
+
+ # Refresh index so e.g. git-diff-files(1) is accurate
+ git update-index --refresh
+
+ # Find a local branch, remote branch, or tag (annotated or
+ # not), or failing all of that just show the short commit ID,
+ # in that order of preference; if none of that works, bail out
+ local name
+ name=$(
+ git symbolic-ref --quiet HEAD ||
+ git describe --tags --exact-match HEAD ||
+ git rev-parse --short HEAD
+ ) || return
+ name=${name##*/}
+ [[ -n $name ]] || return
+
+ # Check various files in .git to flag processes
+ local proc
+ [[ -d .git/rebase-merge || -d .git/rebase-apply ]] &&
+ proc=${proc:+"$proc",}'REBASE'
+ [[ -f .git/MERGE_HEAD ]] &&
+ proc=${proc:+"$proc",}'MERGE'
+ [[ -f .git/CHERRY_PICK_HEAD ]] &&
+ proc=${proc:+"$proc",}'PICK'
+ [[ -f .git/REVERT_HEAD ]] &&
+ proc=${proc:+"$proc",}'REVERT'
+ [[ -f .git/BISECT_LOG ]] &&
+ proc=${proc:+"$proc",}'BISECT'
+
+ # Collect symbols representing repository state
+ local state
+
+ # Upstream HEAD has commits after local HEAD; we're "behind"
+ (($(git rev-list --count 'HEAD..@{u}'))) &&
+ state=${state}'<'
+
+ # Local HEAD has commits after upstream HEAD; we're "ahead"
+ (($(git rev-list --count '@{u}..HEAD'))) &&
+ state=${state}'>'
+
+ # Tracked files are modified
+ git diff-files --no-ext-diff --quiet ||
+ state=${state}'!'
+
+ # Changes are staged
+ git diff-index --cached --no-ext-diff --quiet HEAD ||
+ state=${state}'+'
+
+ # There are some untracked and unignored files
+ git ls-files --directory --error-unmatch --exclude-standard \
+ --no-empty-directory --others -- ':/*' &&
+ state=${state}'?'
+
+ # There are stashed changes
+ git rev-parse --quiet --verify refs/stash &&
+ state=${state}'^'
+
+ } >/dev/null 2>&1
# Print the status in brackets; add a git: prefix only if there
# might be another VCS prompt (because PROMPT_VCS is set)
printf '(%s%s%s%s)' \
- "${PROMPT_VCS:+git:}" "$name" "${proc:+:$proc}" "$state"
+ "${PROMPT_VCS:+git:}" "$name" "${proc:+:"$proc"}" "$state"
;;
# Subversion prompt function