configs/home/.zsh/themes/spaceship-prompt/lib/core.zsh

169 lines
5.1 KiB
Bash
Raw Normal View History

2022-12-01 13:28:20 +01:00
#!/usr/bin/env zsh
# ------------------------------------------------------------------------------
# CORE RENDERER
# Tools for loading sections, building sections and invoking the renderer
# ------------------------------------------------------------------------------
# Loads the sections from files and functions
# USAGE:
# spaceship::core::load_sections
spaceship::core::load_sections() {
local load_async=false
# Iterate over sections
for section in $(spaceship::union $SPACESHIP_PROMPT_ORDER $SPACESHIP_RPROMPT_ORDER); do
if spaceship::defined "spaceship_$section"; then
# Custom section is declared, nothing else to do
continue
elif [[ -f "$SPACESHIP_ROOT/sections/$section.zsh" ]]; then
builtin source "$SPACESHIP_ROOT/sections/$section.zsh"
spaceship::precompile "$SPACESHIP_ROOT/sections/$section.zsh"
else
# section is not found!
spaceship::core::skip_section "$section"
continue
fi
if spaceship::is_section_async "$section"; then
load_async=true
fi
done
if $load_async; then
spaceship::worker::load
fi
}
# Iterate over sections, start async jobs and store results in cache
# USAGE:
# spaceship::core::start
spaceship::core::start() {
# Clear the cache before every render
spaceship::cache::clear
for section in $(spaceship::union $SPACESHIP_PROMPT_ORDER $SPACESHIP_RPROMPT_ORDER); do
spaceship::core::refresh_section "$section"
done
}
# A function to be called after async job execution
# USAGE:
# spaceship::core::async_callback
spaceship::core::async_callback() {
local job="$1" code="$2" output="$3" exec_time="$4" err="$5" has_next="$6"
local section="${job#"spaceship_"}" # TODO: Move spaceship_ to a constant
# Notify the worker that the job is done
spaceship::worker::callback "$@"
case $job in
"[async]")
# Handle all the errors that could indicate a crashed async worker.
# See zsh-async documentation for the definition of the exit codes.
if (( code == 2 )) || (( code == 3 )) || (( code == 130 )); then
# Our worker died unexpectedly, try to recover immediately.
spaceship::worker::init
spaceship::core::start
return
fi
;;
"[async/eval]")
if (( code )); then
# Looks like eval failed, rerun async tasks just in case.
spaceship::core::start
return
fi
;;
";")
# Ignore the async evals used to alter worker environment
return
;;
*)
# Hanlde regular successfully finished jobs
# Refresh async section when the last async job has finished
if [[ "${#SPACESHIP_JOBS}" -eq 0 ]]; then
spaceship::core::refresh_section "async"
spaceship::core::render
fi
# Skip prompt re-rendering if section is empty
if [[ "$(spaceship::cache::get $section)" == "$output" ]]; then
return
fi
# Update section cache
spaceship::cache::set "$section" "$output"
;;
esac
if [[ "$has_next" == 0 ]]; then
spaceship::core::render
fi
}
# Refreshes the cache of a section. If the section is async, it will be
# executed in a separate process.
# USAGE:
# spaceship::core::refresh_section [--sync] [section]
spaceship::core::refresh_section() {
# Parse CLI options
zparseopts -E -D -sync=sync
local section="$1"
[[ -z $section ]] && return 1
# Option EXTENDED_GLOB is set locally to force filename generation on
# argument to conditions, i.e. allow usage of explicit glob qualifier (#q).
# See the description of filename generation in
# http://zsh.sourceforge.net/Doc/Release/Conditional-Expressions.html
setopt EXTENDED_GLOB LOCAL_OPTIONS
if ! spaceship::defined "spaceship_$section"; then
spaceship::core::skip_section "$section"
return 1
fi
if spaceship::is_section_async "$section" && [[ -z $sync ]]; then
spaceship::worker::run "spaceship_$section"
else
spaceship::cache::set "$section" "$(spaceship_$section)"
fi
}
# Removes a section from both prompts and prints a message,
# so that we avoid printing errors over and over.
# USAGE:
# spaceship::core::skip_section <section>
spaceship::core::skip_section() {
local section="$1"
print -P "%F{yellow}Warning!%f The '%F{cyan}${section}%f' section was not found. Removing it from the prompt."
SPACESHIP_PROMPT_ORDER=("${(@)SPACESHIP_PROMPT_ORDER:#${section}}")
SPACESHIP_RPROMPT_ORDER=("${(@)SPACESHIP_RPROMPT_ORDER:#${section}}")
}
# Compose whole prompt from sections
# USAGE:
# spaceship::core::compose_order [section...]
spaceship::core::compose_order() {
# Treat the first argument as list of prompt sections
# Compose whole prompt from diferent parts
for section in $@; do
spaceship::section::render "$(spaceship::cache::get $section)"
done
}
# Render and reset the prompt asyncronously.
# USAGE:
# spaceship::core::render
spaceship::core::render() {
spaceship::populate
# .reset-prompt: bypass the zsh-syntax-highlighting wrapper
# https://github.com/sorin-ionescu/prezto/issues/1026
# https://github.com/zsh-users/zsh-autosuggestions/issues/107#issuecomment-183824034
zle && zle .reset-prompt && zle -R
}