I want to have the same prompt in both Bash and Zsh. And I want it to:
In Bash, I do have:
BLK="\[$(tput setaf 0; tput bold)\]"
RED="\[$(tput setaf 1; tput bold)\]"
grn="\[$(tput setaf 2)\]"
GRN="\[$(tput setaf 2; tput bold)\]"
yel="\[$(tput setaf 3)\]"
reset_color="\[$(tput sgr0)\]"
PS1='\n\
`if [[ $? -gt 0 ]]; then printf "\[\033[01;31m\]$?"; tput bel; else printf "\[\033[01;32m\]0"; fi`\
\[\033]0;$PWD\007\] \
\[\033[0;32m\]\u@\h\
\[\033[01;30m\]:\
\[\033[;;33m\]\w\
\[\033[36m\]`__git_ps1`\
\[\033[0m\]\n$ '
In Zsh, that's my config:
BLK=$(tput setaf 0; tput bold)
RED=$(tput setaf 1; tput bold)
grn=$(tput setaf 2)
GRN=$(tput setaf 2; tput bold)
yel=$(tput setaf 3)
reset_color=$(tput sgr0)
PROMPT="
%(?.$GRN.$RED)%?$reset_color $grn%n@%m$BLK:$reset_color$yel%~ $reset_color
%(!.#.$) "
And this is how it looks like in the terminal:
Both prompts do ring the bell when there is an error with the last command. But, in Bash, it prints 0 instead of the right return code of the command that failed.
How to fix that?
PS- Any better way to improve the above code is welcomed!
The command to test $?
itself resets $?
to the result of the test. You need to save the value you want to display first.
PS1='\n\
$(st=$?; if [[ $st -gt 0 ]]; then printf "\[\033[01;31m\]$st"; tput bel; else printf "\[\033[01;32m\]0"; fi)\
\[\033]0;$PWD\007\] \
\[\033[0;32m\]\u@\h\
\[\033[01;30m\]:\
\[\033[;;33m\]\w\
\[\033[36m\]`__git_ps1`\
\[\033[0m\]\n$ '
I would recommend building up the value of PS1
using PROMPT_COMMAND
, instead of embedding executable code. This gives you more flexibility
for commenting and separating any computations you need from the actual
formatting. make_prompt
doesn't need quite so many lines, but it's
just a demonstration.
set_title () {
printf '\033]0;%s%s' "$1" "$(tput bel)"
}
make_prompt () {
local st=$?
local c bell
bell=$(tput bel)
# Green for success, red and a bell for failure
if [[ $st -gt 0 ]]; then
c=31
else
c=32 bell=
fi
win_title=$(set_title "$PWD")
git_status=$(__git_ps1)
PS1="\n"
PS1+="\[\e[01;${c}m$bell\]" # exit status color and bell
PS1+=$st
PS1+="\[$win_title\]" # Set the title of the window
PS1+="\[\e[0;32m\]" # Color for user and host
PS1+="\u@\h"
PS1+="\[\e[01;30m\]" # Color for : separator
PS1+=":"
PS1+="\[\e[;;33m\]" # Color for directory
PS1+="\w"
PS1+="\[\e[36m\]" # Color for git branch
PS1+=$git_status
PS1+="\[\e[0m\]" # Reset to terminal defaults
PS1+="\n$ "
}
PROMPT_COMMAND=make_prompt
zsh
already has terminal-agnostic escape sequences for adding color.
PROMPT="%B%(?.%F{green}.%F{red}$(tput bel))%?%f%b %F{green}%n@%m%F{black}%B:%b%F{yellow}%~ %f%(!.#.$) "