Initial async prompt utility wrapper

This commit is contained in:
Marc Cornellà 2024-05-30 19:51:35 +02:00
parent a4424dfefd
commit c4a126c2ac
No known key found for this signature in database
GPG key ID: 0314585E776A9C1B
4 changed files with 39 additions and 26 deletions

View file

@ -26,7 +26,6 @@ autoload -Uz is-at-least
# This API is subject to change and optimization. Rely on it at your own risk. # This API is subject to change and optimization. Rely on it at your own risk.
function _omz_register_handler { function _omz_register_handler {
setopt localoptions noksharrays
typeset -ga _omz_async_functions typeset -ga _omz_async_functions
# we want to do nothing if there's no $1 function or we already set it up # we want to do nothing if there's no $1 function or we already set it up
if [[ -z "$1" ]] || (( ! ${+functions[$1]} )) \ if [[ -z "$1" ]] || (( ! ${+functions[$1]} )) \
@ -42,6 +41,25 @@ function _omz_register_handler {
fi fi
} }
function _omz_make_async_function {
local sync_func=$1
# Check if the sync function has already been made async
if (( ${+functions[${sync_func}_async]} )); then
return
fi
# Register the sync function as a handler
_omz_register_handler ${sync_func}
# Redefine the original function to output the async result
eval "function ${sync_func}_async {
if [[ -n \"\${_OMZ_ASYNC_OUTPUT[${sync_func}]}\" ]]; then
echo -n \"\${_OMZ_ASYNC_OUTPUT[${sync_func}]}\"
fi
}"
}
# Set up async handlers and callbacks # Set up async handlers and callbacks
function _omz_async_request { function _omz_async_request {
local -i ret=$? local -i ret=$?

View file

@ -11,7 +11,7 @@ function __git_prompt_git() {
GIT_OPTIONAL_LOCKS=0 command git "$@" GIT_OPTIONAL_LOCKS=0 command git "$@"
} }
function _omz_git_prompt_info() { function git_prompt_info() {
# If we are on a folder not tracked by git, get out. # If we are on a folder not tracked by git, get out.
# Otherwise, check for hide-info at global and local repository level # Otherwise, check for hide-info at global and local repository level
if ! __git_prompt_git rev-parse --git-dir &> /dev/null \ if ! __git_prompt_git rev-parse --git-dir &> /dev/null \
@ -41,31 +41,29 @@ function _omz_git_prompt_info() {
# Use async version if setting is enabled or undefined # Use async version if setting is enabled or undefined
if zstyle -T ':omz:alpha:lib:git' async-prompt; then if zstyle -T ':omz:alpha:lib:git' async-prompt; then
function git_prompt_info() {
if [[ -n "${_OMZ_ASYNC_OUTPUT[_omz_git_prompt_info]}" ]]; then
echo -n "${_OMZ_ASYNC_OUTPUT[_omz_git_prompt_info]}"
fi
}
function git_prompt_status() {
if [[ -n "${_OMZ_ASYNC_OUTPUT[_omz_git_prompt_status]}" ]]; then
echo -n "${_OMZ_ASYNC_OUTPUT[_omz_git_prompt_status]}"
fi
}
# Conditionally register the async handler, only if it's needed in $PROMPT # Conditionally register the async handler, only if it's needed in $PROMPT
# or any of the other prompt variables # or any of the other prompt variables
function _defer_async_git_register() { function _defer_async_git_register() {
# Check if the user wants to register some async functions
local -a async_functions
zstyle -a ':omz:alpha:lib:git' async-functions async_functions
if (( ${#async_functions} )); then
for async_function in $async_functions; do
_omz_make_async_function $async_function
done
fi
# Check if git_prompt_info is used in a prompt variable # Check if git_prompt_info is used in a prompt variable
case "${PS1}:${PS2}:${PS3}:${PS4}:${RPROMPT}:${RPS1}:${RPS2}:${RPS3}:${RPS4}" in case "${PS1}:${PS2}:${PS3}:${PS4}:${RPROMPT}:${RPS1}:${RPS2}:${RPS3}:${RPS4}" in
*(\$\(git_prompt_info\)|\`git_prompt_info\`)*) *(\$\(git_prompt_info\)|\`git_prompt_info\`)*)
_omz_register_handler _omz_git_prompt_info _omz_make_async_function git_prompt_info
;; ;;
esac esac
case "${PS1}:${PS2}:${PS3}:${PS4}:${RPROMPT}:${RPS1}:${RPS2}:${RPS3}:${RPS4}" in case "${PS1}:${PS2}:${PS3}:${PS4}:${RPROMPT}:${RPS1}:${RPS2}:${RPS3}:${RPS4}" in
*(\$\(git_prompt_status\)|\`git_prompt_status\`)*) *(\$\(git_prompt_status\)|\`git_prompt_status\`)*)
_omz_register_handler _omz_git_prompt_status _omz_make_async_function git_prompt_status
;; ;;
esac esac
@ -76,13 +74,6 @@ if zstyle -T ':omz:alpha:lib:git' async-prompt; then
# Register the async handler first. This needs to be done before # Register the async handler first. This needs to be done before
# the async request prompt is run # the async request prompt is run
precmd_functions=(_defer_async_git_register $precmd_functions) precmd_functions=(_defer_async_git_register $precmd_functions)
else
function git_prompt_info() {
_omz_git_prompt_info
}
function git_prompt_status() {
_omz_git_prompt_status
}
fi fi
# Checks if working tree is dirty # Checks if working tree is dirty
@ -213,7 +204,7 @@ function git_prompt_long_sha() {
SHA=$(__git_prompt_git rev-parse HEAD 2> /dev/null) && echo "$ZSH_THEME_GIT_PROMPT_SHA_BEFORE$SHA$ZSH_THEME_GIT_PROMPT_SHA_AFTER" SHA=$(__git_prompt_git rev-parse HEAD 2> /dev/null) && echo "$ZSH_THEME_GIT_PROMPT_SHA_BEFORE$SHA$ZSH_THEME_GIT_PROMPT_SHA_AFTER"
} }
function _omz_git_prompt_status() { function git_prompt_status() {
[[ "$(__git_prompt_git config --get oh-my-zsh.hide-status 2>/dev/null)" = 1 ]] && return [[ "$(__git_prompt_git config --get oh-my-zsh.hide-status 2>/dev/null)" = 1 ]] && return
# Maps a git status prefix to an internal constant # Maps a git status prefix to an internal constant

View file

@ -23,4 +23,8 @@ vcs_status() {
fi fi
} }
PROMPT='%2~ $(vcs_status)»%b ' # Register the sync function
autoload -Uz _omz_make_async_function
_omz_make_async_function vcs_status
PROMPT='%2~ $(vcs_status_async)»%b '

View file

@ -1,5 +1,5 @@
PROMPT="%(?:%{$fg_bold[green]%}%1{➜%} :%{$fg_bold[red]%}%1{➜%} ) %{$fg[cyan]%}%c%{$reset_color%}" PROMPT="%(?:%{$fg_bold[green]%}%1{➜%} :%{$fg_bold[red]%}%1{➜%} ) %{$fg[cyan]%}%c%{$reset_color%}"
PROMPT+=' $(git_prompt_info)' PROMPT+=' $(git_prompt_info_async)'
ZSH_THEME_GIT_PROMPT_PREFIX="%{$fg_bold[blue]%}git:(%{$fg[red]%}" ZSH_THEME_GIT_PROMPT_PREFIX="%{$fg_bold[blue]%}git:(%{$fg[red]%}"
ZSH_THEME_GIT_PROMPT_SUFFIX="%{$reset_color%} " ZSH_THEME_GIT_PROMPT_SUFFIX="%{$reset_color%} "