##// END OF EJS Templates
Merge pull request #507 from takluyver/prompt-manager...
Fernando Perez -
r5526:272152cc merge
parent child Browse files
Show More
@@ -5,11 +5,11 b' app = c.InteractiveShellApp'
5 # and merge it into the current one.
5 # and merge it into the current one.
6 load_subconfig('ipython_config.py', profile='default')
6 load_subconfig('ipython_config.py', profile='default')
7
7
8 c.InteractiveShell.prompt_in1 = r'\C_LightGreen\u@\h\C_LightBlue[\C_LightCyan\Y1\C_LightBlue]\C_Green|\#> '
8 c.PromptManager.in_template = r'{color.LightGreen}\u@\h{color.LightBlue}[{color.LightCyan}\Y1{color.LightBlue}]{color.Green}|\#> '
9 c.InteractiveShell.prompt_in2 = r'\C_Green|\C_LightGreen\D\C_Green> '
9 c.PromptManager.in2_template = r'{color.Green}|{color.LightGreen}\D{color.Green}> '
10 c.InteractiveShell.prompt_out = r'<\#> '
10 c.PromptManager.out_template = r'<\#> '
11
11
12 c.InteractiveShell.prompts_pad_left = True
12 c.PromptManager.justify = True
13
13
14 c.InteractiveShell.separate_in = ''
14 c.InteractiveShell.separate_in = ''
15 c.InteractiveShell.separate_out = ''
15 c.InteractiveShell.separate_out = ''
@@ -25,7 +25,6 b' Authors:'
25 import __builtin__
25 import __builtin__
26
26
27 from IPython.config.configurable import Configurable
27 from IPython.config.configurable import Configurable
28 from IPython.core import prompts
29 from IPython.utils import io
28 from IPython.utils import io
30 from IPython.utils.traitlets import Instance, List
29 from IPython.utils.traitlets import Instance, List
31 from IPython.utils.warn import warn
30 from IPython.utils.warn import warn
@@ -34,32 +33,20 b' from IPython.utils.warn import warn'
34 # Main displayhook class
33 # Main displayhook class
35 #-----------------------------------------------------------------------------
34 #-----------------------------------------------------------------------------
36
35
37 # TODO: The DisplayHook class should be split into two classes, one that
36 # TODO: Move the various attributes (cache_size, [others now moved]). Some
38 # manages the prompts and their synchronization and another that just does the
37 # of these are also attributes of InteractiveShell. They should be on ONE object
39 # displayhook logic and calls into the prompt manager.
38 # only and the other objects should ask that one object for their values.
40
41 # TODO: Move the various attributes (cache_size, colors, input_sep,
42 # output_sep, output_sep2, ps1, ps2, ps_out, pad_left). Some of these are also
43 # attributes of InteractiveShell. They should be on ONE object only and the
44 # other objects should ask that one object for their values.
45
39
46 class DisplayHook(Configurable):
40 class DisplayHook(Configurable):
47 """The custom IPython displayhook to replace sys.displayhook.
41 """The custom IPython displayhook to replace sys.displayhook.
48
42
49 This class does many things, but the basic idea is that it is a callable
43 This class does many things, but the basic idea is that it is a callable
50 that gets called anytime user code returns a value.
44 that gets called anytime user code returns a value.
51
52 Currently this class does more than just the displayhook logic and that
53 extra logic should eventually be moved out of here.
54 """
45 """
55
46
56 shell = Instance('IPython.core.interactiveshell.InteractiveShellABC')
47 shell = Instance('IPython.core.interactiveshell.InteractiveShellABC')
57
48
58 def __init__(self, shell=None, cache_size=1000,
49 def __init__(self, shell=None, cache_size=1000, config=None):
59 colors='NoColor', input_sep='\n',
60 output_sep='\n', output_sep2='',
61 ps1 = None, ps2 = None, ps_out = None, pad_left=True,
62 config=None):
63 super(DisplayHook, self).__init__(shell=shell, config=config)
50 super(DisplayHook, self).__init__(shell=shell, config=config)
64
51
65 cache_size_min = 3
52 cache_size_min = 3
@@ -75,36 +62,10 b' class DisplayHook(Configurable):'
75 self.do_full_cache = 1
62 self.do_full_cache = 1
76
63
77 self.cache_size = cache_size
64 self.cache_size = cache_size
78 self.input_sep = input_sep
79
65
80 # we need a reference to the user-level namespace
66 # we need a reference to the user-level namespace
81 self.shell = shell
67 self.shell = shell
82
68
83 # Set input prompt strings and colors
84 if cache_size == 0:
85 if ps1.find('%n') > -1 or ps1.find(r'\#') > -1 \
86 or ps1.find(r'\N') > -1:
87 ps1 = '>>> '
88 if ps2.find('%n') > -1 or ps2.find(r'\#') > -1 \
89 or ps2.find(r'\N') > -1:
90 ps2 = '... '
91 self.ps1_str = self._set_prompt_str(ps1,'In [\\#]: ','>>> ')
92 self.ps2_str = self._set_prompt_str(ps2,' .\\D.: ','... ')
93 self.ps_out_str = self._set_prompt_str(ps_out,'Out[\\#]: ','')
94
95 self.color_table = prompts.PromptColors
96 self.prompt1 = prompts.Prompt1(self,sep=input_sep,prompt=self.ps1_str,
97 pad_left=pad_left)
98 self.prompt2 = prompts.Prompt2(self,prompt=self.ps2_str,pad_left=pad_left)
99 self.prompt_out = prompts.PromptOut(self,sep='',prompt=self.ps_out_str,
100 pad_left=pad_left)
101 self.set_colors(colors)
102
103 # Store the last prompt string each time, we need it for aligning
104 # continuation and auto-rewrite prompts
105 self.last_prompt = ''
106 self.output_sep = output_sep
107 self.output_sep2 = output_sep2
108 self._,self.__,self.___ = '','',''
69 self._,self.__,self.___ = '','',''
109
70
110 # these are deliberately global:
71 # these are deliberately global:
@@ -115,32 +76,6 b' class DisplayHook(Configurable):'
115 def prompt_count(self):
76 def prompt_count(self):
116 return self.shell.execution_count
77 return self.shell.execution_count
117
78
118 def _set_prompt_str(self,p_str,cache_def,no_cache_def):
119 if p_str is None:
120 if self.do_full_cache:
121 return cache_def
122 else:
123 return no_cache_def
124 else:
125 return p_str
126
127 def set_colors(self, colors):
128 """Set the active color scheme and configure colors for the three
129 prompt subsystems."""
130
131 # FIXME: This modifying of the global prompts.prompt_specials needs
132 # to be fixed. We need to refactor all of the prompts stuff to use
133 # proper configuration and traits notifications.
134 if colors.lower()=='nocolor':
135 prompts.prompt_specials = prompts.prompt_specials_nocolor
136 else:
137 prompts.prompt_specials = prompts.prompt_specials_color
138
139 self.color_table.set_active_scheme(colors)
140 self.prompt1.set_colors()
141 self.prompt2.set_colors()
142 self.prompt_out.set_colors()
143
144 #-------------------------------------------------------------------------
79 #-------------------------------------------------------------------------
145 # Methods used in __call__. Override these methods to modify the behavior
80 # Methods used in __call__. Override these methods to modify the behavior
146 # of the displayhook.
81 # of the displayhook.
@@ -180,8 +115,8 b' class DisplayHook(Configurable):'
180 ``io.stdout``.
115 ``io.stdout``.
181 """
116 """
182 # Use write, not print which adds an extra space.
117 # Use write, not print which adds an extra space.
183 io.stdout.write(self.output_sep)
118 io.stdout.write(self.shell.separate_out)
184 outprompt = str(self.prompt_out)
119 outprompt = self.shell.prompt_manager.render('out')
185 if self.do_full_cache:
120 if self.do_full_cache:
186 io.stdout.write(outprompt)
121 io.stdout.write(outprompt)
187
122
@@ -235,11 +170,12 b' class DisplayHook(Configurable):'
235 # So that multi-line strings line up with the left column of
170 # So that multi-line strings line up with the left column of
236 # the screen, instead of having the output prompt mess up
171 # the screen, instead of having the output prompt mess up
237 # their first line.
172 # their first line.
238 # We use the ps_out_str template instead of the expanded prompt
173 # We use the prompt template instead of the expanded prompt
239 # because the expansion may add ANSI escapes that will interfere
174 # because the expansion may add ANSI escapes that will interfere
240 # with our ability to determine whether or not we should add
175 # with our ability to determine whether or not we should add
241 # a newline.
176 # a newline.
242 if self.ps_out_str and not self.ps_out_str.endswith('\n'):
177 prompt_template = self.shell.prompt_manager.out_template
178 if prompt_template and not prompt_template.endswith('\n'):
243 # But avoid extraneous empty lines.
179 # But avoid extraneous empty lines.
244 result_repr = '\n' + result_repr
180 result_repr = '\n' + result_repr
245
181
@@ -286,7 +222,7 b' class DisplayHook(Configurable):'
286
222
287 def finish_displayhook(self):
223 def finish_displayhook(self):
288 """Finish up all displayhook activities."""
224 """Finish up all displayhook activities."""
289 io.stdout.write(self.output_sep2)
225 io.stdout.write(self.shell.separate_out2)
290 io.stdout.flush()
226 io.stdout.flush()
291
227
292 def __call__(self, result=None):
228 def __call__(self, result=None):
@@ -51,7 +51,7 b' from IPython.core.error import TryNext'
51
51
52 __all__ = ['editor', 'fix_error_editor', 'synchronize_with_editor',
52 __all__ = ['editor', 'fix_error_editor', 'synchronize_with_editor',
53 'input_prefilter', 'shutdown_hook', 'late_startup_hook',
53 'input_prefilter', 'shutdown_hook', 'late_startup_hook',
54 'generate_prompt', 'show_in_pager','pre_prompt_hook',
54 'show_in_pager','pre_prompt_hook',
55 'pre_run_code_hook', 'clipboard_get']
55 'pre_run_code_hook', 'clipboard_get']
56
56
57 def editor(self,filename, linenum=None):
57 def editor(self,filename, linenum=None):
@@ -187,13 +187,6 b' def late_startup_hook(self):'
187 #print "default startup hook ok" # dbg
187 #print "default startup hook ok" # dbg
188
188
189
189
190 def generate_prompt(self, is_continuation):
191 """ calculate and return a string with the prompt to display """
192 if is_continuation:
193 return str(self.displayhook.prompt2)
194 return str(self.displayhook.prompt1)
195
196
197 def show_in_pager(self,s):
190 def show_in_pager(self,s):
198 """ Run a string through pager """
191 """ Run a string through pager """
199 # raising TryNext here will use the default paging functionality
192 # raising TryNext here will use the default paging functionality
@@ -63,6 +63,7 b' from IPython.core.plugin import PluginManager'
63 from IPython.core.prefilter import PrefilterManager, ESC_MAGIC
63 from IPython.core.prefilter import PrefilterManager, ESC_MAGIC
64 from IPython.core.profiledir import ProfileDir
64 from IPython.core.profiledir import ProfileDir
65 from IPython.core.pylabtools import pylab_activate
65 from IPython.core.pylabtools import pylab_activate
66 from IPython.core.prompts import PromptManager
66 from IPython.external.Itpl import ItplNS
67 from IPython.external.Itpl import ItplNS
67 from IPython.utils import PyColorize
68 from IPython.utils import PyColorize
68 from IPython.utils import io
69 from IPython.utils import io
@@ -594,10 +595,8 b' class InteractiveShell(SingletonConfigurable, Magic):'
594 io.stderr = io.IOStream(sys.stderr)
595 io.stderr = io.IOStream(sys.stderr)
595
596
596 def init_prompts(self):
597 def init_prompts(self):
597 # TODO: This is a pass for now because the prompts are managed inside
598 self.prompt_manager = PromptManager(shell=self, config=self.config)
598 # the DisplayHook. Once there is a separate prompt manager, this
599 self.configurables.append(self.prompt_manager)
599 # will initialize that object and all prompt related information.
600 pass
601
600
602 def init_display_formatter(self):
601 def init_display_formatter(self):
603 self.display_formatter = DisplayFormatter(config=self.config)
602 self.display_formatter = DisplayFormatter(config=self.config)
@@ -613,13 +612,6 b' class InteractiveShell(SingletonConfigurable, Magic):'
613 config=self.config,
612 config=self.config,
614 shell=self,
613 shell=self,
615 cache_size=self.cache_size,
614 cache_size=self.cache_size,
616 input_sep = self.separate_in,
617 output_sep = self.separate_out,
618 output_sep2 = self.separate_out2,
619 ps1 = self.prompt_in1,
620 ps2 = self.prompt_in2,
621 ps_out = self.prompt_out,
622 pad_left = self.prompts_pad_left
623 )
615 )
624 self.configurables.append(self.displayhook)
616 self.configurables.append(self.displayhook)
625 # This is a context manager that installs/revmoes the displayhook at
617 # This is a context manager that installs/revmoes the displayhook at
@@ -2149,7 +2141,7 b' class InteractiveShell(SingletonConfigurable, Magic):'
2149 after the user's input prompt. This helps the user understand that the
2141 after the user's input prompt. This helps the user understand that the
2150 input line was transformed automatically by IPython.
2142 input line was transformed automatically by IPython.
2151 """
2143 """
2152 rw = self.displayhook.prompt1.auto_rewrite() + cmd
2144 rw = self.prompt_manager.render('rewrite') + cmd
2153
2145
2154 try:
2146 try:
2155 # plain ascii works better w/ pyreadline, on some machines, so
2147 # plain ascii works better w/ pyreadline, on some machines, so
@@ -2554,12 +2554,12 b' Defaulting color scheme to \'NoColor\'"""'
2554
2554
2555 # Set prompt colors
2555 # Set prompt colors
2556 try:
2556 try:
2557 shell.displayhook.set_colors(new_scheme)
2557 shell.prompt_manager.color_scheme = new_scheme
2558 except:
2558 except:
2559 color_switch_err('prompt')
2559 color_switch_err('prompt')
2560 else:
2560 else:
2561 shell.colors = \
2561 shell.colors = \
2562 shell.displayhook.color_table.active_scheme_name
2562 shell.prompt_manager.color_scheme_table.active_scheme_name
2563 # Set exception colors
2563 # Set exception colors
2564 try:
2564 try:
2565 shell.InteractiveTB.set_colors(scheme = new_scheme)
2565 shell.InteractiveTB.set_colors(scheme = new_scheme)
@@ -3237,7 +3237,7 b' Defaulting color scheme to \'NoColor\'"""'
3237
3237
3238 # Shorthands
3238 # Shorthands
3239 shell = self.shell
3239 shell = self.shell
3240 oc = shell.displayhook
3240 pm = shell.prompt_manager
3241 meta = shell.meta
3241 meta = shell.meta
3242 disp_formatter = self.shell.display_formatter
3242 disp_formatter = self.shell.display_formatter
3243 ptformatter = disp_formatter.formatters['text/plain']
3243 ptformatter = disp_formatter.formatters['text/plain']
@@ -3252,23 +3252,23 b' Defaulting color scheme to \'NoColor\'"""'
3252 save_dstore('xmode',shell.InteractiveTB.mode)
3252 save_dstore('xmode',shell.InteractiveTB.mode)
3253 save_dstore('rc_separate_out',shell.separate_out)
3253 save_dstore('rc_separate_out',shell.separate_out)
3254 save_dstore('rc_separate_out2',shell.separate_out2)
3254 save_dstore('rc_separate_out2',shell.separate_out2)
3255 save_dstore('rc_prompts_pad_left',shell.prompts_pad_left)
3255 save_dstore('rc_prompts_pad_left',pm.justify)
3256 save_dstore('rc_separate_in',shell.separate_in)
3256 save_dstore('rc_separate_in',shell.separate_in)
3257 save_dstore('rc_plain_text_only',disp_formatter.plain_text_only)
3257 save_dstore('rc_plain_text_only',disp_formatter.plain_text_only)
3258 save_dstore('prompt_templates',(pm.in_template, pm.in2_template, pm.out_template))
3258
3259
3259 if mode == False:
3260 if mode == False:
3260 # turn on
3261 # turn on
3261 oc.prompt1.p_template = '>>> '
3262 pm.in_template = '>>> '
3262 oc.prompt2.p_template = '... '
3263 pm.in2_template = '... '
3263 oc.prompt_out.p_template = ''
3264 pm.out_template = ''
3264
3265
3265 # Prompt separators like plain python
3266 # Prompt separators like plain python
3266 oc.input_sep = oc.prompt1.sep = ''
3267 shell.separate_in = ''
3267 oc.output_sep = ''
3268 shell.separate_out = ''
3268 oc.output_sep2 = ''
3269 shell.separate_out2 = ''
3269
3270
3270 oc.prompt1.pad_left = oc.prompt2.pad_left = \
3271 pm.justify = False
3271 oc.prompt_out.pad_left = False
3272
3272
3273 ptformatter.pprint = False
3273 ptformatter.pprint = False
3274 disp_formatter.plain_text_only = True
3274 disp_formatter.plain_text_only = True
@@ -3276,17 +3276,14 b' Defaulting color scheme to \'NoColor\'"""'
3276 shell.magic_xmode('Plain')
3276 shell.magic_xmode('Plain')
3277 else:
3277 else:
3278 # turn off
3278 # turn off
3279 oc.prompt1.p_template = shell.prompt_in1
3279 pm.in_template, pm.in2_template, pm.out_template = dstore.prompt_templates
3280 oc.prompt2.p_template = shell.prompt_in2
3281 oc.prompt_out.p_template = shell.prompt_out
3282
3280
3283 oc.input_sep = oc.prompt1.sep = dstore.rc_separate_in
3281 shell.separate_in = dstore.rc_separate_in
3284
3282
3285 oc.output_sep = dstore.rc_separate_out
3283 shell.separate_out = dstore.rc_separate_out
3286 oc.output_sep2 = dstore.rc_separate_out2
3284 shell.separate_out2 = dstore.rc_separate_out2
3287
3285
3288 oc.prompt1.pad_left = oc.prompt2.pad_left = \
3286 pm.justify = dstore.rc_prompts_pad_left
3289 oc.prompt_out.pad_left = dstore.rc_prompts_pad_left
3290
3287
3291 ptformatter.pprint = dstore.rc_pprint
3288 ptformatter.pprint = dstore.rc_pprint
3292 disp_formatter.plain_text_only = dstore.rc_plain_text_only
3289 disp_formatter.plain_text_only = dstore.rc_plain_text_only
@@ -3603,6 +3600,7 b' Defaulting color scheme to \'NoColor\'"""'
3603 PrefilterManager
3600 PrefilterManager
3604 AliasManager
3601 AliasManager
3605 IPCompleter
3602 IPCompleter
3603 PromptManager
3606 DisplayFormatter
3604 DisplayFormatter
3607
3605
3608 To view what is configurable on a given class, just pass the class name::
3606 To view what is configurable on a given class, just pass the class name::
@@ -5,6 +5,7 b' Authors:'
5
5
6 * Fernando Perez
6 * Fernando Perez
7 * Brian Granger
7 * Brian Granger
8 * Thomas Kluyver
8 """
9 """
9
10
10 #-----------------------------------------------------------------------------
11 #-----------------------------------------------------------------------------
@@ -23,20 +24,23 b' import os'
23 import re
24 import re
24 import socket
25 import socket
25 import sys
26 import sys
27 import time
26
28
29 from IPython.config.configurable import Configurable
27 from IPython.core import release
30 from IPython.core import release
28 from IPython.external.Itpl import ItplNS
29 from IPython.utils import coloransi
31 from IPython.utils import coloransi
32 from IPython.utils.traitlets import (Unicode, Instance, Dict, Bool, Int)
30
33
31 #-----------------------------------------------------------------------------
34 #-----------------------------------------------------------------------------
32 # Color schemes for prompts
35 # Color schemes for prompts
33 #-----------------------------------------------------------------------------
36 #-----------------------------------------------------------------------------
34
37
35 PromptColors = coloransi.ColorSchemeTable()
36 InputColors = coloransi.InputTermColors # just a shorthand
38 InputColors = coloransi.InputTermColors # just a shorthand
37 Colors = coloransi.TermColors # just a shorthand
39 Colors = coloransi.TermColors # just a shorthand
38
40
39 PromptColors.add_scheme(coloransi.ColorScheme(
41 color_lists = dict(normal=Colors(), inp=InputColors(), nocolor=coloransi.NoColors())
42
43 PColNoColors = coloransi.ColorScheme(
40 'NoColor',
44 'NoColor',
41 in_prompt = InputColors.NoColor, # Input prompt
45 in_prompt = InputColors.NoColor, # Input prompt
42 in_number = InputColors.NoColor, # Input prompt number
46 in_number = InputColors.NoColor, # Input prompt number
@@ -47,10 +51,10 b' PromptColors.add_scheme(coloransi.ColorScheme('
47 out_number = Colors.NoColor, # Output prompt number
51 out_number = Colors.NoColor, # Output prompt number
48
52
49 normal = Colors.NoColor # color off (usu. Colors.Normal)
53 normal = Colors.NoColor # color off (usu. Colors.Normal)
50 ))
54 )
51
55
52 # 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:
53 __PColLinux = coloransi.ColorScheme(
57 PColLinux = coloransi.ColorScheme(
54 'Linux',
58 'Linux',
55 in_prompt = InputColors.Green,
59 in_prompt = InputColors.Green,
56 in_number = InputColors.LightGreen,
60 in_number = InputColors.LightGreen,
@@ -62,25 +66,35 b' __PColLinux = coloransi.ColorScheme('
62
66
63 normal = Colors.Normal
67 normal = Colors.Normal
64 )
68 )
65 # Don't forget to enter it into the table!
66 PromptColors.add_scheme(__PColLinux)
67
69
68 # Slightly modified Linux for light backgrounds
70 # Slightly modified Linux for light backgrounds
69 __PColLightBG = __PColLinux.copy('LightBG')
71 PColLightBG = PColLinux.copy('LightBG')
70
72
71 __PColLightBG.colors.update(
73 PColLightBG.colors.update(
72 in_prompt = InputColors.Blue,
74 in_prompt = InputColors.Blue,
73 in_number = InputColors.LightBlue,
75 in_number = InputColors.LightBlue,
74 in_prompt2 = InputColors.Blue
76 in_prompt2 = InputColors.Blue
75 )
77 )
76 PromptColors.add_scheme(__PColLightBG)
77
78 del Colors,InputColors
79
78
80 #-----------------------------------------------------------------------------
79 #-----------------------------------------------------------------------------
81 # Utilities
80 # Utilities
82 #-----------------------------------------------------------------------------
81 #-----------------------------------------------------------------------------
83
82
83 class LazyEvaluate(object):
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."""
86 def __init__(self, func, *args, **kwargs):
87 self.func = func
88 self.args = args
89 self.kwargs = kwargs
90
91 def __call__(self, **kwargs):
92 self.kwargs.update(kwargs)
93 return self.func(*self.args, **self.kwargs)
94
95 def __str__(self):
96 return str(self())
97
84 def multiple_replace(dict, text):
98 def multiple_replace(dict, text):
85 """ Replace in 'text' all occurences of any key in the given
99 """ Replace in 'text' all occurences of any key in the given
86 dictionary by its corresponding value. Returns the new string."""
100 dictionary by its corresponding value. Returns the new string."""
@@ -121,51 +135,43 b' HOME = os.environ.get("HOME","//////:::::ZZZZZ,,,~~~")'
121 USER = os.environ.get("USER")
135 USER = os.environ.get("USER")
122 HOSTNAME = socket.gethostname()
136 HOSTNAME = socket.gethostname()
123 HOSTNAME_SHORT = HOSTNAME.split(".")[0]
137 HOSTNAME_SHORT = HOSTNAME.split(".")[0]
124 ROOT_SYMBOL = "$#"[os.name=='nt' or os.getuid()==0]
138 ROOT_SYMBOL = "#" if (os.name=='nt' or os.getuid()==0) else "$"
125
139
126 prompt_specials_color = {
140 prompt_abbreviations = {
127 # Prompt/history count
141 # Prompt/history count
128 '%n' : '${self.col_num}' '${self.cache.prompt_count}' '${self.col_p}',
142 '%n' : '{color.number}' '{count}' '{color.prompt}',
129 r'\#': '${self.col_num}' '${self.cache.prompt_count}' '${self.col_p}',
143 r'\#': '{color.number}' '{count}' '{color.prompt}',
130 # Just the prompt counter number, WITHOUT any coloring wrappers, so users
144 # Just the prompt counter number, WITHOUT any coloring wrappers, so users
131 # can get numbers displayed in whatever color they want.
145 # can get numbers displayed in whatever color they want.
132 r'\N': '${self.cache.prompt_count}',
146 r'\N': '{count}',
133
147
134 # Prompt/history count, with the actual digits replaced by dots. Used
148 # Prompt/history count, with the actual digits replaced by dots. Used
135 # mainly in continuation prompts (prompt_in2)
149 # mainly in continuation prompts (prompt_in2)
136 #r'\D': '${"."*len(str(self.cache.prompt_count))}',
150 r'\D': '{dots}',
137
138 # More robust form of the above expression, that uses the __builtin__
139 # module. Note that we can NOT use __builtins__ (note the 's'), because
140 # that can either be a dict or a module, and can even mutate at runtime,
141 # depending on the context (Python makes no guarantees on it). In
142 # contrast, __builtin__ is always a module object, though it must be
143 # explicitly imported.
144 r'\D': '${"."*__builtin__.len(__builtin__.str(self.cache.prompt_count))}',
145
151
146 # Current working directory
147 r'\w': '${os.getcwd()}',
148 # Current time
152 # Current time
149 r'\t' : '${time.strftime("%H:%M:%S")}',
153 r'\T' : '{time}',
154 # Current working directory
155 r'\w': '{cwd}',
150 # Basename of current working directory.
156 # Basename of current working directory.
151 # (use os.sep to make this portable across OSes)
157 # (use os.sep to make this portable across OSes)
152 r'\W' : '${os.getcwd().split("%s")[-1]}' % os.sep,
158 r'\W' : '{cwd_last}',
153 # 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
154 # N terms of the path, after replacing $HOME with '~'
160 # N terms of the path, after replacing $HOME with '~'
155 r'\X0': '${os.getcwd().replace("%s","~")}' % HOME,
161 r'\X0': '{cwd_x[0]}',
156 r'\X1': '${self.cwd_filt(1)}',
162 r'\X1': '{cwd_x[1]}',
157 r'\X2': '${self.cwd_filt(2)}',
163 r'\X2': '{cwd_x[2]}',
158 r'\X3': '${self.cwd_filt(3)}',
164 r'\X3': '{cwd_x[3]}',
159 r'\X4': '${self.cwd_filt(4)}',
165 r'\X4': '{cwd_x[4]}',
160 r'\X5': '${self.cwd_filt(5)}',
166 r'\X5': '{cwd_x[5]}',
161 # 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
162 # N+1 in the list. Somewhat like %cN in tcsh.
168 # N+1 in the list. Somewhat like %cN in tcsh.
163 r'\Y0': '${self.cwd_filt2(0)}',
169 r'\Y0': '{cwd_y[0]}',
164 r'\Y1': '${self.cwd_filt2(1)}',
170 r'\Y1': '{cwd_y[1]}',
165 r'\Y2': '${self.cwd_filt2(2)}',
171 r'\Y2': '{cwd_y[2]}',
166 r'\Y3': '${self.cwd_filt2(3)}',
172 r'\Y3': '{cwd_y[3]}',
167 r'\Y4': '${self.cwd_filt2(4)}',
173 r'\Y4': '{cwd_y[4]}',
168 r'\Y5': '${self.cwd_filt2(5)}',
174 r'\Y5': '{cwd_y[5]}',
169 # Hostname up to first .
175 # Hostname up to first .
170 r'\h': HOSTNAME_SHORT,
176 r'\h': HOSTNAME_SHORT,
171 # Full hostname
177 # Full hostname
@@ -184,253 +190,189 b' prompt_specials_color = {'
184 r'\$': ROOT_SYMBOL,
190 r'\$': ROOT_SYMBOL,
185 }
191 }
186
192
187 # A copy of the prompt_specials dictionary but with all color escapes removed,
188 # so we can correctly compute the prompt length for the auto_rewrite method.
189 prompt_specials_nocolor = prompt_specials_color.copy()
190 prompt_specials_nocolor['%n'] = '${self.cache.prompt_count}'
191 prompt_specials_nocolor[r'\#'] = '${self.cache.prompt_count}'
192
193 # Add in all the InputTermColors color escapes as valid prompt characters.
194 # They all get added as \\C_COLORNAME, so that we don't have any conflicts
195 # with a color name which may begin with a letter used by any other of the
196 # allowed specials. This of course means that \\C will never be allowed for
197 # anything else.
198 input_colors = coloransi.InputTermColors
199 for _color in dir(input_colors):
200 if _color[0] != '_':
201 c_name = r'\C_'+_color
202 prompt_specials_color[c_name] = getattr(input_colors,_color)
203 prompt_specials_nocolor[c_name] = ''
204
205 # we default to no color for safety. Note that prompt_specials is a global
206 # variable used by all prompt objects.
207 prompt_specials = prompt_specials_nocolor
208
209 #-----------------------------------------------------------------------------
193 #-----------------------------------------------------------------------------
210 # More utilities
194 # More utilities
211 #-----------------------------------------------------------------------------
195 #-----------------------------------------------------------------------------
212
196
213 def str_safe(arg):
197 def cwd_filt(depth):
214 """Convert to a string, without ever raising an exception.
198 """Return the last depth elements of the current working directory.
215
216 If str(arg) fails, <ERROR: ... > is returned, where ... is the exception
217 error message."""
218
219 try:
220 out = str(arg)
221 except UnicodeError:
222 try:
223 out = arg.encode('utf_8','replace')
224 except Exception,msg:
225 # let's keep this little duplication here, so that the most common
226 # case doesn't suffer from a double try wrapping.
227 out = '<ERROR: %s>' % msg
228 except Exception,msg:
229 out = '<ERROR: %s>' % msg
230 #raise # dbg
231 return out
232
199
233 #-----------------------------------------------------------------------------
200 $HOME is always replaced with '~'.
234 # Prompt classes
201 If depth==0, the full path is returned."""
235 #-----------------------------------------------------------------------------
236
202
237 class BasePrompt(object):
203 cwd = os.getcwd().replace(HOME,"~")
238 """Interactive prompt similar to Mathematica's."""
204 out = os.sep.join(cwd.split(os.sep)[-depth:])
239
205 return out or os.sep
240 def _get_p_template(self):
241 return self._p_template
242
243 def _set_p_template(self,val):
244 self._p_template = val
245 self.set_p_str()
246
247 p_template = property(_get_p_template,_set_p_template,
248 doc='Template for prompt string creation')
249
250 def __init__(self, cache, sep, prompt, pad_left=False):
251
252 # Hack: we access information about the primary prompt through the
253 # cache argument. We need this, because we want the secondary prompt
254 # to be aligned with the primary one. Color table info is also shared
255 # by all prompt classes through the cache. Nice OO spaghetti code!
256 self.cache = cache
257 self.sep = sep
258
259 # regexp to count the number of spaces at the end of a prompt
260 # expression, useful for prompt auto-rewriting
261 self.rspace = re.compile(r'(\s*)$')
262 # Flag to left-pad prompt strings to match the length of the primary
263 # prompt
264 self.pad_left = pad_left
265
266 # Set template to create each actual prompt (where numbers change).
267 # Use a property
268 self.p_template = prompt
269 self.set_p_str()
270
271 def set_p_str(self):
272 """ Set the interpolating prompt strings.
273
274 This must be called every time the color settings change, because the
275 prompt_specials global may have changed."""
276
277 import os,time # needed in locals for prompt string handling
278 loc = locals()
279 try:
280 self.p_str = ItplNS('%s%s%s' %
281 ('${self.sep}${self.col_p}',
282 multiple_replace(prompt_specials, self.p_template),
283 '${self.col_norm}'),self.cache.shell.user_ns,loc)
284
285 self.p_str_nocolor = ItplNS(multiple_replace(prompt_specials_nocolor,
286 self.p_template),
287 self.cache.shell.user_ns,loc)
288 except:
289 print "Illegal prompt template (check $ usage!):",self.p_template
290 self.p_str = self.p_template
291 self.p_str_nocolor = self.p_template
292
293 def write(self, msg):
294 sys.stdout.write(msg)
295 return ''
296
206
297 def __str__(self):
207 def cwd_filt2(depth):
298 """Return a string form of the prompt.
208 """Return the last depth elements of the current working directory.
299
300 This for is useful for continuation and output prompts, since it is
301 left-padded to match lengths with the primary one (if the
302 self.pad_left attribute is set)."""
303
304 out_str = str_safe(self.p_str)
305 if self.pad_left:
306 # We must find the amount of padding required to match lengths,
307 # taking the color escapes (which are invisible on-screen) into
308 # account.
309 esc_pad = len(out_str) - len(str_safe(self.p_str_nocolor))
310 format = '%%%ss' % (len(str(self.cache.last_prompt))+esc_pad)
311 return format % out_str
312 else:
313 return out_str
314
209
315 # these path filters are put in as methods so that we can control the
210 $HOME is always replaced with '~'.
316 # namespace where the prompt strings get evaluated
211 If depth==0, the full path is returned."""
317 def cwd_filt(self, depth):
318 """Return the last depth elements of the current working directory.
319
212
320 $HOME is always replaced with '~'.
213 full_cwd = os.getcwd()
321 If depth==0, the full path is returned."""
214 cwd = full_cwd.replace(HOME,"~").split(os.sep)
215 if '~' in cwd and len(cwd) == depth+1:
216 depth += 1
217 drivepart = ''
218 if sys.platform == 'win32' and len(cwd) > depth:
219 drivepart = os.path.splitdrive(full_cwd)[0]
220 out = drivepart + '/'.join(cwd[-depth:])
322
221
323 cwd = os.getcwd().replace(HOME,"~")
222 return out or os.sep
324 out = os.sep.join(cwd.split(os.sep)[-depth:])
325 if out:
326 return out
327 else:
328 return os.sep
329
223
330 def cwd_filt2(self, depth):
224 #-----------------------------------------------------------------------------
331 """Return the last depth elements of the current working directory.
225 # Prompt classes
332
226 #-----------------------------------------------------------------------------
333 $HOME is always replaced with '~'.
334 If depth==0, the full path is returned."""
335
336 full_cwd = os.getcwd()
337 cwd = full_cwd.replace(HOME,"~").split(os.sep)
338 if '~' in cwd and len(cwd) == depth+1:
339 depth += 1
340 drivepart = ''
341 if sys.platform == 'win32' and len(cwd) > depth:
342 drivepart = os.path.splitdrive(full_cwd)[0]
343 out = drivepart + '/'.join(cwd[-depth:])
344
227
345 if out:
228 lazily_evaluate = {'time': LazyEvaluate(time.strftime, "%H:%M:%S"),
346 return out
229 'cwd': LazyEvaluate(os.getcwd),
230 'cwd_last': LazyEvaluate(lambda: os.getcwd().split(os.sep)[-1]),
231 'cwd_x': [LazyEvaluate(lambda: os.getcwd().replace("%s","~"))] +\
232 [LazyEvaluate(cwd_filt, x) for x in range(1,6)],
233 'cwd_y': [LazyEvaluate(cwd_filt2, x) for x in range(6)]
234 }
235
236
237 class PromptManager(Configurable):
238 """This is the primary interface for producing IPython's prompts."""
239 shell = Instance('IPython.core.interactiveshell.InteractiveShellABC')
240
241 color_scheme_table = Instance(coloransi.ColorSchemeTable)
242 color_scheme = Unicode('Linux', config=True)
243 def _color_scheme_changed(self, name, new_value):
244 self.color_scheme_table.set_active_scheme(new_value)
245 for pname in ['in', 'in2', 'out', 'rewrite']:
246 # We need to recalculate the number of invisible characters
247 self.update_prompt(pname)
248
249 lazy_evaluate_fields = Dict(help="""
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
252 things like the current time in the prompts. Functions are only called
253 if they are used in the prompt.
254 """)
255 def _lazy_evaluate_fields_default(self): return lazily_evaluate.copy()
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)
261
262 justify = Bool(True, config=True, help="""
263 If True (default), each prompt will be right-aligned with the
264 preceding one.
265 """)
266
267 # We actually store the expanded templates here:
268 templates = Dict()
269
270 # The number of characters in the last prompt rendered, not including
271 # colour characters.
272 width = Int()
273
274 # The number of characters in each prompt which don't contribute to width
275 invisible_chars = Dict()
276 def _invisible_chars_default(self):
277 return {'in': 0, 'in2': 0, 'out': 0, 'rewrite': 0}
278
279 def __init__(self, shell, config=None):
280 super(PromptManager, self).__init__(shell=shell, config=config)
281
282 # Prepare colour scheme table
283 self.color_scheme_table = coloransi.ColorSchemeTable([PColNoColors,
284 PColLinux, PColLightBG], self.color_scheme)
285
286 # Prepare templates
287 self.update_prompt('in', self.in_template)
288 self.update_prompt('in2', self.in2_template)
289 self.update_prompt('out', self.out_template)
290 self.update_prompt('rewrite', self.rewrite_template)
291 self.on_trait_change(self._update_prompt_trait, ['in_template',
292 'in2_template', 'out_template', 'rewrite_template'])
293
294 def update_prompt(self, name, new_template=None):
295 """This is called when a prompt template is updated. It processes
296 abbreviations used in the prompt template (like \#) and calculates how
297 many invisible characters (ANSI colour escapes) the resulting prompt
298 contains.
299
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.
302 """
303 if new_template is not None:
304 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))
307 self.invisible_chars[name] = invis_chars
308
309 def _update_prompt_trait(self, traitname, new_template):
310 name = traitname[:-9] # Cut off '_template'
311 self.update_prompt(name, new_template)
312
313 def render(self, name, color=True, just=None, **kwargs):
314 """
315 Render the selected prompt.
316
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 if color:
336 scheme = self.color_scheme_table.active_colors
337 if name=='out':
338 colors = color_lists['normal']
339 colors.number, colors.prompt, colors.normal = \
340 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 else:
348 colors = color_lists['inp']
349 colors.number, colors.prompt, colors.normal = \
350 scheme.in_number, scheme.in_prompt, scheme.in_normal
351 if name=='in2':
352 colors.prompt = scheme.in_prompt2
347 else:
353 else:
348 return os.sep
354 # No color
349
355 colors = color_lists['nocolor']
350 def __nonzero__(self):
356 colors.number, colors.prompt, colors.normal = '', '', ''
351 """Implement boolean behavior.
357
352
358 count = self.shell.execution_count # Shorthand
353 Checks whether the p_str attribute is non-empty"""
359 # Build the dictionary to be passed to string formatting
354
360 fmtargs = dict(color=colors, count=count,
355 return bool(self.p_template)
361 dots="."*len(str(count)) )
356
362 fmtargs.update(self.lazy_evaluate_fields)
357
363 fmtargs.update(kwargs)
358 class Prompt1(BasePrompt):
364
359 """Input interactive prompt similar to Mathematica's."""
365 # Prepare the prompt
360
366 prompt = colors.prompt + self.templates[name] + colors.normal
361 def __init__(self, cache, sep='\n', prompt='In [\\#]: ', pad_left=True):
367
362 BasePrompt.__init__(self, cache, sep, prompt, pad_left)
368 # Fill in required fields
363
369 res = prompt.format(**fmtargs)
364 def set_colors(self):
370
365 self.set_p_str()
371 # Handle justification of prompt
366 Colors = self.cache.color_table.active_colors # shorthand
372 invis_chars = self.invisible_chars[name] if color else 0
367 self.col_p = Colors.in_prompt
373 just = self.justify if (just is None) else just
368 self.col_num = Colors.in_number
374 if just:
369 self.col_norm = Colors.in_normal
375 res = res.rjust(self.width + invis_chars)
370 # We need a non-input version of these escapes for the '--->'
376 self.width = len(res) - invis_chars
371 # auto-call prompts used in the auto_rewrite() method.
377 return res
372 self.col_p_ni = self.col_p.replace('\001','').replace('\002','')
373 self.col_norm_ni = Colors.normal
374
375 def __str__(self):
376 self.cache.last_prompt = str_safe(self.p_str_nocolor).split('\n')[-1]
377 return str_safe(self.p_str)
378
379 def auto_rewrite(self):
380 """Return a string of the form '--->' which lines up with the previous
381 input string. Useful for systems which re-write the user input when
382 handling automatically special syntaxes."""
383
384 curr = str(self.cache.last_prompt)
385 nrspaces = len(self.rspace.search(curr).group())
386 return '%s%s>%s%s' % (self.col_p_ni,'-'*(len(curr)-nrspaces-1),
387 ' '*nrspaces,self.col_norm_ni)
388
389
390 class PromptOut(BasePrompt):
391 """Output interactive prompt similar to Mathematica's."""
392
393 def __init__(self, cache, sep='', prompt='Out[\\#]: ', pad_left=True):
394 BasePrompt.__init__(self, cache, sep, prompt, pad_left)
395 if not self.p_template:
396 self.__str__ = lambda: ''
397
398 def set_colors(self):
399 self.set_p_str()
400 Colors = self.cache.color_table.active_colors # shorthand
401 self.col_p = Colors.out_prompt
402 self.col_num = Colors.out_number
403 self.col_norm = Colors.normal
404
405
406 class Prompt2(BasePrompt):
407 """Interactive continuation prompt."""
408
409 def __init__(self, cache, prompt=' .\\D.: ', pad_left=True):
410 self.cache = cache
411 self.p_template = prompt
412 self.pad_left = pad_left
413 self.set_p_str()
414
415 def set_p_str(self):
416 import os,time # needed in locals for prompt string handling
417 loc = locals()
418 self.p_str = ItplNS('%s%s%s' %
419 ('${self.col_p2}',
420 multiple_replace(prompt_specials, self.p_template),
421 '$self.col_norm'),
422 self.cache.shell.user_ns,loc)
423 self.p_str_nocolor = ItplNS(multiple_replace(prompt_specials_nocolor,
424 self.p_template),
425 self.cache.shell.user_ns,loc)
426
427 def set_colors(self):
428 self.set_p_str()
429 Colors = self.cache.color_table.active_colors
430 self.col_p2 = Colors.in_prompt2
431 self.col_norm = Colors.in_normal
432 # FIXME (2004-06-16) HACK: prevent crashes for users who haven't
433 # updated their prompt_in2 definitions. Remove eventually.
434 self.col_p = Colors.out_prompt
435 self.col_num = Colors.out_number
436
378
@@ -148,7 +148,7 b' class TestMagicRunPass(tt.TempFileMixin):'
148 """Test that prompts correctly generate after %run"""
148 """Test that prompts correctly generate after %run"""
149 self.run_tmpfile()
149 self.run_tmpfile()
150 _ip = get_ipython()
150 _ip = get_ipython()
151 p2 = str(_ip.displayhook.prompt2).strip()
151 p2 = _ip.prompt_manager.render('in2').strip()
152 nt.assert_equals(p2[:3], '...')
152 nt.assert_equals(p2[:3], '...')
153
153
154 def test_run_profile( self ):
154 def test_run_profile( self ):
@@ -356,7 +356,7 b' class TerminalInteractiveShell(InteractiveShell):'
356 self.hooks.pre_prompt_hook()
356 self.hooks.pre_prompt_hook()
357 if more:
357 if more:
358 try:
358 try:
359 prompt = self.hooks.generate_prompt(True)
359 prompt = self.prompt_manager.render('in2')
360 except:
360 except:
361 self.showtraceback()
361 self.showtraceback()
362 if self.autoindent:
362 if self.autoindent:
@@ -364,7 +364,7 b' class TerminalInteractiveShell(InteractiveShell):'
364
364
365 else:
365 else:
366 try:
366 try:
367 prompt = self.hooks.generate_prompt(False)
367 prompt = self.separate_in + self.prompt_manager.render('in')
368 except:
368 except:
369 self.showtraceback()
369 self.showtraceback()
370 try:
370 try:
@@ -15,12 +15,7 b' import os'
15
15
16 from IPython.utils.ipstruct import Struct
16 from IPython.utils.ipstruct import Struct
17
17
18 def make_color_table(in_class):
18 color_templates = (
19 """Build a set of color attributes in a class.
20
21 Helper function for building the *TermColors classes."""
22
23 color_templates = (
24 # Dark colors
19 # Dark colors
25 ("Black" , "0;30"),
20 ("Black" , "0;30"),
26 ("Red" , "0;31"),
21 ("Red" , "0;31"),
@@ -50,6 +45,11 b' def make_color_table(in_class):'
50 ("BlinkLightGray", "5;37"),
45 ("BlinkLightGray", "5;37"),
51 )
46 )
52
47
48 def make_color_table(in_class):
49 """Build a set of color attributes in a class.
50
51 Helper function for building the *TermColors classes."""
52
53 for name,value in color_templates:
53 for name,value in color_templates:
54 setattr(in_class,name,in_class._base % value)
54 setattr(in_class,name,in_class._base % value)
55
55
@@ -98,6 +98,14 b' class InputTermColors:'
98 # Build the actual color table as a set of class attributes:
98 # Build the actual color table as a set of class attributes:
99 make_color_table(InputTermColors)
99 make_color_table(InputTermColors)
100
100
101 class NoColors:
102 """This defines all the same names as the colour classes, but maps them to
103 empty strings, so it can easily be substituted to turn off colours."""
104 NoColor = ''
105
106 for name, value in color_templates:
107 setattr(NoColors, name, '')
108
101 class ColorScheme:
109 class ColorScheme:
102 """Generic color scheme class. Just a name and a Struct."""
110 """Generic color scheme class. Just a name and a Struct."""
103 def __init__(self,__scheme_name_,colordict=None,**colormap):
111 def __init__(self,__scheme_name_,colordict=None,**colormap):
@@ -75,7 +75,6 b' def eval_formatter_slicing_check(f):'
75 nt.assert_equals(s, ns['stuff'][::2])
75 nt.assert_equals(s, ns['stuff'][::2])
76
76
77 nt.assert_raises(SyntaxError, f.format, "{n:x}", **ns)
77 nt.assert_raises(SyntaxError, f.format, "{n:x}", **ns)
78
79
78
80 def eval_formatter_no_slicing_check(f):
79 def eval_formatter_no_slicing_check(f):
81 ns = dict(n=12, pi=math.pi, stuff='hello there', os=os)
80 ns = dict(n=12, pi=math.pi, stuff='hello there', os=os)
@@ -83,6 +82,9 b' def eval_formatter_no_slicing_check(f):'
83 s = f.format('{n:x} {pi**2:+f}', **ns)
82 s = f.format('{n:x} {pi**2:+f}', **ns)
84 nt.assert_equals(s, "c +9.869604")
83 nt.assert_equals(s, "c +9.869604")
85
84
85 s = f.format('{stuff[slice(1,4)]}', **ns)
86 nt.assert_equals(s, 'ell')
87
86 nt.assert_raises(SyntaxError, f.format, "{a[:]}")
88 nt.assert_raises(SyntaxError, f.format, "{a[:]}")
87
89
88 def test_eval_formatter():
90 def test_eval_formatter():
@@ -133,7 +133,7 b' class ZMQInteractiveShell(InteractiveShell):'
133 FIXME: this payload is currently not correctly processed by the
133 FIXME: this payload is currently not correctly processed by the
134 frontend.
134 frontend.
135 """
135 """
136 new = self.displayhook.prompt1.auto_rewrite() + cmd
136 new = self.prompt_manager.render('rewrite') + cmd
137 payload = dict(
137 payload = dict(
138 source='IPython.zmq.zmqshell.ZMQInteractiveShell.auto_rewrite_input',
138 source='IPython.zmq.zmqshell.ZMQInteractiveShell.auto_rewrite_input',
139 transformed_input=new,
139 transformed_input=new,
@@ -124,11 +124,12 b' attributes::'
124 c.InteractiveShell.confirm_exit = False
124 c.InteractiveShell.confirm_exit = False
125 c.InteractiveShell.deep_reload = True
125 c.InteractiveShell.deep_reload = True
126 c.InteractiveShell.editor = 'nano'
126 c.InteractiveShell.editor = 'nano'
127 c.InteractiveShell.prompt_in1 = 'In [\#]: '
128 c.InteractiveShell.prompt_in2 = ' .\D.: '
129 c.InteractiveShell.prompt_out = 'Out[\#]: '
130 c.InteractiveShell.prompts_pad_left = True
131 c.InteractiveShell.xmode = 'Context'
127 c.InteractiveShell.xmode = 'Context'
128
129 c.PromptManager.in_template = 'In [\#]: '
130 c.PromptManager.in2_template = ' .\D.: '
131 c.PromptManager.out_template = 'Out[\#]: '
132 c.PromptManager.justify = True
132
133
133 c.PrefilterManager.multi_line_specials = True
134 c.PrefilterManager.multi_line_specials = True
134
135
@@ -117,6 +117,15 b' Backwards incompatible changes'
117 traits, rather than several ip/port pair ``_addr`` traits. This better matches the
117 traits, rather than several ip/port pair ``_addr`` traits. This better matches the
118 rest of the code, where the ip cannot not be set separately for each channel.
118 rest of the code, where the ip cannot not be set separately for each channel.
119
119
120 * Custom prompts are now configured using a new class,
121 :class:`~IPython.core.prompts.PromptManager`, which has traits for :attr:`in_template`,
122 :attr:`in2_template` (the ``...:`` continuation prompt), :attr:`out_template`
123 and :attr:`rewrite_template`. This uses Python's string formatting system, so
124 you can use ``{time}`` and ``{cwd}``, although we have preserved the abbreviations
125 from previous versions, e.g. ``\#`` (prompt number) and ``\w`` (working
126 directory). For the list of available fields, refer to the source of
127 :file:`IPython/core/prompts.py`.
128
120 * The class inheritance of the Launchers in :mod:`IPython.parallel.apps.launcher`
129 * The class inheritance of the Launchers in :mod:`IPython.parallel.apps.launcher`
121 used by ipcluster has changed, so that trait names are more consistent across
130 used by ipcluster has changed, so that trait names are more consistent across
122 batch systems. This may require a few renames in your config files, if you
131 batch systems. This may require a few renames in your config files, if you
General Comments 0
You need to be logged in to leave comments. Login now