在 terminal
和 vim
配色时,常会用到颜色名字或者对应的数字,一种方式就是查看网页,如 256 COLORS - CHEAT SHEET,另一种方便的方式,直接在命令行中输出颜色面板和名字,方便配色时引用。
检查当前 Terminal 是否支持 24bit 色彩
可以使用以下脚本,在命令行中运行一下,看输出的结果,可以判断当前 terminal
对 truecolors (24bit)支持的情况。
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";}' |
如下是在iTerm.app
中的运行结果:
![[iterm terminal 24bit colors]](/blog/img/linux/terminal-check-24bit-colors.png)
如下图是在Terminal.app
中的运行结果,目前应该是只支持 256 色,相比而言,iTerm.app
的色彩支持更好:
![[terminal app 256 colors]](/blog/img/linux/terminal-app-256-colors.png)
Terminal escape sequences 说明
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 和 ANSI escape code。
24bit true colour
24bit 彩色通过 RBG 方式明确指定,其中 fg
为 38
,bg
为 48
。
printf "\x1b[${fg};2;${red};${green};${blue}m\n"printf "\x1b[${bg};2;${red};${green};${blue}m\n" |
以下结果输出为白色的则表示不支持 24bit 颜色,如下图是在 iTerm.app
中输出的真彩结果:
![[iterm2 24bit true colors support]](/blog/img/linux/iterm2-24bit-true-colors-support.png)
24bit true colors support in neovim and vim
- neovim - since commit 8dd415e887923f99ab5daaeba9f0303e173dd1aa; need to set termguicolors to enable true color.
- vim - (from 7.4.1770) since commit 8a633e3427b47286869aa4b96f2bfc1fe65b25cd; need to set termguicolors to enable true color.
打印 256 色到控制台
如下脚本,会输出 256 色示例到控制台,显示对应颜色和色号:
curl -s https://gist.githubusercontent.com/HaleTom/89ffe32783f89f403bba96bd7bcd1263/raw/ | bash |
控制台输出如下图:
![[xterm-256colors-table]](/blog/img/linux/xterm-256colors-table.png)
上面输出的结果中第一行的 16 色(3/4bit)分别对应 8 个背景色和 8 个前景色,可以参考文章说明:table for 16-color terminal escape sequences
ANSI 16 colors escape codes
8 背景色和 8 前景色以及粗细字体组合:
![[xterm-16colors-table]](/blog/img/linux/xterm-16colors-table.png)
bash 前景色和背景色 256 色输出示例
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 '\x1b[38;5;%dm%3d ' $i $i; (((i+3) % 18)) || printf '\x1b[0m\n\t'; doneprintf '\n' |
![[bash-256-colors]](/blog/img/linux/bash-256-colors.png)
zsh 中前景色和背景色设置模式说明
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. |
zsh 前景色和背景色 256 色输出示例
# You can switch foreground and background colors with the standout mode %S (%s).# As you can see, it does not matter in which order the colors and modes (works the same for boldface and underline modes) are set.# You can set a foreground color with %F{color} before or after starting standout mode with %S, it is just used as background after %S until you stop standout mode with %s.print -P $'\t unchanged output colors'print -P $'\t%f%k default colors %S standout mode %s'print -P $'\t%F{blue}%K{red} blue on red %f%k'print -P $'\t%S%F{blue}%K{red} red on blue %s blue on red %f%k'print -P $'\t%K{default}%F{blue}%Sdefault background on blue %s%f%k'print -P $'\t%K{red}%F{default}%S red on default foreground %f%k%s' |
![[zsh-fg-bg-colors-example]](/blog/img/linux/zsh-fg-bg-colors-example.png)
powerlevel9k 输出前景色和背景色
上面这个前景色和背景色输出示例,在oh-my-zsh
主题powerlevel9k
中有个帮助方法,可以用来查看类似的效果,命令如下所示:
getColorCode foreground getColorCode background |
上述二个命令输出截图部分如下:
![[powerlevel9k get color code]](/blog/img/linux/powerlevel9k-get-color-code.png)
scripts source code
下面是一些在命令行控制台输出颜色的 bash
或者 zsh
脚本源码。
# prints a color table of 8bg * 8fg * 2 states (regular/bold)echoecho Table for 16-color terminal escape sequences.echo Replace ESC with \\033 in bash.echoecho "Background | Foreground colors"echo "---------------------------------------------------------------------"for((bg=40;bg<=47;bg++)); do for((bold=0;bold<=1;bold++)) do echo -en "\033[0m"" ESC[${bg}m | " for((fg=30;fg<=37;fg++)); do if [ $bold == "0" ]; then echo -en "\033[${bg}m\033[${fg}m [${fg}m " else echo -en "\033[${bg}m\033[1;${fg}m [1;${fg}m" fi done echo -e "\033[0m" done echo "--------------------------------------------------------------------- "doneecho |
# 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 |
for 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 "\e[48;5;${i}mcolour${i}\e[0m\n"; done |
# 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 |
# 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 |
for 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" |
################################################################# 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 "${([email protected])__P9K_COLORS}"; do print -P "$(foregroundColor $i)$(getColor $i) - $i%f" done elif [[ "${colorName}" == "background" ]]; then # call via `getColorCode background` for i in "${([email protected])__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 ))} |
References
- 256 COLORS - CHEAT SHEET
- table for 16-color terminal escape sequences
- Bash Colors
- Xterm 256color chart SVG
- Xterm 256color chart PNG
- zsh 256colors: default background color as foreground color
- colors.zsh of powerlevel9k
- ANSI escape code
- How to change the output color of echo in Linux
- Print a 256-color test pattern in the terminal
- Colours in terminal