Index: pym/portage/__init__.py =================================================================== --- pym/portage/__init__.py (revision 13640) +++ pym/portage/__init__.py (working copy) @@ -5431,7 +5431,7 @@ # Allow color.map to control colors associated with einfo, ewarn, etc... mycolors = [] for c in ("GOOD", "WARN", "BAD", "HILITE", "BRACKET"): - mycolors.append("%s=$'%s'" % (c, portage.output.codes[c])) + mycolors.append("%s=$'%s'" % (c, portage.output.map_code_to_color_code(c))) mysettings["PORTAGE_COLORMAP"] = "\n".join(mycolors) def prepare_build_dirs(myroot, mysettings, cleanup): Index: pym/portage/output.py =================================================================== --- pym/portage/output.py (revision 13640) +++ pym/portage/output.py (working copy) @@ -24,69 +24,48 @@ havecolor=1 dotitles=1 +codes={} +color_codes={} + esc_seq = "\x1b[" -g_attr = {} -g_attr["normal"] = 0 +color_codes["normal"] = esc_seq + "0m" +color_codes["reset"] = esc_seq + "39;49;00m" -g_attr["bold"] = 1 -g_attr["faint"] = 2 -g_attr["standout"] = 3 -g_attr["underline"] = 4 -g_attr["blink"] = 5 -g_attr["overline"] = 6 # Why is overline actually useful? -g_attr["reverse"] = 7 -g_attr["invisible"] = 8 +color_codes["bold"] = esc_seq + "01m" +color_codes["faint"] = esc_seq + "02m" +color_codes["standout"] = esc_seq + "03m" +color_codes["underline"] = esc_seq + "04m" +color_codes["blink"] = esc_seq + "05m" +color_codes["overline"] = esc_seq + "06m" +color_codes["reverse"] = esc_seq + "07m" +color_codes["invisible"] = esc_seq + "08m" -g_attr["no-attr"] = 22 -g_attr["no-standout"] = 23 -g_attr["no-underline"] = 24 -g_attr["no-blink"] = 25 -g_attr["no-overline"] = 26 -g_attr["no-reverse"] = 27 -# 28 isn't defined? -# 29 isn't defined? -g_attr["black"] = 30 -g_attr["red"] = 31 -g_attr["green"] = 32 -g_attr["yellow"] = 33 -g_attr["blue"] = 34 -g_attr["magenta"] = 35 -g_attr["cyan"] = 36 -g_attr["white"] = 37 -# 38 isn't defined? -g_attr["default"] = 39 -g_attr["bg_black"] = 40 -g_attr["bg_red"] = 41 -g_attr["bg_green"] = 42 -g_attr["bg_yellow"] = 43 -g_attr["bg_blue"] = 44 -g_attr["bg_magenta"] = 45 -g_attr["bg_cyan"] = 46 -g_attr["bg_white"] = 47 -g_attr["bg_default"] = 49 +color_codes["no-attr"] = esc_seq + "22m" +color_codes["no-standout"] = esc_seq + "23m" +color_codes["no-underline"] = esc_seq + "24m" +color_codes["no-blink"] = esc_seq + "25m" +color_codes["no-overline"] = esc_seq + "26m" +color_codes["no-reverse"] = esc_seq + "27m" +color_codes["bg_black"] = esc_seq + "40m" +color_codes["bg_darkred"] = esc_seq + "41m" +color_codes["bg_darkgreen"] = esc_seq + "42m" +color_codes["bg_brown"] = esc_seq + "43m" +color_codes["bg_darkblue"] = esc_seq + "44m" +color_codes["bg_purple"] = esc_seq + "45m" +color_codes["bg_teal"] = esc_seq + "46m" +color_codes["bg_lightgray"] = esc_seq + "47m" +color_codes["bg_default"] = esc_seq + "49m" +color_codes["bg_darkyellow"] = color_codes["bg_brown"] -# make_seq("blue", "black", "normal") def color(fg, bg="default", attr=["normal"]): - mystr = esc_seq[:] + "%02d" % g_attr[fg] + mystr = color_codes[fg] for x in [bg]+attr: - mystr += ";%02d" % g_attr[x] - return mystr+"m" + mystr += color_codes[x] + return mystr - -codes={} -codes["reset"] = esc_seq + "39;49;00m" - -codes["bold"] = esc_seq + "01m" -codes["faint"] = esc_seq + "02m" -codes["standout"] = esc_seq + "03m" -codes["underline"] = esc_seq + "04m" -codes["blink"] = esc_seq + "05m" -codes["overline"] = esc_seq + "06m" # Who made this up? Seriously. -codes["reverse"] = esc_seq + "07m" - ansi_color_codes = [] for x in xrange(30, 38): ansi_color_codes.append("%im" % x) @@ -97,76 +76,67 @@ '0xFF55FF', '0x00AAAA', '0x55FFFF', '0xAAAAAA', '0xFFFFFF'] for x in xrange(len(rgb_ansi_colors)): - codes[rgb_ansi_colors[x]] = esc_seq + ansi_color_codes[x] + color_codes[rgb_ansi_colors[x]] = esc_seq + ansi_color_codes[x] del x -codes["black"] = codes["0x000000"] -codes["darkgray"] = codes["0x555555"] +color_codes["black"] = color_codes["0x000000"] +color_codes["darkgray"] = color_codes["0x555555"] -codes["red"] = codes["0xFF5555"] -codes["darkred"] = codes["0xAA0000"] +color_codes["red"] = color_codes["0xFF5555"] +color_codes["darkred"] = color_codes["0xAA0000"] -codes["green"] = codes["0x55FF55"] -codes["darkgreen"] = codes["0x00AA00"] +color_codes["green"] = color_codes["0x55FF55"] +color_codes["darkgreen"] = color_codes["0x00AA00"] -codes["yellow"] = codes["0xFFFF55"] -codes["brown"] = codes["0xAA5500"] +color_codes["yellow"] = color_codes["0xFFFF55"] +color_codes["brown"] = color_codes["0xAA5500"] -codes["blue"] = codes["0x5555FF"] -codes["darkblue"] = codes["0x0000AA"] +color_codes["blue"] = color_codes["0x5555FF"] +color_codes["darkblue"] = color_codes["0x0000AA"] -codes["fuchsia"] = codes["0xFF55FF"] -codes["purple"] = codes["0xAA00AA"] +color_codes["fuchsia"] = color_codes["0xFF55FF"] +color_codes["purple"] = color_codes["0xAA00AA"] -codes["turquoise"] = codes["0x55FFFF"] -codes["teal"] = codes["0x00AAAA"] +color_codes["turquoise"] = color_codes["0x55FFFF"] +color_codes["teal"] = color_codes["0x00AAAA"] -codes["white"] = codes["0xFFFFFF"] -codes["lightgray"] = codes["0xAAAAAA"] +color_codes["white"] = color_codes["0xFFFFFF"] +color_codes["lightgray"] = color_codes["0xAAAAAA"] -codes["darkteal"] = codes["turquoise"] +color_codes["darkteal"] = color_codes["turquoise"] # Some terminals have darkyellow instead of brown. -codes["0xAAAA00"] = codes["brown"] -codes["darkyellow"] = codes["0xAAAA00"] +color_codes["0xAAAA00"] = color_codes["brown"] +color_codes["darkyellow"] = color_codes["0xAAAA00"] -codes["bg_black"] = esc_seq + "40m" -codes["bg_darkred"] = esc_seq + "41m" -codes["bg_darkgreen"] = esc_seq + "42m" -codes["bg_brown"] = esc_seq + "43m" -codes["bg_darkblue"] = esc_seq + "44m" -codes["bg_purple"] = esc_seq + "45m" -codes["bg_teal"] = esc_seq + "46m" -codes["bg_lightgray"] = esc_seq + "47m" -codes["bg_darkyellow"] = codes["bg_brown"] # Colors from /etc/init.d/functions.sh -codes["NORMAL"] = esc_seq + "0m" -codes["GOOD"] = codes["green"] -codes["WARN"] = codes["yellow"] -codes["BAD"] = codes["red"] -codes["HILITE"] = codes["teal"] -codes["BRACKET"] = codes["blue"] +codes["NORMAL"] = [ "normal" ] +codes["GOOD"] = [ "green" ] +codes["WARN"] = [ "yellow" ] +codes["BAD"] = [ "red" ] +codes["HILITE"] = [ "teal" ] +codes["BRACKET"] = [ "blue" ] # Portage functions -codes["INFORM"] = codes["darkgreen"] -codes["UNMERGE_WARN"] = codes["red"] -codes["SECURITY_WARN"] = codes["red"] -codes["MERGE_LIST_PROGRESS"] = codes["yellow"] -codes["PKG_BLOCKER"] = codes["red"] -codes["PKG_BLOCKER_SATISFIED"] = codes["darkblue"] -codes["PKG_MERGE"] = codes["darkgreen"] -codes["PKG_MERGE_SYSTEM"] = codes["darkgreen"] -codes["PKG_MERGE_WORLD"] = codes["green"] -codes["PKG_UNINSTALL"] = codes["red"] -codes["PKG_NOMERGE"] = codes["darkblue"] -codes["PKG_NOMERGE_SYSTEM"] = codes["darkblue"] -codes["PKG_NOMERGE_WORLD"] = codes["blue"] -codes["PROMPT_CHOICE_DEFAULT"] = codes["green"] -codes["PROMPT_CHOICE_OTHER"] = codes["red"] +codes["INFORM"] = [ "darkgreen" ] +codes["UNMERGE_WARN"] = [ "red" ] +codes["SECURITY_WARN"] = [ "red" ] +codes["MERGE_LIST_PROGRESS"] = [ "yellow" ] +codes["PKG_BLOCKER"] = [ "red" ] +codes["PKG_BLOCKER_SATISFIED"] = [ "darkblue" ] +codes["PKG_MERGE"] = [ "darkgreen" ] +codes["PKG_MERGE_SYSTEM"] = [ "darkgreen" ] +codes["PKG_MERGE_WORLD"] = [ "green" ] +codes["PKG_UNINSTALL"] = [ "red" ] +codes["PKG_NOMERGE"] = [ "darkblue" ] +codes["PKG_NOMERGE_SYSTEM"] = [ "darkblue" ] +codes["PKG_NOMERGE_WORLD"] = [ "blue" ] +codes["PROMPT_CHOICE_DEFAULT"] = [ "green" ] +codes["PROMPT_CHOICE_OTHER"] = [ "red" ] -def parse_color_map(onerror=None): +def _parse_color_map(onerror=None): """ Parse /etc/portage/color.map and return a dict of error codes. @@ -183,26 +153,38 @@ token = token[1:-1] return token try: - s = shlex.shlex(open(myfile)) - s.wordchars = s.wordchars + ";" # for ansi codes - while True: - k, o, v = s.get_token(), s.get_token(), s.get_token() - if k is s.eof: - break - if o != "=": - e = ParseError("%s%s'%s'" % ( - s.error_leader(myfile, s.lineno), - "expected '=' operator: ", o)) + lineno=0 + for line in open(COLOR_MAP_FILE): + lineno += 1 + + print "line: ", + print line + commenter_pos = line.find("#") + line = line[:commenter_pos].strip() + print "processed line: '", + print line, + print "'" + + if len(line) == 0: + continue + + split_line = line.split("=") + if len(split_line) != 2: + e = ParseError("'%s', line %s: %s" % ( + myfile, lineno, + "expected exactly one occurence of '=' operator")) + raise e if onerror: onerror(e) else: raise e continue - k = strip_quotes(k, s.quotes) - v = strip_quotes(v, s.quotes) - if not k in codes: - e = ParseError("%s%s'%s'" % ( - s.error_leader(myfile, s.lineno), + + k = strip_quotes(split_line[0].strip(), "\"") + v = strip_quotes(split_line[1].strip(), "\"") + if not k in codes and not k in color_codes: + e = ParseError("'%s', line %s: %s'%s'" % ( + myfile, lineno, "Unknown variable: ", k)) if onerror: onerror(e) @@ -210,21 +192,31 @@ raise e continue if ansi_code_pattern.match(v): - codes[k] = esc_seq + v + if k in codes: + codes[k] = [ esc_seq + v ] + elif k in color_codes: + color_codes[k] = esc_seq + v else: code_list = [] for x in v.split(" "): - if x in codes: - code_list.append(codes[x]) + if x in color_codes: + if k in codes: + code_list.append(x) + elif k in color_codes: + code_list.append(color_codes[x]) else: - e = ParseError("%s%s'%s'" % ( - s.error_leader(myfile, s.lineno), + e = ParseError("'%s', line %s: %s'%s'" % ( + myfile, lineno, "Undefined: ", x)) if onerror: onerror(e) else: raise e - codes[k] = "".join(code_list) + if k in codes: + codes[k] = code_list + print codes[k] + elif k in color_codes: + color_codes[k] = "".join(code_list) except (IOError, OSError), e: if e.errno == errno.ENOENT: raise FileNotFound(myfile) @@ -232,17 +224,6 @@ raise PermissionDenied(myfile) raise -try: - parse_color_map(onerror=lambda e: writemsg("%s\n" % str(e), noiselevel=-1)) -except FileNotFound: - pass -except PermissionDenied, e: - writemsg("Permission denied: '%s'\n" % str(e), noiselevel=-1) - del e -except PortageException, e: - writemsg("%s\n" % str(e), noiselevel=-1) - del e - def nc_len(mystr): tmp = re.sub(esc_seq + "^m]+m", "", mystr); return len(tmp) @@ -308,12 +289,25 @@ havecolor=0 def resetColor(): - return codes["reset"] + return color_codes["reset"] +def map_code_to_color_code(code): + #fix my bad python + ret = "" + for color_code in codes[code]: + if color_code in color_codes: + ret += color_codes[color_code] + return ret + def colorize(color_key, text): global havecolor if havecolor: - return codes[color_key] + text + codes["reset"] + if color_key in color_codes: + return color_codes[color_key] + text + color_codes["reset"] + elif color_key in codes: + return map_code_to_color_code(color_key) + text + color_codes["reset"] + else: + return text else: return text @@ -350,9 +344,9 @@ global havecolor if havecolor and self._styles: for style in self._styles: - self._file.write(codes[style]) + self._file.write(color_codes[style]) self._file.write(s) - self._file.write(codes["reset"]) + self._file.write(color_codes["reset"]) else: self._file.write(s) if self.write_listener: @@ -715,3 +709,14 @@ image = image + "[" + (bar_width * "=") + \ ">" + ((max_bar_width - bar_width) * " ") + "]" return image + +try: + _parse_color_map(onerror=lambda e: writemsg("%s\n" % str(e), noiselevel=-1)) +except FileNotFound: + pass +except PermissionDenied, e: + writemsg("Permission denied: '%s'\n" % str(e), noiselevel=-1) + del e +except PortageException, e: + writemsg("%s\n" % str(e), noiselevel=-1) + del e Index: man/color.map.5 =================================================================== --- man/color.map.5 (revision 13640) +++ man/color.map.5 (working copy) @@ -10,8 +10,13 @@ value defined internally. .SH "SYNTAX" \fBVARIABLE\fR = \fI[space delimited list of attributes]\fR +.TP +\fBATTRIBUTE\fR = \fI[space delimited list of attributes]\fR .SH "VARIABLES" .TP +\fBNORMAL\fR = \fI"normal"\fR +Defines color used for some words occuring in other contexts than those below. +.TP \fBBAD\fR = \fI"red"\fR Defines color used for some words occuring in bad context. .TP @@ -89,10 +94,12 @@ .TP .B green .TP -\fBbrown\fR = \fBdarkyellow\fR +.B brown .TP .B yellow .TP +.B darkyellow +.TP .B darkblue .TP .B blue @@ -103,7 +110,7 @@ .TP .B teal .TP -.B turquoise +\fBturquoise\fR = \fBdarkteal\fR .TP .B lightgray .TP @@ -133,6 +140,10 @@ .B Other attributes .RS .TP +.B normal +.TP +.B no-attr +.TP .B reset .TP .B bold @@ -141,11 +152,25 @@ .TP .B standout .TP +.B no-standout +.TP .B underline .TP +.B no-underline +.TP .B blink .TP +.B no-blink +.TP +.B overline +.TP +.B no-overline +.TP .B reverse +.TP +.B no-reverse +.TP +.B invisible .RE .SH "REPORTING BUGS" Please report bugs via http://bugs.gentoo.org/