Permalink
Browse files

Merge pull request #1083 from takluyver/prompts

Fixes that finish up the recent PromptManager work:

* InteractiveShell.prompt_foo traits show deprecation warning, and map to new PromptManager traits
* PromptManager properly added to IPython App, so it will show up in config
* add helpstrings to PromptManager traits.
* Docs / embed references to Shell.prompt_foo also updated
* Prompt rewriting in autocall scenarios is now controlled by a boolean, `show_rewritten_input`, attribute of the InteractiveShell.

Closes #1075.
  • Loading branch information...
2 parents c309789 + ff4cb84 commit 4b8920a558ddf77639c1eaf5753308442785b6fe @fperez fperez committed Dec 1, 2011
@@ -315,10 +315,41 @@ def _exiter_default(self):
help="Save multi-line entries as one entry in readline history"
)
- prompt_in1 = Unicode('In [\\#]: ', config=True)
- prompt_in2 = Unicode(' .\\D.: ', config=True)
- prompt_out = Unicode('Out[\\#]: ', config=True)
- prompts_pad_left = CBool(True, config=True)
+ # deprecated prompt traits:
+
+ prompt_in1 = Unicode('In [\\#]: ', config=True,
+ help="Deprecated, use PromptManager.in_template")
+ prompt_in2 = Unicode(' .\\D.: ', config=True,
+ help="Deprecated, use PromptManager.in2_template")
+ prompt_out = Unicode('Out[\\#]: ', config=True,
+ help="Deprecated, use PromptManager.out_template")
+ prompts_pad_left = CBool(True, config=True,
+ help="Deprecated, use PromptManager.justify")
+
+ def _prompt_trait_changed(self, name, old, new):
+ table = {
+ 'prompt_in1' : 'in_template',
+ 'prompt_in2' : 'in2_template',
+ 'prompt_out' : 'out_template',
+ 'prompts_pad_left' : 'justify',
+ }
+ warn("InteractiveShell.{name} is deprecated, use PromptManager.{newname}\n".format(
+ name=name, newname=table[name])
+ )
+ # protect against weird cases where self.config may not exist:
+ if self.config is not None:
+ # propagate to corresponding PromptManager trait
+ setattr(self.config.PromptManager, table[name], new)
+
+ _prompt_in1_changed = _prompt_trait_changed
+ _prompt_in2_changed = _prompt_trait_changed
+ _prompt_out_changed = _prompt_trait_changed
+ _prompt_pad_left_changed = _prompt_trait_changed
+
+ show_rewritten_input = CBool(True, config=True,
+ help="Show rewritten input, e.g. for autocall."
+ )
+
quiet = CBool(False, config=True)
history_length = Integer(10000, config=True)
@@ -2141,6 +2172,9 @@ def auto_rewrite_input(self, cmd):
after the user's input prompt. This helps the user understand that the
input line was transformed automatically by IPython.
"""
+ if not self.show_rewritten_input:
+ return
+
rw = self.prompt_manager.render('rewrite') + cmd
try:
View
@@ -254,10 +254,12 @@ def _color_scheme_changed(self, name, new_value):
""")
def _lazy_evaluate_fields_default(self): return lazily_evaluate.copy()
- in_template = Unicode('In [\\#]: ', config=True)
- in2_template = Unicode(' .\\D.: ', config=True)
- out_template = Unicode('Out[\\#]: ', config=True)
- rewrite_template = Unicode("------> ", config=True)
+ in_template = Unicode('In [\\#]: ', config=True,
+ help="Input prompt. '\\#' will be transformed to the prompt number")
+ in2_template = Unicode(' .\\D.: ', config=True,
+ help="Continuation prompt.")
+ out_template = Unicode('Out[\\#]: ', config=True,
+ help="Output prompt. '\\#' will be transformed to the prompt number")
justify = Bool(True, config=True, help="""
If True (default), each prompt will be right-aligned with the
@@ -270,11 +272,12 @@ def _lazy_evaluate_fields_default(self): return lazily_evaluate.copy()
# The number of characters in the last prompt rendered, not including
# colour characters.
width = Int()
+ txtwidth = Int() # Not including right-justification
# The number of characters in each prompt which don't contribute to width
invisible_chars = Dict()
def _invisible_chars_default(self):
- return {'in': 0, 'in2': 0, 'out': 0, 'rewrite': 0}
+ return {'in': 0, 'in2': 0, 'out': 0, 'rewrite':0}
def __init__(self, shell, config=None):
super(PromptManager, self).__init__(shell=shell, config=config)
@@ -283,13 +286,13 @@ def __init__(self, shell, config=None):
self.color_scheme_table = coloransi.ColorSchemeTable([PColNoColors,
PColLinux, PColLightBG], self.color_scheme)
- # Prepare templates
+ # Prepare templates & numbers of invisible characters
self.update_prompt('in', self.in_template)
self.update_prompt('in2', self.in2_template)
self.update_prompt('out', self.out_template)
- self.update_prompt('rewrite', self.rewrite_template)
+ self.update_prompt('rewrite')
self.on_trait_change(self._update_prompt_trait, ['in_template',
- 'in2_template', 'out_template', 'rewrite_template'])
+ 'in2_template', 'out_template'])
def update_prompt(self, name, new_template=None):
"""This is called when a prompt template is updated. It processes
@@ -302,48 +305,26 @@ def update_prompt(self, name, new_template=None):
"""
if new_template is not None:
self.templates[name] = multiple_replace(prompt_abbreviations, new_template)
- invis_chars = len(self.render(name, color=True, just=False)) - \
- len(self.render(name, color=False, just=False))
+ invis_chars = len(self._render(name, color=True)) - \
+ len(self._render(name, color=False))
self.invisible_chars[name] = invis_chars
def _update_prompt_trait(self, traitname, new_template):
name = traitname[:-9] # Cut off '_template'
self.update_prompt(name, new_template)
- def render(self, name, color=True, just=None, **kwargs):
+ def _render(self, name, color=True, **kwargs):
+ """Render but don't justify, or update the width or txtwidth attributes.
"""
- Render the selected prompt.
+ if name == 'rewrite':
+ return self._render_rewrite(color=color)
- Parameters
- ----------
- name : str
- Which prompt to render. One of 'in', 'in2', 'out', 'rewrite'
- color : bool
- If True (default), include ANSI escape sequences for a coloured prompt.
- just : bool
- If True, justify the prompt to the width of the last prompt. The
- default is stored in self.justify.
- **kwargs :
- Additional arguments will be passed to the string formatting operation,
- so they can override the values that would otherwise fill in the
- template.
-
- Returns
- -------
- A string containing the rendered prompt.
- """
if color:
scheme = self.color_scheme_table.active_colors
if name=='out':
colors = color_lists['normal']
colors.number, colors.prompt, colors.normal = \
scheme.out_number, scheme.out_prompt, scheme.normal
- elif name=='rewrite':
- colors = color_lists['normal']
- # We need a non-input version of these escapes
- colors.number = scheme.in_number.replace("\001","").replace("\002","")
- colors.prompt = scheme.in_prompt.replace("\001","").replace("\002","")
- colors.normal = scheme.normal
else:
colors = color_lists['inp']
colors.number, colors.prompt, colors.normal = \
@@ -358,21 +339,58 @@ def render(self, name, color=True, just=None, **kwargs):
count = self.shell.execution_count # Shorthand
# Build the dictionary to be passed to string formatting
fmtargs = dict(color=colors, count=count,
- dots="."*len(str(count)) )
+ dots="."*len(str(count)),
+ width=self.width, txtwidth=self.txtwidth )
fmtargs.update(self.lazy_evaluate_fields)
fmtargs.update(kwargs)
# Prepare the prompt
prompt = colors.prompt + self.templates[name] + colors.normal
# Fill in required fields
- res = prompt.format(**fmtargs)
+ return prompt.format(**fmtargs)
+
+ def _render_rewrite(self, color=True):
+ """Render the ---> rewrite prompt."""
+ if color:
+ scheme = self.color_scheme_table.active_colors
+ # We need a non-input version of these escapes
+ color_prompt = scheme.in_prompt.replace("\001","").replace("\002","")
+ color_normal = scheme.normal
+ else:
+ color_prompt, color_normal = '', ''
+
+ return color_prompt + "-> ".rjust(self.txtwidth, "-") + color_normal
+
+ def render(self, name, color=True, just=None, **kwargs):
+ """
+ Render the selected prompt.
+
+ Parameters
+ ----------
+ name : str
+ Which prompt to render. One of 'in', 'in2', 'out', 'rewrite'
+ color : bool
+ If True (default), include ANSI escape sequences for a coloured prompt.
+ just : bool
+ If True, justify the prompt to the width of the last prompt. The
+ default is stored in self.justify.
+ **kwargs :
+ Additional arguments will be passed to the string formatting operation,
+ so they can override the values that would otherwise fill in the
+ template.
+
+ Returns
+ -------
+ A string containing the rendered prompt.
+ """
+ res = self._render(name, color=color, **kwargs)
# Handle justification of prompt
invis_chars = self.invisible_chars[name] if color else 0
+ self.txtwidth = len(res) - invis_chars
just = self.justify if (just is None) else just
if just:
res = res.rjust(self.width + invis_chars)
self.width = len(res) - invis_chars
return res
-
@@ -38,6 +38,7 @@
from IPython.core.completer import IPCompleter
from IPython.core.crashhandler import CrashHandler
from IPython.core.formatters import PlainTextFormatter
+from IPython.core.prompts import PromptManager
from IPython.core.application import (
ProfileDir, BaseIPythonApplication, base_flags, base_aliases
)
@@ -133,9 +134,9 @@ def make_report(self,traceback):
classic_config = Config()
classic_config.InteractiveShell.cache_size = 0
classic_config.PlainTextFormatter.pprint = False
-classic_config.InteractiveShell.prompt_in1 = '>>> '
-classic_config.InteractiveShell.prompt_in2 = '... '
-classic_config.InteractiveShell.prompt_out = ''
+classic_config.PromptManager.in_template = '>>> '
+classic_config.PromptManager.in2_template = '... '
+classic_config.PromptManager.out_template = ''
classic_config.InteractiveShell.separate_in = ''
classic_config.InteractiveShell.separate_out = ''
classic_config.InteractiveShell.separate_out2 = ''
@@ -197,6 +198,7 @@ def _classes_default(self):
InteractiveShellApp, # ShellApp comes before TerminalApp, because
self.__class__, # it will also affect subclasses (e.g. QtConsole)
TerminalInteractiveShell,
+ PromptManager,
ProfileDir,
PlainTextFormatter,
IPCompleter,
View
@@ -202,9 +202,9 @@ def ipexec(fname, options=None):
# For these subprocess calls, eliminate all prompt printing so we only see
# output from script execution
- prompt_opts = [ '--InteractiveShell.prompt_in1=""',
- '--InteractiveShell.prompt_in2=""',
- '--InteractiveShell.prompt_out=""'
+ prompt_opts = [ '--PromptManager.in_template=""',
+ '--PromptManager.in2_template=""',
+ '--PromptManager.out_template=""'
]
cmdargs = ' '.join(default_argv() + prompt_opts + options)
@@ -23,10 +23,10 @@
except NameError:
nested = 0
cfg = Config()
- shell_config = cfg.InteractiveShellEmbed
- shell_config.prompt_in1 = 'In <\\#>: '
- shell_config.prompt_in2 = ' .\\D.: '
- shell_config.prompt_out = 'Out<\\#>: '
+ prompt_config = cfg.PromptManager
+ prompt_config.in_template = 'In <\\#>: '
+ prompt_config.in2_template = ' .\\D.: '
+ prompt_config.out_template = 'Out<\\#>: '
else:
print "Running nested copies of IPython."
print "The prompts for the nested copy have been modified"
@@ -46,12 +46,12 @@
# Make a second instance, you can have as many as you want.
cfg2 = cfg.copy()
-shell_config = cfg2.InteractiveShellEmbed
-shell_config.prompt_in1 = 'In2<\\#>: '
+prompt_config = cfg2.PromptManager
+prompt_config.in_template = 'In2<\\#>: '
if not nested:
- shell_config.prompt_in1 = 'In2<\\#>: '
- shell_config.prompt_in2 = ' .\\D.: '
- shell_config.prompt_out = 'Out<\\#>: '
+ prompt_config.in_template = 'In2<\\#>: '
+ prompt_config.in2_template = ' .\\D.: '
+ prompt_config.out_template = 'Out<\\#>: '
ipshell2 = InteractiveShellEmbed(config=cfg,
banner1 = 'Second IPython instance.')
@@ -227,7 +227,7 @@ All options with a [no] prepended can be specified in negated form
circular file inclusions, IPython will stop if it reaches 15
recursive inclusions.
- ``InteractiveShell.prompt_in1=<string>``
+ ``PromptManager.in_template=<string>``
Specify the string used for input prompts. Note that if you are using
numbered prompts, the number is represented with a '\#' in the
@@ -236,17 +236,17 @@ All options with a [no] prepended can be specified in negated form
discusses in detail all the available escapes to customize your
prompts.
- ``InteractiveShell.prompt_in2=<string>``
+ ``PromptManager.in2_template=<string>``
Similar to the previous option, but used for the continuation
prompts. The special sequence '\D' is similar to '\#', but
with all digits replaced dots (so you can have your
continuation prompt aligned with your input prompt). Default:
' .\D.:' (note three spaces at the start for alignment with
'In [\#]').
- ``InteractiveShell.prompt_out=<string>``
+ ``PromptManager.out_template=<string>``
String used for output prompts, also uses numbers like
- prompt_in1. Default: 'Out[\#]:'
+ in_template. Default: 'Out[\#]:'
``--quick``
start in bare bones mode (no config file loaded).
@@ -155,8 +155,9 @@ Prompt customization
The sh profile uses the following prompt configurations::
- o.prompt_in1= r'\C_LightBlue[\C_LightCyan\Y2\C_LightBlue]\C_Green|\#>'
- o.prompt_in2= r'\C_Green|\C_LightGreen\D\C_Green>'
+ c.PromptManager.in_template = r'{color.LightGreen}\u@\h{color.LightBlue}[{color.LightCyan}\Y1{color.LightBlue}]{color.Green}|\#> '
+ c.PromptManager.in2_template = r'{color.Green}|{color.LightGreen}\D{color.Green}> '
+ c.PromptManager.out_template = r'<\#> '
You can change the prompt configuration to your liking by editing
ipython_config.py.

0 comments on commit 4b8920a

Please sign in to comment.