if [[ ! -o interactive ]]; then
return 0 2>/dev/null || exit 0
fi
if [[ -n "${SLICK_PATH:-}" && -x "${SLICK_PATH}" ]]; then
:
elif command -v slick &> /dev/null; then
SLICK_PATH="$(command -v slick)"
elif [[ -x "$HOME/.cargo/bin/slick" ]]; then
SLICK_PATH="$HOME/.cargo/bin/slick"
else
return 0 2>/dev/null || exit 0
fi
function slick_prompt_install_widget {
local widget=$1
local function_name=$2
local backup_widget=$3
local current_widget=${widgets[$widget]-}
if [[ -n "$backup_widget" && -n "$current_widget" && "$current_widget" != "user:$function_name" ]]; then
zle -A "$widget" "$backup_widget"
fi
zle -N "$widget" "$function_name"
}
autoload -Uz add-zsh-hook
add-zsh-hook -D precmd slick_prompt_precmd
add-zsh-hook -D preexec slick_prompt_preexec
zmodload zsh/datetime
add-zsh-hook precmd slick_prompt_precmd
add-zsh-hook preexec slick_prompt_preexec
slick_prompt_install_widget zle-keymap-select slick_prompt_zle_keymap_select slick_prompt_original_zle_keymap_select
slick_prompt_install_widget zle-line-init slick_prompt_zle_line_init slick_prompt_original_zle_line_init
slick_prompt_install_widget accept-line slick_prompt_accept_line slick_prompt_original_accept_line
typeset -g slick_prompt_data
typeset -g slick_prompt_fd
typeset -g slick_prompt_timestamp
typeset -g slick_prompt_elapsed
typeset -gi slick_prompt_exit_status=${slick_prompt_exit_status:-0}
typeset -gi slick_prompt_dollar_psvar_index=${slick_prompt_dollar_psvar_index:-0}
typeset -gi slick_prompt_backtick_psvar_index=${slick_prompt_backtick_psvar_index:-0}
typeset -gi slick_prompt_backslash_psvar_index=${slick_prompt_backslash_psvar_index:-0}
function slick_prompt_literal_psvars_valid {
emulate -L zsh
(( slick_prompt_dollar_psvar_index >= 1 &&
slick_prompt_backtick_psvar_index >= 1 &&
slick_prompt_backslash_psvar_index >= 1 )) &&
[[ "${psvar[$slick_prompt_dollar_psvar_index]-}" == '$' &&
"${psvar[$slick_prompt_backtick_psvar_index]-}" == '`' &&
"${psvar[$slick_prompt_backslash_psvar_index]-}" == '\' ]]
}
function slick_prompt_install_literal_psvars {
emulate -L zsh
if slick_prompt_literal_psvars_valid; then
return
fi
psvar+=('$' '`' '\')
slick_prompt_dollar_psvar_index=$(( ${#psvar} - 2 ))
slick_prompt_backtick_psvar_index=$(( ${#psvar} - 1 ))
slick_prompt_backslash_psvar_index=${#psvar}
}
slick_prompt_install_literal_psvars
function slick_prompt_transient_enabled {
[[ "${SLICK_PROMPT_TRANSIENT:-1}" != "0" ]]
}
function slick_prompt_rfc3339_timestamp {
local timestamp
if [[ "${SLICK_PROMPT_SHORT_TIMESTAMP:-0}" == "1" ]]; then
strftime -s timestamp '%H:%M:%S' $EPOCHSECONDS
print -r -- "$timestamp"
else
strftime -s timestamp '%Y-%m-%dT%H:%M:%S%z' $EPOCHSECONDS
print -r -- "${timestamp[1,-3]}:${timestamp[-2,-1]}"
fi
}
function slick_prompt_render {
emulate -L zsh
local exit_status=${1:-0}
local transient=${2:-0}
local transient_timestamp=${3:-}
local -a args
args=(
"$SLICK_PATH"
prompt
-k "${KEYMAP:-main}"
-r "$exit_status"
-d "${slick_prompt_data:-}"
)
if [[ -n "${slick_prompt_elapsed:-}" ]]; then
args+=(-e "$slick_prompt_elapsed")
fi
if [[ "$transient" == 1 ]]; then
args+=(--transient)
if [[ -n "$transient_timestamp" ]]; then
args+=(--transient-timestamp "$transient_timestamp")
fi
fi
_SLICK_PROMPT_PSVAR_DOLLAR="$slick_prompt_dollar_psvar_index" \
_SLICK_PROMPT_PSVAR_BACKTICK="$slick_prompt_backtick_psvar_index" \
_SLICK_PROMPT_PSVAR_BACKSLASH="$slick_prompt_backslash_psvar_index" \
"${args[@]}"
}
function slick_prompt_set_prompt {
slick_prompt_install_literal_psvars
PROMPT=$(slick_prompt_render "$@")
}
function slick_prompt_refresh {
local line
if read -r -u $1 line; then
slick_prompt_data="$line"
slick_prompt_set_prompt "$slick_prompt_exit_status"
zle && zle reset-prompt
return fi
unset slick_prompt_timestamp
unset slick_prompt_elapsed
zle -F $1
exec {1}<&-
if [[ "$1" == "$slick_prompt_fd" ]]; then
unset slick_prompt_fd
fi
}
function slick_prompt_zle_line_init {
slick_prompt_set_prompt "$slick_prompt_exit_status"
zle && zle reset-prompt
if [[ -n ${widgets[slick_prompt_original_zle_line_init]-} ]]; then
zle slick_prompt_original_zle_line_init
if ! slick_prompt_literal_psvars_valid; then
slick_prompt_set_prompt "$slick_prompt_exit_status"
zle && zle reset-prompt
fi
fi
}
function slick_prompt_zle_keymap_select {
slick_prompt_set_prompt "$slick_prompt_exit_status"
zle && zle reset-prompt
if [[ -n ${widgets[slick_prompt_original_zle_keymap_select]-} ]]; then
zle slick_prompt_original_zle_keymap_select
if ! slick_prompt_literal_psvars_valid; then
slick_prompt_set_prompt "$slick_prompt_exit_status"
zle && zle reset-prompt
fi
fi
}
function slick_prompt_accept_line {
local transient=0
local transient_timestamp
if slick_prompt_transient_enabled; then
transient=1
transient_timestamp=$(slick_prompt_rfc3339_timestamp)
slick_prompt_set_prompt "$slick_prompt_exit_status" 1 "$transient_timestamp"
zle reset-prompt
fi
if [[ -n ${widgets[slick_prompt_original_accept_line]-} ]]; then
zle slick_prompt_original_accept_line
else
zle .accept-line
fi
if ! slick_prompt_literal_psvars_valid; then
slick_prompt_set_prompt "$slick_prompt_exit_status" "$transient" "$transient_timestamp"
fi
}
function slick_prompt_precmd() {
slick_prompt_exit_status=$?
slick_prompt_data=""
if [[ -n "$slick_prompt_fd" ]]; then
zle -F $slick_prompt_fd
exec {slick_prompt_fd}<&-
unset slick_prompt_fd
fi
if [[ -n "$slick_prompt_timestamp" ]]; then
slick_prompt_elapsed=$(( EPOCHSECONDS - slick_prompt_timestamp ))
[[ $slick_prompt_elapsed -lt 0 ]] && slick_prompt_elapsed=0
else
unset slick_prompt_elapsed
fi
exec {slick_prompt_fd}< <($SLICK_PATH precmd)
zle -F $slick_prompt_fd slick_prompt_refresh
}
function slick_prompt_preexec() {
if [[ -n "$slick_prompt_fd" ]]; then
zle -F $slick_prompt_fd
exec {slick_prompt_fd}<&-
unset slick_prompt_fd
fi
slick_prompt_timestamp=$EPOCHSECONDS
}