Make liquidprompt bash AND zsh compliant

The script now can be sourced from either bash and zsh
No more shebang and small improvments added too
This commit is contained in:
Luc Didry 2012-08-12 00:46:05 +02:00
parent b9223d3404
commit f51d6d21b5

View File

@ -1,8 +1,7 @@
#!/bin/bash
################################################################################ ################################################################################
# LIQUID PROMPT # LIQUID PROMPT
# An intelligent and non intrusive prompt for bash # An intelligent and non intrusive prompt for bash and zsh
################################################################################ ################################################################################
@ -33,20 +32,34 @@
# François Schmidts <fschmidts@olfeo.com> # Simpler SSH_IP acquiring method. # François Schmidts <fschmidts@olfeo.com> # Simpler SSH_IP acquiring method.
# Thomas Debesse <thomas.debesse@gmail.com> # Fix columns use. # Thomas Debesse <thomas.debesse@gmail.com> # Fix columns use.
# Florian Le Frioux <florian@lefrioux.fr> # Use ± mark when root in VCS dir. # Florian Le Frioux <florian@lefrioux.fr> # Use ± mark when root in VCS dir.
# Luc Didry <luc@fiat-tux.fr> # Zsh port
# See the README.md file for a summary of features. # See the README.md file for a summary of features.
WORKING_SHELL=$(ps -p $$ | tail -n1 | awk '{print $NF}')
# Check for recent enough version of bash. if [[ "$WORKING_SHELL" == "bash" ]]; then
[[ -z "$BASH_VERSION" || -z "$PS1" || -z "$TERM" ]] && return; # Check for recent enough version of bash.
[[ -z "$BASH_VERSION" || -z "$PS1" || -z "$TERM" ]] && return;
bash=${BASH_VERSION%.*}; bmajor=${bash%.*}; bminor=${bash#*.} bash=${BASH_VERSION%.*}; bmajor=${bash%.*}; bminor=${bash#*.}
if [[ $bmajor -lt 3 ]] || [[ $bmajor -eq 3 && $bminor -lt 2 ]]; then if [[ $bmajor -lt 3 ]] || [[ $bmajor -eq 3 && $bminor -lt 2 ]]; then
unset bash bmajor bminor
return
fi
unset bash bmajor bminor unset bash bmajor bminor
return
OPENESCAPE="\["
CLOSEESCAPE="\]"
USERSYMBOL="\u"
HOSTSYMBOL="\h"
elif [[ "$WORKING_SHELL" == "zsh" ]]; then
OPENESCAPE="%{"
CLOSEESCAPE="%}"
USERSYMBOL="%n"
HOSTSYMBOL="%m"
fi fi
unset bash bmajor bminor
################# #################
@ -96,61 +109,61 @@ esac
# Colors declarations # Colors declarations
if [[ "$OS" == "FreeBSD" ]] ; then if [[ "$OS" == "FreeBSD" ]] ; then
BLACK="\[$(tput AF 0)\]" BLACK="${OPENESCAPE}$(tput AF 0)${CLOSEESCAPE}"
BOLD_GRAY="\[$(tput md ; tput AF 0)\]" BOLD_GRAY="${OPENESCAPE}$(tput md ; tput AF 0)${CLOSEESCAPE}"
WHITE="\[$(tput AF 7)\]" WHITE="${OPENESCAPE}$(tput AF 7)${CLOSEESCAPE}"
BOLD_WHITE="\[$(tput md ; tput AF 7)\]" BOLD_WHITE="${OPENESCAPE}$(tput md ; tput AF 7)${CLOSEESCAPE}"
RED="\[$(tput AF 1)\]" RED="${OPENESCAPE}$(tput AF 1)${CLOSEESCAPE}"
BOLD_RED="\[$(tput md ; tput AF 1)\]" BOLD_RED="${OPENESCAPE}$(tput md ; tput AF 1)${CLOSEESCAPE}"
WARN_RED="\[$(tput AF 0 ; tput setab 1)\]" WARN_RED="${OPENESCAPE}$(tput AF 0 ; tput setab 1)${CLOSEESCAPE}"
CRIT_RED="\[$(tput md; tput AF 7 ; tput setab 1)\]" CRIT_RED="${OPENESCAPE}$(tput md; tput AF 7 ; tput setab 1)${CLOSEESCAPE}"
GREEN="\[$(tput AF 2)\]" GREEN="${OPENESCAPE}$(tput AF 2)${CLOSEESCAPE}"
BOLD_GREEN="\[$(tput md ; tput AF 2)\]" BOLD_GREEN="${OPENESCAPE}$(tput md ; tput AF 2)${CLOSEESCAPE}"
YELLOW="\[$(tput AF 3)\]" YELLOW="${OPENESCAPE}$(tput AF 3)${CLOSEESCAPE}"
BOLD_YELLOW="\[$(tput md ; tput AF 3)\]" BOLD_YELLOW="${OPENESCAPE}$(tput md ; tput AF 3)${CLOSEESCAPE}"
BLUE="\[$(tput AF 4)\]" BLUE="${OPENESCAPE}$(tput AF 4)${CLOSEESCAPE}"
BOLD_BLUE="\[$(tput md ; tput AF 4)\]" BOLD_BLUE="${OPENESCAPE}$(tput md ; tput AF 4)${CLOSEESCAPE}"
PURPLE="\[$(tput AF 5)\]" PURPLE="${OPENESCAPE}$(tput AF 5)${CLOSEESCAPE}"
PINK="\[$(tput md ; tput AF 5)\]" PINK="${OPENESCAPE}$(tput md ; tput AF 5)${CLOSEESCAPE}"
CYAN="\[$(tput AF 6)\]" CYAN="${OPENESCAPE}$(tput AF 6)${CLOSEESCAPE}"
BOLD_CYAN="\[$(tput md ; tput AF 6)\]" BOLD_CYAN="${OPENESCAPE}$(tput md ; tput AF 6)${CLOSEESCAPE}"
NO_COL="\[$(tput me)\]" NO_COL="${OPENESCAPE}$(tput me)${CLOSEESCAPE}"
else else
# default to Linux # default to Linux
BLACK="\[$(tput setaf 0)\]" BLACK="${OPENESCAPE}$(tput setaf 0)${CLOSEESCAPE}"
BOLD_GRAY="\[$(tput bold ; tput setaf 0)\]" BOLD_GRAY="${OPENESCAPE}$(tput bold ; tput setaf 0)${CLOSEESCAPE}"
WHITE="\[$(tput setaf 7)\]" WHITE="${OPENESCAPE}$(tput setaf 7)${CLOSEESCAPE}"
BOLD_WHITE="\[$(tput bold ; tput setaf 7)\]" BOLD_WHITE="${OPENESCAPE}$(tput bold ; tput setaf 7)${CLOSEESCAPE}"
RED="\[$(tput setaf 1)\]" RED="${OPENESCAPE}$(tput setaf 1)${CLOSEESCAPE}"
BOLD_RED="\[$(tput bold ; tput setaf 1)\]" BOLD_RED="${OPENESCAPE}$(tput bold ; tput setaf 1)${CLOSEESCAPE}"
WARN_RED="\[$(tput setaf 0 ; tput setab 1)\]" WARN_RED="${OPENESCAPE}$(tput setaf 0 ; tput setab 1)${CLOSEESCAPE}"
CRIT_RED="\[$(tput bold; tput setaf 7 ; tput setab 1)\]" CRIT_RED="${OPENESCAPE}$(tput bold; tput setaf 7 ; tput setab 1)${CLOSEESCAPE}"
GREEN="\[$(tput setaf 2)\]" GREEN="${OPENESCAPE}$(tput setaf 2)${CLOSEESCAPE}"
BOLD_GREEN="\[$(tput bold ; tput setaf 2)\]" BOLD_GREEN="${OPENESCAPE}$(tput bold ; tput setaf 2)${CLOSEESCAPE}"
YELLOW="\[$(tput setaf 3)\]" YELLOW="${OPENESCAPE}$(tput setaf 3)${CLOSEESCAPE}"
BOLD_YELLOW="\[$(tput bold ; tput setaf 3)\]" BOLD_YELLOW="${OPENESCAPE}$(tput bold ; tput setaf 3)${CLOSEESCAPE}"
BLUE="\[$(tput setaf 4)\]" BLUE="${OPENESCAPE}$(tput setaf 4)${CLOSEESCAPE}"
BOLD_BLUE="\[$(tput bold ; tput setaf 4)\]" BOLD_BLUE="${OPENESCAPE}$(tput bold ; tput setaf 4)${CLOSEESCAPE}"
PURPLE="\[$(tput setaf 5)\]" PURPLE="${OPENESCAPE}$(tput setaf 5)${CLOSEESCAPE}"
PINK="\[$(tput bold ; tput setaf 5)\]" PINK="${OPENESCAPE}$(tput bold ; tput setaf 5)${CLOSEESCAPE}"
CYAN="\[$(tput setaf 6)\]" CYAN="${OPENESCAPE}$(tput setaf 6)${CLOSEESCAPE}"
BOLD_CYAN="\[$(tput bold ; tput setaf 6)\]" BOLD_CYAN="${OPENESCAPE}$(tput bold ; tput setaf 6)${CLOSEESCAPE}"
NO_COL="\[$(tput sgr0)\]" NO_COL="${OPENESCAPE}$(tput sgr0)${CLOSEESCAPE}"
fi fi
@ -167,7 +180,7 @@ fi
# get cpu number # get cpu number
__cpunum_Linux() __cpunum_Linux()
{ {
grep -c ^[Pp]rocessor /proc/cpuinfo grep -c '^[Pp]rocessor' /proc/cpuinfo
} }
__cpunum_FreeBSD() __cpunum_FreeBSD()
@ -225,12 +238,12 @@ __user()
if [[ "$EUID" -ne "0" ]] ; then if [[ "$EUID" -ne "0" ]] ; then
# if user is not login user # if user is not login user
if [[ ${USER} != "$(logname 2>/dev/null)" ]]; then if [[ ${USER} != "$(logname 2>/dev/null)" ]]; then
user="${FG}\u${NO_COL}" user="${FG}${USERSYMBOL}${NO_COL}"
else else
user="\u" user="${USERSYMBOL}"
fi fi
else else
user="${BOLD_YELLOW}\u${NO_COL}" user="${BOLD_YELLOW}${USERSYMBOL}${NO_COL}"
fi fi
echo -ne $user echo -ne $user
@ -249,11 +262,11 @@ __connection()
# Are we in an SSH connexion? # Are we in an SSH connexion?
SSH_FLAG=0 SSH_FLAG=0
SSH_IP=${SSH_CLIENT%% *} SSH_IP=${SSH_CLIENT%% *}
if [[ $SSH_IP ]] ; then if [[ ! -z $SSH_IP ]] ; then
SSH_FLAG=1 SSH_FLAG=1
fi fi
SSH2_IP=$(echo $SSH2_CLIENT | awk '{ print $1 }') SSH2_IP=$(echo $SSH2_CLIENT | awk '{ print $1 }')
if [[ $SSH2_IP ]] ; then if [[ ! -z $SSH2_IP ]] ; then
SSH_FLAG=1 SSH_FLAG=1
fi fi
@ -282,14 +295,14 @@ __host_color()
if [[ $LP_HOSTNAME_ALWAYS == 0 ]] ; then if [[ $LP_HOSTNAME_ALWAYS == 0 ]] ; then
ret="${ret}" # no hostname if local ret="${ret}" # no hostname if local
else else
ret="${ret}@\h" ret="${ret}@${HOSTSYMBOL}"
fi fi
elif [[ "$conn" == "ssh" ]] ; then elif [[ "$conn" == "ssh" ]] ; then
ret="${ret}@${BOLD_CYAN}\h" ret="${ret}@${BOLD_CYAN}${HOSTSYMBOL}"
elif [[ "$conn" == "tel" ]] ; then elif [[ "$conn" == "tel" ]] ; then
ret="${ret}@${WARN_RED}\h" ret="${ret}@${WARN_RED}${HOSTSYMBOL}"
else else
ret="${ret}@\h" ret="${ret}@${HOSTSYMBOL}"
fi fi
echo -ne "${ret}${NO_COL}" echo -ne "${ret}${NO_COL}"
@ -303,7 +316,7 @@ __proxy()
fi fi
} }
# BASH function that shortens # BASH/ZSH function that shortens
# a very long path for display by removing # a very long path for display by removing
# the left most parts and replacing them # the left most parts and replacing them
# with a leading ... # with a leading ...
@ -319,8 +332,11 @@ __shorten_path()
{ {
# the character that will replace the part of the path that is masked # the character that will replace the part of the path that is masked
local mask=" … " local mask=" … "
# index of the directory to keep from the root (starts at 0) # index of the directory to keep from the root (starts at 0 whith bash, 1 with zsh)
local keep=$((LP_PATH_KEEP-1)) local keep=$((LP_PATH_KEEP-1))
if [[ "$WORKING_SHELL" == "zsh" ]]; then
keep=$LP_PATH_KEEP
fi
local len_percent=$2 local len_percent=$2
@ -337,55 +353,108 @@ __shorten_path()
# the path and stores their # the path and stores their
# positions # positions
# #
local pos=() if [[ "$WORKING_SHELL" == "bash" ]]; then
for ((i=0;i<len;i++)) local pos=()
do for ((i=0;i<len;i++))
if [[ "${p:i:1}" == "/" ]] do
then if [[ "${p:i:1}" == "/" ]]
pos=(${pos[@]} $i) then
slashes=$((${slashes}+1)) pos=(${pos[@]} $i)
slashes=$((${slashes}+1))
fi
done
pos=(${pos[@]} $len)
# we have the '/'s, let's find the
# left-most that doesn't break the
# length limit
#
local i=$keep
if [[ $keep > $slashes ]] ; then
i=$slashes
fi fi
done while [[ "$((len-pos[i]))" -gt "$((max_len-mask_len))" ]]
pos=(${pos[@]} $len) do
i=$((i+1))
done
# we have the '/'s, let's find the # let us check if it's OK to
# left-most that doesn't break the # print the whole thing
# length limit #
# if [[ "${pos[i]}" -eq "0" ]]
local i=$keep then
if [[ $keep > $slashes ]] ; then # the path is shorter than
i=$slashes # the maximum allowed length,
fi # so no need for ...
while [[ "$((len-pos[i]))" -gt "$((max_len-mask_len))" ]] #
do echo "$p"
i=$((i+1))
done
# let us check if it's OK to elif [[ "${pos[i]}" = "$len" ]]
# print the whole thing then
# # constraints are broken because
if [[ "${pos[i]}" -eq "0" ]] # the maximum allowed size is smaller
then # than the last part of the path, plus
# the path is shorter than # ' … '
# the maximum allowed length, #
# so no need for ... echo "${p:0:((${pos[${keep}]}+1))}${mask}${p:((len-max_len+mask_len))}"
# else
echo "$p" # constraints are satisfied, at least
# some parts of the path, plus ' … ', are
# shorter than the maximum allowed size
#
echo "${p:0:((${pos[${keep}]}+1))}${mask}${p:pos[i]}"
fi
elif [[ "$WORKING_SHELL" == "zsh" ]]; then
pos=()
for ((i=0;i<len;i++))
do
if [[ "$(echo $p[$i,$i])" == "/" ]]
then
pos+=($i)
slashes=$(( $slashes + 1 ))
fi
done
pos+=($len)
elif [[ "${pos[i]}" = "$len" ]] # we have the '/'s, let's find the
then # left-most that doesn't break the
# constraints are broken because # length limit
# the maximum allowed size is smaller
# than the last part of the path, plus
# ' … '
# #
echo "${p:0:((${pos[${keep}]}+1))}${mask}${p:((len-max_len+mask_len))}" local i=$keep
else if [[ $keep > $slashes ]] ; then
# constraints are satisfied, at least i=$slashes
# some parts of the path, plus ' … ', are fi
# shorter than the maximum allowed size i=$(( $i + 1 ))
while [[ $(( $len - $pos[$i] )) -gt $(( $max_len - $mask_len )) ]]
do
i=$(( $i + 1 ))
done
# let us check if it's OK to
# print the whole thing
# #
echo "${p:0:((${pos[${keep}]}+1))}${mask}${p:pos[i]}" if [[ $pos[$i] -eq "0" ]]
then
# the path is shorter than
# the maximum allowed length,
# so no need for ...
#
echo "$p"
elif [[ $pos[$i] == "$len" ]]
then
# constraints are broken because
# the maximum allowed size is smaller
# than the last part of the path, plus
# ' … '
#
echo "$( echo $p[1,$(( $pos[$keep] ))] )${mask}$( echo $p[$(( 0 - $max_len + $mask_len )),-1] )"
else
# constraints are satisfied, at least
# some parts of the path, plus ' … ', are
# shorter than the maximum allowed size
#
echo "$( echo $p[1,$(( $pos[$keep] ))])${mask}$( echo $p[$pos[$i],-1] )"
fi
fi fi
else else
echo "$p" echo "$p"
@ -695,7 +764,10 @@ __smart_mark()
COL=${BOLD_RED} COL=${BOLD_RED}
fi fi
local mark="\\\$" local mark="\$"
if [[ "$WORKING_SHELL" == "zsh" ]]; then
mark="%(!.#.$)"
fi
if [[ ! -z $(__git_branch) ]] ; then if [[ ! -z $(__git_branch) ]] ; then
mark="±" mark="±"
elif [[ ! -z $(__hg_branch) ]] ; then elif [[ ! -z $(__hg_branch) ]] ; then
@ -799,9 +871,19 @@ prompt_on()
# if liquidprompt has not been already set # if liquidprompt has not been already set
if [[ -z "$LP_LIQUIDPROMPT" ]] ; then if [[ -z "$LP_LIQUIDPROMPT" ]] ; then
LP_OLD_PS1="$PS1" LP_OLD_PS1="$PS1"
LP_OLD_PROMPT_COMMAND="$PROMPT_COMMAND" if [[ "$WORKING_SHELL" == "bash" ]]; then
LP_OLD_PROMPT_COMMAND="$PROMPT_COMMAND"
elif [[ "$WORKING_SHELL" == "zsh" ]]; then
LP_OLD_PROMPT_COMMAND="$precmd"
fi
fi
if [[ "$WORKING_SHELL" == "bash" ]]; then
PROMPT_COMMAND=__set_bash_prompt
elif [[ "$WORKING_SHELL" == "zsh" ]]; then
function precmd {
__set_bash_prompt
}
fi fi
PROMPT_COMMAND=__set_bash_prompt
# Keep in mind that LP has been sourced # Keep in mind that LP has been sourced
# (to avoid recursive prompt command). # (to avoid recursive prompt command).
@ -812,14 +894,22 @@ prompt_on()
prompt_off() prompt_off()
{ {
PS1=$LP_OLD_PS1 PS1=$LP_OLD_PS1
PROMPT_COMMAND=$LP_OLD_PROMPT_COMMAND if [[ "$WORKING_SHELL" == "bash" ]]; then
PROMPT_COMMAND=$LP_OLD_PROMPT_COMMAND
elif [[ "$WORKING_SHELL" == "zsh" ]]; then
precmd=$LP_OLD_PROMPT_COMMAND
fi
} }
# Use an empty prompt: just the \$ mark # Use an empty prompt: just the \$ mark
prompt_OFF() prompt_OFF()
{ {
PS1="\$ " PS1="\$ "
PROMPT_COMMAND=$LP_OLD_PROMPT_COMMAND if [[ "$WORKING_SHELL" == "bash" ]]; then
PROMPT_COMMAND=$LP_OLD_PROMPT_COMMAND
elif [[ "$WORKING_SHELL" == "zsh" ]]; then
precmd=$LP_OLD_PROMPT_COMMAND
fi
} }
# By default, sourcing liquidprompt.bash will activate the liquid prompt # By default, sourcing liquidprompt.bash will activate the liquid prompt