terminal colors tools and tutorial

terminalvim 配色时,常会用到颜色名字或者对应的数字,一种方式就是查看网页,如 256 COLORS - CHEAT SHEET,另一种方便的方式,直接在命令行中输出颜色面板和名字,方便配色时引用。

check terminal support for 256 colours

可以使用以下脚本,在命令行中运行一下,看输出的结果,可以判断当前 terminal 对 256 色(8bit)支持的情况。

awk 'BEGIN{    s="/\\/\\/\\/\\/\\"; s=s s s s s s s s;    for (colnum = 0; colnum<77; colnum++) {        r = 255-(colnum*255/76);        g = (colnum*510/76);        b = (colnum*255/76);        if (g>255) g = 510-g;        printf "\033[48;2;%d;%d;%dm", r,g,b;        printf "\033[38;2;%d;%d;%dm", 255-r,255-g,255-b;        printf "%s\033[0m", substr(s,colnum+1,1);    }    printf "\n";}'

如下脚本,会输出 256 色示例到控制台,显示对应颜色和色号:

#!/bin/bash# Tom Hale, 2016. MIT Licence.# Print out 256 colours, with each number printed in its corresponding colour# See http://askubuntu.com/questions/821157/print-a-256-color-test-pattern-in-the-terminal/821163#821163set -eu # Fail on errors or undeclared variablesprintable_colours=256# Return a colour that contrasts with the given colour# Bash only does integer division, so keep it integralfunction contrast_colour {    local r g b luminance    colour="$1"    if (( colour < 16 )); then # Initial 16 ANSI colours        (( colour == 0 )) && printf "15" || printf "0"        return    fi    # Greyscale # rgb_R = rgb_G = rgb_B = (number - 232) * 10 + 8    if (( colour > 231 )); then # Greyscale ramp        (( colour < 244 )) && printf "15" || printf "0"        return    fi    # All other colours:    # 6x6x6 colour cube = 16 + 36*R + 6*G + B  # Where RGB are [0..5]    # See http://stackoverflow.com/a/27165165/5353461    # r=$(( (colour-16) / 36 ))    g=$(( ((colour-16) % 36) / 6 ))    # b=$(( (colour-16) % 6 ))    # If luminance is bright, print number in black, white otherwise.    # Green contributes 587/1000 to human perceived luminance - ITU R-REC-BT.601    (( g > 2)) && printf "0" || printf "15"    return    # Uncomment the below for more precise luminance calculations    # # Calculate percieved brightness    # # See https://www.w3.org/TR/AERT#color-contrast    # # and http://www.itu.int/rec/R-REC-BT.601    # # Luminance is in range 0..5000 as each value is 0..5    # luminance=$(( (r * 299) + (g * 587) + (b * 114) ))    # (( $luminance > 2500 )) && printf "0" || printf "15"}# Print a coloured block with the number of that colourfunction print_colour {    local colour="$1" contrast    contrast=$(contrast_colour "$1")    printf "\e[48;5;%sm" "$colour"                # Start block of colour    printf "\e[38;5;%sm%3d" "$contrast" "$colour" # In contrast, print number    printf "\e[0m "                               # Reset colour}# Starting at $1, print a run of $2 coloursfunction print_run {    local i    printf "  "    for (( i = "$1"; i < "$1" + "$2" && i < printable_colours; i++ )) do        print_colour "$i"    done    printf "  "}# Print blocks of coloursfunction print_blocks {    local start="$1" i    local end="$2" # inclusive    local block_cols="$3"    local block_rows="$4"    local blocks_per_line="$5"    local block_length=$((block_cols * block_rows))    # Print sets of blocks    for (( i = start; i <= end; i += (blocks_per_line-1) * block_length )) do        printf "\n" # Space before each set of blocks        # For each block row        for (( row = 0; row < block_rows; row++ )) do            # Print block columns for all blocks on the line            for (( block = 0; block < blocks_per_line; block++ )) do                print_run $(( i + (block * block_length) )) "$block_cols"            done            (( i += block_cols )) # Prepare to print the next row            printf "\n"        done    done}printf "\n"print_run 0 16 # The first 16 colours are spread over the whole spectrumprintf "\n"print_blocks 16 231 6 6 3 # 6x6x6 colour cube between 16 and 231 inclusiveprint_blocks 232 255 12 2 1 # Not 50, but 24 Shades of Grey

输出如下图:

上面输出的结果中第一行的 16 色(3/4bit)分别对应 8 个背景色和 8 个前景色,可以参考文章说明:table for 16-color terminal escape sequences

8 背景色和 8 前景色组合结果

