I\'m writing various utilities, and I\'m really liking colorized text. Nothing fancy, just using escape sequences. I\'ve created a simple class that has a pprint(msg, color) fun
Actually, it's possible — for xterm, and compatible terminals.
xtermcontrol for instance uses the OSC 10 control sequence to retrieve the default foreground/background colors. It's been documented in xterm since 2002.
For other terminals:
OSC 10
(tested with the equivalent CentOS 5).Curious when it was added, bear in mind that VTE's developers don't write documentation. So... studying the git log shows
commit 1b8c6b1aac587b79476a60a5830385abc939430d
Author: Egmont Koblinger <egmont@gmail.com>
Date: Wed Jan 22 00:13:51 2014 +0100
emulation: Add support for OSC 1?1[017] (fg, bg, highlight colors)
https://bugzilla.gnome.org/show_bug.cgi?id=567444
On the other hand, the default colors are not the same as the current colors. Users have been able to do this with xterm since patch #93 in 1999 using the DECRQSS
control sequence. That is, putting the terminal into raw mode and doing something like
printf '\033P$m\033\\'
would get it to reply with the string filled out with the SGR parameters.
If colors were set using SGR, those codes would be part of the reply, e.g.
\033P1$r0;33m\033\\
to denote foreground color number 3 (encoded as 33
).
You could stop there (because you could extract those parameters and reuse them to set the terminal to the same state later), but then getting the actual RGB colors would be possible using OSC 4
. You'd use the color number (from the SGR sequence), and send something like this:
printf '\033]4;3;?\033\\'
So it's certainly doable with xterm. There'll be a demo/test-script for DECRQSS
in the next update for xterm.
For other programs, you need more time:
xtermcontrol's developer overlooked DECRQSS
(it has no feature for setting/getting SGR codes).
VTE's developers copy xterm features in response to bug reports; the VTE source does not mention DECRQSS
. Its git log mentions OSC 4
in 2009, but the implementation is incomplete (it only allows one to set a color, not get the color).
Rather than using obfuscated escape sequences, use the tput
facility instead. Here is an excerpt from my ~/.bashrc
that I use for my PS1 prompt:
BLACK=$(tput setaf 0)
RED=$(tput setaf 1)
GREEN=$(tput setaf 2)
YELLOW=$(tput setaf 3)
LIME_YELLOW=$(tput setaf 190)
POWDER_BLUE=$(tput setaf 153)
BLUE=$(tput setaf 4)
MAGENTA=$(tput setaf 5)
CYAN=$(tput setaf 6)
WHITE=$(tput setaf 7)
BRIGHT=$(tput bold)
NORMAL=$(tput sgr0)
BLINK=$(tput blink)
REVERSE=$(tput smso)
UNDERLINE=$(tput smul)
To reset the color information such that subsequent text is in the normal terminal color you would append ${NORMAL}
to the end like so:
echo "${RED}this is red ${NORMAL}this is normal"
RED = 31
GREEN = 32
ESCAPE = '%s[' % chr(27)
RESET = '%s0m' % ESCAPE
FORMAT = '1;%dm'
def colorize(text, color):
return ESCAPE + (FORMAT % (color, )) + text + RESET
This function will return a string that will print colorized, with the terminal automatically being reset afterwards.
I don't believe that's possible and it's unlikely to be portable if it were. The best you can do is send sgr0
which resets all attributes to default (not previous). On xterms, sgr0
is Esc[m
. If you want to reset the colors and not affect other attributes, send op
which on xterms is Esc[39;49m
.
These codes should not be hardcoded. You should use terminfo, termcap or [n]curses.