Skip to content

Commit

Permalink
Rework color code generation
Browse files Browse the repository at this point in the history
The actual escape sequence generation is the same, but add a new
function lp_terminal_format(), which generates a static sequence for
formatting the terminal. It is designed for alternate themes, with
Powerline specifically in mind.

The function will return nothing if tput is not available.
  • Loading branch information
Rycieos committed Nov 25, 2020
1 parent 46df995 commit 09cfced
Showing 1 changed file with 129 additions and 63 deletions.
192 changes: 129 additions & 63 deletions liquidprompt
Original file line number Diff line number Diff line change
Expand Up @@ -121,104 +121,67 @@ _LP_SED_EXTENDED=r
# 3. Load the configuration
__lp_source_config() {

# TermInfo feature detection
typeset -a af_colors ab_colors
local af_color ab_color

# TODO handle this case better. With no colors, no need for any escaping
if ! command -v tput >/dev/null; then
echo "liquidprompt: 'tput' not available; will not be able to format terminal" >&2
fi

local ti_sgr0="$( { tput sgr0 || tput me ; } 2>/dev/null )"
local ti_bold="$( { tput bold || tput md ; } 2>/dev/null )"
_LP_TI_BELL="$( { tput bel || tput bl ; } 2>/dev/null )"
if tput setaf 0 >/dev/null 2>&1; then
foreground_color() { af_color="${af_colors[$1+1]:=$(tput setaf "$1")}"; }
elif tput AF 0 >/dev/null 2>&1; then
# FreeBSD
foreground_color() { af_color="${af_colors[$1+1]:=$(tput AF "$1")}"; }
elif tput AF 0 0 0 >/dev/null 2>&1; then
# OpenBSD
foreground_color() { af_color="${af_colors[$1+1]:=$(tput AF "$1" 0 0)}"; }
else
echo "liquidprompt: terminal $TERM does not support foreground colors" >&2
foreground_color() { : ; }
fi
if tput setab 0 >/dev/null 2>&1; then
background_color() { ab_color="${ab_colors[$1+1]:=$(tput setab "$1")}"; }
elif tput AB 0 >/dev/null 2>&1; then
# FreeBSD
background_color() { ab_color="${ab_colors[$1+1]:=$(tput AB "$1")}"; }
elif tput AB 0 0 0 >/dev/null 2>&1; then
# OpenBSD
background_color() { ab_color="${ab_colors[$1+1]:=$(tput AB "$1" 0 0)}"; }
else
echo "liquidprompt: terminal $TERM does not support background colors" >&2
background_color() { : ; }
fi
local af_color= ab_color=

# Colors: variables are local so they will have a value only
# during config loading and will not conflict with other values
# with the same names defined by the user outside the config.
local BOLD="${_LP_OPEN_ESC}${ti_bold}${_LP_CLOSE_ESC}"
local BOLD="${_LP_OPEN_ESC}${_LP_TI_BOLD-}${_LP_CLOSE_ESC}"

# Foreground colors
foreground_color 0
__lp_foreground_color 0
local BLACK="${_LP_OPEN_ESC}${af_color}${_LP_CLOSE_ESC}"
local BOLD_GRAY="${_LP_OPEN_ESC}${ti_bold}${af_color}${_LP_CLOSE_ESC}"
local BOLD_GRAY="${_LP_OPEN_ESC}${_LP_TI_BOLD-}${af_color}${_LP_CLOSE_ESC}"

foreground_color 1
__lp_foreground_color 1
local RED="${_LP_OPEN_ESC}${af_color}${_LP_CLOSE_ESC}"
local BOLD_RED="${_LP_OPEN_ESC}${ti_bold}${af_color}${_LP_CLOSE_ESC}"
foreground_color 0
background_color 1
local BOLD_RED="${_LP_OPEN_ESC}${_LP_TI_BOLD-}${af_color}${_LP_CLOSE_ESC}"
__lp_foreground_color 0
__lp_background_color 1
local WARN_RED="${_LP_OPEN_ESC}${af_color}${ab_color}${_LP_CLOSE_ESC}"
foreground_color 7
local CRIT_RED="${_LP_OPEN_ESC}${ti_bold}${af_color}${ab_color}${_LP_CLOSE_ESC}"
foreground_color 3
local DANGER_RED="${_LP_OPEN_ESC}${ti_bold}${af_color}${ab_color}${_LP_CLOSE_ESC}"
__lp_foreground_color 7
local CRIT_RED="${_LP_OPEN_ESC}${_LP_TI_BOLD-}${af_color}${ab_color}${_LP_CLOSE_ESC}"
__lp_foreground_color 3
local DANGER_RED="${_LP_OPEN_ESC}${_LP_TI_BOLD-}${af_color}${ab_color}${_LP_CLOSE_ESC}"

foreground_color 2
__lp_foreground_color 2
local GREEN="${_LP_OPEN_ESC}${af_color}${_LP_CLOSE_ESC}"
local BOLD_GREEN="${_LP_OPEN_ESC}${ti_bold}${af_color}${_LP_CLOSE_ESC}"
local BOLD_GREEN="${_LP_OPEN_ESC}${_LP_TI_BOLD-}${af_color}${_LP_CLOSE_ESC}"

foreground_color 3
__lp_foreground_color 3
local YELLOW="${_LP_OPEN_ESC}${af_color}${_LP_CLOSE_ESC}"
local BOLD_YELLOW="${_LP_OPEN_ESC}${ti_bold}${af_color}${_LP_CLOSE_ESC}"
local BOLD_YELLOW="${_LP_OPEN_ESC}${_LP_TI_BOLD-}${af_color}${_LP_CLOSE_ESC}"

foreground_color 4
__lp_foreground_color 4
local BLUE="${_LP_OPEN_ESC}${af_color}${_LP_CLOSE_ESC}"
local BOLD_BLUE="${_LP_OPEN_ESC}${ti_bold}${af_color}${_LP_CLOSE_ESC}"
local BOLD_BLUE="${_LP_OPEN_ESC}${_LP_TI_BOLD-}${af_color}${_LP_CLOSE_ESC}"

foreground_color 5
__lp_foreground_color 5
local PURPLE="${_LP_OPEN_ESC}${af_color}${_LP_CLOSE_ESC}"
local MAGENTA="${PURPLE}"
local PINK="${_LP_OPEN_ESC}${ti_bold}${af_color}${_LP_CLOSE_ESC}"
local PINK="${_LP_OPEN_ESC}${_LP_TI_BOLD-}${af_color}${_LP_CLOSE_ESC}"
local BOLD_PURPLE="${PINK}"
local BOLD_MAGENTA="${PINK}"

foreground_color 6
__lp_foreground_color 6
local CYAN="${_LP_OPEN_ESC}${af_color}${_LP_CLOSE_ESC}"
local BOLD_CYAN="${_LP_OPEN_ESC}${ti_bold}${af_color}${_LP_CLOSE_ESC}"
local BOLD_CYAN="${_LP_OPEN_ESC}${_LP_TI_BOLD-}${af_color}${_LP_CLOSE_ESC}"

foreground_color 7
__lp_foreground_color 7
local WHITE="${_LP_OPEN_ESC}${af_color}${_LP_CLOSE_ESC}"
local BOLD_WHITE="${_LP_OPEN_ESC}${ti_bold}${af_color}${_LP_CLOSE_ESC}"
local BOLD_WHITE="${_LP_OPEN_ESC}${_LP_TI_BOLD-}${af_color}${_LP_CLOSE_ESC}"

# NO_COL is special: it will be used at runtime, not just during config loading
NO_COL="${_LP_OPEN_ESC}${ti_sgr0}${_LP_CLOSE_ESC}"
NO_COL="${_LP_OPEN_ESC}${_LP_TI_RESET-}${_LP_CLOSE_ESC}"

# compute the hash of the hostname
# and get the corresponding number in [1-6] (red,green,yellow,blue,purple or cyan)
# FIXME Add more formats (bold? 256 colors?)
# cksum is separated with tab on SunOS, space on others
local cksum="$(hostname | cksum)"
foreground_color "$(( 1 + ${cksum%%[$' \t']*} % 6 ))"
__lp_foreground_color "$(( 1 + ${cksum%%[$' \t']*} % 6 ))"
LP_COLOR_HOST_HASH="${_LP_OPEN_ESC}${af_color}${_LP_CLOSE_ESC}"

unset -f foreground_color background_color


# Default values (globals)
LP_BATTERY_THRESHOLD=${LP_BATTERY_THRESHOLD:-75}
Expand Down Expand Up @@ -261,6 +224,7 @@ __lp_source_config() {
LP_ENABLE_FQDN=${LP_ENABLE_FQDN:-0}
LP_DISABLED_VCS_PATHS=("${LP_DISABLED_VCS_PATHS[@]-}")
LP_ENABLE_SUDO=${LP_ENABLE_SUDO:-0}
LP_ENABLE_COLOR=${LP_ENABLE_COLOR:-1}

LP_MARK_DEFAULT="${LP_MARK_DEFAULT:-$_LP_MARK_SYMBOL}"
LP_MARK_BATTERY="${LP_MARK_BATTERY:-""}"
Expand Down Expand Up @@ -406,6 +370,52 @@ lp_activate() {
} >/dev/null
fi

# TermInfo feature detection
_lp_af_colors=() _lp_ab_colors=()

__lp_foreground_color() { return 2 ; }
__lp_background_color() { return 2 ; }

# TODO handle this case better. With no colors, no need for any escaping
if ! command -v tput >/dev/null; then
echo "liquidprompt: 'tput' not available; will not be able to format terminal" >&2
LP_ENABLE_COLOR=0
else
_LP_TI_RESET="$( { tput sgr0 || tput me ; } 2>/dev/null )"
_LP_TI_BOLD="$( { tput bold || tput md ; } 2>/dev/null )"
_LP_TI_UNDERLINE="$( { tput smul || tput us ; } 2>/dev/null )"
_LP_TI_COLORS="$( tput colors 2>/dev/null )"
_LP_TI_COLORS=${_LP_TI_COLORS:-8}

_LP_TI_BELL="$( { tput bel || tput bl ; } 2>/dev/null )"

if tput setaf 0 >/dev/null 2>&1; then
__lp_foreground_color() { af_color="${_lp_af_colors[$1+1]:=$(tput setaf "$1")}"; }
elif tput AF 0 >/dev/null 2>&1; then
# FreeBSD
__lp_foreground_color() { af_color="${_lp_af_colors[$1+1]:=$(tput AF "$1")}"; }
elif tput AF 0 0 0 >/dev/null 2>&1; then
# OpenBSD
__lp_foreground_color() { af_color="${_lp_af_colors[$1+1]:=$(tput AF "$1" 0 0)}"; }
else
echo "liquidprompt: terminal $TERM does not support foreground colors" >&2
fi
if tput setab 0 >/dev/null 2>&1; then
__lp_background_color() { ab_color="${_lp_ab_colors[$1+1]:=$(tput setab "$1")}"; }
elif tput AB 0 >/dev/null 2>&1; then
# FreeBSD
__lp_background_color() { ab_color="${_lp_ab_colors[$1+1]:=$(tput AB "$1")}"; }
elif tput AB 0 0 0 >/dev/null 2>&1; then
# OpenBSD
__lp_background_color() { ab_color="${_lp_ab_colors[$1+1]:=$(tput AB "$1" 0 0)}"; }
else
echo "liquidprompt: terminal $TERM does not support background colors" >&2
fi
fi

# If tput doesn't exist or lookup failed, still try to send bell
_LP_TI_BELL=${_LP_TI_BELL:-$'\a'}

__lp_source_config

# Disable feature if the tool is not installed
Expand Down Expand Up @@ -615,6 +625,62 @@ _lp_sb() {
[[ -n "$1" ]] && echo -nE " $1 "
}

# Generates a terminal escape sequence to format the terminal.
lp_terminal_format() { # fg, bg, bold, underline, fallback_fg, fallback_bg
lp_terminal_format=
(( LP_ENABLE_COLOR )) || return 2

local af_color ab_color fg=$1 bg=${2:-"-1"} previous_af_color=${_lp_last_af_color-}

lp_terminal_format=${_LP_OPEN_ESC}${_LP_TI_RESET}

if (( $fg >= _LP_TI_COLORS )) && [[ -n ${5-} ]]; then
_lp_last_af_color=$5
elif (( $fg == -2 )); then
: # do nothing, _lp_last_af_color already correct
elif (( $fg == -3 )); then
_lp_last_af_color=$_lp_last_ab_color
elif (( $fg >= 0 )); then
_lp_last_af_color=$fg
else # -1
_lp_last_af_color=-1
fi

if (( ${_lp_last_af_color:-"-1"} >= 0 )); then
__lp_foreground_color "$_lp_last_af_color" && lp_terminal_format+=$af_color
fi

if (( $bg >= _LP_TI_COLORS )) && [[ -n ${6-} ]]; then
_lp_last_ab_color=$6
elif (( $bg == -2 )); then
: # do nothing, _lp_last_ab_color already correct
elif (( $bg == -3 )); then
_lp_last_ab_color=$previous_af_color
elif (( $bg >= 0 )); then
_lp_last_ab_color=$bg
else # -1
_lp_last_ab_color=-1
fi

if (( ${_lp_last_ab_color:-"-1"} >= 0 )); then
__lp_background_color "$_lp_last_ab_color" && lp_terminal_format+=$ab_color
fi

# It turns out there are sequences to reset bold and underline to normal
# (\E[22m and \E[24m in xterm), but they aren't universally supported. This
# means we must reset to all defaults then enable if they are wanted.
# Explicit is safer anyway.
if (( ${3:-0} )); then
lp_terminal_format+=$_LP_TI_BOLD
fi

if (( ${4:-0} )); then
lp_terminal_format+=$_LP_TI_UNDERLINE
fi

lp_terminal_format+=$_LP_CLOSE_ESC
}

##########################
# Working Directory Path #
##########################
Expand Down

0 comments on commit 09cfced

Please sign in to comment.