# ===== use colorized output autoload -Uz colors; colors case "$OSTYPE" in darwin*|bsd*) export CLICOLOR=1 export LSCOLORS=gxfxcxdxbxegedabagacad ;; *) export LS_COLORS=di='36;40:ln=35;40:so=32;40:pi=33;40:ex=31;40:bd=34;46:cd=34;43:su=0;41:sg=0;46:tw=0;42:ow=0;45:' ;; esac # ===== setopts and misc # only show RPROMPT on the current prompt setopt transient_rprompt # only show the rprompt on the current prompt # ===== set the prompt zshrc_prompt_precmd() { # call vcs_info before every prompt vcs_info # regex to remove all zerospace elements. Used to calculate the width of # the top prompt. local zero='%([BSUBfksu]|([FB]|){*})' # linedrawing characters local top_left_corner="╭" local top_right_corner="╮" local bottom_left_corner="╰" local bottom_right_corner="╯" local dash="─" # check $TERM and use non unicode symbols if necessary if [[ $TERM == "linux" ]]; then top_left_corner="+" top_right_corner="+" bottom_left_corner="+" bottom_right_corner="+" dash="-" fi # commonly used design elements local bracket_open="%F{blue}${dash}(%f" local bracket_close="%F{blue}%)${dash}%f" local separator="%F{cyan}${dash}%f" # current directory, truncated if necessary (WIDTH is replaced later) local directory="%F{magenta}%WIDTH<..<%~%<<%f" # current time (HH:MM) local time="%F{yellow}%D{%H:%M}%f" # username, green for normal users, red for root local user="%(!.%F{red}.%F{green})%n%f" # information about unstaged/staged changes in VCS in current directory local vcs="${vcs_info_msg_0_}" local vcs_width=${#${(S%%%)vcs//$~zero/}} if [[ $vcs_width -ne 0 ]]; then # add brackets if vcs is non-empty vcs="${bracket_open}${vcs}${bracket_close}" fi # hostname, underlined if running on a remote system through SSH local host="%F{green}%m%f" if [[ -n $SSH_CONNECTION ]]; then host="%U${host}%u" fi # exitcode in parentheses if not zero local exitcode="%(?..[%F{red}%?%f])" # prompt symbol, $ in cyan for normal users, # in red for root local symbol="%(!.%F{red}#%f.%F{cyan}>%f)" # battery percentage, if acpi is available local battery_pct= if [[ -d /sys/class/power_supply/BAT*(#qN) ]] && type acpi &> /dev/null; then battery_pct="$(acpi -b | cut -d, -f2 | sed -e 's/[^0-9]//g' | head -n1)" # colorize battery percentage or display status if [[ $battery_pct -le 20 ]]; then battery_pct="%F{red}${battery_pct}%%%f" elif [[ $battery_pct -le 65 ]]; then battery_pct="%F{yellow}${battery_pct}%%%f" else battery_pct="%F{green}${battery_pct}%%%f" fi if [[ $(acpi -a | cut -d':' -f2) == " on-line" ]]; then battery_pct="%F{yellow}⌁%f${battery_pct}%F{yellow}⌁%f" fi fi # prefix characters in first and second line local top_prefix="%F{cyan}${top_left_corner}%f" local bottom_prefix="%F{cyan}${bottom_left_corner}%f" # suffix characters in first and second line local top_suffix="%F{cyan}${top_right_corner}%f" local bottom_suffix="%F{cyan}${bottom_right_corner}%f" # remove useless space after RPROMPT ZLE_RPROMPT_INDENT=-1 # combine them to create the prompt local top_left="" local top_right="${bracket_open}${time}${bracket_close}" local top_middle="${vcs}" local bottom_left="${bracket_open}${user}%F{green}@%f${host}${bracket_close}${exitcode}${separator}${symbol}" local bottom_right= # if $battery_pct is empty, just add a vertical line if [[ -n $battery_pct ]]; then bottom_right="${separator}${bracket_open}${battery_pct}${bracket_close}" else bottom_right="%F{blue}${dash}%f" fi # calculate width of prompt components local width_top_prefix=${#${(S%%%)top_prefix//$~zero/}} local width_top_suffix=${#${(S%%%)top_suffix//$~zero/}} local width_top_left=${#${(S%%%)top_left//$~zero/}} local width_top_middle=${#${(S%%%)top_middle//$~zero/}} local width_top_right=${#${(S%%%)top_right//$~zero/}} # calculate the maximum width of ${top_left}: # (-4 for brackets and as spacing between top_left, top_middle and top_right) local top_left_width_max=$(( COLUMNS - $width_top_prefix - $width_top_left - 2 - $width_top_middle - $width_top_right - 2 - $width_top_suffix )) # truncated directory if necessary top_left="${bracket_open}${directory/WIDTH/${top_left_width_max}}${bracket_close}${top_left}" width_top_left=${#${(S%%)top_left//$~zero/}} # calculate the width of the top prompt to fill the middle with separators local width=$(( COLUMNS - width_top_prefix - width_top_left - width_top_middle - width_top_right - width_top_suffix )) local top_left_separator="%F{cyan}${(pl:$((width / 2))::$dash:)}%f" local top_right_separator="%F{cyan}${(pl:$((width / 2 + width % 2))::$dash:)}%f" PROMPT="${top_prefix}${top_left}${top_left_separator}${top_middle}${top_right_separator}${top_right}${top_suffix} ${bottom_prefix}${bottom_left} " RPROMPT="${bottom_right}${bottom_suffix}" } precmd_functions+=(zshrc_prompt_precmd)