@ -32,49 +32,33 @@
# Load dependencies.
pmodload 'helper'
prompt_sorin_git_info() {
if (( _prompt_sorin_precmd_async_pid > 0 )); then
# Append Git status.
if [[ -s "$_prompt_sorin_precmd_async_data" ]]; then
alias typeset='typeset -g'
source "$_prompt_sorin_precmd_async_data"
RPROMPT+='${git_info:+${(e)git_info[status]}}'
unalias typeset
function prompt_sorin_git_info {
# We can safely split on ':' because it isn't allowed in ref names.
IFS=':' read _git_target _git_post_target <<<"$3"
# The target actually contains 3 space separated possibilities, so we need to
# make sure we grab the first one.
_git_target=$(coalesce ${(@)${(z)_git_target}})
if [[ -z "$_git_target" ]]; then
# No git target detected, flush the git fragment and redisplay the prompt.
if [[ -n "$_prompt_sorin_git" ]]; then
_prompt_sorin_git=''
zle && zle reset-prompt
fi
# Reset PID.
_prompt_sorin_precmd_async_pid=0
# Redisplay prompt.
else
# Git target detected, update the git fragment and redisplay the prompt.
_prompt_sorin_git="${_git_target}${_git_post_target}"
zle && zle reset-prompt
fi
}
function prompt_sorin_precmd_ async {
# Get Git repository information.
function prompt_sorin_async_git {
cd -q "$1"
if (( $+functions[git-info] )); then
git-info
### TODO XXX
# This section exists to patch over vulnerabilities when sourcing the
# file in $_prompt_sorin_precmd_async_data. Without it if a branch is named
# $foo it will expand if we have a $foo variable, and a branch named
# $(IFS=_;cmd=rm_-rf_~;$cmd) could delete the users home directory.
# This is a stopgap to prevent code execution and fix the vulnerability,
# but it eventually needs to be removed in favor of zsh_async and not using
# a file to store the prompt data in.
###
local tmp_prompt_var=$(typeset -p git_info)
# Replace all $ with $\ to escape
tmp_prompt_var=${tmp_prompt_var//\$/\\$}
# Unescape the first \$ as it's our $( )
tmp_prompt_var=${tmp_prompt_var:s/\\$/\$}
# Escape all backticks ` to \`
tmp_prompt_var=${tmp_prompt_var//\`/\\\`}
printf "%s\n" "$tmp_prompt_var" >! "$_prompt_sorin_precmd_async_data"
print ${git_info[status]}
fi
# Signal completion to parent process.
kill -WINCH $$
}
function prompt_sorin_precmd {
@ -84,18 +68,21 @@ function prompt_sorin_precmd {
# Format PWD.
_prompt_sorin_pwd=$(prompt-pwd)
# Define prompts.
RPROMPT='${editor_info[overwrite]}%(?:: %F{1}⏎%f)${VIM:+" %B%F{6}V%f%b"}'
# Kill the old process of slow commands if it is still running.
if (( _prompt_sorin_precmd_async_pid > 0 )); then
kill -KILL "$_prompt_sorin_precmd_async_pid" &>/dev/null
async_flush_jobs async_sorin_git
# Handle updating git data. We also clear the git prompt data if we're in a
# different git root now.
if (( $+functions[git-dir] )); then
local new_git_root="$(git-dir 2>/dev/null)"
if [[ $new_git_root != $_sorin_cur_git_root ]]; then
_prompt_sorin_git=''
_sorin_cur_git_root=$new_git_root
fi
fi
# Compute slow commands in the background.
trap prompt_sorin_git_info WINCH
prompt_sorin_precmd_async &!
_prompt_sorin_precmd_async_pid=$!
async_job async_sorin_git prompt_sorin_async_git "$PWD"
}
function prompt_sorin_setup {
@ -107,6 +94,7 @@ function prompt_sorin_setup {
# Load required functions.
autoload -Uz add-zsh-hook
autoload -Uz async && async
# Add hook for calling git-info before each command.
add-zsh-hook precmd prompt_sorin_precmd
@ -133,11 +121,19 @@ function prompt_sorin_setup {
zstyle ':prezto:module:git:info:unmerged' format ' %%B%F{3}═%f%%b'
zstyle ':prezto:module:git:info:untracked' format ' %%B%F{7}◼%f%%b'
zstyle ':prezto:module:git:info:keys' format \
'status' '$(coalesce "%b" "%p" "%c")%s%A%B%S%a%d%m%r%U%u'
'status' '%b %p %c:%s%A%B%S%a%d%m%r%U%u'
# Get the async worker set up
async_start_worker async_sorin_git -n
async_register_callback async_sorin_git prompt_sorin_git_info
_sorin_cur_git_root=''
_prompt_sorin_git=''
_prompt_sorin_pwd=''
# Define prompts.
PROMPT='${SSH_TTY:+"%F{9}%n%f%F{7}@%f%F{3}%m%f "}%F{4}${_prompt_sorin_pwd}%(!. %B%F{1}#%f%b.)${editor_info[keymap]} '
RPROMPT=''
RPROMPT='${editor_info[overwrite]}%(?:: %F{1}⏎%f)${VIM:+" %B%F{6}V%f%b"}${_prompt_sorin_git} '
SPROMPT='zsh: correct %F{1}%R%f to %F{2}%r%f [nyae]? '
}