# ===== 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() { # 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" # 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')" # colorize battery percentage or display status if [[ $(acpi -a | cut -d':' -f2) == " on-line" ]]; then battery_pct="charging" elif [[ $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 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" # use %{ .. %} for bottom_right_corner to remove useless space after RPROMPT local bottom_suffix="%F{cyan}%{${bottom_right_corner}%}%f" # combine them to create the prompt local top_left="" local top_right="${bracket_open}${time}${bracket_close}" 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_right=${#${(S%%%)top_right//$~zero/}} # calculate the maximum width of ${top_left}: # (-4 for brackets, -1 as spacing between top_left and top_right) local top_left_width_max=$(( COLUMNS - $width_top_prefix - $width_top_left - 4 - 1 - $width_top_right - $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_right - width_top_suffix )) local top_separator="%F{cyan}${(pl:${width}::$dash:)}%f" PROMPT="${top_prefix}${top_left}${top_separator}${top_right}${top_suffix} ${bottom_prefix}${bottom_left} " RPROMPT="${bottom_right}${bottom_suffix}" } precmd_functions+=(zshrc_prompt_precmd)