##// END OF EJS Templates
Deprecate more complicated way of defining colors. (#14305)...
M Bussonnier -
r28606:5f4d6acd merge
parent child Browse files
Show More
@@ -1,210 +1,221 b''
1 1 """Tools for coloring text in ANSI terminals.
2 2 """
3 3
4 4 #*****************************************************************************
5 5 # Copyright (C) 2002-2006 Fernando Perez. <fperez@colorado.edu>
6 6 #
7 7 # Distributed under the terms of the BSD License. The full license is in
8 8 # the file COPYING, distributed as part of this software.
9 9 #*****************************************************************************
10 10
11 11
12 12 import os
13 import warnings
13 14
14 15 from IPython.utils.ipstruct import Struct
15 16
16 17 __all__ = ["TermColors", "InputTermColors", "ColorScheme", "ColorSchemeTable"]
17 18
18 19 _sentinel = object()
19 20
20 21 color_templates = (
21 22 # Dark colors
22 23 ("Black" , "0;30"),
23 24 ("Red" , "0;31"),
24 25 ("Green" , "0;32"),
25 26 ("Brown" , "0;33"),
26 27 ("Blue" , "0;34"),
27 28 ("Purple" , "0;35"),
28 29 ("Cyan" , "0;36"),
29 30 ("LightGray" , "0;37"),
30 31 # Light colors
31 32 ("DarkGray" , "1;30"),
32 33 ("LightRed" , "1;31"),
33 34 ("LightGreen" , "1;32"),
34 35 ("Yellow" , "1;33"),
35 36 ("LightBlue" , "1;34"),
36 37 ("LightPurple" , "1;35"),
37 38 ("LightCyan" , "1;36"),
38 39 ("White" , "1;37"),
39 40 # Blinking colors. Probably should not be used in anything serious.
40 41 ("BlinkBlack" , "5;30"),
41 42 ("BlinkRed" , "5;31"),
42 43 ("BlinkGreen" , "5;32"),
43 44 ("BlinkYellow" , "5;33"),
44 45 ("BlinkBlue" , "5;34"),
45 46 ("BlinkPurple" , "5;35"),
46 47 ("BlinkCyan" , "5;36"),
47 48 ("BlinkLightGray", "5;37"),
48 49 )
49 50
50 51 def make_color_table(in_class):
51 52 """Build a set of color attributes in a class.
52 53
53 54 Helper function for building the :class:`TermColors` and
54 55 :class`InputTermColors`.
55 56 """
56 57 for name,value in color_templates:
57 58 setattr(in_class,name,in_class._base % value)
58 59
59 60 class TermColors:
60 61 """Color escape sequences.
61 62
62 63 This class defines the escape sequences for all the standard (ANSI?)
63 64 colors in terminals. Also defines a NoColor escape which is just the null
64 65 string, suitable for defining 'dummy' color schemes in terminals which get
65 66 confused by color escapes.
66 67
67 68 This class should be used as a mixin for building color schemes."""
68 69
69 70 NoColor = '' # for color schemes in color-less terminals.
70 71 Normal = '\033[0m' # Reset normal coloring
71 72 _base = '\033[%sm' # Template for all other colors
72 73
73 74 # Build the actual color table as a set of class attributes:
74 75 make_color_table(TermColors)
75 76
76 77 class InputTermColors:
77 78 """Color escape sequences for input prompts.
78 79
79 80 This class is similar to TermColors, but the escapes are wrapped in \\001
80 81 and \\002 so that readline can properly know the length of each line and
81 82 can wrap lines accordingly. Use this class for any colored text which
82 83 needs to be used in input prompts, such as in calls to raw_input().
83 84
84 85 This class defines the escape sequences for all the standard (ANSI?)
85 86 colors in terminals. Also defines a NoColor escape which is just the null
86 87 string, suitable for defining 'dummy' color schemes in terminals which get
87 88 confused by color escapes.
88 89
89 90 This class should be used as a mixin for building color schemes."""
90 91
91 92 NoColor = '' # for color schemes in color-less terminals.
92 93
93 94 if os.name == 'nt' and os.environ.get('TERM','dumb') == 'emacs':
94 95 # (X)emacs on W32 gets confused with \001 and \002 so we remove them
95 96 Normal = '\033[0m' # Reset normal coloring
96 97 _base = '\033[%sm' # Template for all other colors
97 98 else:
98 99 Normal = '\001\033[0m\002' # Reset normal coloring
99 100 _base = '\001\033[%sm\002' # Template for all other colors
100 101
101 102 # Build the actual color table as a set of class attributes:
102 103 make_color_table(InputTermColors)
103 104
104 105 class NoColors:
105 106 """This defines all the same names as the colour classes, but maps them to
106 107 empty strings, so it can easily be substituted to turn off colours."""
107 108 NoColor = ''
108 109 Normal = ''
109 110
110 111 for name, value in color_templates:
111 112 setattr(NoColors, name, '')
112 113
113 114 class ColorScheme:
114 115 """Generic color scheme class. Just a name and a Struct."""
115 116
116 117 name: str
117 118 colors: Struct
118 119
119 def __init__(self,__scheme_name_,colordict=None,**colormap):
120 def __init__(self, __scheme_name_, colordict=None, **colormap):
120 121 self.name = __scheme_name_
122 if colormap:
123 warnings.warn(
124 "Passing each colors as a kwarg to ColorScheme is "
125 "considered for deprecation. Please pass a "
126 "a single dict as second parameter. If you are using this"
127 "feature, please comment an subscribe to issue "
128 "https://github.com/ipython/ipython/issues/14304",
129 PendingDeprecationWarning,
130 stacklevel=2,
131 )
121 132 if colordict is None:
122 133 self.colors = Struct(**colormap)
123 134 else:
124 135 self.colors = Struct(colordict)
125 136
126 137 def copy(self,name=None):
127 138 """Return a full copy of the object, optionally renaming it."""
128 139 if name is None:
129 140 name = self.name
130 141 return ColorScheme(name, self.colors.dict())
131 142
132 143 class ColorSchemeTable(dict):
133 144 """General class to handle tables of color schemes.
134 145
135 146 It's basically a dict of color schemes with a couple of shorthand
136 147 attributes and some convenient methods.
137 148
138 149 active_scheme_name -> obvious
139 150 active_colors -> actual color table of the active scheme"""
140 151
141 152 def __init__(self, scheme_list=None, default_scheme=''):
142 153 """Create a table of color schemes.
143 154
144 155 The table can be created empty and manually filled or it can be
145 156 created with a list of valid color schemes AND the specification for
146 157 the default active scheme.
147 158 """
148 159
149 160 # create object attributes to be set later
150 161 self.active_scheme_name = ''
151 162 self.active_colors = None
152 163
153 164 if scheme_list:
154 165 if default_scheme == '':
155 166 raise ValueError('you must specify the default color scheme')
156 167 for scheme in scheme_list:
157 168 self.add_scheme(scheme)
158 169 self.set_active_scheme(default_scheme)
159 170
160 171 def copy(self):
161 172 """Return full copy of object"""
162 173 return ColorSchemeTable(self.values(),self.active_scheme_name)
163 174
164 175 def __setitem__(self, key: str, value: ColorScheme):
165 176 assert isinstance(key, str)
166 177 assert isinstance(value, ColorScheme)
167 178 super().__setitem__(key, value)
168 179
169 180 def add_scheme(self, new_scheme):
170 181 """Add a new color scheme to the table."""
171 182 if not isinstance(new_scheme, ColorScheme):
172 183 raise ValueError('ColorSchemeTable only accepts ColorScheme instances')
173 184 self[new_scheme.name] = new_scheme
174 185
175 186 def set_active_scheme(self, scheme, case_sensitive=_sentinel):
176 187 """Set the currently active scheme.
177 188
178 189 Names are by default compared in a case-insensitive way, but this can
179 190 be changed by setting the parameter case_sensitive to true."""
180 191
181 192 if case_sensitive is _sentinel:
182 193 case_sensitive = False
183 194 else:
184 195 warnings.warn(
185 196 "set_active_scheme(case_sensitive=...) is Pending "
186 197 "deprecation. Please comment on "
187 198 "https://github.com/ipython/ipython/issues/14306 "
188 199 "to let the ipython maintainer that you are affected.",
189 200 PendingDeprecationWarning,
190 201 stacklevel=2,
191 202 )
192 203
193 204 scheme_names = list(self.keys())
194 205 if case_sensitive:
195 206 valid_schemes = scheme_names
196 207 scheme_test = scheme
197 208 else:
198 209 valid_schemes = [s.lower() for s in scheme_names]
199 210 scheme_test = scheme.lower()
200 211 try:
201 212 scheme_idx = valid_schemes.index(scheme_test)
202 213 except ValueError as e:
203 214 raise ValueError('Unrecognized color scheme: ' + scheme + \
204 215 '\nValid schemes: '+str(scheme_names).replace("'', ",'')) from e
205 216 else:
206 217 active = scheme_names[scheme_idx]
207 218 self.active_scheme_name = active
208 219 self.active_colors = self[active].colors
209 220 # Now allow using '' as an index for the current active scheme
210 221 self[''] = self[active]
General Comments 0
You need to be logged in to leave comments. Login now