# tastytea prompt theme prompt_tastytea_help() { cat <<'EOF' Minimal + vcs_info on the left, PWD on the right (shortened to 1/3 screen). This prompt is colour-scheme-able. You can invoke it thus: prompt tastytea [user [root [remote [vcs [path [highlight [inactive]]]]]]] Set DEFAULT_USER to only show non-default users in prompt. You need to set up vcs_info before enabling the prompt. EOF if [[ ! -v ASYNC_VERSION ]]; then print "Load https://github.com/mafredri/zsh-async" \ "for asynchronous VCS info support." fi } # Reduce directory elements to first letter until directory path is reasonably # short. Never shrink first element. Don't shrink relatively short elements. Try # to not shrink last element. function prompt_tastytea_shrunkpwd() { local dir=${(D)PWD} local -i max_width=$(( ${COLUMNS} / 3 )) if [[ ${#dir} -le ${max_width} ]]; then print -n ${dir} return fi # Maybe shorten all elements but the first and last local -a short_dir=(${(s:/:)dir}) local -i allowed_element_width=$(( ( ${max_width} - ${#short_dir[1]} - ${#short_dir[-1]} ) / ${#short_dir} )) for index in {2..$(( ${#short_dir} - 1 ))}; do if [[ ${#short_dir[index]} -gt ${allowed_element_width} ]]; then [[ ${#${(j:/:)short_dir}} -le ${max_width} ]] && break short_dir[index]=${short_dir[index][1]} fi done # If the last element is too long, replace the mid-section with … if [[ ${#short_dir[-1]} -gt ${allowed_element_width} ]]; then local -i current_width=${#${(j:/:)short_dir}} if [[ ${current_width} -gt ${max_width} ]]; then local -i half_length=$(( ( ${max_width} - ( ${current_width} - ${#short_dir[-1]} ) ) / 2 - 1 )) short_dir[-1]=${short_dir[-1][1,${half_length}]}"…"${short_dir[-1][$(( ${half_length} * -1 )),-1]} fi fi local out=${(j:/:)short_dir} [[ ${out[1]} != '~' ]] && out[1]="/${out[1]}" print -n ${out} } # Needs function prompt_tastytea_vcs_async() { # From https://vincent.bernat.ch/en/blog/2019-zsh-async-vcs-info function prompt_tastytea_vcs_async_start() { async_start_worker prompt_tastytea_vcs_info async_register_callback prompt_tastytea_vcs_info \ prompt_tastytea_vcs_info_done } function prompt_tastytea_vcs_info_job() { cd -q ${1} vcs_info print "${vcs_info_msg_0_}" } function prompt_tastytea_vcs_info_done() { local job=${1} local return_code=${2} local stdout=${3} local more=${6} if [[ ${job} == '[async]' ]]; then if [[ ${return_code} -eq 2 ]]; then # Need to restart the worker prompt_tastytea_vcs_async_start return fi fi vcs_info_msg_0_="${stdout}" (( ${more} )) || zle reset-prompt } function prompt_tastytea_vcs_chpwd() { # Change colour of old value vcs_info_msg_0_="${vcs_info_msg_0_//\%F\{${prompt_tastytea_colours[vcs]}/%F{${prompt_tastytea_colours[inactive]}}" vcs_info_msg_0_="${vcs_info_msg_0_//\%F\{${prompt_tastytea_colours[highlight]}/%F{${prompt_tastytea_colours[inactive]}}" } function prompt_tastytea_vcs_precmd() { async_flush_jobs prompt_tastytea_vcs_info async_job prompt_tastytea_vcs_info prompt_tastytea_vcs_info_job $PWD } prompt_tastytea_vcs_async_start add-zsh-hook precmd prompt_tastytea_vcs_precmd add-zsh-hook chpwd prompt_tastytea_vcs_chpwd } function prompt_tastytea_vcs() { autoload -U vcs_info add-zsh-hook zmodload zsh/zutil zstyle ':vcs_info:*' formats "%F{${prompt_tastytea_colours[vcs]}}(%b)%u%c%f " zstyle ':vcs_info:*' actionformats "%F{${prompt_tastytea_colours[vcs]}}(%b|%F{${prompt_tastytea_colours[highlight]}}%a%F{${prompt_tastytea_colours[vcs]}})%u%c%f " zstyle ':vcs_info:*' stagedstr "%F{${prompt_tastytea_colours[highlight]}}●" zstyle ':vcs_info:*' unstagedstr "%F{${prompt_tastytea_colours[highlight]}}○" # Use asynchronous VCS prompt if zsh-async is available if [[ -v ASYNC_VERSION ]]; then [[ ${ASYNC_INIT_DONE} -eq 0 ]] && async_init prompt_tastytea_vcs_async else add-zsh-hook precmd vcs_info fi } function prompt_tastytea_setup() { if [[ ${ZSH_VERSION[1]} -lt 5 ]]; then print -u2 "This theme needs Zsh >= 5" return 1 fi # Needs to be global for async functions typeset -gA prompt_tastytea_colours prompt_tastytea_colours[user]="${1:-207}" # bright pink prompt_tastytea_colours[root]="${2:-196}" # bright red prompt_tastytea_colours[remote]="${3:-226}" # bright yellow prompt_tastytea_colours[vcs]="${4:-97}" # dark pink prompt_tastytea_colours[path]="${5:-61}" # dark violet prompt_tastytea_colours[highlight]="${6:-201}" # pink prompt_tastytea_colours[inactive]="${7:-237}" # grey prompt_tastytea_colours[prompt]=${prompt_tastytea_colours[user]} if [[ -v SSH_CONNECTION ]]; then prompt_tastytea_colours[prompt]=${prompt_tastytea_colours[remote]} fi if [[ ${EUID} -eq 0 ]]; then prompt_tastytea_colours[prompt]=${prompt_tastytea_colours[root]} fi # Show username if it is not the default user local showuser="" if [[ "${USERNAME}" != "${DEFAULT_USER}" ]] && [[ -n "${USERNAME}" ]]; then showuser="%B%F{${prompt_tastytea_colours[prompt]}}%n%f%b " fi prompt_tastytea_vcs prompt_opts=(cr percent sp subst) PS1="${showuser}"'${vcs_info_msg_0_}'"%B%F{${prompt_tastytea_colours[prompt]}}%#%f%b " RPS1="%F{${prompt_tastytea_colours[path]}}%(?..[%B%F{${prompt_tastytea_colours[highlight]}}%?%b%F{${prompt_tastytea_colours[path]}}] )"'$(prompt_tastytea_shrunkpwd)'"%f" PS2='%F{${prompt_tastytea_colours[prompt]}}%_>%f ' PS3='%F{${prompt_tastytea_colours[prompt]}}?#%f ' PS4='%F{${prompt_tastytea_colours[prompt]}}+%N:%i>%f ' prompt_cleanup 'prompt_tastytea_cleanup' } function prompt_tastytea_cleanup() { if [[ -v ASYNC_VERSION ]]; then async_stop_worker prompt_tastytea_vcs_info fi } prompt_tastytea_setup "$@" # Local Variables: # mode: shell-script # End: # vim: set ft=zsh: