diff --git a/lib/async_prompt.zsh b/lib/async_prompt.zsh index 7f32c8a37..dfd895734 100644 --- a/lib/async_prompt.zsh +++ b/lib/async_prompt.zsh @@ -11,19 +11,34 @@ zmodload zsh/system # function _git_prompt_status_async { # # Do some expensive operation that outputs to stdout # } -# _omz_async_functions+=(_git_prompt_status_async) +# _omz_register_handler _git_prompt_status_async # # Then add a stub prompt function in `$PROMPT` or similar prompt variables, # which will show the output of "$_OMZ_ASYNC_OUTPUT[handler_name]": # # function git_prompt_status { -# echo $_OMZ_ASYNC_OUTPUT[_git_prompt_status] +# echo -n $_OMZ_ASYNC_OUTPUT[_git_prompt_status] # } # # RPROMPT='$(git_prompt_status)' # # This API is subject to change and optimization. Rely on it at your own risk. -typeset -ga _omz_async_functions + +function _omz_register_handler { + typeset -ga _omz_async_functions + # we want to do nothing if there's no $1 function or we already set it up + if [[ -z "$1" ]] || (( ! ${+functions[$1]} )) \ + || (( ${+_omz_async_functions[$1]} )); then + return + fi + _omz_async_functions+=("$1") + # let's add the hook to async_request if it's not there yet + if (( ! ${+precmd_functions[_omz_async_request]} )) \ + && (( ${+functions[_omz_async_request]})); then + autoload -Uz add-zsh-hook + add-zsh-hook precmd _omz_async_request + fi +} # Set up async handlers and callbacks function _omz_async_request { @@ -122,6 +137,3 @@ function _omz_async_callback() { _OMZ_ASYNC_FDS[$handler]=-1 _OMZ_ASYNC_PIDS[$handler]=-1 } - -autoload -Uz add-zsh-hook -add-zsh-hook precmd _omz_async_request diff --git a/lib/git.zsh b/lib/git.zsh index e59911fac..ec1d09d1b 100644 --- a/lib/git.zsh +++ b/lib/git.zsh @@ -9,70 +9,47 @@ function __git_prompt_git() { GIT_OPTIONAL_LOCKS=0 command git "$@" } +function _omz_git_prompt_status() { + # If we are on a folder not tracked by git, get out. + # Otherwise, check for hide-info at global and local repository level + if ! __git_prompt_git rev-parse --git-dir &> /dev/null \ + || [[ "$(__git_prompt_git config --get oh-my-zsh.hide-info 2>/dev/null)" == 1 ]]; then + return 0 + fi + + # Get either: + # - the current branch name + # - the tag name if we are on a tag + # - the short SHA of the current commit + local ref + ref=$(__git_prompt_git symbolic-ref --short HEAD 2> /dev/null) \ + || ref=$(__git_prompt_git describe --tags --exact-match HEAD 2> /dev/null) \ + || ref=$(__git_prompt_git rev-parse --short HEAD 2> /dev/null) \ + || return 0 + + # Use global ZSH_THEME_GIT_SHOW_UPSTREAM=1 for including upstream remote info + local upstream + if (( ${+ZSH_THEME_GIT_SHOW_UPSTREAM} )); then + upstream=$(__git_prompt_git rev-parse --abbrev-ref --symbolic-full-name "@{upstream}" 2>/dev/null) \ + && upstream=" -> ${upstream}" + fi + + echo "${ZSH_THEME_GIT_PROMPT_PREFIX}${ref:gs/%/%%}${upstream:gs/%/%%}$(parse_git_dirty)${ZSH_THEME_GIT_PROMPT_SUFFIX}" +} + # Enable async prompt by default unless the setting is at false / no if zstyle -T ':omz:alpha:lib:git' async-prompt; then _omz_async_functions+=(_omz_git_prompt_status) function git_prompt_info() { + _omz_register_handler _omz_git_prompt_status if [[ -n "$_OMZ_ASYNC_OUTPUT[_omz_git_prompt_status]" ]]; then echo -n "$_OMZ_ASYNC_OUTPUT[_omz_git_prompt_status]" fi } - - function _omz_git_prompt_status() { - # If we are on a folder not tracked by git, get out. - # Otherwise, check for hide-info at global and local repository level - if ! __git_prompt_git rev-parse --git-dir &> /dev/null \ - || [[ "$(__git_prompt_git config --get oh-my-zsh.hide-info 2>/dev/null)" == 1 ]]; then - return 0 - fi - - # Get either: - # - the current branch name - # - the tag name if we are on a tag - # - the short SHA of the current commit - local ref - ref=$(__git_prompt_git symbolic-ref --short HEAD 2> /dev/null) \ - || ref=$(__git_prompt_git describe --tags --exact-match HEAD 2> /dev/null) \ - || ref=$(__git_prompt_git rev-parse --short HEAD 2> /dev/null) \ - || return 0 - - # Use global ZSH_THEME_GIT_SHOW_UPSTREAM=1 for including upstream remote info - local upstream - if (( ${+ZSH_THEME_GIT_SHOW_UPSTREAM} )); then - upstream=$(__git_prompt_git rev-parse --abbrev-ref --symbolic-full-name "@{upstream}" 2>/dev/null) \ - && upstream=" -> ${upstream}" - fi - - echo "${ZSH_THEME_GIT_PROMPT_PREFIX}${ref:gs/%/%%}${upstream:gs/%/%%}$(parse_git_dirty)${ZSH_THEME_GIT_PROMPT_SUFFIX}" - } else function git_prompt_info() { - # If we are on a folder not tracked by git, get out. - # Otherwise, check for hide-info at global and local repository level - if ! __git_prompt_git rev-parse --git-dir &> /dev/null \ - || [[ "$(__git_prompt_git config --get oh-my-zsh.hide-info 2>/dev/null)" == 1 ]]; then - return 0 - fi - - # Get either: - # - the current branch name - # - the tag name if we are on a tag - # - the short SHA of the current commit - local ref - ref=$(__git_prompt_git symbolic-ref --short HEAD 2> /dev/null) \ - || ref=$(__git_prompt_git describe --tags --exact-match HEAD 2> /dev/null) \ - || ref=$(__git_prompt_git rev-parse --short HEAD 2> /dev/null) \ - || return 0 - - # Use global ZSH_THEME_GIT_SHOW_UPSTREAM=1 for including upstream remote info - local upstream - if (( ${+ZSH_THEME_GIT_SHOW_UPSTREAM} )); then - upstream=$(__git_prompt_git rev-parse --abbrev-ref --symbolic-full-name "@{upstream}" 2>/dev/null) \ - && upstream=" -> ${upstream}" - fi - - echo "${ZSH_THEME_GIT_PROMPT_PREFIX}${ref:gs/%/%%}${upstream:gs/%/%%}$(parse_git_dirty)${ZSH_THEME_GIT_PROMPT_SUFFIX}" + _omz_git_prompt_status } fi