2a483f9430
The previous value was BOLD_WHITE but it does not work for black on white terminal. Using BOLD instead should work on any configuration.
1003 lines
28 KiB
Bash
Executable File
1003 lines
28 KiB
Bash
Executable File
|
|
################################################################################
|
|
# LIQUID PROMPT
|
|
# An intelligent and non intrusive prompt for bash and zsh
|
|
################################################################################
|
|
|
|
|
|
# Licensed under the AGPL version 3
|
|
#
|
|
# This program is free software: you can redistribute it and/or modify
|
|
# it under the terms of the GNU Affero General Public License as
|
|
# published by the Free Software Foundation, either version 3 of the
|
|
# License, or (at your option) any later version.
|
|
#
|
|
# This program is distributed in the hope that it will be useful,
|
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
# GNU Affero General Public License for more details.
|
|
#
|
|
# You should have received a copy of the GNU Affero General Public License
|
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
###########
|
|
# AUTHORS #
|
|
###########
|
|
|
|
# nojhan <nojhan@gmail.com> # Main author.
|
|
# Aurelien Requiem <aurelien@requiem.fr> # Major clean refactoring, variable path length, error codes, several bugfixes.
|
|
# Joris Dedieu <joris@pontiac3.nfrance.com> # Portability framework, FreeBSD support, bugfixes.
|
|
# Ludovic Rousseau <ludovic.rousseau@gmail.com> # Lot of bugfixes.
|
|
# Yann 'Ze' Richard <ze@nbox.org> # Do not fail on missing commands.
|
|
# François Schmidts <fschmidts@olfeo.com> # Simpler SSH_IP acquiring method.
|
|
# Thomas Debesse <thomas.debesse@gmail.com> # Fix columns use.
|
|
# 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.
|
|
|
|
# Check for recent enough version of bash.
|
|
if test -n "$BASH_VERSION" -a -n "$PS1" -a -n "$TERM" ; then
|
|
bash=${BASH_VERSION%.*}; bmajor=${bash%.*}; bminor=${bash#*.}
|
|
if [[ $bmajor -lt 3 ]] || [[ $bmajor -eq 3 && $bminor -lt 2 ]]; then
|
|
unset bash bmajor bminor
|
|
return
|
|
fi
|
|
unset bash bmajor bminor
|
|
|
|
_LP_WORKING_SHELL=bash
|
|
_LP_OPEN_ESC="\["
|
|
_LP_CLOSE_ESC="\]"
|
|
_LP_USER_SYMBOL="\u"
|
|
_LP_HOST_SYMBOL="\h"
|
|
elif test -n "$ZSH_VERSION" ; then
|
|
_LP_WORKING_SHELL=zsh
|
|
_LP_OPEN_ESC="%{"
|
|
_LP_CLOSE_ESC="%}"
|
|
_LP_USER_SYMBOL="%n"
|
|
_LP_HOST_SYMBOL="%m"
|
|
else
|
|
echo "liquidprompt: shell not supported" >&2
|
|
return
|
|
fi
|
|
|
|
|
|
###############
|
|
# OS specific #
|
|
###############
|
|
|
|
# LP_OS detection, default to Linux
|
|
LP_OS="Linux"
|
|
case $(uname) in
|
|
"Linux" ) LP_OS="Linux" ;;
|
|
"FreeBSD") LP_OS="FreeBSD" ;;
|
|
"Darwin") LP_OS="Darwin" ;;
|
|
"DragonFly") LP_OS="FreeBSD" ;;
|
|
"SunOS") LP_OS="SunOS" ;;
|
|
esac
|
|
|
|
# Colors declarations
|
|
if [[ "$LP_OS" == "FreeBSD" ]] ; then
|
|
|
|
BOLD="${_LP_OPEN_ESC}$(tput md)${_LP_CLOSE_ESC}"
|
|
|
|
BLACK="${_LP_OPEN_ESC}$(tput AF 0)${_LP_CLOSE_ESC}"
|
|
BOLD_GRAY="${_LP_OPEN_ESC}$(tput md ; tput AF 0)${_LP_CLOSE_ESC}"
|
|
WHITE="${_LP_OPEN_ESC}$(tput AF 7)${_LP_CLOSE_ESC}"
|
|
BOLD_WHITE="${_LP_OPEN_ESC}$(tput md ; tput AF 7)${_LP_CLOSE_ESC}"
|
|
|
|
RED="${_LP_OPEN_ESC}$(tput AF 1)${_LP_CLOSE_ESC}"
|
|
BOLD_RED="${_LP_OPEN_ESC}$(tput md ; tput AF 1)${_LP_CLOSE_ESC}"
|
|
WARN_RED="${_LP_OPEN_ESC}$(tput AF 0 ; tput setab 1)${_LP_CLOSE_ESC}"
|
|
CRIT_RED="${_LP_OPEN_ESC}$(tput md; tput AF 7 ; tput setab 1)${_LP_CLOSE_ESC}"
|
|
|
|
GREEN="${_LP_OPEN_ESC}$(tput AF 2)${_LP_CLOSE_ESC}"
|
|
BOLD_GREEN="${_LP_OPEN_ESC}$(tput md ; tput AF 2)${_LP_CLOSE_ESC}"
|
|
|
|
YELLOW="${_LP_OPEN_ESC}$(tput AF 3)${_LP_CLOSE_ESC}"
|
|
BOLD_YELLOW="${_LP_OPEN_ESC}$(tput md ; tput AF 3)${_LP_CLOSE_ESC}"
|
|
|
|
BLUE="${_LP_OPEN_ESC}$(tput AF 4)${_LP_CLOSE_ESC}"
|
|
BOLD_BLUE="${_LP_OPEN_ESC}$(tput md ; tput AF 4)${_LP_CLOSE_ESC}"
|
|
|
|
PURPLE="${_LP_OPEN_ESC}$(tput AF 5)${_LP_CLOSE_ESC}"
|
|
PINK="${_LP_OPEN_ESC}$(tput md ; tput AF 5)${_LP_CLOSE_ESC}"
|
|
|
|
CYAN="${_LP_OPEN_ESC}$(tput AF 6)${_LP_CLOSE_ESC}"
|
|
BOLD_CYAN="${_LP_OPEN_ESC}$(tput md ; tput AF 6)${_LP_CLOSE_ESC}"
|
|
|
|
NO_COL="${_LP_OPEN_ESC}$(tput me)${_LP_CLOSE_ESC}"
|
|
|
|
else
|
|
# default to Linux
|
|
BOLD="${_LP_OPEN_ESC}$(tput bold)${_LP_CLOSE_ESC}"
|
|
|
|
BLACK="${_LP_OPEN_ESC}$(tput setaf 0)${_LP_CLOSE_ESC}"
|
|
BOLD_GRAY="${_LP_OPEN_ESC}$(tput bold ; tput setaf 0)${_LP_CLOSE_ESC}"
|
|
WHITE="${_LP_OPEN_ESC}$(tput setaf 7)${_LP_CLOSE_ESC}"
|
|
BOLD_WHITE="${_LP_OPEN_ESC}$(tput bold ; tput setaf 7)${_LP_CLOSE_ESC}"
|
|
|
|
RED="${_LP_OPEN_ESC}$(tput setaf 1)${_LP_CLOSE_ESC}"
|
|
BOLD_RED="${_LP_OPEN_ESC}$(tput bold ; tput setaf 1)${_LP_CLOSE_ESC}"
|
|
WARN_RED="${_LP_OPEN_ESC}$(tput setaf 0 ; tput setab 1)${_LP_CLOSE_ESC}"
|
|
CRIT_RED="${_LP_OPEN_ESC}$(tput bold; tput setaf 7 ; tput setab 1)${_LP_CLOSE_ESC}"
|
|
|
|
GREEN="${_LP_OPEN_ESC}$(tput setaf 2)${_LP_CLOSE_ESC}"
|
|
BOLD_GREEN="${_LP_OPEN_ESC}$(tput bold ; tput setaf 2)${_LP_CLOSE_ESC}"
|
|
|
|
YELLOW="${_LP_OPEN_ESC}$(tput setaf 3)${_LP_CLOSE_ESC}"
|
|
BOLD_YELLOW="${_LP_OPEN_ESC}$(tput bold ; tput setaf 3)${_LP_CLOSE_ESC}"
|
|
|
|
BLUE="${_LP_OPEN_ESC}$(tput setaf 4)${_LP_CLOSE_ESC}"
|
|
BOLD_BLUE="${_LP_OPEN_ESC}$(tput bold ; tput setaf 4)${_LP_CLOSE_ESC}"
|
|
|
|
PURPLE="${_LP_OPEN_ESC}$(tput setaf 5)${_LP_CLOSE_ESC}"
|
|
PINK="${_LP_OPEN_ESC}$(tput bold ; tput setaf 5)${_LP_CLOSE_ESC}"
|
|
|
|
CYAN="${_LP_OPEN_ESC}$(tput setaf 6)${_LP_CLOSE_ESC}"
|
|
BOLD_CYAN="${_LP_OPEN_ESC}$(tput bold ; tput setaf 6)${_LP_CLOSE_ESC}"
|
|
|
|
NO_COL="${_LP_OPEN_ESC}$(tput sgr0)${_LP_CLOSE_ESC}"
|
|
|
|
fi
|
|
|
|
# get cpu number
|
|
_lp_cpunum_Linux()
|
|
{
|
|
grep -c '^[Pp]rocessor' /proc/cpuinfo
|
|
}
|
|
|
|
_lp_cpunum_FreeBSD()
|
|
{
|
|
sysctl -n hw.ncpu
|
|
}
|
|
|
|
_lp_cpunum_Darwin()
|
|
{
|
|
_lp_cpunum_FreeBSD
|
|
}
|
|
|
|
_lp_cpunum_SunOS()
|
|
{
|
|
kstat -m cpu_info | grep -c "module: cpu_info"
|
|
}
|
|
|
|
_lp_CPUNUM=$(_lp_cpunum_$LP_OS)
|
|
|
|
|
|
# get current load
|
|
|
|
_lp_load_Linux()
|
|
{
|
|
local load
|
|
load=$(awk '{print $1}' /proc/loadavg)
|
|
echo -n "$load"
|
|
}
|
|
|
|
_lp_load_FreeBSD()
|
|
{
|
|
local load
|
|
load=$(LANG=C sysctl -n vm.loadavg | awk '{print $2}')
|
|
echo -n "$load"
|
|
}
|
|
|
|
_lp_load_Darwin()
|
|
{
|
|
_lp_load_FreeBSD
|
|
}
|
|
|
|
_lp_load_SunOS()
|
|
{
|
|
local load
|
|
load=$(LANG=C uptime | awk '{print substr($10,0,length($10))}')
|
|
echo -n "$load"
|
|
}
|
|
|
|
|
|
#################
|
|
# CONFIGURATION #
|
|
#################
|
|
|
|
# Note: configuration is called _after_ colors declarations, because of themes.
|
|
|
|
# Default values
|
|
LP_BATTERY_THRESHOLD=${LP_BATTERY_THRESHOLD:-75}
|
|
LP_LOAD_THRESHOLD=${LP_LOAD_THRESHOLD:-60}
|
|
LP_PATH_LENGTH=${LP_PATH_LENGTH:-35}
|
|
LP_PATH_KEEP=${LP_PATH_KEEP:-2}
|
|
LP_HOSTNAME_ALWAYS=${LP_HOSTNAME_ALWAYS:-0}
|
|
LP_PS1=${LP_PS1:-""}
|
|
LP_BATTERY_MARK=${LP_BATTERY_MARK:-"⌁"}
|
|
LP_ADAPTER_MARK=${LP_ADAPTER_MARK:-"⏚"}
|
|
LP_LOAD_MARK=${LP_LOAD_MARK:-"⌂"}
|
|
LP_PROXY_MARK=${LP_PROXY_MARK:-"↥"}
|
|
LP_GIT_MARK=${LP_GIT_MARK:-"±"}
|
|
LP_MERCURIAL_MARK=${LP_MERCURIAL_MARK:-"☿"}
|
|
LP_SUBVERSION_MARK=${LP_SUBVERSION_MARK:-"‡"}
|
|
|
|
LP_COLOR_PATH=${LP_COLOR_PATH:-$BOLD}
|
|
LP_COLOR_PATH_ROOT=${LP_COLOR_PATH_ROOT:-$BOLD_YELLOW}
|
|
LP_COLOR_PROXY=${LP_COLOR_PROXY:-$BOLD_BLUE}
|
|
LP_COLOR_JOB_D=${LP_COLOR_JOB_D:-$YELLOW}
|
|
LP_COLOR_JOB_R=${LP_COLOR_JOB_R:-$BOLD_YELLOW}
|
|
LP_COLOR_JOB_Z=${LP_COLOR_JOB_Z:-$BOLD_YELLOW}
|
|
LP_COLOR_ERR=${LP_COLOR_ERR:-$PURPLE}
|
|
LP_COLOR_MARK=${LP_COLOR_MARK:-$BOLD_WHITE}
|
|
LP_COLOR_MARK_ROOT=${LP_COLOR_MARK_ROOT:-$BOLD_RED}
|
|
LP_COLOR_USER_LOGGED=${LP_COLOR_USER_LOGGED:-}
|
|
LP_COLOR_USER_ALT=${LP_COLOR_USER_ALT:-$BOLD}
|
|
LP_COLOR_USER_ROOT=${_ROOT:-$BOLD_YELLOW}
|
|
LP_COLOR_HOST=${LP_COLOR_HOST:-}
|
|
LP_COLOR_SSH=${LP_COLOR_SSH:-$BOLD_CYAN}
|
|
LP_COLOR_TELNET=${LP_COLOR_TELNET:-$WARN_RED}
|
|
LP_COLOR_WRITE=${LP_COLOR_WRITE:-$GREEN}
|
|
LP_COLOR_NOWRITE=${LP_COLOR_NOWRITE:-$RED}
|
|
|
|
|
|
# Default config file may be the XDG standard ~/.config/liquidpromptrc,
|
|
# but heirloom dotfile has priority.
|
|
_lp_source_config()
|
|
{
|
|
local configfile
|
|
if [[ -f "/etc/liquidpromptrc" ]]
|
|
then
|
|
source "/etc/liquidpromptrc"
|
|
fi
|
|
if [[ -f "$HOME/.liquidpromptrc" ]]
|
|
then
|
|
configfile="$HOME/.liquidpromptrc"
|
|
elif [[ -z "$XDG_HOME_DIR" ]]
|
|
then
|
|
configfile="$HOME/.config/liquidpromptrc"
|
|
else
|
|
configfile="$XDG_HOME_DIR/liquidpromptrc"
|
|
fi
|
|
if [[ -f "$configfile" ]]
|
|
then
|
|
source "$configfile"
|
|
fi
|
|
}
|
|
# do source config files
|
|
_lp_source_config
|
|
|
|
|
|
###############
|
|
# Who are we? #
|
|
###############
|
|
|
|
# Yellow for root, bold if the user is not the login one, else no color.
|
|
_lp_user()
|
|
{
|
|
local user
|
|
# if user is not root
|
|
if [[ "$EUID" -ne "0" ]] ; then
|
|
# if user is not login user
|
|
if [[ ${USER} != "$(logname 2>/dev/null)" ]]; then
|
|
user="${LP_COLOR_USER_ALT}${_LP_USER_SYMBOL}${NO_COL}"
|
|
else
|
|
user="${LP_COLOR_USER_LOGGED}${_LP_USER_SYMBOL}${NO_COL}"
|
|
fi
|
|
else
|
|
user="${LP_COLOR_USER_ROOT}${_LP_USER_SYMBOL}${NO_COL}"
|
|
fi
|
|
|
|
echo -ne $user
|
|
}
|
|
|
|
|
|
#################
|
|
# Where are we? #
|
|
#################
|
|
|
|
_lp_connection()
|
|
{
|
|
local THIS_TTY
|
|
THIS_TTY=$(awk -v pid=$$ -v wkshell=${_LP_WORKING_SHELL} '$0 ~ pid && $0 ~ wkshell { print $7 }' < <(ps aux) )
|
|
local SESS_SRC
|
|
SESS_SRC=$(who | awk -v thistty="$THIS_TTY" '$0 ~ thistty { print $6 }')
|
|
|
|
# Are we in an SSH connexion?
|
|
local SSH_FLAG
|
|
SSH_FLAG=0
|
|
local SSH_IP
|
|
SSH_IP=${SSH_CLIENT%% *}
|
|
if [[ ! -z $SSH_IP ]] ; then
|
|
SSH_FLAG=1
|
|
fi
|
|
local SSH2_IP
|
|
SSH2_IP=$(echo $SSH2_CLIENT | awk '{ print $1 }')
|
|
if [[ ! -z $SSH2_IP ]] ; then
|
|
SSH_FLAG=1
|
|
fi
|
|
|
|
local CONN
|
|
if [[ $SSH_FLAG -eq 1 ]] ; then
|
|
CONN="ssh"
|
|
elif [[ -z $SESS_SRC ]] ; then
|
|
CONN="lcl"
|
|
elif [[ $SESS_SRC = "(:0.0)" || $SESS_SRC = "" ]] ; then
|
|
CONN="lcl"
|
|
else
|
|
CONN="tel"
|
|
fi
|
|
|
|
echo -ne $CONN
|
|
}
|
|
|
|
# Put the hostname if not locally connected
|
|
# color it in cyan within SSH, and a warning red if within telnet
|
|
# else diplay the host without color
|
|
_lp_host_color()
|
|
{
|
|
local conn
|
|
conn=$(_lp_connection)
|
|
|
|
local ret
|
|
ret="${NO_COL}"
|
|
if [[ "$conn" == "lcl" ]] ; then
|
|
if [[ $LP_HOSTNAME_ALWAYS == 0 ]] ; then
|
|
ret="${ret}" # no hostname if local
|
|
else
|
|
ret="${ret}@${LP_COLOR_HOST}${_LP_HOST_SYMBOL}"
|
|
fi
|
|
elif [[ "$conn" == "ssh" ]] ; then
|
|
ret="${ret}@${LP_COLOR_SSH}${_LP_HOST_SYMBOL}"
|
|
elif [[ "$conn" == "tel" ]] ; then
|
|
ret="${ret}@${LP_COLOR_TELNET}${_LP_HOST_SYMBOL}"
|
|
else
|
|
ret="${ret}@${_LP_HOST_SYMBOL}" # defaults to no color
|
|
fi
|
|
|
|
echo -ne "${ret}${NO_COL}"
|
|
}
|
|
|
|
# put an arrow if an http proxy is set
|
|
_lp_proxy()
|
|
{
|
|
if [[ ! -z "$http_proxy" ]] ; then
|
|
echo -ne $LP_PROXY_MARK
|
|
fi
|
|
}
|
|
|
|
# BASH/ZSH function that shortens
|
|
# a very long path for display by removing
|
|
# the left most parts and replacing them
|
|
# with a leading ...
|
|
#
|
|
# the first argument is the path
|
|
#
|
|
# the second argument is the maximum allowed
|
|
# length including the '/'s and ...
|
|
# http://hbfs.wordpress.com/2009/09/01/short-pwd-in-bash-prompts/
|
|
#
|
|
# + keep some left part of the path if asked
|
|
_lp_shorten_path()
|
|
{
|
|
# the character that will replace the part of the path that is masked
|
|
local mask=" … "
|
|
# index of the directory to keep from the root (starts at 0 whith bash, 1 with zsh)
|
|
local keep=$((LP_PATH_KEEP-1))
|
|
if [[ "$_LP_WORKING_SHELL" == "zsh" ]]; then
|
|
keep=$LP_PATH_KEEP
|
|
fi
|
|
|
|
local len_percent=$2
|
|
|
|
local p=$(echo "$1" | sed -e "s|$HOME|~|")
|
|
local len="${#p}"
|
|
|
|
local max_len=$((${COLUMNS:-80}*$len_percent/100))
|
|
local mask_len="${#mask}"
|
|
local slashes=0
|
|
|
|
if [[ "$_LP_WORKING_SHELL" == "bash" ]]; then
|
|
if [[ "$len" -gt "$max_len" ]]
|
|
then
|
|
# finds all the '/' in
|
|
# the path and stores their
|
|
# positions
|
|
#
|
|
local pos=()
|
|
for ((i=0;i<len;i++))
|
|
do
|
|
if [[ "${p:i:1}" == "/" ]]
|
|
then
|
|
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
|
|
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
|
|
#
|
|
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 "${p:0:((${pos[${keep}]}+1))}${mask}${p:((len-max_len+mask_len))}"
|
|
else
|
|
# 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
|
|
else
|
|
echo "$p"
|
|
fi
|
|
elif [[ "$_LP_WORKING_SHELL" == "zsh" ]]; then
|
|
if [[ "$len" -gt "$max_len" ]]; then
|
|
echo "%-${keep}~%${max_len}<${mask}<%~%<<"
|
|
else
|
|
echo "%~"
|
|
fi
|
|
fi
|
|
}
|
|
|
|
# Display a ":"
|
|
# colored in green if user have write permission on the current directory
|
|
# colored in red if it have not.
|
|
_lp_permissions_color()
|
|
{
|
|
if [[ -w "${PWD}" ]]; then
|
|
echo "${LP_COLOR_WRITE}:${NO_COL}"
|
|
else
|
|
echo "${LP_COLOR_NOWRITE}:${NO_COL}"
|
|
fi
|
|
}
|
|
|
|
|
|
################
|
|
# Related jobs #
|
|
################
|
|
|
|
# Either attached running jobs (started with $ myjob &)
|
|
# or attached stopped jobs (suspended with Ctrl-Z)
|
|
# or detached screens sessions running on the host
|
|
_lp_jobcount_color()
|
|
{
|
|
local running=$(( $(jobs -r | wc -l) ))
|
|
local stopped=$(( $(jobs -s | wc -l) ))
|
|
local screens=$(screen -ls 2> /dev/null | grep -c Detach )
|
|
local m_detached="d"
|
|
local m_stop="z"
|
|
local m_run="&"
|
|
local rep
|
|
|
|
# d/&/z
|
|
if [[ $screens != "0" && $running != "0" && $stopped != "0" ]] ; then
|
|
rep="${NO_COL}${LP_COLOR_JOB_D}${screens}${m_detached}${NO_COL}/${LP_COLOR_JOB_R}${running}${m_run}${NO_COL}/${LP_COLOR_JOB_Z}${stopped}${m_stop}${NO_COL}"
|
|
|
|
# _/&/_
|
|
elif [[ $screens == "0" && $running != "0" && $stopped == "0" ]] ; then
|
|
rep="${NO_COL}${LP_COLOR_JOB_R}${running}${m_run}${NO_COL}"
|
|
|
|
# _/_/z
|
|
elif [[ $screens == "0" && $running == "0" && $stopped != "0" ]] ; then
|
|
rep="${NO_COL}${LP_COLOR_JOB_Z}${stopped}${m_stop}${NO_COL}"
|
|
|
|
# d/_/_
|
|
elif [[ $screens != "0" && $running == "0" && $stopped == "0" ]] ; then
|
|
rep="${NO_COL}${LP_COLOR_JOB_D}${screens}${m_detached}${NO_COL}"
|
|
|
|
# d/&/_
|
|
elif [[ $screens != "0" && $running != "0" && $stopped == "0" ]] ; then
|
|
rep="${NO_COL}${LP_COLOR_JOB_D}${screens}${m_detached}${NO_COL}/${LP_COLOR_JOB_R}${running}${m_run}${NO_COL}"
|
|
|
|
# d/_/z
|
|
elif [[ $screens != "0" && $running == "0" && $stopped != "0" ]] ; then
|
|
rep="${NO_COL}${LP_COLOR_JOB_D}${screens}${m_detached}${NO_COL}/${LP_COLOR_JOB_Z}${stopped}${m_stop}${NO_COL}"
|
|
|
|
# _/&/z
|
|
elif [[ $screens == "0" && $running != "0" && $stopped != "0" ]] ; then
|
|
rep="${NO_COL}${LP_COLOR_JOB_R}${running}${m_run}${NO_COL}/${LP_COLOR_JOB_Z}${stopped}${m_stop}${NO_COL}"
|
|
fi
|
|
echo -ne "$rep"
|
|
}
|
|
|
|
# Display the return value of the last command, if different from zero
|
|
_lp_return_value()
|
|
{
|
|
if [[ "$1" -ne "0" ]]
|
|
then
|
|
echo -ne "$1"
|
|
fi
|
|
}
|
|
|
|
|
|
######################
|
|
# VCS branch display #
|
|
######################
|
|
|
|
# GIT #
|
|
|
|
# Get the branch name of the current directory
|
|
_lp_git_branch()
|
|
{
|
|
if git rev-parse --git-dir >/dev/null 2>&1 && [[ ! -z "$(git branch)" ]] ; then
|
|
echo -n "$(git branch 2>/dev/null | sed -n '/^\*/s/^\* //p;')"
|
|
fi
|
|
}
|
|
|
|
# Set a color depending on the branch state:
|
|
# - green if the repository is up to date
|
|
# - yellow if there is some commits not pushed
|
|
# - red if there is changes to commit
|
|
#
|
|
# Add the number of pending commits and the impacted lines.
|
|
_lp_git_branch_color()
|
|
{
|
|
command -v git >/dev/null 2>&1 || return 1;
|
|
local branch
|
|
branch=$(_lp_git_branch)
|
|
if [[ ! -z "$branch" ]] ; then
|
|
|
|
local GD
|
|
git diff --quiet >/dev/null 2>&1
|
|
GD=$?
|
|
|
|
local GDC
|
|
git diff --cached --quiet >/dev/null 2>&1
|
|
GDC=$?
|
|
|
|
local has_commit
|
|
has_commit=$(git rev-list --no-merges --count origin/${branch}..${branch} 2>/dev/null)
|
|
if [[ -z "$has_commit" ]] ; then
|
|
has_commit=0
|
|
fi
|
|
if [[ "$GD" -eq 1 || "$GDC" -eq "1" ]] ; then
|
|
local has_line
|
|
has_lines=$(git diff --numstat | awk 'NF==3 {plus+=$1; minus+=$2} END {printf("+%d/-%d\n", plus, minus)}')
|
|
if [[ "$has_commit" -gt "0" ]] ; then
|
|
# Changes to commit and commits to push
|
|
ret="${RED}${branch}${NO_COL}(${PURPLE}$has_lines${NO_COL},${YELLOW}$has_commit${NO_COL})"
|
|
else
|
|
ret="${RED}${branch}${NO_COL}(${PURPLE}$has_lines${NO_COL})" # changes to commit
|
|
fi
|
|
else
|
|
if [[ "$has_commit" -gt "0" ]] ; then
|
|
# some commit(s) to push
|
|
ret="${YELLOW}${branch}${NO_COL}(${YELLOW}$has_commit${NO_COL})"
|
|
else
|
|
ret="${GREEN}${branch}${NO_COL}" # nothing to commit or push
|
|
fi
|
|
fi
|
|
echo -ne "$ret"
|
|
fi
|
|
}
|
|
|
|
|
|
# MERCURIAL #
|
|
|
|
# Get the branch name of the current directory
|
|
_lp_hg_branch()
|
|
{
|
|
local branch
|
|
branch="$(hg branch 2>/dev/null)"
|
|
if [[ $? -eq 0 ]] && [[ ! -z "$(hg branch)" ]] ; then
|
|
echo -n "$(hg branch)"
|
|
fi
|
|
}
|
|
|
|
# Set a color depending on the branch state:
|
|
# - green if the repository is up to date
|
|
# - red if there is changes to commit
|
|
# - TODO: yellow if there is some commits not pushed
|
|
_lp_hg_branch_color()
|
|
{
|
|
command -v hg >/dev/null 2>&1 || return 1;
|
|
local branch
|
|
local ret
|
|
branch=$(_lp_hg_branch)
|
|
if [[ ! -z "$branch" ]] ; then
|
|
if [[ $(( $(hg status --quiet -n | wc -l) )) = 0 ]] ; then
|
|
ret="${GREEN}${branch}${NO_COL}"
|
|
else
|
|
ret="${RED}${branch}${NO_COL}" # changes to commit
|
|
fi
|
|
echo -ne "$ret"
|
|
fi
|
|
}
|
|
|
|
# SUBVERSION #
|
|
|
|
# Get the branch name of the current directory
|
|
# For the first level of the repository, gives the repository name
|
|
_lp_svn_branch()
|
|
{
|
|
local infos
|
|
local ret
|
|
infos=$(svn info --xml 2>/dev/null)
|
|
ret=$?
|
|
if [[ $ret -eq 0 ]] ; then
|
|
local root
|
|
root=$(echo "$infos" | awk -v FS=">|</" '/^<root>/ { print $2 }')
|
|
local subrep
|
|
subrep=$(echo "$infos" | awk -v FS=">|</" '/^<url>/ { print $2 }')
|
|
if [[ "$subrep" == *"url>"* ]] ; then
|
|
echo -n $root
|
|
else
|
|
local branch
|
|
branch=$(basename $subrep)
|
|
echo -n $branch
|
|
fi
|
|
fi
|
|
}
|
|
|
|
# Set a color depending on the branch state:
|
|
# - green if the repository is up to date
|
|
# - red if there is changes to commit
|
|
# Note that, due to subversion way of managing changes,
|
|
# informations are only displayed for the CURRENT directory.
|
|
_lp_svn_branch_color()
|
|
{
|
|
command -v svn >/dev/null 2>&1 || return 1;
|
|
local branch
|
|
branch=$(_lp_svn_branch)
|
|
if [[ ! -z "$branch" ]] ; then
|
|
local commits
|
|
commits=$(( $(svn status | grep -v "?" -c) ))
|
|
if [[ $commits = 0 ]] ; then
|
|
local ret
|
|
ret="${GREEN}${branch}${NO_COL}"
|
|
else
|
|
ret="${RED}${branch}${NO_COL}(${YELLOW}$commits${NO_COL})" # changes to commit
|
|
fi
|
|
echo -ne "$ret"
|
|
fi
|
|
}
|
|
|
|
|
|
##################
|
|
# Battery status #
|
|
##################
|
|
|
|
# Get the battery status in percent
|
|
# returns 0 (and battery level) if battery is discharging and under threshold
|
|
# returns 1 (and battery level) if battery is discharging and above threshold
|
|
# returns 2 (and battery level) if battery is charging but under threshold
|
|
# returns 3 (and battery level) if battery is charging and above threshold
|
|
# returns 4 if no battery support
|
|
_lp_battery()
|
|
{
|
|
command -v acpi >/dev/null 2>&1 || return 4; # or no battery support
|
|
local acpi
|
|
acpi="$(acpi --battery 2>/dev/null)"
|
|
local bat
|
|
bat=$( echo $acpi | sed "s/^Battery .*, \([0-9]*\)%.*$/\1/")
|
|
|
|
if [[ -z "${bat}" ]] ; then
|
|
# not battery level found
|
|
return 4
|
|
|
|
# discharging
|
|
elif [[ "$acpi" == *"Discharging"* ]] ; then
|
|
if [[ ${bat} -le $LP_BATTERY_THRESHOLD ]] ; then
|
|
# under threshold
|
|
echo -n "${bat}"
|
|
return 0
|
|
else
|
|
# above threshold
|
|
echo -n "${bat}"
|
|
return 1
|
|
fi
|
|
|
|
# charging
|
|
else
|
|
if [[ ${bat} -le $LP_BATTERY_THRESHOLD ]] ; then
|
|
# under threshold
|
|
echo -n "${bat}"
|
|
return 2
|
|
else
|
|
# above threshold
|
|
echo -n "${bat}"
|
|
return 3
|
|
fi
|
|
fi
|
|
}
|
|
|
|
# Compute a gradient of background/foreground colors depending on the battery status
|
|
# Display:
|
|
# a green ⏚ if the battery is charging and above threshold
|
|
# a yellow ⏚ if the battery is charging and under threshold
|
|
# a yellow ⌁ if the battery is discharging but above threshold
|
|
# a red ⌁ if the battery is discharging and above threshold
|
|
_lp_battery_color()
|
|
{
|
|
local mark=$LP_BATTERY_MARK
|
|
local chargingmark=$LP_ADAPTER_MARK
|
|
local bat
|
|
local ret
|
|
bat=$(_lp_battery)
|
|
ret=$?
|
|
|
|
if [[ $ret == 4 || $bat == 100 ]] ; then
|
|
# no battery support or battery full: nothing displayed
|
|
return
|
|
elif [[ $ret == 3 && $bat != 100 ]] ; then
|
|
# charging and above threshold and not 100%
|
|
# green ⏚
|
|
echo -ne "${GREEN}$chargingmark${NO_COL}"
|
|
return
|
|
elif [[ $ret == 2 ]] ; then
|
|
# charging but under threshold
|
|
# yellow ⏚
|
|
echo -ne "${YELLOW}$chargingmark${NO_COL}"
|
|
return
|
|
elif [[ $ret == 1 ]] ; then
|
|
# discharging but above threshold
|
|
# yellow ⌁
|
|
echo -ne "${YELLOW}$mark${NO_COL}"
|
|
return
|
|
|
|
# discharging and under threshold
|
|
elif [[ "$bat" != "" ]] ; then
|
|
local ret
|
|
ret="${mark}${NO_COL}"
|
|
if [[ ${bat} -le 100 ]] && [[ ${bat} -gt 75 ]] ; then
|
|
ret="${ret}${GREEN}"
|
|
elif [[ ${bat} -le 75 ]] && [[ ${bat} -gt 50 ]] ; then
|
|
ret="${ret}${BOLD_GREEN}"
|
|
elif [[ ${bat} -le 50 ]] && [[ ${bat} -gt 20 ]] ; then
|
|
ret="${ret}${BOLD_YELLOW}"
|
|
elif [[ ${bat} -le 20 ]] && [[ ${bat} -gt 10 ]] ; then
|
|
ret="${ret}${BOLD_RED}"
|
|
elif [[ ${bat} -le 10 ]] && [[ ${bat} -gt 5 ]] ; then
|
|
ret="${ret}${WARN_RED}"
|
|
else
|
|
ret="${ret}${CRIT_RED}"
|
|
fi
|
|
|
|
if [[ "$_LP_WORKING_SHELL" == "bash" ]]; then
|
|
echo -ne "${ret}${bat}%${NO_COL}"
|
|
elif [[ "$_LP_WORKING_SHELL" == "zsh" ]]; then
|
|
echo -ne "${ret}${bat}%%${NO_COL}"
|
|
fi
|
|
fi
|
|
}
|
|
|
|
|
|
###############
|
|
# System load #
|
|
###############
|
|
|
|
# Compute a gradient of background/forground colors depending on the battery status
|
|
_lp_load_color()
|
|
{
|
|
# Colour progression is important ...
|
|
# bold gray -> bold green -> bold yellow -> bold red ->
|
|
# black on red -> bold white on red
|
|
#
|
|
# Then we have to choose the values at which the colours switch, with
|
|
# anything past yellow being pretty important.
|
|
|
|
local loadval
|
|
local load
|
|
loadval=$(_lp_load_$LP_OS)
|
|
load=$(echo $loadval | sed 's/\.//g;s/^0*//g' )
|
|
if [[ -z "$load" ]] ; then
|
|
load=0
|
|
fi
|
|
let "load=$load/$_lp_CPUNUM"
|
|
|
|
if [[ $load -ge $LP_LOAD_THRESHOLD ]]
|
|
then
|
|
local ret
|
|
ret="${LP_LOAD_MARK}${NO_COL}"
|
|
if [[ $load -lt 70 ]] ; then
|
|
ret="${ret}"
|
|
elif [[ $load -ge 1 ]] && [[ $load -lt 80 ]] ; then
|
|
ret="${ret}${BOLD_GREEN}"
|
|
elif [[ $load -ge 80 ]] && [[ $load -lt 95 ]] ; then
|
|
ret="${ret}${BOLD_YELLOW}"
|
|
elif [[ $load -ge 95 ]] && [[ $load -lt 150 ]] ; then
|
|
ret="${ret}${BOLD_RED}"
|
|
elif [[ $load -ge 150 ]] && [[ $load -lt 200 ]] ; then
|
|
ret="${ret}${WARN_RED}"
|
|
else
|
|
ret="${ret}${CRIT_RED}"
|
|
fi
|
|
if [[ "$_LP_WORKING_SHELL" == "bash" ]]; then
|
|
ret="${ret}$load%${NO_COL}"
|
|
elif [[ "$_LP_WORKING_SHELL" == "zsh" ]]; then
|
|
ret="${ret}$load%%${NO_COL}"
|
|
fi
|
|
echo -ne "${ret}"
|
|
fi
|
|
}
|
|
|
|
|
|
##########
|
|
# DESIGN #
|
|
##########
|
|
|
|
# Set the prompt mark to ± if git, to ☿ if mercurial, to ‡ if subversion
|
|
# to # if root and else $
|
|
_lp_smart_mark()
|
|
{
|
|
local COL
|
|
COL=${LP_COLOR_MARK}
|
|
if [[ "$EUID" -eq "0" ]] ; then
|
|
COL=${LP_COLOR_MARK_ROOT}
|
|
fi
|
|
|
|
local mark
|
|
mark="\$"
|
|
if [[ "$_LP_WORKING_SHELL" == "zsh" ]]; then
|
|
mark="%(!.#.$)"
|
|
fi
|
|
if [[ ! -z $(_lp_git_branch) ]] ; then
|
|
mark=$LP_GIT_MARK
|
|
elif [[ ! -z $(_lp_hg_branch) ]] ; then
|
|
mark=$LP_MERCURIAL_MARK
|
|
elif [[ ! -z $(_lp_svn_branch) ]] ; then
|
|
mark=$LP_SUBVERSION_MARK
|
|
fi
|
|
echo -ne "${COL}${mark}${NO_COL}"
|
|
}
|
|
|
|
# insert a space on the right
|
|
_lp_sr()
|
|
{
|
|
if [[ ! -z "$1" ]] ; then
|
|
echo -n "$1 "
|
|
fi
|
|
}
|
|
|
|
# insert a space on the left
|
|
_lp_sl()
|
|
{
|
|
if [[ ! -z "$1" ]] ; then
|
|
echo -n " $1"
|
|
fi
|
|
}
|
|
|
|
# insert two space, before and after
|
|
_lp_sb()
|
|
{
|
|
if [[ ! -z "$1" ]] ; then
|
|
echo -n " $1 "
|
|
fi
|
|
}
|
|
|
|
|
|
########################
|
|
# Construct the prompt #
|
|
########################
|
|
|
|
_lp_set_bash_prompt()
|
|
{
|
|
# as this get the last returned code, it should be called first
|
|
LP_RET=$(_lp_sl "$(_lp_return_value $?)")
|
|
|
|
# execute the old prompt
|
|
$LP_OLD_PROMPT_COMMAND
|
|
|
|
# left of main prompt: space at right
|
|
LP_JOBS=$(_lp_sr "$(_lp_jobcount_color)")
|
|
LP_LOAD=$(_lp_sr "$(_lp_load_color)")
|
|
LP_BATT=$(_lp_sr "$(_lp_battery_color)")
|
|
|
|
# in main prompt: no space
|
|
LP_USER=$(_lp_user)
|
|
LP_HOST=$(_lp_host_color)
|
|
LP_PERM=$(_lp_permissions_color)
|
|
LP_PWD=$(_lp_shorten_path "$PWD" $LP_PATH_LENGTH)
|
|
LP_PROXY=$(_lp_proxy)
|
|
|
|
# right of main prompt: space at left
|
|
LP_GIT=$(_lp_sl "$(_lp_git_branch_color)")
|
|
LP_HG=$(_lp_sl "$(_lp_hg_branch_color)")
|
|
LP_SVN=$(_lp_sl "$(_lp_svn_branch_color)")
|
|
|
|
# end of the prompt line: double spaces
|
|
LP_MARK=$(_lp_sb "$(_lp_smart_mark)")
|
|
|
|
if [[ -z $LP_PS1 ]] ; then
|
|
# add jobs, load and battery
|
|
PS1="${LP_BATT}${LP_LOAD}${LP_JOBS}"
|
|
# add user, host and permissions colon
|
|
PS1="${PS1}[${LP_USER}${LP_HOST}${LP_PERM}"
|
|
|
|
# if not root
|
|
if [[ "$EUID" -ne "0" ]]
|
|
then
|
|
# path in foreground color
|
|
PS1="${PS1}${LP_COLOR_PATH}${LP_PWD}${NO_COL}]${LP_COLOR_PROXY}${LP_PROXY}${NO_COL}"
|
|
# add VCS infos
|
|
PS1="${PS1}${LP_GIT}${LP_HG}${LP_SVN}"
|
|
else
|
|
# path in yellow
|
|
PS1="${PS1}${LP_PATH_ROOT}${LP_PWD}${NO_COL}]${LP_COLOR_PROXY}${LP_PROXY}${NO_COL}"
|
|
# do not add VCS infos
|
|
fi
|
|
# add return code and prompt mark
|
|
PS1="${PS1}${LP_COLOR_ERR}${LP_RET}${NO_COL}${LP_MARK}"
|
|
|
|
# Glue the bash prompt always go to the first column.
|
|
# Avoid glitches after interrupting a command with Ctrl-C
|
|
# Does not seem to be necessary anymore?
|
|
#PS1="\[\033[G\]${PS1}${NO_COL}"
|
|
else
|
|
PS1=$LP_PS1
|
|
fi
|
|
}
|
|
|
|
# Activate the liquid prompt
|
|
prompt_on()
|
|
{
|
|
# if liquidprompt has not been already set
|
|
if [[ -z "$LP_LIQUIDPROMPT" ]] ; then
|
|
LP_OLD_PS1="$PS1"
|
|
if [[ "$_LP_WORKING_SHELL" == "bash" ]]; then
|
|
LP_OLD_PROMPT_COMMAND="$PROMPT_COMMAND"
|
|
elif [[ "$_LP_WORKING_SHELL" == "zsh" ]]; then
|
|
LP_OLD_PROMPT_COMMAND="$precmd"
|
|
fi
|
|
fi
|
|
if [[ "$_LP_WORKING_SHELL" == "bash" ]]; then
|
|
PROMPT_COMMAND=_lp_set_bash_prompt
|
|
elif [[ "$_LP_WORKING_SHELL" == "zsh" ]]; then
|
|
function precmd {
|
|
_lp_set_bash_prompt
|
|
}
|
|
fi
|
|
|
|
# Keep in mind that LP has been sourced
|
|
# (to avoid recursive prompt command).
|
|
LP_LIQUIDPROMPT=1
|
|
}
|
|
|
|
# Come back to the old prompt
|
|
prompt_off()
|
|
{
|
|
PS1=$LP_OLD_PS1
|
|
if [[ "$_LP_WORKING_SHELL" == "bash" ]]; then
|
|
PROMPT_COMMAND=$LP_OLD_PROMPT_COMMAND
|
|
elif [[ "$_LP_WORKING_SHELL" == "zsh" ]]; then
|
|
precmd=$LP_OLD_PROMPT_COMMAND
|
|
fi
|
|
}
|
|
|
|
# Use an empty prompt: just the \$ mark
|
|
prompt_OFF()
|
|
{
|
|
PS1="\$ "
|
|
if [[ "$_LP_WORKING_SHELL" == "bash" ]]; then
|
|
PROMPT_COMMAND=$LP_OLD_PROMPT_COMMAND
|
|
elif [[ "$_LP_WORKING_SHELL" == "zsh" ]]; then
|
|
precmd=$LP_OLD_PROMPT_COMMAND
|
|
fi
|
|
}
|
|
|
|
# By default, sourcing liquidprompt.bash will activate the liquid prompt
|
|
prompt_on
|
|
|
|
# vim: set ts=4 sw=4 tw=120 ft=sh:
|