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