##// END OF EJS Templates
Use \T for timestamp in templates to distinguish it from \t = <tab>
Thomas Kluyver -
Show More
@@ -1,378 +1,378 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2 """Classes for handling input/output prompts.
2 """Classes for handling input/output prompts.
3
3
4 Authors:
4 Authors:
5
5
6 * Fernando Perez
6 * Fernando Perez
7 * Brian Granger
7 * Brian Granger
8 * Thomas Kluyver
8 * Thomas Kluyver
9 """
9 """
10
10
11 #-----------------------------------------------------------------------------
11 #-----------------------------------------------------------------------------
12 # Copyright (C) 2008-2011 The IPython Development Team
12 # Copyright (C) 2008-2011 The IPython Development Team
13 # Copyright (C) 2001-2007 Fernando Perez <fperez@colorado.edu>
13 # Copyright (C) 2001-2007 Fernando Perez <fperez@colorado.edu>
14 #
14 #
15 # Distributed under the terms of the BSD License. The full license is in
15 # Distributed under the terms of the BSD License. The full license is in
16 # the file COPYING, distributed as part of this software.
16 # the file COPYING, distributed as part of this software.
17 #-----------------------------------------------------------------------------
17 #-----------------------------------------------------------------------------
18
18
19 #-----------------------------------------------------------------------------
19 #-----------------------------------------------------------------------------
20 # Imports
20 # Imports
21 #-----------------------------------------------------------------------------
21 #-----------------------------------------------------------------------------
22
22
23 import os
23 import os
24 import re
24 import re
25 import socket
25 import socket
26 import sys
26 import sys
27 import time
27 import time
28
28
29 from IPython.config.configurable import Configurable
29 from IPython.config.configurable import Configurable
30 from IPython.core import release
30 from IPython.core import release
31 from IPython.utils import coloransi
31 from IPython.utils import coloransi
32 from IPython.utils.traitlets import (Unicode, Instance, Dict, Bool, Int)
32 from IPython.utils.traitlets import (Unicode, Instance, Dict, Bool, Int)
33
33
34 #-----------------------------------------------------------------------------
34 #-----------------------------------------------------------------------------
35 # Color schemes for prompts
35 # Color schemes for prompts
36 #-----------------------------------------------------------------------------
36 #-----------------------------------------------------------------------------
37
37
38 InputColors = coloransi.InputTermColors # just a shorthand
38 InputColors = coloransi.InputTermColors # just a shorthand
39 Colors = coloransi.TermColors # just a shorthand
39 Colors = coloransi.TermColors # just a shorthand
40
40
41 color_lists = dict(normal=Colors(), inp=InputColors(), nocolor=coloransi.NoColors())
41 color_lists = dict(normal=Colors(), inp=InputColors(), nocolor=coloransi.NoColors())
42
42
43 PColNoColors = coloransi.ColorScheme(
43 PColNoColors = coloransi.ColorScheme(
44 'NoColor',
44 'NoColor',
45 in_prompt = InputColors.NoColor, # Input prompt
45 in_prompt = InputColors.NoColor, # Input prompt
46 in_number = InputColors.NoColor, # Input prompt number
46 in_number = InputColors.NoColor, # Input prompt number
47 in_prompt2 = InputColors.NoColor, # Continuation prompt
47 in_prompt2 = InputColors.NoColor, # Continuation prompt
48 in_normal = InputColors.NoColor, # color off (usu. Colors.Normal)
48 in_normal = InputColors.NoColor, # color off (usu. Colors.Normal)
49
49
50 out_prompt = Colors.NoColor, # Output prompt
50 out_prompt = Colors.NoColor, # Output prompt
51 out_number = Colors.NoColor, # Output prompt number
51 out_number = Colors.NoColor, # Output prompt number
52
52
53 normal = Colors.NoColor # color off (usu. Colors.Normal)
53 normal = Colors.NoColor # color off (usu. Colors.Normal)
54 )
54 )
55
55
56 # make some schemes as instances so we can copy them for modification easily:
56 # make some schemes as instances so we can copy them for modification easily:
57 PColLinux = coloransi.ColorScheme(
57 PColLinux = coloransi.ColorScheme(
58 'Linux',
58 'Linux',
59 in_prompt = InputColors.Green,
59 in_prompt = InputColors.Green,
60 in_number = InputColors.LightGreen,
60 in_number = InputColors.LightGreen,
61 in_prompt2 = InputColors.Green,
61 in_prompt2 = InputColors.Green,
62 in_normal = InputColors.Normal, # color off (usu. Colors.Normal)
62 in_normal = InputColors.Normal, # color off (usu. Colors.Normal)
63
63
64 out_prompt = Colors.Red,
64 out_prompt = Colors.Red,
65 out_number = Colors.LightRed,
65 out_number = Colors.LightRed,
66
66
67 normal = Colors.Normal
67 normal = Colors.Normal
68 )
68 )
69
69
70 # Slightly modified Linux for light backgrounds
70 # Slightly modified Linux for light backgrounds
71 PColLightBG = PColLinux.copy('LightBG')
71 PColLightBG = PColLinux.copy('LightBG')
72
72
73 PColLightBG.colors.update(
73 PColLightBG.colors.update(
74 in_prompt = InputColors.Blue,
74 in_prompt = InputColors.Blue,
75 in_number = InputColors.LightBlue,
75 in_number = InputColors.LightBlue,
76 in_prompt2 = InputColors.Blue
76 in_prompt2 = InputColors.Blue
77 )
77 )
78
78
79 #-----------------------------------------------------------------------------
79 #-----------------------------------------------------------------------------
80 # Utilities
80 # Utilities
81 #-----------------------------------------------------------------------------
81 #-----------------------------------------------------------------------------
82
82
83 class LazyEvaluate(object):
83 class LazyEvaluate(object):
84 """This is used for formatting strings with values that need to be updated
84 """This is used for formatting strings with values that need to be updated
85 at that time, such as the current time or working directory."""
85 at that time, such as the current time or working directory."""
86 def __init__(self, func, *args, **kwargs):
86 def __init__(self, func, *args, **kwargs):
87 self.func = func
87 self.func = func
88 self.args = args
88 self.args = args
89 self.kwargs = kwargs
89 self.kwargs = kwargs
90
90
91 def __call__(self, **kwargs):
91 def __call__(self, **kwargs):
92 self.kwargs.update(kwargs)
92 self.kwargs.update(kwargs)
93 return self.func(*self.args, **self.kwargs)
93 return self.func(*self.args, **self.kwargs)
94
94
95 def __str__(self):
95 def __str__(self):
96 return str(self())
96 return str(self())
97
97
98 def multiple_replace(dict, text):
98 def multiple_replace(dict, text):
99 """ Replace in 'text' all occurences of any key in the given
99 """ Replace in 'text' all occurences of any key in the given
100 dictionary by its corresponding value. Returns the new string."""
100 dictionary by its corresponding value. Returns the new string."""
101
101
102 # Function by Xavier Defrang, originally found at:
102 # Function by Xavier Defrang, originally found at:
103 # http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/81330
103 # http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/81330
104
104
105 # Create a regular expression from the dictionary keys
105 # Create a regular expression from the dictionary keys
106 regex = re.compile("(%s)" % "|".join(map(re.escape, dict.keys())))
106 regex = re.compile("(%s)" % "|".join(map(re.escape, dict.keys())))
107 # For each match, look-up corresponding value in dictionary
107 # For each match, look-up corresponding value in dictionary
108 return regex.sub(lambda mo: dict[mo.string[mo.start():mo.end()]], text)
108 return regex.sub(lambda mo: dict[mo.string[mo.start():mo.end()]], text)
109
109
110 #-----------------------------------------------------------------------------
110 #-----------------------------------------------------------------------------
111 # Special characters that can be used in prompt templates, mainly bash-like
111 # Special characters that can be used in prompt templates, mainly bash-like
112 #-----------------------------------------------------------------------------
112 #-----------------------------------------------------------------------------
113
113
114 # If $HOME isn't defined (Windows), make it an absurd string so that it can
114 # If $HOME isn't defined (Windows), make it an absurd string so that it can
115 # never be expanded out into '~'. Basically anything which can never be a
115 # never be expanded out into '~'. Basically anything which can never be a
116 # reasonable directory name will do, we just want the $HOME -> '~' operation
116 # reasonable directory name will do, we just want the $HOME -> '~' operation
117 # to become a no-op. We pre-compute $HOME here so it's not done on every
117 # to become a no-op. We pre-compute $HOME here so it's not done on every
118 # prompt call.
118 # prompt call.
119
119
120 # FIXME:
120 # FIXME:
121
121
122 # - This should be turned into a class which does proper namespace management,
122 # - This should be turned into a class which does proper namespace management,
123 # since the prompt specials need to be evaluated in a certain namespace.
123 # since the prompt specials need to be evaluated in a certain namespace.
124 # Currently it's just globals, which need to be managed manually by code
124 # Currently it's just globals, which need to be managed manually by code
125 # below.
125 # below.
126
126
127 # - I also need to split up the color schemes from the prompt specials
127 # - I also need to split up the color schemes from the prompt specials
128 # somehow. I don't have a clean design for that quite yet.
128 # somehow. I don't have a clean design for that quite yet.
129
129
130 HOME = os.environ.get("HOME","//////:::::ZZZZZ,,,~~~")
130 HOME = os.environ.get("HOME","//////:::::ZZZZZ,,,~~~")
131
131
132 # We precompute a few more strings here for the prompt_specials, which are
132 # We precompute a few more strings here for the prompt_specials, which are
133 # fixed once ipython starts. This reduces the runtime overhead of computing
133 # fixed once ipython starts. This reduces the runtime overhead of computing
134 # prompt strings.
134 # prompt strings.
135 USER = os.environ.get("USER")
135 USER = os.environ.get("USER")
136 HOSTNAME = socket.gethostname()
136 HOSTNAME = socket.gethostname()
137 HOSTNAME_SHORT = HOSTNAME.split(".")[0]
137 HOSTNAME_SHORT = HOSTNAME.split(".")[0]
138 ROOT_SYMBOL = "#" if (os.name=='nt' or os.getuid()==0) else "$"
138 ROOT_SYMBOL = "#" if (os.name=='nt' or os.getuid()==0) else "$"
139
139
140 prompt_abbreviations = {
140 prompt_abbreviations = {
141 # Prompt/history count
141 # Prompt/history count
142 '%n' : '{color.number}' '{count}' '{color.prompt}',
142 '%n' : '{color.number}' '{count}' '{color.prompt}',
143 r'\#': '{color.number}' '{count}' '{color.prompt}',
143 r'\#': '{color.number}' '{count}' '{color.prompt}',
144 # Just the prompt counter number, WITHOUT any coloring wrappers, so users
144 # Just the prompt counter number, WITHOUT any coloring wrappers, so users
145 # can get numbers displayed in whatever color they want.
145 # can get numbers displayed in whatever color they want.
146 r'\N': '{count}',
146 r'\N': '{count}',
147
147
148 # Prompt/history count, with the actual digits replaced by dots. Used
148 # Prompt/history count, with the actual digits replaced by dots. Used
149 # mainly in continuation prompts (prompt_in2)
149 # mainly in continuation prompts (prompt_in2)
150 r'\D': '{dots}',
150 r'\D': '{dots}',
151
151
152 # Current time
152 # Current time
153 r'\t' : '{time}',
153 r'\T' : '{time}',
154 # Current working directory
154 # Current working directory
155 r'\w': '{cwd}',
155 r'\w': '{cwd}',
156 # Basename of current working directory.
156 # Basename of current working directory.
157 # (use os.sep to make this portable across OSes)
157 # (use os.sep to make this portable across OSes)
158 r'\W' : '{cwd_last}',
158 r'\W' : '{cwd_last}',
159 # These X<N> are an extension to the normal bash prompts. They return
159 # These X<N> are an extension to the normal bash prompts. They return
160 # N terms of the path, after replacing $HOME with '~'
160 # N terms of the path, after replacing $HOME with '~'
161 r'\X0': '{cwd_x[0])}',
161 r'\X0': '{cwd_x[0])}',
162 r'\X1': '{cwd_x[1])}',
162 r'\X1': '{cwd_x[1])}',
163 r'\X2': '{cwd_x[2])}',
163 r'\X2': '{cwd_x[2])}',
164 r'\X3': '{cwd_x[3])}',
164 r'\X3': '{cwd_x[3])}',
165 r'\X4': '{cwd_x[4])}',
165 r'\X4': '{cwd_x[4])}',
166 r'\X5': '{cwd_x[5])}',
166 r'\X5': '{cwd_x[5])}',
167 # Y<N> are similar to X<N>, but they show '~' if it's the directory
167 # Y<N> are similar to X<N>, but they show '~' if it's the directory
168 # N+1 in the list. Somewhat like %cN in tcsh.
168 # N+1 in the list. Somewhat like %cN in tcsh.
169 r'\Y0': '{cwd_y[0])}',
169 r'\Y0': '{cwd_y[0])}',
170 r'\Y1': '{cwd_y[1])}',
170 r'\Y1': '{cwd_y[1])}',
171 r'\Y2': '{cwd_y[2])}',
171 r'\Y2': '{cwd_y[2])}',
172 r'\Y3': '{cwd_y[3])}',
172 r'\Y3': '{cwd_y[3])}',
173 r'\Y4': '{cwd_y[4])}',
173 r'\Y4': '{cwd_y[4])}',
174 r'\Y5': '{cwd_y[5])}',
174 r'\Y5': '{cwd_y[5])}',
175 # Hostname up to first .
175 # Hostname up to first .
176 r'\h': HOSTNAME_SHORT,
176 r'\h': HOSTNAME_SHORT,
177 # Full hostname
177 # Full hostname
178 r'\H': HOSTNAME,
178 r'\H': HOSTNAME,
179 # Username of current user
179 # Username of current user
180 r'\u': USER,
180 r'\u': USER,
181 # Escaped '\'
181 # Escaped '\'
182 '\\\\': '\\',
182 '\\\\': '\\',
183 # Newline
183 # Newline
184 r'\n': '\n',
184 r'\n': '\n',
185 # Carriage return
185 # Carriage return
186 r'\r': '\r',
186 r'\r': '\r',
187 # Release version
187 # Release version
188 r'\v': release.version,
188 r'\v': release.version,
189 # Root symbol ($ or #)
189 # Root symbol ($ or #)
190 r'\$': ROOT_SYMBOL,
190 r'\$': ROOT_SYMBOL,
191 }
191 }
192
192
193 #-----------------------------------------------------------------------------
193 #-----------------------------------------------------------------------------
194 # More utilities
194 # More utilities
195 #-----------------------------------------------------------------------------
195 #-----------------------------------------------------------------------------
196
196
197 def cwd_filt(self, depth):
197 def cwd_filt(self, depth):
198 """Return the last depth elements of the current working directory.
198 """Return the last depth elements of the current working directory.
199
199
200 $HOME is always replaced with '~'.
200 $HOME is always replaced with '~'.
201 If depth==0, the full path is returned."""
201 If depth==0, the full path is returned."""
202
202
203 cwd = os.getcwd().replace(HOME,"~")
203 cwd = os.getcwd().replace(HOME,"~")
204 out = os.sep.join(cwd.split(os.sep)[-depth:])
204 out = os.sep.join(cwd.split(os.sep)[-depth:])
205 return out or os.sep
205 return out or os.sep
206
206
207 def cwd_filt2(self, depth):
207 def cwd_filt2(self, depth):
208 """Return the last depth elements of the current working directory.
208 """Return the last depth elements of the current working directory.
209
209
210 $HOME is always replaced with '~'.
210 $HOME is always replaced with '~'.
211 If depth==0, the full path is returned."""
211 If depth==0, the full path is returned."""
212
212
213 full_cwd = os.getcwd()
213 full_cwd = os.getcwd()
214 cwd = full_cwd.replace(HOME,"~").split(os.sep)
214 cwd = full_cwd.replace(HOME,"~").split(os.sep)
215 if '~' in cwd and len(cwd) == depth+1:
215 if '~' in cwd and len(cwd) == depth+1:
216 depth += 1
216 depth += 1
217 drivepart = ''
217 drivepart = ''
218 if sys.platform == 'win32' and len(cwd) > depth:
218 if sys.platform == 'win32' and len(cwd) > depth:
219 drivepart = os.path.splitdrive(full_cwd)[0]
219 drivepart = os.path.splitdrive(full_cwd)[0]
220 out = drivepart + '/'.join(cwd[-depth:])
220 out = drivepart + '/'.join(cwd[-depth:])
221
221
222 return out or os.sep
222 return out or os.sep
223
223
224 #-----------------------------------------------------------------------------
224 #-----------------------------------------------------------------------------
225 # Prompt classes
225 # Prompt classes
226 #-----------------------------------------------------------------------------
226 #-----------------------------------------------------------------------------
227
227
228 lazily_evaluate = {'time': LazyEvaluate(time.strftime, "%H:%M:%S"),
228 lazily_evaluate = {'time': LazyEvaluate(time.strftime, "%H:%M:%S"),
229 'cwd': LazyEvaluate(os.getcwd),
229 'cwd': LazyEvaluate(os.getcwd),
230 'cwd_last': LazyEvaluate(lambda: os.getcwd().split(os.sep)[-1]),
230 'cwd_last': LazyEvaluate(lambda: os.getcwd().split(os.sep)[-1]),
231 'cwd_x': [LazyEvaluate(lambda: os.getcwd().replace("%s","~"))] +\
231 'cwd_x': [LazyEvaluate(lambda: os.getcwd().replace("%s","~"))] +\
232 [LazyEvaluate(cwd_filt, x) for x in range(1,6)],
232 [LazyEvaluate(cwd_filt, x) for x in range(1,6)],
233 'cwd_y': [LazyEvaluate(cwd_filt2, x) for x in range(6)]
233 'cwd_y': [LazyEvaluate(cwd_filt2, x) for x in range(6)]
234 }
234 }
235
235
236
236
237 class PromptManager(Configurable):
237 class PromptManager(Configurable):
238 """This is the primary interface for producing IPython's prompts."""
238 """This is the primary interface for producing IPython's prompts."""
239 shell = Instance('IPython.core.interactiveshell.InteractiveShellABC')
239 shell = Instance('IPython.core.interactiveshell.InteractiveShellABC')
240
240
241 color_scheme_table = Instance(coloransi.ColorSchemeTable)
241 color_scheme_table = Instance(coloransi.ColorSchemeTable)
242 color_scheme = Unicode('Linux', config=True)
242 color_scheme = Unicode('Linux', config=True)
243 def _color_scheme_changed(self, name, new_value):
243 def _color_scheme_changed(self, name, new_value):
244 self.color_scheme_table.set_active_scheme(new_value)
244 self.color_scheme_table.set_active_scheme(new_value)
245 for pname in ['in', 'in2', 'out', 'rewrite']:
245 for pname in ['in', 'in2', 'out', 'rewrite']:
246 # We need to recalculate the number of invisible characters
246 # We need to recalculate the number of invisible characters
247 self.update_prompt(pname)
247 self.update_prompt(pname)
248
248
249 lazy_evaluate_fields = Dict(help="""
249 lazy_evaluate_fields = Dict(help="""
250 This maps field names used in the prompt templates to functions which
250 This maps field names used in the prompt templates to functions which
251 will be called when the prompt is rendered. This allows us to include
251 will be called when the prompt is rendered. This allows us to include
252 things like the current time in the prompts. Functions are only called
252 things like the current time in the prompts. Functions are only called
253 if they are used in the prompt.
253 if they are used in the prompt.
254 """)
254 """)
255 def _lazy_evaluate_fields_default(self): return lazily_evaluate.copy()
255 def _lazy_evaluate_fields_default(self): return lazily_evaluate.copy()
256
256
257 in_template = Unicode('In [\\#]: ', config=True)
257 in_template = Unicode('In [\\#]: ', config=True)
258 in2_template = Unicode(' .\\D.: ', config=True)
258 in2_template = Unicode(' .\\D.: ', config=True)
259 out_template = Unicode('Out[\\#]: ', config=True)
259 out_template = Unicode('Out[\\#]: ', config=True)
260 rewrite_template = Unicode("------> ", config=True)
260 rewrite_template = Unicode("------> ", config=True)
261
261
262 justify = Bool(True, config=True, help="""
262 justify = Bool(True, config=True, help="""
263 If True (default), each prompt will be right-aligned with the
263 If True (default), each prompt will be right-aligned with the
264 preceding one.
264 preceding one.
265 """)
265 """)
266
266
267 # We actually store the expanded templates here:
267 # We actually store the expanded templates here:
268 templates = Dict()
268 templates = Dict()
269
269
270 # The number of characters in the last prompt rendered, not including
270 # The number of characters in the last prompt rendered, not including
271 # colour characters.
271 # colour characters.
272 width = Int()
272 width = Int()
273
273
274 # The number of characters in each prompt which don't contribute to width
274 # The number of characters in each prompt which don't contribute to width
275 invisible_chars = Dict()
275 invisible_chars = Dict()
276 def _invisible_chars_default(self):
276 def _invisible_chars_default(self):
277 return {'in': 0, 'in2': 0, 'out': 0, 'rewrite': 0}
277 return {'in': 0, 'in2': 0, 'out': 0, 'rewrite': 0}
278
278
279 def __init__(self, shell, config=None):
279 def __init__(self, shell, config=None):
280 super(PromptManager, self).__init__(shell=shell, config=config)
280 super(PromptManager, self).__init__(shell=shell, config=config)
281
281
282 # Prepare colour scheme table
282 # Prepare colour scheme table
283 self.color_scheme_table = coloransi.ColorSchemeTable([PColNoColors,
283 self.color_scheme_table = coloransi.ColorSchemeTable([PColNoColors,
284 PColLinux, PColLightBG], self.color_scheme)
284 PColLinux, PColLightBG], self.color_scheme)
285
285
286 # Prepare templates
286 # Prepare templates
287 self.update_prompt('in', self.in_template)
287 self.update_prompt('in', self.in_template)
288 self.update_prompt('in2', self.in2_template)
288 self.update_prompt('in2', self.in2_template)
289 self.update_prompt('out', self.out_template)
289 self.update_prompt('out', self.out_template)
290 self.update_prompt('rewrite', self.rewrite_template)
290 self.update_prompt('rewrite', self.rewrite_template)
291 self.on_trait_change(self._update_prompt_trait, ['in_template',
291 self.on_trait_change(self._update_prompt_trait, ['in_template',
292 'in2_template', 'out_template', 'rewrite_template'])
292 'in2_template', 'out_template', 'rewrite_template'])
293
293
294 def update_prompt(self, name, new_template=None):
294 def update_prompt(self, name, new_template=None):
295 """This is called when a prompt template is updated. It processes
295 """This is called when a prompt template is updated. It processes
296 abbreviations used in the prompt template (like \#) and calculates how
296 abbreviations used in the prompt template (like \#) and calculates how
297 many invisible characters (ANSI colour escapes) the resulting prompt
297 many invisible characters (ANSI colour escapes) the resulting prompt
298 contains.
298 contains.
299
299
300 It is also called for each prompt on changing the colour scheme. In both
300 It is also called for each prompt on changing the colour scheme. In both
301 cases, traitlets should take care of calling this automatically.
301 cases, traitlets should take care of calling this automatically.
302 """
302 """
303 if new_template is not None:
303 if new_template is not None:
304 self.templates[name] = multiple_replace(prompt_abbreviations, new_template)
304 self.templates[name] = multiple_replace(prompt_abbreviations, new_template)
305 invis_chars = len(self.render(name, color=True, just=False)) - \
305 invis_chars = len(self.render(name, color=True, just=False)) - \
306 len(self.render(name, color=False, just=False))
306 len(self.render(name, color=False, just=False))
307 self.invisible_chars[name] = invis_chars
307 self.invisible_chars[name] = invis_chars
308
308
309 def _update_prompt_trait(self, traitname, new_template):
309 def _update_prompt_trait(self, traitname, new_template):
310 name = traitname[:-9] # Cut off '_template'
310 name = traitname[:-9] # Cut off '_template'
311 self.update_prompt(name, new_template)
311 self.update_prompt(name, new_template)
312
312
313 def render(self, name, color=True, just=None, **kwargs):
313 def render(self, name, color=True, just=None, **kwargs):
314 """
314 """
315 Render the selected prompt.
315 Render the selected prompt.
316
316
317 Parameters
317 Parameters
318 ----------
318 ----------
319 name : str
319 name : str
320 Which prompt to render. One of 'in', 'in2', 'out', 'rewrite'
320 Which prompt to render. One of 'in', 'in2', 'out', 'rewrite'
321 color : bool
321 color : bool
322 If True (default), include ANSI escape sequences for a coloured prompt.
322 If True (default), include ANSI escape sequences for a coloured prompt.
323 just : bool
323 just : bool
324 If True, justify the prompt to the width of the last prompt. The
324 If True, justify the prompt to the width of the last prompt. The
325 default is stored in self.justify.
325 default is stored in self.justify.
326 **kwargs :
326 **kwargs :
327 Additional arguments will be passed to the string formatting operation,
327 Additional arguments will be passed to the string formatting operation,
328 so they can override the values that would otherwise fill in the
328 so they can override the values that would otherwise fill in the
329 template.
329 template.
330
330
331 Returns
331 Returns
332 -------
332 -------
333 A string containing the rendered prompt.
333 A string containing the rendered prompt.
334 """
334 """
335 if color:
335 if color:
336 scheme = self.color_scheme_table.active_colors
336 scheme = self.color_scheme_table.active_colors
337 if name=='out':
337 if name=='out':
338 colors = color_lists['normal']
338 colors = color_lists['normal']
339 colors.number, colors.prompt, colors.normal = \
339 colors.number, colors.prompt, colors.normal = \
340 scheme.out_number, scheme.out_prompt, scheme.normal
340 scheme.out_number, scheme.out_prompt, scheme.normal
341 elif name=='rewrite':
341 elif name=='rewrite':
342 colors = color_lists['normal']
342 colors = color_lists['normal']
343 # We need a non-input version of these escapes
343 # We need a non-input version of these escapes
344 colors.number = scheme.in_number.replace("\001","").replace("\002","")
344 colors.number = scheme.in_number.replace("\001","").replace("\002","")
345 colors.prompt = scheme.in_prompt.replace("\001","").replace("\002","")
345 colors.prompt = scheme.in_prompt.replace("\001","").replace("\002","")
346 colors.normal = scheme.normal
346 colors.normal = scheme.normal
347 else:
347 else:
348 colors = color_lists['inp']
348 colors = color_lists['inp']
349 colors.number, colors.prompt, colors.normal = \
349 colors.number, colors.prompt, colors.normal = \
350 scheme.in_number, scheme.in_prompt, scheme.in_normal
350 scheme.in_number, scheme.in_prompt, scheme.in_normal
351 if name=='in2':
351 if name=='in2':
352 colors.prompt = scheme.in_prompt2
352 colors.prompt = scheme.in_prompt2
353 else:
353 else:
354 # No color
354 # No color
355 colors = color_lists['nocolor']
355 colors = color_lists['nocolor']
356 colors.number, colors.prompt, colors.normal = '', '', ''
356 colors.number, colors.prompt, colors.normal = '', '', ''
357
357
358 count = self.shell.execution_count # Shorthand
358 count = self.shell.execution_count # Shorthand
359 # Build the dictionary to be passed to string formatting
359 # Build the dictionary to be passed to string formatting
360 fmtargs = dict(color=colors, count=count,
360 fmtargs = dict(color=colors, count=count,
361 dots="."*len(str(count)) )
361 dots="."*len(str(count)) )
362 fmtargs.update(self.lazy_evaluate_fields)
362 fmtargs.update(self.lazy_evaluate_fields)
363 fmtargs.update(kwargs)
363 fmtargs.update(kwargs)
364
364
365 # Prepare the prompt
365 # Prepare the prompt
366 prompt = colors.prompt + self.templates[name] + colors.normal
366 prompt = colors.prompt + self.templates[name] + colors.normal
367
367
368 # Fill in required fields
368 # Fill in required fields
369 res = prompt.format(**fmtargs)
369 res = prompt.format(**fmtargs)
370
370
371 # Handle justification of prompt
371 # Handle justification of prompt
372 invis_chars = self.invisible_chars[name] if color else 0
372 invis_chars = self.invisible_chars[name] if color else 0
373 just = self.justify if (just is None) else just
373 just = self.justify if (just is None) else just
374 if just:
374 if just:
375 res = res.rjust(self.width + invis_chars)
375 res = res.rjust(self.width + invis_chars)
376 self.width = len(res) - invis_chars
376 self.width = len(res) - invis_chars
377 return res
377 return res
378
378
General Comments 0
You need to be logged in to leave comments. Login now