# Zsh prompt theme, needs Zsh >= 5.0.0. Asynchronous prompt if zsh-async is # detected. Requires 256 colours. function() # Keep local variables in here { # Make theme variables global for later use typeset -gA zsh_theme_colours zsh_theme_colours[prompt]="207" # bright pink zsh_theme_colours[vcs]="97" # dark pink zsh_theme_colours[highlight]="201" # pink zsh_theme_colours[minor]="61" # dark violet zsh_theme_colours[inactive]="236" # grey # This will use potentially user defined colours [[ -n "${SSH_CONNECTION}" ]] && zsh_theme_colours[prompt]="11" # bright yellow [[ ${EUID} -eq 0 ]] && zsh_theme_colours[prompt]="9" # bright red # Show username if it is not the default user local showuser="" if [[ "${USERNAME}" != "${DEFAULT_USER}" ]] && [[ -n "${USERNAME}" ]]; then showuser="%n " fi autoload -Uz vcs_info zmodload zsh/zutil zstyle ':vcs_info:*' enable git svn hg # vcs_info_printsys zstyle ':vcs_info:*' formats "%F{${zsh_theme_colours[vcs]}}(%b)%u%c%f " zstyle ':vcs_info:*' actionformats "%F{${zsh_theme_colours[vcs]}}(%b|%F{${zsh_theme_colours[highlight]}}%a%F{${zsh_theme_colours[vcs]}})%u%c%f " zstyle ':vcs_info:*' stagedstr "%F{${zsh_theme_colours[highlight]}}●%f" zstyle ':vcs_info:*' unstagedstr "%F{${zsh_theme_colours[highlight]}}○%f" zstyle ':vcs_info:*' check-for-changes true # Needs mafredri/zsh-async, async_init must be called before using function _async_vcs_prompt() { # From https://vincent.bernat.ch/en/blog/2019-zsh-async-vcs-info function _my_vcs_async_start() { async_start_worker vcs_info async_register_callback vcs_info _my_vcs_info_done } function _my_vcs_info() { cd -q ${1} vcs_info print "${vcs_info_msg_0_}" } function _my_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 _my_vcs_async_start return fi fi vcs_info_msg_0_="${stdout}" (( ${more} )) || zle reset-prompt } function _my_vcs_chpwd() { # Change colour of old value vcs_info_msg_0_="${vcs_info_msg_0_//\%F\{${zsh_theme_colours[vcs]}/%F{${zsh_theme_colours[inactive]}}" vcs_info_msg_0_="${vcs_info_msg_0_//\%F\{${zsh_theme_colours[highlight]}/%F{${zsh_theme_colours[inactive]}}" } function _my_vcs_precmd() { async_flush_jobs vcs_info async_job vcs_info _my_vcs_info $PWD } _my_vcs_async_start autoload -Uz add-zsh-hook add-zsh-hook precmd _my_vcs_precmd add-zsh-hook chpwd _my_vcs_chpwd } # Use asynchronous VCS prompt if zsh-async is available if [[ -v ASYNC_VERSION ]]; then [[ ${ASYNC_INIT_DONE} -eq 0 ]] && async_init _async_vcs_prompt else add-zsh-hook precmd vcs_info 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 _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 )) for index in {2..$(( ${#short_dir} - 1 ))}; do if [[ ${#short_dir[index]} -gt ${allowed_element_width} ]] && \ [[ ${#${(j:/:)short_dir}} -gt ${max_width} ]]; then 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} } setopt PROMPT_SUBST PROMPT="%B%F{${zsh_theme_colours[prompt]}}${showuser}%b"'${vcs_info_msg_0_}'"%B%F{${zsh_theme_colours[prompt]}}%#%f%b " RPROMPT="%F{${zsh_theme_colours[minor]}}%(?..[%B%F{${zsh_theme_colours[highlight]}}%?%b%F{${zsh_theme_colours[minor]}}] )"'$(_shrunkpwd)'"%f" }