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 Zsh prompt with Git status.
|
|
|
|
# Source gitstatus.plugin.zsh from $GITSTATUS_DIR or from the same directory
|
|
# in which the current script resides if the variable isn't set.
|
|
source "${GITSTATUS_DIR:-${${(%):-%x}:h}}/gitstatus.plugin.zsh" || return
|
|
|
|
# Sets GITSTATUS_PROMPT to reflect the state of the current git repository. Empty if not
|
|
# in a git repository. In addition, sets GITSTATUS_PROMPT_LEN to the number of columns
|
|
# $GITSTATUS_PROMPT will occupy when printed.
|
|
#
|
|
# Example:
|
|
#
|
|
# GITSTATUS_PROMPT='master ⇣42⇡42 ⇠42⇢42 *42 merge ~42 +42 !42 ?42'
|
|
# GITSTATUS_PROMPT_LEN=39
|
|
#
|
|
# 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() {
|
|
emulate -L zsh
|
|
typeset -g GITSTATUS_PROMPT=''
|
|
typeset -gi GITSTATUS_PROMPT_LEN=0
|
|
|
|
# Call gitstatus_query synchronously. Note that gitstatus_query can also be called
|
|
# asynchronously; see documentation in gitstatus.plugin.zsh.
|
|
gitstatus_query 'MY' || return 1 # error
|
|
[[ $VCS_STATUS_RESULT == 'ok-sync' ]] || return 0 # not a git repo
|
|
|
|
local clean='%76F' # green foreground
|
|
local modified='%178F' # yellow foreground
|
|
local untracked='%39F' # blue foreground
|
|
local conflicted='%196F' # 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+='%f#'
|
|
where=$VCS_STATUS_TAG
|
|
else
|
|
p+='%f@'
|
|
where=${VCS_STATUS_COMMIT[1,8]}
|
|
fi
|
|
|
|
(( $#where > 32 )) && where[13,-13]="…" # truncate long branch names and tags
|
|
p+="${clean}${where//\%/%%}" # escape %
|
|
|
|
# ⇣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}%f"
|
|
|
|
# The length of GITSTATUS_PROMPT after removing %f and %F.
|
|
GITSTATUS_PROMPT_LEN="${(m)#${${GITSTATUS_PROMPT//\%\%/x}//\%(f|<->F)}}"
|
|
}
|
|
|
|
# Start gitstatusd instance with name "MY". The same name is passed to
|
|
# gitstatus_query in gitstatus_prompt_update. The flags with -1 as values
|
|
# enable staged, unstaged, conflicted and untracked counters.
|
|
gitstatus_stop 'MY' && gitstatus_start -s -1 -u -1 -c -1 -d -1 'MY'
|
|
|
|
# On every prompt, fetch git status and set GITSTATUS_PROMPT.
|
|
autoload -Uz add-zsh-hook
|
|
add-zsh-hook precmd gitstatus_prompt_update
|
|
|
|
# Enable/disable the right prompt options.
|
|
setopt no_prompt_bang prompt_percent prompt_subst
|
|
|
|
# Customize prompt. Put $GITSTATUS_PROMPT in it to reflect git status.
|
|
#
|
|
# Example:
|
|
#
|
|
# user@host ~/projects/skynet master ⇡42
|
|
# % █
|
|
#
|
|
# The current directory gets truncated from the left if the whole prompt doesn't fit on the line.
|
|
PROMPT='%70F%n@%m%f ' # green user@host
|
|
PROMPT+='%39F%$((-GITSTATUS_PROMPT_LEN-1))<…<%~%<<%f' # blue current working directory
|
|
PROMPT+='${GITSTATUS_PROMPT:+ $GITSTATUS_PROMPT}' # git status
|
|
PROMPT+=$'\n' # new line
|
|
PROMPT+='%F{%(?.76.196)}%#%f ' # %/# (normal/root); green/red (ok/error)
|