Skip to content

Instantly share code, notes, and snippets.

@pdf
Last active August 29, 2015 14:01
Show Gist options
  • Select an option

  • Save pdf/47099d5ad8f9b64f69a3 to your computer and use it in GitHub Desktop.

Select an option

Save pdf/47099d5ad8f9b64f69a3 to your computer and use it in GitHub Desktop.
Generate unique terminal colours for hosts based on hashed hostname, for PS1 or PowerLine
#!/bin/sh -e
# Maximum acceptable decimal colour representation
hostcolour_max_dec=16777215
# Requires the `rand` command, this doesn't seem to be packaged on some distros in the standard repositories
# If anyone knows of an alternative that will take a seed, a max, and is more widely available, let me know.
# Generate decimal colour
hostcolour_bg_dec="$(rand -M ${hostcolour_max_dec} -s $(printf "%.0f" "$(echo -n $(hostname -f) | md5sum | sed 's#^\([^[:space:]]*\).*$#0x\1#g')" 2>/dev/null | sed -e 's#^.*\([0-9]\{18\}\)$#\1#g'))"
# Convert to hex
hostcolour_bg_hex="$(printf "%06x" ${hostcolour_bg_dec})"
# Split to RGB
# Stupid Dash doesn't have ${var:offset:length} subs, so use sed
rgb_r=$(printf "%d" $(echo ${hostcolour_bg_hex} | sed -e 's#^\(..\).*$#0x\1#g'))
rgb_g=$(printf "%d" $(echo ${hostcolour_bg_hex} | sed -e 's#^..\(..\).*$#0x\1#g'))
rgb_b=$(printf "%d" $(echo ${hostcolour_bg_hex} | sed -e 's#^....\(..\)$#0x\1#g'))
# Calculate colour-weighted brightness, and set appropriate foreground
if [ $(echo $rgb_r $rgb_g $rgb_b | awk '{print int(sqrt(($1 * $1 * .241) + ($2 * $2 * .691) + ($3 * $3 * .068)))}') -gt 130 ]; then
hostcolour_fg_ansi=16
else
hostcolour_fg_ansi=231
fi
# If we happen to get white, we don't have grey
if [ "$rgb_r" = "255" -a "$rgb_g" = "255" -a "$rgb_b" = "255" ]; then
grey_possible=0
else
grey_possible=1
sep="42.5"
grey=0
fi
# Work out whether we have a greyscale colour so we can do appropriate conversion
while [ $grey_possible -ne 0 ] ; do
if [ -n "$(echo $sep $rgb_r | awk '{if ($2 < $1) print "true"}')" -o -n "$(echo $sep $rgb_g | awk '{if ($2 < $1) print "true"}')" -o -n "$(echo $sep $rgb_b | awk '{if ($2 < $1) print "true"}')" ] ; then
if [ -n "$(echo $sep $rgb_r $rgb_g $rgb_b | awk '{if ($2 < $1 && $3 < $1 && $4 < $1) print "true"}')" ] ; then
grey=1
fi
grey_possible=0
fi
sep="$(echo $sep | awk '{print $1 + 42.5}')"
done
# Generate ANSI colour from RGB
if [ $grey -eq 1 ]; then
hostcolour_bg_ansi=$(echo $rgb_r $rgb_g $rgb_b | awk '{print 232 + int((($1 + $2 + $3)/33)+0.5)}')
else
hostcolour_bg_ansi=16
hostcolour_bg_ansi=$(( ${hostcolour_bg_ansi} + $(echo $rgb_r | awk '{print $1 / 256 * 6}' | awk '{print int($1-0.5) * 36}')))
hostcolour_bg_ansi=$(( ${hostcolour_bg_ansi} + $(echo $rgb_g | awk '{print $1 / 256 * 6}' | awk '{print int($1-0.5) * 6}')))
hostcolour_bg_ansi=$(( ${hostcolour_bg_ansi} + $(echo $rgb_b | awk '{print $1 / 256 * 6}' | awk '{print int($1-0.5)}')))
fi
# Update global PowerLine config, you could instead write out the colour to a file for sourcing in `PS1`
powerline_conf="/etc/xdg/powerline/colors.json"
if [ -n "${hostcolour_fg_ansi}" -a -n "${hostcolour_bg_ansi}" -a -n "${hostcolour_bg_hex}" -a -w "${powerline_conf}" ]; then
sed -e "s#\(['\"]host_bg['\"]: \)\(\[[0-9]\+[[:space:]]*,[[:space:]]*['\"]*[0-9a-f]\+['\"]*\]\|[0-9]*\)[[:space:]]*\(,*\)\$#\1[${hostcolour_bg_ansi}, \"${hostcolour_bg_hex}\"]\3#g" -i "${powerline_conf}"
sed -e "s#\(['\"]host_fg['\"]: \)\(\[[0-9]\+[[:space:]]*,[[:space:]]*['\"]*[0-9a-f]\+['\"]*\]\|[0-9]*\)[[:space:]]*\(,*\)\$#\1${hostcolour_fg_ansi}\3#g" -i "${powerline_conf}"
fi
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment