diff options
author | The Android Open Source Project <initial-contribution@android.com> | 2008-10-21 07:00:00 -0700 |
---|---|---|
committer | The Android Open Source Project <initial-contribution@android.com> | 2008-10-21 07:00:00 -0700 |
commit | cf31fe9b4fb650b27e19f5d7ee7297e383660caf (patch) | |
tree | d04ca6a45d579dca5e5469606c48c405aee68f4b /color.py | |
download | git-repo-cf31fe9b4fb650b27e19f5d7ee7297e383660caf.tar.gz |
Initial Contributionv1.0
Diffstat (limited to 'color.py')
-rw-r--r-- | color.py | 154 |
1 files changed, 154 insertions, 0 deletions
diff --git a/color.py b/color.py new file mode 100644 index 00000000..b3a558cd --- /dev/null +++ b/color.py | |||
@@ -0,0 +1,154 @@ | |||
1 | # | ||
2 | # Copyright (C) 2008 The Android Open Source Project | ||
3 | # | ||
4 | # Licensed under the Apache License, Version 2.0 (the "License"); | ||
5 | # you may not use this file except in compliance with the License. | ||
6 | # You may obtain a copy of the License at | ||
7 | # | ||
8 | # http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | # | ||
10 | # Unless required by applicable law or agreed to in writing, software | ||
11 | # distributed under the License is distributed on an "AS IS" BASIS, | ||
12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
13 | # See the License for the specific language governing permissions and | ||
14 | # limitations under the License. | ||
15 | |||
16 | import os | ||
17 | import sys | ||
18 | |||
19 | import pager | ||
20 | from git_config import GitConfig | ||
21 | |||
22 | COLORS = {None :-1, | ||
23 | 'normal' :-1, | ||
24 | 'black' : 0, | ||
25 | 'red' : 1, | ||
26 | 'green' : 2, | ||
27 | 'yellow' : 3, | ||
28 | 'blue' : 4, | ||
29 | 'magenta': 5, | ||
30 | 'cyan' : 6, | ||
31 | 'white' : 7} | ||
32 | |||
33 | ATTRS = {None :-1, | ||
34 | 'bold' : 1, | ||
35 | 'dim' : 2, | ||
36 | 'ul' : 4, | ||
37 | 'blink' : 5, | ||
38 | 'reverse': 7} | ||
39 | |||
40 | RESET = "\033[m" | ||
41 | |||
42 | def is_color(s): return s in COLORS | ||
43 | def is_attr(s): return s in ATTRS | ||
44 | |||
45 | def _Color(fg = None, bg = None, attr = None): | ||
46 | fg = COLORS[fg] | ||
47 | bg = COLORS[bg] | ||
48 | attr = ATTRS[attr] | ||
49 | |||
50 | if attr >= 0 or fg >= 0 or bg >= 0: | ||
51 | need_sep = False | ||
52 | code = "\033[" | ||
53 | |||
54 | if attr >= 0: | ||
55 | code += chr(ord('0') + attr) | ||
56 | need_sep = True | ||
57 | |||
58 | if fg >= 0: | ||
59 | if need_sep: | ||
60 | code += ';' | ||
61 | need_sep = True | ||
62 | |||
63 | if fg < 8: | ||
64 | code += '3%c' % (ord('0') + fg) | ||
65 | else: | ||
66 | code += '38;5;%d' % fg | ||
67 | |||
68 | if bg >= 0: | ||
69 | if need_sep: | ||
70 | code += ';' | ||
71 | need_sep = True | ||
72 | |||
73 | if bg < 8: | ||
74 | code += '4%c' % (ord('0') + bg) | ||
75 | else: | ||
76 | code += '48;5;%d' % bg | ||
77 | code += 'm' | ||
78 | else: | ||
79 | code = '' | ||
80 | return code | ||
81 | |||
82 | |||
83 | class Coloring(object): | ||
84 | def __init__(self, config, type): | ||
85 | self._section = 'color.%s' % type | ||
86 | self._config = config | ||
87 | self._out = sys.stdout | ||
88 | |||
89 | on = self._config.GetString(self._section) | ||
90 | if on is None: | ||
91 | on = self._config.GetString('color.ui') | ||
92 | |||
93 | if on == 'auto': | ||
94 | if pager.active or os.isatty(1): | ||
95 | self._on = True | ||
96 | else: | ||
97 | self._on = False | ||
98 | elif on in ('true', 'always'): | ||
99 | self._on = True | ||
100 | else: | ||
101 | self._on = False | ||
102 | |||
103 | @property | ||
104 | def is_on(self): | ||
105 | return self._on | ||
106 | |||
107 | def write(self, fmt, *args): | ||
108 | self._out.write(fmt % args) | ||
109 | |||
110 | def nl(self): | ||
111 | self._out.write('\n') | ||
112 | |||
113 | def printer(self, opt=None, fg=None, bg=None, attr=None): | ||
114 | s = self | ||
115 | c = self.colorer(opt, fg, bg, attr) | ||
116 | def f(fmt, *args): | ||
117 | s._out.write(c(fmt, *args)) | ||
118 | return f | ||
119 | |||
120 | def colorer(self, opt=None, fg=None, bg=None, attr=None): | ||
121 | if self._on: | ||
122 | c = self._parse(opt, fg, bg, attr) | ||
123 | def f(fmt, *args): | ||
124 | str = fmt % args | ||
125 | return ''.join([c, str, RESET]) | ||
126 | return f | ||
127 | else: | ||
128 | def f(fmt, *args): | ||
129 | return fmt % args | ||
130 | return f | ||
131 | |||
132 | def _parse(self, opt, fg, bg, attr): | ||
133 | if not opt: | ||
134 | return _Color(fg, bg, attr) | ||
135 | |||
136 | v = self._config.GetString('%s.%s' % (self._section, opt)) | ||
137 | if v is None: | ||
138 | return _Color(fg, bg, attr) | ||
139 | |||
140 | v = v.trim().lowercase() | ||
141 | if v == "reset": | ||
142 | return RESET | ||
143 | elif v == '': | ||
144 | return _Color(fg, bg, attr) | ||
145 | |||
146 | have_fg = False | ||
147 | for a in v.split(' '): | ||
148 | if is_color(a): | ||
149 | if have_fg: bg = a | ||
150 | else: fg = a | ||
151 | elif is_attr(a): | ||
152 | attr = a | ||
153 | |||
154 | return _Color(fg, bg, attr) | ||