[color]: support for 8-color terminals, better default colors

[opt/cfg]: --force-256-color on terminals that support but don't advertise it
This commit is contained in:
philemon 2016-12-12 16:27:30 +03:00
commit 39167e90be
Signed by untrusted user who does not match committer: mmgen
GPG key ID: 62DBE9E5212F05BE
4 changed files with 78 additions and 36 deletions

View file

@ -14,6 +14,9 @@
# Uncomment to disable color output:
# color false
# Uncomment to force 256-color output when 'color' is true:
# force_256_color true
# Uncomment to use testnet instead of mainnet:
# testnet true

View file

@ -17,42 +17,78 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
"""
color.py: color routines for the MMGen suite
color.py: color handling for the MMGen suite
"""
# If 88- or 256-color support is compiled, the following apply.
# P s = 3 8 ; 5 ; P s -> Set foreground color to the second P s .
# P s = 4 8 ; 5 ; P s -> Set background color to the second P s .
import os
if os.environ['TERM'][-8:] == '256color':
_blk,_red,_grn,_yel,_blu,_mag,_cya,_bright,_dim,_ybright,_ydim,_pnk,_orng,_gry,_pur = [
'\033[38;5;%s;1m' % c for c in 232,210,121,229,75,90,122,231,245,187,243,218,215,246,147]
_redbg = '\033[38;5;232;48;5;210;1m'
_grnbg = '\033[38;5;232;48;5;121;1m'
_grybg = '\033[38;5;231;48;5;240;1m'
_reset = '\033[0m'
else:
_blk,_red,_grn,_yel,_blu,_mag,_cya,_reset,_grnbg = \
['\033[%sm' % c for c in '30;1','31;1','32;1','33;1','34;1','35;1','36;1','0','30;102']
_gry=_orng=_pnk=_redbg=_ybright=_ydim=_bright=_dim=_grybg=_mag=_pur # TODO
_colors = {
'black': ( 232, (30,0) ),
'red': ( 210, (31,1) ),
'green': ( 121, (32,1) ),
'yellow': ( 229, (33,1) ),
'blue': ( 75, (34,1) ),
'magenta': ( 213, (35,1) ),
'cyan': ( 122, (36,1) ),
'pink': ( 218, (35,1) ),
'orange': ( 216, (31,1) ),
'gray': ( 246, (30,1) ),
'purple': ( 141, (35,1) ),
_colors = 'red','grn','grnbg','yel','cya','blu','pnk','orng','gry','mag','pur','reset'
for c in _colors: globals()['clr_'+c] = ''
'brown': ( 208, (33,0) ),
'grndim': ( 108, (32,0) ),
'redbg': ( (232,210), (30,101) ),
'grnbg': ( (232,121), (30,102) ),
'blubg': ( (232,75), (30,104) ),
'yelbg': ( (232,229), (30,103) ),
}
for c in _colors:
e = _colors[c]
if type(e[0]) == int:
globals()['_256_'+c] = '\033[38;5;{};1m'.format(e[0])
else:
globals()['_256_'+c] = '\033[38;5;{};48;5;{};1m'.format(*e[0])
if e[1][1] == 0:
globals()['_16_'+c] = '\033[{}m'.format(e[1][0])
else:
globals()['_16_'+c] = '\033[{};{}m'.format(*e[1])
globals()['_clr_'+c] = ''; _reset = ''
exec "def {c}(s): return _clr_{c}+s+_reset".format(c=c)
def nocolor(s): return s
def red(s): return clr_red+s+clr_reset
def green(s): return clr_grn+s+clr_reset
def grnbg(s): return clr_grnbg+s+clr_reset
def yellow(s): return clr_yel+s+clr_reset
def cyan(s): return clr_cya+s+clr_reset
def blue(s): return clr_blu+s+clr_reset
def pink(s): return clr_pnk+s+clr_reset
def orange(s): return clr_orng+s+clr_reset
def gray(s): return clr_gry+s+clr_reset
def magenta(s): return clr_mag+s+clr_reset
def purple(s): return clr_pur+s+clr_reset
def init_color(enable_color=True):
def init_color(enable_color=True,num_colors='auto'):
if enable_color:
assert num_colors in ['auto',8,16,256]
globals()['_reset'] = '\033[0m'
if num_colors in [8,16]:
pfx = '_16_'
elif num_colors in [256]:
pfx = '_256_'
else:
try:
import os
assert os.environ['TERM'][-8:] == '256color'
pfx = '_256_'
except:
try:
import subprocess
a = subprocess.check_output(['infocmp','-0'])
b = [e.split('#')[1] for e in a.split(',') if e[:6] == 'colors'][0]
pfx = ('_16_','_256_')[b=='256']
except:
pfx = '_16_'
for c in _colors:
globals()['clr_'+c] = globals()['_'+c]
globals()['_clr_'+c] = globals()[pfx+c]
def test_color():
try:
import colorama
colorama.init(strip=True,convert=True)
except:
pass
for desc,n in ('auto','auto'),('8-color',8),('256-color',256):
if n != 'auto': init_color(num_colors=n)
print('{:9}: {}'.format(desc,' '.join([globals()[c](c) for c in sorted(_colors)])))
if __name__ == '__main__': test_color()

View file

@ -65,6 +65,7 @@ class g(object):
no_license = False
hold_protect = True
color = (False,True)[sys.stdout.isatty()]
force_256_color = False
testnet = False
rpc_host = ''
rpc_port = 0
@ -93,7 +94,7 @@ class g(object):
# User opt sets global var:
common_opts = (
'color','no_license','rpc_host','rpc_port','testnet','rpc_user','rpc_password',
'bitcoin_data_dir'
'bitcoin_data_dir','force_256_color'
)
required_opts = (
'quiet','verbose','debug','outdir','echo_passphrase','passwd_file','stdout',
@ -110,13 +111,14 @@ class g(object):
cfg_file_opts = (
'color','debug','hash_preset','http_timeout','no_license','rpc_host','rpc_port',
'quiet','tx_fee','tx_fee_adj','usr_randchars','testnet','rpc_user','rpc_password',
'bitcoin_data_dir'
'bitcoin_data_dir','force_256_color'
)
env_opts = (
'MMGEN_BOGUS_WALLET_DATA',
'MMGEN_DEBUG',
'MMGEN_QUIET',
'MMGEN_DISABLE_COLOR',
'MMGEN_FORCE_256_COLOR',
'MMGEN_DISABLE_HOLD_PROTECT',
'MMGEN_MIN_URANDCHARS',
'MMGEN_NO_LICENSE',

View file

@ -68,6 +68,7 @@ def _show_hash_presets():
# most, but not all, of these set the corresponding global var
common_opts_data = """
--, --color=0|1 Disable or enable color output
--, --force-256-color Force 256-color output when color is enabled
--, --bitcoin-data-dir=d Specify Bitcoin data directory location 'd'
--, --data-dir=d Specify {pnm} data directory location 'd'
--, --no-license Suppress the GPL license prompt
@ -116,7 +117,7 @@ def opt_postproc_initializations():
check_or_create_dir(g.data_dir) # dies on error
from mmgen.color import init_color
init_color(g.color)
init_color(enable_color=g.color,num_colors=('auto',256)[bool(g.force_256_color)])
if g.platform == 'win': start_mscolor()