zsh: prompt: complete internal redesign + improvements
The prompt now no longer requires "setopt promptsubst" and even has
a bit more functionality:
- show exitcode if not equal zero
- underlined hostname if remote-connected via ssh
- extra prompt symbol for root and different color username
- improved battery status (color + charge detection)
Furthermore time and username@hostname have been swapped.
This commit is contained in:
parent
cb93e83215
commit
2b7107a84a
2 changed files with 116 additions and 59 deletions
165
zsh/prompt.zsh
165
zsh/prompt.zsh
|
|
@ -1,70 +1,131 @@
|
|||
function precmd {
|
||||
# ===== setopts and misc
|
||||
# only show RPROMPT on the current prompt
|
||||
setopt transient_rprompt # only show the rprompt on the current prompt
|
||||
|
||||
local TERMWIDTH
|
||||
(( TERMWIDTH = ${COLUMNS} - 1 ))
|
||||
# set RPROMPT_INDENT to zero in order to remove the useless space on the bottom
|
||||
# right of the prompt.
|
||||
ZLE_RPROMPT_INDENT=0
|
||||
|
||||
###
|
||||
# Truncate the path if it's too long.
|
||||
# ===== set the prompt
|
||||
zshrc_prompt_precmd() {
|
||||
|
||||
PR_FILLBAR=""
|
||||
PR_PWDLEN=""
|
||||
# regex to remove all zerospace elements. Used to calculate the width of
|
||||
# the top prompt.
|
||||
local zero='%([BSUBfksu]|([FB]|){*})'
|
||||
|
||||
local promptsize=${#${(%):---(%n@%m)---()--}}
|
||||
local pwdsize=${#${(%):-%~}}
|
||||
# linedrawing characters
|
||||
local top_left_corner="╭"
|
||||
local top_right_corner="╮"
|
||||
local bottom_left_corner="╰"
|
||||
local bottom_right_corner="╯"
|
||||
local dash="─"
|
||||
|
||||
if [[ "$promptsize + $pwdsize" -gt $TERMWIDTH ]]; then
|
||||
((PR_PWDLEN=$TERMWIDTH - $promptsize))
|
||||
else
|
||||
PR_FILLBAR="\${(l.(($TERMWIDTH - ($promptsize + $pwdsize)))..${PR_HBAR}.)}"
|
||||
fi
|
||||
}
|
||||
|
||||
function show_battery {
|
||||
if [[ $HAS_PMSET -eq 1 ]]; then
|
||||
~/.zsh/scripts/battery_osx.sh
|
||||
# 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
|
||||
}
|
||||
|
||||
function setprompt {
|
||||
PR_HBAR="─"
|
||||
# commonly used design elements
|
||||
local bracket_open="%F{blue}${dash}(%f"
|
||||
local bracket_close="%F{blue}%)${dash}%f"
|
||||
local separator="%F{cyan}${dash}%f"
|
||||
|
||||
if [[ "$TERM" != "xterm" ]]; then
|
||||
PR_ULCORNER="╭"
|
||||
PR_LLCORNER="╰"
|
||||
PR_LRCORNER="╯"
|
||||
PR_URCORNER="╮"
|
||||
# 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 type acpi &> /dev/null ; then
|
||||
battery_pct="$(acpi -b | cut -d, -f2 | sed -e 's/[^0-9]//g')"
|
||||
fi
|
||||
|
||||
# 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
|
||||
PR_ULCORNER="+"
|
||||
PR_LLCORNER="+"
|
||||
PR_LRCORNER="+"
|
||||
PR_URCORNER="+"
|
||||
battery_pct="%F{green}${battery_pct}%%%f"
|
||||
fi
|
||||
|
||||
PR_RESET="%{$terminfo[sgr0]%}"
|
||||
# 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"
|
||||
|
||||
###
|
||||
# Finally, the prompt.
|
||||
# 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"
|
||||
|
||||
PROMPT='%F{cyan}$PR_ULCORNER%F{blue}$PR_HBAR(\
|
||||
%F{magenta}%$PR_PWDLEN<...<%~%<<\
|
||||
%F{blue})$PR_HBAR%F{cyan}$PR_HBAR${(e)PR_FILLBAR}%F{blue}$PR_HBAR(\
|
||||
%F{green}%n@%m%F{blue}\
|
||||
%F{blue})$PR_HBAR%F{cyan}$PR_URCORNER\
|
||||
# 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=
|
||||
|
||||
%F{cyan}$PR_LLCORNER%F{blue}$PR_HBAR(\
|
||||
%F{yellow}%D{%H:%M}\
|
||||
%F{blue})$PR_HBAR%F{cyan}$PR_HBAR\
|
||||
%f '
|
||||
# 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
|
||||
|
||||
RPROMPT='%F{cyan}$PR_HBAR%F{blue}$PR_HBAR(\
|
||||
%F{yellow}$(show_battery)\
|
||||
%F{blue})$PR_HBAR%F{cyan}$PR_LRCORNER\
|
||||
%f'
|
||||
# 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/}}
|
||||
|
||||
PS2='%F{cyan}$PR_HBAR%F{blue}$PR_HBAR(\
|
||||
%F{green}%_
|
||||
%F{blue})$PR_HBAR%F{cyan}$PR_HBAR\
|
||||
%f '
|
||||
# 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}"
|
||||
}
|
||||
|
||||
setprompt
|
||||
precmd_functions+=(zshrc_prompt_precmd)
|
||||
|
|
|
|||
|
|
@ -34,9 +34,5 @@ unsetopt menu_complete # do not autoselect the first completion entry
|
|||
# setopt correct # spelling correction for commands
|
||||
# setopt correctall # spelling correction for arguments
|
||||
|
||||
# ===== Prompt
|
||||
setopt prompt_subst # Enable parameter expansion, command substitution, and arithmetic expansion in the prompt
|
||||
setopt transient_rprompt # only show the rprompt on the current prompt
|
||||
|
||||
# ===== Scripts and Functions
|
||||
setopt multios # perform implicit tees or cats when multiple redirections are attempted
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue