##// END OF EJS Templates
Merge pull request #1083 from takluyver/prompts...
Fernando Perez -
r5556:4b8920a5 merge
parent child Browse files
Show More
@@ -315,10 +315,41 b' class InteractiveShell(SingletonConfigurable, Magic):'
315 315 help="Save multi-line entries as one entry in readline history"
316 316 )
317 317
318 prompt_in1 = Unicode('In [\\#]: ', config=True)
319 prompt_in2 = Unicode(' .\\D.: ', config=True)
320 prompt_out = Unicode('Out[\\#]: ', config=True)
321 prompts_pad_left = CBool(True, config=True)
318 # deprecated prompt traits:
319
320 prompt_in1 = Unicode('In [\\#]: ', config=True,
321 help="Deprecated, use PromptManager.in_template")
322 prompt_in2 = Unicode(' .\\D.: ', config=True,
323 help="Deprecated, use PromptManager.in2_template")
324 prompt_out = Unicode('Out[\\#]: ', config=True,
325 help="Deprecated, use PromptManager.out_template")
326 prompts_pad_left = CBool(True, config=True,
327 help="Deprecated, use PromptManager.justify")
328
329 def _prompt_trait_changed(self, name, old, new):
330 table = {
331 'prompt_in1' : 'in_template',
332 'prompt_in2' : 'in2_template',
333 'prompt_out' : 'out_template',
334 'prompts_pad_left' : 'justify',
335 }
336 warn("InteractiveShell.{name} is deprecated, use PromptManager.{newname}\n".format(
337 name=name, newname=table[name])
338 )
339 # protect against weird cases where self.config may not exist:
340 if self.config is not None:
341 # propagate to corresponding PromptManager trait
342 setattr(self.config.PromptManager, table[name], new)
343
344 _prompt_in1_changed = _prompt_trait_changed
345 _prompt_in2_changed = _prompt_trait_changed
346 _prompt_out_changed = _prompt_trait_changed
347 _prompt_pad_left_changed = _prompt_trait_changed
348
349 show_rewritten_input = CBool(True, config=True,
350 help="Show rewritten input, e.g. for autocall."
351 )
352
322 353 quiet = CBool(False, config=True)
323 354
324 355 history_length = Integer(10000, config=True)
@@ -2141,6 +2172,9 b' class InteractiveShell(SingletonConfigurable, Magic):'
2141 2172 after the user's input prompt. This helps the user understand that the
2142 2173 input line was transformed automatically by IPython.
2143 2174 """
2175 if not self.show_rewritten_input:
2176 return
2177
2144 2178 rw = self.prompt_manager.render('rewrite') + cmd
2145 2179
2146 2180 try:
@@ -254,10 +254,12 b' class PromptManager(Configurable):'
254 254 """)
255 255 def _lazy_evaluate_fields_default(self): return lazily_evaluate.copy()
256 256
257 in_template = Unicode('In [\\#]: ', config=True)
258 in2_template = Unicode(' .\\D.: ', config=True)
259 out_template = Unicode('Out[\\#]: ', config=True)
260 rewrite_template = Unicode("------> ", config=True)
257 in_template = Unicode('In [\\#]: ', config=True,
258 help="Input prompt. '\\#' will be transformed to the prompt number")
259 in2_template = Unicode(' .\\D.: ', config=True,
260 help="Continuation prompt.")
261 out_template = Unicode('Out[\\#]: ', config=True,
262 help="Output prompt. '\\#' will be transformed to the prompt number")
261 263
262 264 justify = Bool(True, config=True, help="""
263 265 If True (default), each prompt will be right-aligned with the
@@ -270,11 +272,12 b' class PromptManager(Configurable):'
270 272 # The number of characters in the last prompt rendered, not including
271 273 # colour characters.
272 274 width = Int()
275 txtwidth = Int() # Not including right-justification
273 276
274 277 # The number of characters in each prompt which don't contribute to width
275 278 invisible_chars = Dict()
276 279 def _invisible_chars_default(self):
277 return {'in': 0, 'in2': 0, 'out': 0, 'rewrite': 0}
280 return {'in': 0, 'in2': 0, 'out': 0, 'rewrite':0}
278 281
279 282 def __init__(self, shell, config=None):
280 283 super(PromptManager, self).__init__(shell=shell, config=config)
@@ -283,13 +286,13 b' class PromptManager(Configurable):'
283 286 self.color_scheme_table = coloransi.ColorSchemeTable([PColNoColors,
284 287 PColLinux, PColLightBG], self.color_scheme)
285 288
286 # Prepare templates
289 # Prepare templates & numbers of invisible characters
287 290 self.update_prompt('in', self.in_template)
288 291 self.update_prompt('in2', self.in2_template)
289 292 self.update_prompt('out', self.out_template)
290 self.update_prompt('rewrite', self.rewrite_template)
293 self.update_prompt('rewrite')
291 294 self.on_trait_change(self._update_prompt_trait, ['in_template',
292 'in2_template', 'out_template', 'rewrite_template'])
295 'in2_template', 'out_template'])
293 296
294 297 def update_prompt(self, name, new_template=None):
295 298 """This is called when a prompt template is updated. It processes
@@ -302,48 +305,26 b' class PromptManager(Configurable):'
302 305 """
303 306 if new_template is not None:
304 307 self.templates[name] = multiple_replace(prompt_abbreviations, new_template)
305 invis_chars = len(self.render(name, color=True, just=False)) - \
306 len(self.render(name, color=False, just=False))
308 invis_chars = len(self._render(name, color=True)) - \
309 len(self._render(name, color=False))
307 310 self.invisible_chars[name] = invis_chars
308 311
309 312 def _update_prompt_trait(self, traitname, new_template):
310 313 name = traitname[:-9] # Cut off '_template'
311 314 self.update_prompt(name, new_template)
312 315
313 def render(self, name, color=True, just=None, **kwargs):
316 def _render(self, name, color=True, **kwargs):
317 """Render but don't justify, or update the width or txtwidth attributes.
314 318 """
315 Render the selected prompt.
319 if name == 'rewrite':
320 return self._render_rewrite(color=color)
316 321
317 Parameters
318 ----------
319 name : str
320 Which prompt to render. One of 'in', 'in2', 'out', 'rewrite'
321 color : bool
322 If True (default), include ANSI escape sequences for a coloured prompt.
323 just : bool
324 If True, justify the prompt to the width of the last prompt. The
325 default is stored in self.justify.
326 **kwargs :
327 Additional arguments will be passed to the string formatting operation,
328 so they can override the values that would otherwise fill in the
329 template.
330
331 Returns
332 -------
333 A string containing the rendered prompt.
334 """
335 322 if color:
336 323 scheme = self.color_scheme_table.active_colors
337 324 if name=='out':
338 325 colors = color_lists['normal']
339 326 colors.number, colors.prompt, colors.normal = \
340 327 scheme.out_number, scheme.out_prompt, scheme.normal
341 elif name=='rewrite':
342 colors = color_lists['normal']
343 # We need a non-input version of these escapes
344 colors.number = scheme.in_number.replace("\001","").replace("\002","")
345 colors.prompt = scheme.in_prompt.replace("\001","").replace("\002","")
346 colors.normal = scheme.normal
347 328 else:
348 329 colors = color_lists['inp']
349 330 colors.number, colors.prompt, colors.normal = \
@@ -358,7 +339,8 b' class PromptManager(Configurable):'
358 339 count = self.shell.execution_count # Shorthand
359 340 # Build the dictionary to be passed to string formatting
360 341 fmtargs = dict(color=colors, count=count,
361 dots="."*len(str(count)) )
342 dots="."*len(str(count)),
343 width=self.width, txtwidth=self.txtwidth )
362 344 fmtargs.update(self.lazy_evaluate_fields)
363 345 fmtargs.update(kwargs)
364 346
@@ -366,13 +348,49 b' class PromptManager(Configurable):'
366 348 prompt = colors.prompt + self.templates[name] + colors.normal
367 349
368 350 # Fill in required fields
369 res = prompt.format(**fmtargs)
351 return prompt.format(**fmtargs)
352
353 def _render_rewrite(self, color=True):
354 """Render the ---> rewrite prompt."""
355 if color:
356 scheme = self.color_scheme_table.active_colors
357 # We need a non-input version of these escapes
358 color_prompt = scheme.in_prompt.replace("\001","").replace("\002","")
359 color_normal = scheme.normal
360 else:
361 color_prompt, color_normal = '', ''
362
363 return color_prompt + "-> ".rjust(self.txtwidth, "-") + color_normal
364
365 def render(self, name, color=True, just=None, **kwargs):
366 """
367 Render the selected prompt.
368
369 Parameters
370 ----------
371 name : str
372 Which prompt to render. One of 'in', 'in2', 'out', 'rewrite'
373 color : bool
374 If True (default), include ANSI escape sequences for a coloured prompt.
375 just : bool
376 If True, justify the prompt to the width of the last prompt. The
377 default is stored in self.justify.
378 **kwargs :
379 Additional arguments will be passed to the string formatting operation,
380 so they can override the values that would otherwise fill in the
381 template.
382
383 Returns
384 -------
385 A string containing the rendered prompt.
386 """
387 res = self._render(name, color=color, **kwargs)
370 388
371 389 # Handle justification of prompt
372 390 invis_chars = self.invisible_chars[name] if color else 0
391 self.txtwidth = len(res) - invis_chars
373 392 just = self.justify if (just is None) else just
374 393 if just:
375 394 res = res.rjust(self.width + invis_chars)
376 395 self.width = len(res) - invis_chars
377 396 return res
378
@@ -38,6 +38,7 b' from IPython.core import usage'
38 38 from IPython.core.completer import IPCompleter
39 39 from IPython.core.crashhandler import CrashHandler
40 40 from IPython.core.formatters import PlainTextFormatter
41 from IPython.core.prompts import PromptManager
41 42 from IPython.core.application import (
42 43 ProfileDir, BaseIPythonApplication, base_flags, base_aliases
43 44 )
@@ -133,9 +134,9 b" addflag('term-title', 'TerminalInteractiveShell.term_title',"
133 134 classic_config = Config()
134 135 classic_config.InteractiveShell.cache_size = 0
135 136 classic_config.PlainTextFormatter.pprint = False
136 classic_config.InteractiveShell.prompt_in1 = '>>> '
137 classic_config.InteractiveShell.prompt_in2 = '... '
138 classic_config.InteractiveShell.prompt_out = ''
137 classic_config.PromptManager.in_template = '>>> '
138 classic_config.PromptManager.in2_template = '... '
139 classic_config.PromptManager.out_template = ''
139 140 classic_config.InteractiveShell.separate_in = ''
140 141 classic_config.InteractiveShell.separate_out = ''
141 142 classic_config.InteractiveShell.separate_out2 = ''
@@ -197,6 +198,7 b' class TerminalIPythonApp(BaseIPythonApplication, InteractiveShellApp):'
197 198 InteractiveShellApp, # ShellApp comes before TerminalApp, because
198 199 self.__class__, # it will also affect subclasses (e.g. QtConsole)
199 200 TerminalInteractiveShell,
201 PromptManager,
200 202 ProfileDir,
201 203 PlainTextFormatter,
202 204 IPCompleter,
@@ -202,9 +202,9 b' def ipexec(fname, options=None):'
202 202
203 203 # For these subprocess calls, eliminate all prompt printing so we only see
204 204 # output from script execution
205 prompt_opts = [ '--InteractiveShell.prompt_in1=""',
206 '--InteractiveShell.prompt_in2=""',
207 '--InteractiveShell.prompt_out=""'
205 prompt_opts = [ '--PromptManager.in_template=""',
206 '--PromptManager.in2_template=""',
207 '--PromptManager.out_template=""'
208 208 ]
209 209 cmdargs = ' '.join(default_argv() + prompt_opts + options)
210 210
@@ -23,10 +23,10 b' try:'
23 23 except NameError:
24 24 nested = 0
25 25 cfg = Config()
26 shell_config = cfg.InteractiveShellEmbed
27 shell_config.prompt_in1 = 'In <\\#>: '
28 shell_config.prompt_in2 = ' .\\D.: '
29 shell_config.prompt_out = 'Out<\\#>: '
26 prompt_config = cfg.PromptManager
27 prompt_config.in_template = 'In <\\#>: '
28 prompt_config.in2_template = ' .\\D.: '
29 prompt_config.out_template = 'Out<\\#>: '
30 30 else:
31 31 print "Running nested copies of IPython."
32 32 print "The prompts for the nested copy have been modified"
@@ -46,12 +46,12 b' ipshell = InteractiveShellEmbed(config=cfg,'
46 46
47 47 # Make a second instance, you can have as many as you want.
48 48 cfg2 = cfg.copy()
49 shell_config = cfg2.InteractiveShellEmbed
50 shell_config.prompt_in1 = 'In2<\\#>: '
49 prompt_config = cfg2.PromptManager
50 prompt_config.in_template = 'In2<\\#>: '
51 51 if not nested:
52 shell_config.prompt_in1 = 'In2<\\#>: '
53 shell_config.prompt_in2 = ' .\\D.: '
54 shell_config.prompt_out = 'Out<\\#>: '
52 prompt_config.in_template = 'In2<\\#>: '
53 prompt_config.in2_template = ' .\\D.: '
54 prompt_config.out_template = 'Out<\\#>: '
55 55 ipshell2 = InteractiveShellEmbed(config=cfg,
56 56 banner1 = 'Second IPython instance.')
57 57
@@ -227,7 +227,7 b' All options with a [no] prepended can be specified in negated form'
227 227 circular file inclusions, IPython will stop if it reaches 15
228 228 recursive inclusions.
229 229
230 ``InteractiveShell.prompt_in1=<string>``
230 ``PromptManager.in_template=<string>``
231 231
232 232 Specify the string used for input prompts. Note that if you are using
233 233 numbered prompts, the number is represented with a '\#' in the
@@ -236,7 +236,7 b' All options with a [no] prepended can be specified in negated form'
236 236 discusses in detail all the available escapes to customize your
237 237 prompts.
238 238
239 ``InteractiveShell.prompt_in2=<string>``
239 ``PromptManager.in2_template=<string>``
240 240 Similar to the previous option, but used for the continuation
241 241 prompts. The special sequence '\D' is similar to '\#', but
242 242 with all digits replaced dots (so you can have your
@@ -244,9 +244,9 b' All options with a [no] prepended can be specified in negated form'
244 244 ' .\D.:' (note three spaces at the start for alignment with
245 245 'In [\#]').
246 246
247 ``InteractiveShell.prompt_out=<string>``
247 ``PromptManager.out_template=<string>``
248 248 String used for output prompts, also uses numbers like
249 prompt_in1. Default: 'Out[\#]:'
249 in_template. Default: 'Out[\#]:'
250 250
251 251 ``--quick``
252 252 start in bare bones mode (no config file loaded).
@@ -155,8 +155,9 b' Prompt customization'
155 155
156 156 The sh profile uses the following prompt configurations::
157 157
158 o.prompt_in1= r'\C_LightBlue[\C_LightCyan\Y2\C_LightBlue]\C_Green|\#>'
159 o.prompt_in2= r'\C_Green|\C_LightGreen\D\C_Green>'
158 c.PromptManager.in_template = r'{color.LightGreen}\u@\h{color.LightBlue}[{color.LightCyan}\Y1{color.LightBlue}]{color.Green}|\#> '
159 c.PromptManager.in2_template = r'{color.Green}|{color.LightGreen}\D{color.Green}> '
160 c.PromptManager.out_template = r'<\#> '
160 161
161 162 You can change the prompt configuration to your liking by editing
162 163 ipython_config.py.
General Comments 0
You need to be logged in to leave comments. Login now