From 05c80fd0a98a27e022113c4247a97bba54f7e7f5 Mon Sep 17 00:00:00 2001 From: Tom Ryder Date: Tue, 20 Sep 2016 21:35:53 +1200 Subject: Fork bash prompt changes to zsh --- zsh/zshrc.d/prompt.zsh | 129 +++++++++++++++++++++++++------------------------ 1 file 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 -- cgit v1.2.3