bash 前景色和背景色 256 色输出示例

#!/bin/bashfor i in {0..255} ; do printf "\x1b[38;5;${i}mcolour${i}\x1b[0m\n"; doneprintf '\e[0m\n'for i in {0..255} ; do printf "\x1b[48;5;${i}mcolour${i}\x1b[0m\n"; doneprintf '\e[0m\n'printf '\n\t'for i in {0..255}; do printf '\e[48;5;%dm%3d ' $i $i; (((i+3) % 18)) || printf '\e[0m\n\t'; doneprintf '\e[0m\n'printf '\n\t'for i in {0..255}; do printf '\e[38;5;%dm%3d ' $i $i; (((i+3) % 18)) || printf '\e[0m\n\t'; doneprintf '\n'

The ANSI/VT100 terminals and terminal emulators are not just able to display black and white text ; they can display colors and formatted texts thanks to escape sequences. Those sequences are composed of the Escape character (often represented by ”^[” or ”<Esc>”) followed by some other characters: "<Esc>[FormatCodem".

In Bash, the <Esc> character can be obtained with the following syntaxes:

\e
\033
\x1B

Foreground (text)

For using one of the 256 colors on the foreground (text color), the control sequence is ”<Esc>[38;5;ColorNumberm” where ColorNumber is one of the following colors:

Background

For using one of the 256 colors on the background, the control sequence is ”<Esc>[48;5;ColorNumberm” where ColorNumber is one of the following colors:

详细说明可参考Bash Colors

256color.sh

#!/usr/bin/env bash# This program is free software. It comes without any warranty, to# the extent permitted by applicable law. You can redistribute it# and/or modify it under the terms of the Do What The Fuck You Want# To Public License, Version 2, as published by Sam Hocevar. See# http://sam.zoy.org/wtfpl/COPYING for more details.for fgbg in 38 48 ; do #Foreground/Background    for color in {0..255} ; do #Colors        #Display the color        echo -en "\e[${fgbg};5;${color}m ${color}\t\e[0m"        #Display 10 colors per lines        if [ $((($color + 1) % 10)) == 0 ] ; then            echo #New line        fi    done    echo #New linedoneexit 0

256color-and-formatting.sh

#!/usr/bin/env bash# This program is free software. It comes without any warranty, to# the extent permitted by applicable law. You can redistribute it# and/or modify it under the terms of the Do What The Fuck You Want# To Public License, Version 2, as published by Sam Hocevar. See# http://sam.zoy.org/wtfpl/COPYING for more details.#Backgroundfor clbg in {40..47} {100..107} 49 ; do    #Foreground    for clfg in {30..37} {90..97} 39 ; do        #Formatting        for attr in 0 1 2 4 5 7 ; do            #Print the result            echo -en "\e[${attr};${clbg};${clfg}m ^[${attr};${clbg};${clfg}m \e[0m"        done        echo #Newline    donedoneexit 0

zsh 前景色和背景色 256 色输出示例

以下脚本需要用zsh来运行:

#!/bin/zshfor code ({000..255}) print -P -- "$code: %F{$code}This is how your text would look like%f"for code ({000..255}) print -P -- "$code: %K{$code}This is how your background would look like%k"

powerlevel9k 输出前景色和背景色

上面这个前景色和背景色输出示例,在oh-my-zsh主题powerlevel9k中有个帮助方法,可以用来查看类似的效果,命令如下所示:

 getColorCode foreground getColorCode background

getColorCode background 输出截图部分如下,另外还有 zsh 前景色和背景色使用示例:

powerlevel9k getColorCode

# vim:ft=zsh ts=2 sw=2 sts=2 et fenc=utf-8################################################################# Color functions# This file holds some color-functions for# the powerlevel9k-ZSH-theme# https://github.com/bhilburn/powerlevel9k################################################################typeset -gAh __P9K_COLORS# https://jonasjacek.github.io/colors/# use color names by default to allow dark/light themes to adjust colors based on names__P9K_COLORS=(  black             000  red               001  green             002  yellow            003  blue              004  magenta           005  cyan              006  white             007  grey              008  maroon            009  lime              010  olive             011  navy              012  fuchsia           013  purple            013  aqua              014  teal              014  silver            015  grey0             016  navyblue          017  darkblue          018  blue3             019  blue3             020  blue1             021  darkgreen         022  deepskyblue4      023  deepskyblue4      024  deepskyblue4      025  dodgerblue3       026  dodgerblue2       027  green4            028  springgreen4      029  turquoise4        030  deepskyblue3      031  deepskyblue3      032  dodgerblue1       033  green3            034  springgreen3      035  darkcyan          036  lightseagreen     037  deepskyblue2      038  deepskyblue1      039  green3            040  springgreen3      041  springgreen2      042  cyan3             043  darkturquoise     044  turquoise2        045  green1            046  springgreen2      047  springgreen1      048  mediumspringgreen 049  cyan2             050  cyan1             051  darkred           052  deeppink4         053  purple4           054  purple4           055  purple3           056  blueviolet        057  orange4           058  grey37            059  mediumpurple4     060  slateblue3        061  slateblue3        062  royalblue1        063  chartreuse4       064  darkseagreen4     065  paleturquoise4    066  steelblue         067  steelblue3        068  cornflowerblue    069  chartreuse3       070  darkseagreen4     071  cadetblue         072  cadetblue         073  skyblue3          074  steelblue1        075  chartreuse3       076  palegreen3        077  seagreen3         078  aquamarine3       079  mediumturquoise   080  steelblue1        081  chartreuse2       082  seagreen2         083  seagreen1         084  seagreen1         085  aquamarine1       086  darkslategray2    087  darkred           088  deeppink4         089  darkmagenta       090  darkmagenta       091  darkviolet        092  purple            093  orange4           094  lightpink4        095  plum4             096  mediumpurple3     097  mediumpurple3     098  slateblue1        099  yellow4           100  wheat4            101  grey53            102  lightslategrey    103  mediumpurple      104  lightslateblue    105  yellow4           106  darkolivegreen3   107  darkseagreen      108  lightskyblue3     109  lightskyblue3     110  skyblue2          111  chartreuse2       112  darkolivegreen3   113  palegreen3        114  darkseagreen3     115  darkslategray3    116  skyblue1          117  chartreuse1       118  lightgreen        119  lightgreen        120  palegreen1        121  aquamarine1       122  darkslategray1    123  red3              124  deeppink4         125  mediumvioletred   126  magenta3          127  darkviolet        128  purple            129  darkorange3       130  indianred         131  hotpink3          132  mediumorchid3     133  mediumorchid      134  mediumpurple2     135  darkgoldenrod     136  lightsalmon3      137  rosybrown         138  grey63            139  mediumpurple2     140  mediumpurple1     141  gold3             142  darkkhaki         143  navajowhite3      144  grey69            145  lightsteelblue3   146  lightsteelblue    147  yellow3           148  darkolivegreen3   149  darkseagreen3     150  darkseagreen2     151  lightcyan3        152  lightskyblue1     153  greenyellow       154  darkolivegreen2   155  palegreen1        156  darkseagreen2     157  darkseagreen1     158  paleturquoise1    159  red3              160  deeppink3         161  deeppink3         162  magenta3          163  magenta3          164  magenta2          165  darkorange3       166  indianred         167  hotpink3          168  hotpink2          169  orchid            170  mediumorchid1     171  orange3           172  lightsalmon3      173  lightpink3        174  pink3             175  plum3             176  violet            177  gold3             178  lightgoldenrod3   179  tan               180  mistyrose3        181  thistle3          182  plum2             183  yellow3           184  khaki3            185  lightgoldenrod2   186  lightyellow3      187  grey84            188  lightsteelblue1   189  yellow2           190  darkolivegreen1   191  darkolivegreen1   192  darkseagreen1     193  honeydew2         194  lightcyan1        195  red1              196  deeppink2         197  deeppink1         198  deeppink1         199  magenta2          200  magenta1          201  orangered1        202  indianred1        203  indianred1        204  hotpink           205  hotpink           206  mediumorchid1     207  darkorange        208  salmon1           209  lightcoral        210  palevioletred1    211  orchid2           212  orchid1           213  orange1           214  sandybrown        215  lightsalmon1      216  lightpink1        217  pink1             218  plum1             219  gold1             220  lightgoldenrod2   221  lightgoldenrod2   222  navajowhite1      223  mistyrose1        224  thistle1          225  yellow1           226  lightgoldenrod1   227  khaki1            228  wheat1            229  cornsilk1         230  grey100           231  grey3             232  grey7             233  grey11            234  grey15            235  grey19            236  grey23            237  grey27            238  grey30            239  grey35            240  grey39            241  grey42            242  grey46            243  grey50            244  grey54            245  grey58            246  grey62            247  grey66            248  grey70            249  grey74            250  grey78            251  grey82            252  grey85            253  grey89            254  grey93            255)function termColors() {  if [[ $POWERLEVEL9K_IGNORE_TERM_COLORS == true ]]; then    return  fi  local term_colors  if which tput &>/dev/null; then    term_colors=$(tput colors)  else    term_colors=$(echotc Co)  fi  if (( ! $? && ${term_colors:-0} < 256 )); then    print -P "%F{red}WARNING!%f Your terminal appears to support fewer than 256 colors!"    print -P "If your terminal supports 256 colors, please export the appropriate environment variable"    print -P "_before_ loading this theme in your \~\/.zshrc. In most terminal emulators, putting"    print -P "%F{blue}export TERM=\"xterm-256color\"%f at the top of your \~\/.zshrc is sufficient."  fi}# get the proper color code if it does not exist as a name.function getColor() {  # If Color is not numerical, try to get the color code.  if [[ "$1" != <-> ]]; then    1=$(getColorCode $1)  fi  echo -n "$1"}# empty paramenter resets (stops) background colorfunction backgroundColor() {  echo -n "%K{$(getColor $1)}"}# empty paramenter resets (stops) foreground colorfunction foregroundColor() {  echo -n "%F{$(getColor $1)}"}# Get numerical color codes. That way we translate ANSI codes# into ZSH-Style color codes.function getColorCode() {  # Early exit: Check if given value is already numerical  if [[ "$1" == <-> ]]; then    # Pad color with zeroes    echo -n "${(l:3::0:)1}"    return  fi  local colorName="${1}"  # Check if value is none with any case.  if [[ "${(L)colorName}" == "none" ]]; then      echo -n 'none'  elif [[ "${colorName}" == "foreground"  ]]; then      # for testing purposes in terminal      # call via `getColorCode foreground`      for i in "${(k@)__P9K_COLORS}"; do          print -P "$(foregroundColor $i)$(getColor $i) - $i%f"      done  elif [[ "${colorName}" == "background"  ]]; then      # call via `getColorCode background`      for i in "${(k@)__P9K_COLORS}"; do          print -P "$(backgroundColor $i)$(getColor $i) - $i%k"      done  else      # Strip eventual "bg-" prefixes      colorName=${colorName#bg-}      # Strip eventual "fg-" prefixes      colorName=${colorName#fg-}      # Strip eventual "br" prefixes ("bright" colors)      colorName=${colorName#br}      echo -n $__P9K_COLORS[$colorName]  fi}# Check if two colors are equal, even if one is specified as ANSI code.function isSameColor() {  if [[ "$1" == "NONE" || "$2" == "NONE" ]]; then    return 1  fi  local color1=$(getColorCode "$1")  local color2=$(getColorCode "$2")  return $(( color1 != color2 ))}

man zshmisc

 man zshmisc
# Visual effects    # %B (%b)        # Start (stop) boldface mode.    # %E     Clear to end of line.    # %U (%u)        # Start (stop) underline mode.    # %S (%s)        # Start (stop) standout mode.    # %F (%f)        # Start (stop) using a different foreground colour, if supported by the terminal.  The colour may be  specified  two  ways:        # either as a numeric argument, as normal, or by a sequence in braces following the %F, for example %F{red}.  In the latter        # case the values allowed are as described for the fg zle_highlight attribute; see  Character  Highlighting  in  zshzle(1).        # This means that numeric colours are allowed in the second format also.    # %K (%k)        # Start (stop) using a different bacKground colour.  The syntax is identical to that for %F and %f.    # %{...%}        # Include  a  string  as  a  literal  escape sequence.  The string within the braces should not change the cursor position.        # Brace pairs can nest.        # A positive numeric argument between the % and the { is treated as described for %G below.    # %G  Within a %{...%} sequence, include a `glitch': that is, assume that a single character width will  be  output.   This  is        # useful  when outputting characters that otherwise cannot be correctly handled by the shell, such as the alternate charac-        # ter set on some terminals.  The characters in question can be included within a %{...%} sequence together with the appro-        # priate  number  of  %G sequences to indicate the correct width.  An integer between the `%' and `G' indicates a character        # width other than one.  Hence %{seq%2G%} outputs seq and assumes it takes up the width of two standard characters.        # Multiple uses of %G accumulate in the obvious fashion; the position of the %G is unimportant.  Negative integers are  not        # handled.        # Note that when prompt truncation is in use it is advisable to divide up output into single characters within each %{...%}        # group so that the correct truncation point can be found.

References

  1. 256 COLORS - CHEAT SHEET
  2. table for 16-color terminal escape sequences
  3. Bash Colors
  4. Xterm 256color chart SVG
  5. Xterm 256color chart PNG
  6. zsh 256colors: default background color as foreground color
  7. colors.zsh of powerlevel9k
  8. ANSI escape code
  9. How to change the output color of echo in Linux
  10. Print a 256-color test pattern in the terminal