The distribution does not package the theme, and the predecessor cloned whatever upstream's default branch held the day a hook ran (novox/hq ADR 0205). So upstream's v1.20.0 release is vendored verbatim, with its licence, and shipped as an archive the host unpacks under the account's home and checks by digest. The prompt's configuration is today's ~/.p10k.zsh byte for byte, as a second archive. Inline, its 86 KB would ride in every declaration and be unreviewable JSON. The zsh code that loads both is a contribution to the normal slot (ADR 0204). Instant prompt stays off, as it is today.
112 lines
4.7 KiB
Bash
112 lines
4.7 KiB
Bash
# Simple Bash prompt with Git status.
|
|
|
|
# Source gitstatus.plugin.sh from $GITSTATUS_DIR or from the same directory
|
|
# in which the current script resides if the variable isn't set.
|
|
if [[ -n "${GITSTATUS_DIR-}" ]]; then
|
|
source "$GITSTATUS_DIR" || return
|
|
elif [[ "${BASH_SOURCE[0]}" == */* ]]; then
|
|
source "${BASH_SOURCE[0]%/*}/gitstatus.plugin.sh" || return
|
|
else
|
|
source gitstatus.plugin.sh || return
|
|
fi
|
|
|
|
# Sets GITSTATUS_PROMPT to reflect the state of the current git repository.
|
|
# The value is empty if not in a git repository. Forwards all arguments to
|
|
# gitstatus_query.
|
|
#
|
|
# Example value of GITSTATUS_PROMPT: master ⇣42⇡42 ⇠42⇢42 *42 merge ~42 +42 !42 ?42
|
|
#
|
|
# master current branch
|
|
# ⇣42 local branch is 42 commits behind the remote
|
|
# ⇡42 local branch is 42 commits ahead of the remote
|
|
# ⇠42 local branch is 42 commits behind the push remote
|
|
# ⇢42 local branch is 42 commits ahead of the push remote
|
|
# *42 42 stashes
|
|
# merge merge in progress
|
|
# ~42 42 merge conflicts
|
|
# +42 42 staged changes
|
|
# !42 42 unstaged changes
|
|
# ?42 42 untracked files
|
|
function gitstatus_prompt_update() {
|
|
GITSTATUS_PROMPT=""
|
|
|
|
gitstatus_query "$@" || return 1 # error
|
|
[[ "$VCS_STATUS_RESULT" == ok-sync ]] || return 0 # not a git repo
|
|
|
|
local reset=$'\001\e[0m\002' # no color
|
|
local clean=$'\001\e[38;5;076m\002' # green foreground
|
|
local untracked=$'\001\e[38;5;014m\002' # teal foreground
|
|
local modified=$'\001\e[38;5;011m\002' # yellow foreground
|
|
local conflicted=$'\001\e[38;5;196m\002' # red foreground
|
|
|
|
local p
|
|
|
|
local where # branch name, tag or commit
|
|
if [[ -n "$VCS_STATUS_LOCAL_BRANCH" ]]; then
|
|
where="$VCS_STATUS_LOCAL_BRANCH"
|
|
elif [[ -n "$VCS_STATUS_TAG" ]]; then
|
|
p+="${reset}#"
|
|
where="$VCS_STATUS_TAG"
|
|
else
|
|
p+="${reset}@"
|
|
where="${VCS_STATUS_COMMIT:0:8}"
|
|
fi
|
|
|
|
(( ${#where} > 32 )) && where="${where:0:12}…${where: -12}" # truncate long branch names and tags
|
|
p+="${clean}${where}"
|
|
|
|
# ⇣42 if behind the remote.
|
|
(( VCS_STATUS_COMMITS_BEHIND )) && p+=" ${clean}⇣${VCS_STATUS_COMMITS_BEHIND}"
|
|
# ⇡42 if ahead of the remote; no leading space if also behind the remote: ⇣42⇡42.
|
|
(( VCS_STATUS_COMMITS_AHEAD && !VCS_STATUS_COMMITS_BEHIND )) && p+=" "
|
|
(( VCS_STATUS_COMMITS_AHEAD )) && p+="${clean}⇡${VCS_STATUS_COMMITS_AHEAD}"
|
|
# ⇠42 if behind the push remote.
|
|
(( VCS_STATUS_PUSH_COMMITS_BEHIND )) && p+=" ${clean}⇠${VCS_STATUS_PUSH_COMMITS_BEHIND}"
|
|
(( VCS_STATUS_PUSH_COMMITS_AHEAD && !VCS_STATUS_PUSH_COMMITS_BEHIND )) && p+=" "
|
|
# ⇢42 if ahead of the push remote; no leading space if also behind: ⇠42⇢42.
|
|
(( VCS_STATUS_PUSH_COMMITS_AHEAD )) && p+="${clean}⇢${VCS_STATUS_PUSH_COMMITS_AHEAD}"
|
|
# *42 if have stashes.
|
|
(( VCS_STATUS_STASHES )) && p+=" ${clean}*${VCS_STATUS_STASHES}"
|
|
# 'merge' if the repo is in an unusual state.
|
|
[[ -n "$VCS_STATUS_ACTION" ]] && p+=" ${conflicted}${VCS_STATUS_ACTION}"
|
|
# ~42 if have merge conflicts.
|
|
(( VCS_STATUS_NUM_CONFLICTED )) && p+=" ${conflicted}~${VCS_STATUS_NUM_CONFLICTED}"
|
|
# +42 if have staged changes.
|
|
(( VCS_STATUS_NUM_STAGED )) && p+=" ${modified}+${VCS_STATUS_NUM_STAGED}"
|
|
# !42 if have unstaged changes.
|
|
(( VCS_STATUS_NUM_UNSTAGED )) && p+=" ${modified}!${VCS_STATUS_NUM_UNSTAGED}"
|
|
# ?42 if have untracked files. It's really a question mark, your font isn't broken.
|
|
(( VCS_STATUS_NUM_UNTRACKED )) && p+=" ${untracked}?${VCS_STATUS_NUM_UNTRACKED}"
|
|
|
|
GITSTATUS_PROMPT="${p}${reset}"
|
|
}
|
|
|
|
# Start gitstatusd in the background.
|
|
gitstatus_stop && gitstatus_start -s -1 -u -1 -c -1 -d -1
|
|
|
|
# On every prompt, fetch git status and set GITSTATUS_PROMPT.
|
|
if [[ -z "${PROMPT_COMMAND[*]}" ]]; then
|
|
PROMPT_COMMAND=gitstatus_prompt_update
|
|
elif [[ ! "${PROMPT_COMMAND[*]}" =~ [[:space:]\;]?gitstatus_prompt_update[[:space:]\;]? ]]; then
|
|
# Note: If PROMPT_COMMAND is an array, this will modify its first element.
|
|
PROMPT_COMMAND=$'gitstatus_prompt_update\n'"$PROMPT_COMMAND"
|
|
fi
|
|
|
|
# Retain 3 trailing components of the current directory.
|
|
PROMPT_DIRTRIM=3
|
|
|
|
# Enable promptvars so that ${GITSTATUS_PROMPT} in PS1 is expanded.
|
|
shopt -s promptvars
|
|
|
|
# Customize prompt. Put $GITSTATUS_PROMPT in it reflect git status.
|
|
#
|
|
# Example:
|
|
#
|
|
# user@host ~/projects/skynet master ⇡42
|
|
# $ █
|
|
PS1='\[\033[01;32m\]\u@\h\[\033[00m\] ' # green user@host
|
|
PS1+='\[\033[01;34m\]\w\[\033[00m\]' # blue current working directory
|
|
PS1+='${GITSTATUS_PROMPT:+ $GITSTATUS_PROMPT}' # git status (requires promptvars option)
|
|
PS1+='\n\[\033[01;$((31+!$?))m\]\$\[\033[00m\] ' # green/red (success/error) $/# (normal/root)
|
|
PS1+='\[\e]0;\u@\h: \w\a\]' # terminal title: user@host: dir
|