##// END OF EJS Templates
Update terminal-only magics to new API.
Fernando Perez -
Show More
@@ -1,683 +1,676 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2 """Subclass of InteractiveShell for terminal based frontends."""
2 """Subclass of InteractiveShell for terminal based frontends."""
3
3
4 #-----------------------------------------------------------------------------
4 #-----------------------------------------------------------------------------
5 # Copyright (C) 2001 Janko Hauser <jhauser@zscout.de>
5 # Copyright (C) 2001 Janko Hauser <jhauser@zscout.de>
6 # Copyright (C) 2001-2007 Fernando Perez. <fperez@colorado.edu>
6 # Copyright (C) 2001-2007 Fernando Perez. <fperez@colorado.edu>
7 # Copyright (C) 2008-2011 The IPython Development Team
7 # Copyright (C) 2008-2011 The IPython Development Team
8 #
8 #
9 # Distributed under the terms of the BSD License. The full license is in
9 # Distributed under the terms of the BSD License. The full license is in
10 # the file COPYING, distributed as part of this software.
10 # the file COPYING, distributed as part of this software.
11 #-----------------------------------------------------------------------------
11 #-----------------------------------------------------------------------------
12
12
13 #-----------------------------------------------------------------------------
13 #-----------------------------------------------------------------------------
14 # Imports
14 # Imports
15 #-----------------------------------------------------------------------------
15 #-----------------------------------------------------------------------------
16
16
17 import __builtin__
18 import bdb
17 import bdb
19 import os
18 import os
20 import re
19 import re
21 import sys
20 import sys
22 import textwrap
21 import textwrap
23
22
24 try:
25 from contextlib import nested
23 from contextlib import nested
26 except:
27 from IPython.utils.nested_context import nested
28
24
29 from IPython.core.error import TryNext, UsageError
25 from IPython.core.error import TryNext, UsageError
30 from IPython.core.usage import interactive_usage, default_banner
26 from IPython.core.usage import interactive_usage, default_banner
31 from IPython.core.interactiveshell import InteractiveShell, InteractiveShellABC
27 from IPython.core.interactiveshell import InteractiveShell, InteractiveShellABC
32 from IPython.core.pylabtools import pylab_activate
28 from IPython.core.magic import Magics, register_magics, line_magic
33 from IPython.testing.skipdoctest import skip_doctest
29 from IPython.testing.skipdoctest import skip_doctest
34 from IPython.utils.encoding import get_stream_enc
30 from IPython.utils.encoding import get_stream_enc
35 from IPython.utils import py3compat
31 from IPython.utils import py3compat
36 from IPython.utils.terminal import toggle_set_term_title, set_term_title
32 from IPython.utils.terminal import toggle_set_term_title, set_term_title
37 from IPython.utils.process import abbrev_cwd
33 from IPython.utils.process import abbrev_cwd
38 from IPython.utils.warn import warn, error
34 from IPython.utils.warn import warn, error
39 from IPython.utils.text import num_ini_spaces, SList
35 from IPython.utils.text import num_ini_spaces, SList
40 from IPython.utils.traitlets import Integer, CBool, Unicode
36 from IPython.utils.traitlets import Integer, CBool, Unicode
41
37
42 #-----------------------------------------------------------------------------
38 #-----------------------------------------------------------------------------
43 # Utilities
39 # Utilities
44 #-----------------------------------------------------------------------------
40 #-----------------------------------------------------------------------------
45
41
46 def get_default_editor():
42 def get_default_editor():
47 try:
43 try:
48 ed = os.environ['EDITOR']
44 ed = os.environ['EDITOR']
49 except KeyError:
45 except KeyError:
50 if os.name == 'posix':
46 if os.name == 'posix':
51 ed = 'vi' # the only one guaranteed to be there!
47 ed = 'vi' # the only one guaranteed to be there!
52 else:
48 else:
53 ed = 'notepad' # same in Windows!
49 ed = 'notepad' # same in Windows!
54 return ed
50 return ed
55
51
56
52
57 def get_pasted_lines(sentinel, l_input=py3compat.input):
53 def get_pasted_lines(sentinel, l_input=py3compat.input):
58 """ Yield pasted lines until the user enters the given sentinel value.
54 """ Yield pasted lines until the user enters the given sentinel value.
59 """
55 """
60 print "Pasting code; enter '%s' alone on the line to stop or use Ctrl-D." \
56 print "Pasting code; enter '%s' alone on the line to stop or use Ctrl-D." \
61 % sentinel
57 % sentinel
62 while True:
58 while True:
63 try:
59 try:
64 l = l_input(':')
60 l = l_input(':')
65 if l == sentinel:
61 if l == sentinel:
66 return
62 return
67 else:
63 else:
68 yield l
64 yield l
69 except EOFError:
65 except EOFError:
70 print '<EOF>'
66 print '<EOF>'
71 return
67 return
72
68
73
69
74 def strip_email_quotes(raw_lines):
70 def strip_email_quotes(raw_lines):
75 """ Strip email quotation marks at the beginning of each line.
71 """ Strip email quotation marks at the beginning of each line.
76
72
77 We don't do any more input transofrmations here because the main shell's
73 We don't do any more input transofrmations here because the main shell's
78 prefiltering handles other cases.
74 prefiltering handles other cases.
79 """
75 """
80 lines = [re.sub(r'^\s*(\s?>)+', '', l) for l in raw_lines]
76 lines = [re.sub(r'^\s*(\s?>)+', '', l) for l in raw_lines]
81 return '\n'.join(lines) + '\n'
77 return '\n'.join(lines) + '\n'
82
78
83
79
84 # These two functions are needed by the %paste/%cpaste magics. In practice
80 # These two functions are needed by the %paste/%cpaste magics. In practice
85 # they are basically methods (they take the shell as their first argument), but
81 # they are basically methods (they take the shell as their first argument), but
86 # we leave them as standalone functions because eventually the magics
82 # we leave them as standalone functions because eventually the magics
87 # themselves will become separate objects altogether. At that point, the
83 # themselves will become separate objects altogether. At that point, the
88 # magics will have access to the shell object, and these functions can be made
84 # magics will have access to the shell object, and these functions can be made
89 # methods of the magic object, but not of the shell.
85 # methods of the magic object, but not of the shell.
90
86
91 def store_or_execute(shell, block, name):
87 def store_or_execute(shell, block, name):
92 """ Execute a block, or store it in a variable, per the user's request.
88 """ Execute a block, or store it in a variable, per the user's request.
93 """
89 """
94 # Dedent and prefilter so what we store matches what is executed by
90 # Dedent and prefilter so what we store matches what is executed by
95 # run_cell.
91 # run_cell.
96 b = shell.prefilter(textwrap.dedent(block))
92 b = shell.prefilter(textwrap.dedent(block))
97
93
98 if name:
94 if name:
99 # If storing it for further editing, run the prefilter on it
95 # If storing it for further editing, run the prefilter on it
100 shell.user_ns[name] = SList(b.splitlines())
96 shell.user_ns[name] = SList(b.splitlines())
101 print "Block assigned to '%s'" % name
97 print "Block assigned to '%s'" % name
102 else:
98 else:
103 shell.user_ns['pasted_block'] = b
99 shell.user_ns['pasted_block'] = b
104 shell.run_cell(b)
100 shell.run_cell(b)
105
101
106
102
107 def rerun_pasted(shell, name='pasted_block'):
103 def rerun_pasted(shell, name='pasted_block'):
108 """ Rerun a previously pasted command.
104 """ Rerun a previously pasted command.
109 """
105 """
110 b = shell.user_ns.get(name)
106 b = shell.user_ns.get(name)
111
107
112 # Sanity checks
108 # Sanity checks
113 if b is None:
109 if b is None:
114 raise UsageError('No previous pasted block available')
110 raise UsageError('No previous pasted block available')
115 if not isinstance(b, basestring):
111 if not isinstance(b, basestring):
116 raise UsageError(
112 raise UsageError(
117 "Variable 'pasted_block' is not a string, can't execute")
113 "Variable 'pasted_block' is not a string, can't execute")
118
114
119 print "Re-executing '%s...' (%d chars)"% (b.split('\n',1)[0], len(b))
115 print "Re-executing '%s...' (%d chars)"% (b.split('\n',1)[0], len(b))
120 shell.run_cell(b)
116 shell.run_cell(b)
121
117
122
118
123 #------------------------------------------------------------------------
119 #------------------------------------------------------------------------
124 # Terminal-specific magics
120 # Terminal-specific magics
125 #------------------------------------------------------------------------
121 #------------------------------------------------------------------------
126
122
127 def magic_autoindent(self, parameter_s = ''):
123 @register_magics
124 class TerminalMagics(Magics):
125
126 @line_magic
127 def autoindent(self, parameter_s = ''):
128 """Toggle autoindent on/off (if available)."""
128 """Toggle autoindent on/off (if available)."""
129
129
130 self.shell.set_autoindent()
130 self.shell.set_autoindent()
131 print "Automatic indentation is:",['OFF','ON'][self.shell.autoindent]
131 print "Automatic indentation is:",['OFF','ON'][self.shell.autoindent]
132
132
133 @skip_doctest
133 @skip_doctest
134 def magic_cpaste(self, parameter_s=''):
134 @line_magic
135 def cpaste(self, parameter_s=''):
135 """Paste & execute a pre-formatted code block from clipboard.
136 """Paste & execute a pre-formatted code block from clipboard.
136
137
137 You must terminate the block with '--' (two minus-signs) or Ctrl-D
138 You must terminate the block with '--' (two minus-signs) or Ctrl-D
138 alone on the line. You can also provide your own sentinel with '%paste
139 alone on the line. You can also provide your own sentinel with '%paste
139 -s %%' ('%%' is the new sentinel for this operation)
140 -s %%' ('%%' is the new sentinel for this operation)
140
141
141 The block is dedented prior to execution to enable execution of method
142 The block is dedented prior to execution to enable execution of method
142 definitions. '>' and '+' characters at the beginning of a line are
143 definitions. '>' and '+' characters at the beginning of a line are
143 ignored, to allow pasting directly from e-mails, diff files and
144 ignored, to allow pasting directly from e-mails, diff files and
144 doctests (the '...' continuation prompt is also stripped). The
145 doctests (the '...' continuation prompt is also stripped). The
145 executed block is also assigned to variable named 'pasted_block' for
146 executed block is also assigned to variable named 'pasted_block' for
146 later editing with '%edit pasted_block'.
147 later editing with '%edit pasted_block'.
147
148
148 You can also pass a variable name as an argument, e.g. '%cpaste foo'.
149 You can also pass a variable name as an argument, e.g. '%cpaste foo'.
149 This assigns the pasted block to variable 'foo' as string, without
150 This assigns the pasted block to variable 'foo' as string, without
150 dedenting or executing it (preceding >>> and + is still stripped)
151 dedenting or executing it (preceding >>> and + is still stripped)
151
152
152 '%cpaste -r' re-executes the block previously entered by cpaste.
153 '%cpaste -r' re-executes the block previously entered by cpaste.
153
154
154 Do not be alarmed by garbled output on Windows (it's a readline bug).
155 Do not be alarmed by garbled output on Windows (it's a readline bug).
155 Just press enter and type -- (and press enter again) and the block
156 Just press enter and type -- (and press enter again) and the block
156 will be what was just pasted.
157 will be what was just pasted.
157
158
158 IPython statements (magics, shell escapes) are not supported (yet).
159 IPython statements (magics, shell escapes) are not supported (yet).
159
160
160 See also
161 See also
161 --------
162 --------
162 paste: automatically pull code from clipboard.
163 paste: automatically pull code from clipboard.
163
164
164 Examples
165 Examples
165 --------
166 --------
166 ::
167 ::
167
168
168 In [8]: %cpaste
169 In [8]: %cpaste
169 Pasting code; enter '--' alone on the line to stop.
170 Pasting code; enter '--' alone on the line to stop.
170 :>>> a = ["world!", "Hello"]
171 :>>> a = ["world!", "Hello"]
171 :>>> print " ".join(sorted(a))
172 :>>> print " ".join(sorted(a))
172 :--
173 :--
173 Hello world!
174 Hello world!
174 """
175 """
175
176
176 opts, name = self.parse_options(parameter_s, 'rs:', mode='string')
177 opts, name = self.parse_options(parameter_s, 'rs:', mode='string')
177 if 'r' in opts:
178 if 'r' in opts:
178 rerun_pasted(self.shell)
179 rerun_pasted(self.shell)
179 return
180 return
180
181
181 sentinel = opts.get('s', '--')
182 sentinel = opts.get('s', '--')
182 block = strip_email_quotes(get_pasted_lines(sentinel))
183 block = strip_email_quotes(get_pasted_lines(sentinel))
183 store_or_execute(self.shell, block, name)
184 store_or_execute(self.shell, block, name)
184
185
185
186 @line_magic
186 def magic_paste(self, parameter_s=''):
187 def paste(self, parameter_s=''):
187 """Paste & execute a pre-formatted code block from clipboard.
188 """Paste & execute a pre-formatted code block from clipboard.
188
189
189 The text is pulled directly from the clipboard without user
190 The text is pulled directly from the clipboard without user
190 intervention and printed back on the screen before execution (unless
191 intervention and printed back on the screen before execution (unless
191 the -q flag is given to force quiet mode).
192 the -q flag is given to force quiet mode).
192
193
193 The block is dedented prior to execution to enable execution of method
194 The block is dedented prior to execution to enable execution of method
194 definitions. '>' and '+' characters at the beginning of a line are
195 definitions. '>' and '+' characters at the beginning of a line are
195 ignored, to allow pasting directly from e-mails, diff files and
196 ignored, to allow pasting directly from e-mails, diff files and
196 doctests (the '...' continuation prompt is also stripped). The
197 doctests (the '...' continuation prompt is also stripped). The
197 executed block is also assigned to variable named 'pasted_block' for
198 executed block is also assigned to variable named 'pasted_block' for
198 later editing with '%edit pasted_block'.
199 later editing with '%edit pasted_block'.
199
200
200 You can also pass a variable name as an argument, e.g. '%paste foo'.
201 You can also pass a variable name as an argument, e.g. '%paste foo'.
201 This assigns the pasted block to variable 'foo' as string, without
202 This assigns the pasted block to variable 'foo' as string, without
202 dedenting or executing it (preceding >>> and + is still stripped)
203 dedenting or executing it (preceding >>> and + is still stripped)
203
204
204 Options
205 Options
205 -------
206 -------
206
207
207 -r: re-executes the block previously entered by cpaste.
208 -r: re-executes the block previously entered by cpaste.
208
209
209 -q: quiet mode: do not echo the pasted text back to the terminal.
210 -q: quiet mode: do not echo the pasted text back to the terminal.
210
211
211 IPython statements (magics, shell escapes) are not supported (yet).
212 IPython statements (magics, shell escapes) are not supported (yet).
212
213
213 See also
214 See also
214 --------
215 --------
215 cpaste: manually paste code into terminal until you mark its end.
216 cpaste: manually paste code into terminal until you mark its end.
216 """
217 """
217 opts, name = self.parse_options(parameter_s, 'rq', mode='string')
218 opts, name = self.parse_options(parameter_s, 'rq', mode='string')
218 if 'r' in opts:
219 if 'r' in opts:
219 rerun_pasted(self.shell)
220 rerun_pasted(self.shell)
220 return
221 return
221 try:
222 try:
222 text = self.shell.hooks.clipboard_get()
223 text = self.shell.hooks.clipboard_get()
223 block = strip_email_quotes(text.splitlines())
224 block = strip_email_quotes(text.splitlines())
224 except TryNext as clipboard_exc:
225 except TryNext as clipboard_exc:
225 message = getattr(clipboard_exc, 'args')
226 message = getattr(clipboard_exc, 'args')
226 if message:
227 if message:
227 error(message[0])
228 error(message[0])
228 else:
229 else:
229 error('Could not get text from the clipboard.')
230 error('Could not get text from the clipboard.')
230 return
231 return
231
232
232 # By default, echo back to terminal unless quiet mode is requested
233 # By default, echo back to terminal unless quiet mode is requested
233 if 'q' not in opts:
234 if 'q' not in opts:
234 write = self.shell.write
235 write = self.shell.write
235 write(self.shell.pycolorize(block))
236 write(self.shell.pycolorize(block))
236 if not block.endswith('\n'):
237 if not block.endswith('\n'):
237 write('\n')
238 write('\n')
238 write("## -- End pasted text --\n")
239 write("## -- End pasted text --\n")
239
240
240 store_or_execute(self.shell, block, name)
241 store_or_execute(self.shell, block, name)
241
242
242
243 # Class-level: add a '%cls' magic only on Windows
243 # Class-level: add a '%cls' magic only on Windows
244 if sys.platform == 'win32':
244 if sys.platform == 'win32':
245 def magic_cls(self, s):
245 @line_magic
246 def cls(self, s):
246 """Clear screen.
247 """Clear screen.
247 """
248 """
248 os.system("cls")
249 os.system("cls")
249
250
250 #-----------------------------------------------------------------------------
251 #-----------------------------------------------------------------------------
251 # Main class
252 # Main class
252 #-----------------------------------------------------------------------------
253 #-----------------------------------------------------------------------------
253
254
254 class TerminalInteractiveShell(InteractiveShell):
255 class TerminalInteractiveShell(InteractiveShell):
255
256
256 autoedit_syntax = CBool(False, config=True,
257 autoedit_syntax = CBool(False, config=True,
257 help="auto editing of files with syntax errors.")
258 help="auto editing of files with syntax errors.")
258 banner = Unicode('')
259 banner = Unicode('')
259 banner1 = Unicode(default_banner, config=True,
260 banner1 = Unicode(default_banner, config=True,
260 help="""The part of the banner to be printed before the profile"""
261 help="""The part of the banner to be printed before the profile"""
261 )
262 )
262 banner2 = Unicode('', config=True,
263 banner2 = Unicode('', config=True,
263 help="""The part of the banner to be printed after the profile"""
264 help="""The part of the banner to be printed after the profile"""
264 )
265 )
265 confirm_exit = CBool(True, config=True,
266 confirm_exit = CBool(True, config=True,
266 help="""
267 help="""
267 Set to confirm when you try to exit IPython with an EOF (Control-D
268 Set to confirm when you try to exit IPython with an EOF (Control-D
268 in Unix, Control-Z/Enter in Windows). By typing 'exit' or 'quit',
269 in Unix, Control-Z/Enter in Windows). By typing 'exit' or 'quit',
269 you can force a direct exit without any confirmation.""",
270 you can force a direct exit without any confirmation.""",
270 )
271 )
271 # This display_banner only controls whether or not self.show_banner()
272 # This display_banner only controls whether or not self.show_banner()
272 # is called when mainloop/interact are called. The default is False
273 # is called when mainloop/interact are called. The default is False
273 # because for the terminal based application, the banner behavior
274 # because for the terminal based application, the banner behavior
274 # is controlled by Global.display_banner, which IPythonApp looks at
275 # is controlled by Global.display_banner, which IPythonApp looks at
275 # to determine if *it* should call show_banner() by hand or not.
276 # to determine if *it* should call show_banner() by hand or not.
276 display_banner = CBool(False) # This isn't configurable!
277 display_banner = CBool(False) # This isn't configurable!
277 embedded = CBool(False)
278 embedded = CBool(False)
278 embedded_active = CBool(False)
279 embedded_active = CBool(False)
279 editor = Unicode(get_default_editor(), config=True,
280 editor = Unicode(get_default_editor(), config=True,
280 help="Set the editor used by IPython (default to $EDITOR/vi/notepad)."
281 help="Set the editor used by IPython (default to $EDITOR/vi/notepad)."
281 )
282 )
282 pager = Unicode('less', config=True,
283 pager = Unicode('less', config=True,
283 help="The shell program to be used for paging.")
284 help="The shell program to be used for paging.")
284
285
285 screen_length = Integer(0, config=True,
286 screen_length = Integer(0, config=True,
286 help=
287 help=
287 """Number of lines of your screen, used to control printing of very
288 """Number of lines of your screen, used to control printing of very
288 long strings. Strings longer than this number of lines will be sent
289 long strings. Strings longer than this number of lines will be sent
289 through a pager instead of directly printed. The default value for
290 through a pager instead of directly printed. The default value for
290 this is 0, which means IPython will auto-detect your screen size every
291 this is 0, which means IPython will auto-detect your screen size every
291 time it needs to print certain potentially long strings (this doesn't
292 time it needs to print certain potentially long strings (this doesn't
292 change the behavior of the 'print' keyword, it's only triggered
293 change the behavior of the 'print' keyword, it's only triggered
293 internally). If for some reason this isn't working well (it needs
294 internally). If for some reason this isn't working well (it needs
294 curses support), specify it yourself. Otherwise don't change the
295 curses support), specify it yourself. Otherwise don't change the
295 default.""",
296 default.""",
296 )
297 )
297 term_title = CBool(False, config=True,
298 term_title = CBool(False, config=True,
298 help="Enable auto setting the terminal title."
299 help="Enable auto setting the terminal title."
299 )
300 )
300
301
301 # In the terminal, GUI control is done via PyOS_InputHook
302 # In the terminal, GUI control is done via PyOS_InputHook
302 from IPython.lib.inputhook import enable_gui
303 from IPython.lib.inputhook import enable_gui
303 enable_gui = staticmethod(enable_gui)
304 enable_gui = staticmethod(enable_gui)
304
305
305 def __init__(self, config=None, ipython_dir=None, profile_dir=None,
306 def __init__(self, config=None, ipython_dir=None, profile_dir=None,
306 user_ns=None, user_module=None, custom_exceptions=((),None),
307 user_ns=None, user_module=None, custom_exceptions=((),None),
307 usage=None, banner1=None, banner2=None, display_banner=None):
308 usage=None, banner1=None, banner2=None, display_banner=None):
308
309
309 super(TerminalInteractiveShell, self).__init__(
310 super(TerminalInteractiveShell, self).__init__(
310 config=config, profile_dir=profile_dir, user_ns=user_ns,
311 config=config, profile_dir=profile_dir, user_ns=user_ns,
311 user_module=user_module, custom_exceptions=custom_exceptions
312 user_module=user_module, custom_exceptions=custom_exceptions
312 )
313 )
313 # use os.system instead of utils.process.system by default,
314 # use os.system instead of utils.process.system by default,
314 # because piped system doesn't make sense in the Terminal:
315 # because piped system doesn't make sense in the Terminal:
315 self.system = self.system_raw
316 self.system = self.system_raw
316
317
317 self.init_term_title()
318 self.init_term_title()
318 self.init_usage(usage)
319 self.init_usage(usage)
319 self.init_banner(banner1, banner2, display_banner)
320 self.init_banner(banner1, banner2, display_banner)
320
321
321 #-------------------------------------------------------------------------
322 #-------------------------------------------------------------------------
322 # Things related to the terminal
323 # Things related to the terminal
323 #-------------------------------------------------------------------------
324 #-------------------------------------------------------------------------
324
325
325 @property
326 @property
326 def usable_screen_length(self):
327 def usable_screen_length(self):
327 if self.screen_length == 0:
328 if self.screen_length == 0:
328 return 0
329 return 0
329 else:
330 else:
330 num_lines_bot = self.separate_in.count('\n')+1
331 num_lines_bot = self.separate_in.count('\n')+1
331 return self.screen_length - num_lines_bot
332 return self.screen_length - num_lines_bot
332
333
333 def init_term_title(self):
334 def init_term_title(self):
334 # Enable or disable the terminal title.
335 # Enable or disable the terminal title.
335 if self.term_title:
336 if self.term_title:
336 toggle_set_term_title(True)
337 toggle_set_term_title(True)
337 set_term_title('IPython: ' + abbrev_cwd())
338 set_term_title('IPython: ' + abbrev_cwd())
338 else:
339 else:
339 toggle_set_term_title(False)
340 toggle_set_term_title(False)
340
341
341 #-------------------------------------------------------------------------
342 #-------------------------------------------------------------------------
342 # Things related to aliases
343 # Things related to aliases
343 #-------------------------------------------------------------------------
344 #-------------------------------------------------------------------------
344
345
345 def init_alias(self):
346 def init_alias(self):
346 # The parent class defines aliases that can be safely used with any
347 # The parent class defines aliases that can be safely used with any
347 # frontend.
348 # frontend.
348 super(TerminalInteractiveShell, self).init_alias()
349 super(TerminalInteractiveShell, self).init_alias()
349
350
350 # Now define aliases that only make sense on the terminal, because they
351 # Now define aliases that only make sense on the terminal, because they
351 # need direct access to the console in a way that we can't emulate in
352 # need direct access to the console in a way that we can't emulate in
352 # GUI or web frontend
353 # GUI or web frontend
353 if os.name == 'posix':
354 if os.name == 'posix':
354 aliases = [('clear', 'clear'), ('more', 'more'), ('less', 'less'),
355 aliases = [('clear', 'clear'), ('more', 'more'), ('less', 'less'),
355 ('man', 'man')]
356 ('man', 'man')]
356 elif os.name == 'nt':
357 elif os.name == 'nt':
357 aliases = [('cls', 'cls')]
358 aliases = [('cls', 'cls')]
358
359
359
360
360 for name, cmd in aliases:
361 for name, cmd in aliases:
361 self.alias_manager.define_alias(name, cmd)
362 self.alias_manager.define_alias(name, cmd)
362
363
363 #-------------------------------------------------------------------------
364 #-------------------------------------------------------------------------
364 # Things related to the banner and usage
365 # Things related to the banner and usage
365 #-------------------------------------------------------------------------
366 #-------------------------------------------------------------------------
366
367
367 def _banner1_changed(self):
368 def _banner1_changed(self):
368 self.compute_banner()
369 self.compute_banner()
369
370
370 def _banner2_changed(self):
371 def _banner2_changed(self):
371 self.compute_banner()
372 self.compute_banner()
372
373
373 def _term_title_changed(self, name, new_value):
374 def _term_title_changed(self, name, new_value):
374 self.init_term_title()
375 self.init_term_title()
375
376
376 def init_banner(self, banner1, banner2, display_banner):
377 def init_banner(self, banner1, banner2, display_banner):
377 if banner1 is not None:
378 if banner1 is not None:
378 self.banner1 = banner1
379 self.banner1 = banner1
379 if banner2 is not None:
380 if banner2 is not None:
380 self.banner2 = banner2
381 self.banner2 = banner2
381 if display_banner is not None:
382 if display_banner is not None:
382 self.display_banner = display_banner
383 self.display_banner = display_banner
383 self.compute_banner()
384 self.compute_banner()
384
385
385 def show_banner(self, banner=None):
386 def show_banner(self, banner=None):
386 if banner is None:
387 if banner is None:
387 banner = self.banner
388 banner = self.banner
388 self.write(banner)
389 self.write(banner)
389
390
390 def compute_banner(self):
391 def compute_banner(self):
391 self.banner = self.banner1
392 self.banner = self.banner1
392 if self.profile and self.profile != 'default':
393 if self.profile and self.profile != 'default':
393 self.banner += '\nIPython profile: %s\n' % self.profile
394 self.banner += '\nIPython profile: %s\n' % self.profile
394 if self.banner2:
395 if self.banner2:
395 self.banner += '\n' + self.banner2
396 self.banner += '\n' + self.banner2
396
397
397 def init_usage(self, usage=None):
398 def init_usage(self, usage=None):
398 if usage is None:
399 if usage is None:
399 self.usage = interactive_usage
400 self.usage = interactive_usage
400 else:
401 else:
401 self.usage = usage
402 self.usage = usage
402
403
403 #-------------------------------------------------------------------------
404 #-------------------------------------------------------------------------
404 # Mainloop and code execution logic
405 # Mainloop and code execution logic
405 #-------------------------------------------------------------------------
406 #-------------------------------------------------------------------------
406
407
407 def mainloop(self, display_banner=None):
408 def mainloop(self, display_banner=None):
408 """Start the mainloop.
409 """Start the mainloop.
409
410
410 If an optional banner argument is given, it will override the
411 If an optional banner argument is given, it will override the
411 internally created default banner.
412 internally created default banner.
412 """
413 """
413
414
414 with nested(self.builtin_trap, self.display_trap):
415 with nested(self.builtin_trap, self.display_trap):
415
416
416 while 1:
417 while 1:
417 try:
418 try:
418 self.interact(display_banner=display_banner)
419 self.interact(display_banner=display_banner)
419 #self.interact_with_readline()
420 #self.interact_with_readline()
420 # XXX for testing of a readline-decoupled repl loop, call
421 # XXX for testing of a readline-decoupled repl loop, call
421 # interact_with_readline above
422 # interact_with_readline above
422 break
423 break
423 except KeyboardInterrupt:
424 except KeyboardInterrupt:
424 # this should not be necessary, but KeyboardInterrupt
425 # this should not be necessary, but KeyboardInterrupt
425 # handling seems rather unpredictable...
426 # handling seems rather unpredictable...
426 self.write("\nKeyboardInterrupt in interact()\n")
427 self.write("\nKeyboardInterrupt in interact()\n")
427
428
428 def _replace_rlhist_multiline(self, source_raw, hlen_before_cell):
429 def _replace_rlhist_multiline(self, source_raw, hlen_before_cell):
429 """Store multiple lines as a single entry in history"""
430 """Store multiple lines as a single entry in history"""
430
431
431 # do nothing without readline or disabled multiline
432 # do nothing without readline or disabled multiline
432 if not self.has_readline or not self.multiline_history:
433 if not self.has_readline or not self.multiline_history:
433 return hlen_before_cell
434 return hlen_before_cell
434
435
435 # windows rl has no remove_history_item
436 # windows rl has no remove_history_item
436 if not hasattr(self.readline, "remove_history_item"):
437 if not hasattr(self.readline, "remove_history_item"):
437 return hlen_before_cell
438 return hlen_before_cell
438
439
439 # skip empty cells
440 # skip empty cells
440 if not source_raw.rstrip():
441 if not source_raw.rstrip():
441 return hlen_before_cell
442 return hlen_before_cell
442
443
443 # nothing changed do nothing, e.g. when rl removes consecutive dups
444 # nothing changed do nothing, e.g. when rl removes consecutive dups
444 hlen = self.readline.get_current_history_length()
445 hlen = self.readline.get_current_history_length()
445 if hlen == hlen_before_cell:
446 if hlen == hlen_before_cell:
446 return hlen_before_cell
447 return hlen_before_cell
447
448
448 for i in range(hlen - hlen_before_cell):
449 for i in range(hlen - hlen_before_cell):
449 self.readline.remove_history_item(hlen - i - 1)
450 self.readline.remove_history_item(hlen - i - 1)
450 stdin_encoding = get_stream_enc(sys.stdin, 'utf-8')
451 stdin_encoding = get_stream_enc(sys.stdin, 'utf-8')
451 self.readline.add_history(py3compat.unicode_to_str(source_raw.rstrip(),
452 self.readline.add_history(py3compat.unicode_to_str(source_raw.rstrip(),
452 stdin_encoding))
453 stdin_encoding))
453 return self.readline.get_current_history_length()
454 return self.readline.get_current_history_length()
454
455
455 def interact(self, display_banner=None):
456 def interact(self, display_banner=None):
456 """Closely emulate the interactive Python console."""
457 """Closely emulate the interactive Python console."""
457
458
458 # batch run -> do not interact
459 # batch run -> do not interact
459 if self.exit_now:
460 if self.exit_now:
460 return
461 return
461
462
462 if display_banner is None:
463 if display_banner is None:
463 display_banner = self.display_banner
464 display_banner = self.display_banner
464
465
465 if isinstance(display_banner, basestring):
466 if isinstance(display_banner, basestring):
466 self.show_banner(display_banner)
467 self.show_banner(display_banner)
467 elif display_banner:
468 elif display_banner:
468 self.show_banner()
469 self.show_banner()
469
470
470 more = False
471 more = False
471
472
472 if self.has_readline:
473 if self.has_readline:
473 self.readline_startup_hook(self.pre_readline)
474 self.readline_startup_hook(self.pre_readline)
474 hlen_b4_cell = self.readline.get_current_history_length()
475 hlen_b4_cell = self.readline.get_current_history_length()
475 else:
476 else:
476 hlen_b4_cell = 0
477 hlen_b4_cell = 0
477 # exit_now is set by a call to %Exit or %Quit, through the
478 # exit_now is set by a call to %Exit or %Quit, through the
478 # ask_exit callback.
479 # ask_exit callback.
479
480
480 while not self.exit_now:
481 while not self.exit_now:
481 self.hooks.pre_prompt_hook()
482 self.hooks.pre_prompt_hook()
482 if more:
483 if more:
483 try:
484 try:
484 prompt = self.prompt_manager.render('in2')
485 prompt = self.prompt_manager.render('in2')
485 except:
486 except:
486 self.showtraceback()
487 self.showtraceback()
487 if self.autoindent:
488 if self.autoindent:
488 self.rl_do_indent = True
489 self.rl_do_indent = True
489
490
490 else:
491 else:
491 try:
492 try:
492 prompt = self.separate_in + self.prompt_manager.render('in')
493 prompt = self.separate_in + self.prompt_manager.render('in')
493 except:
494 except:
494 self.showtraceback()
495 self.showtraceback()
495 try:
496 try:
496 line = self.raw_input(prompt)
497 line = self.raw_input(prompt)
497 if self.exit_now:
498 if self.exit_now:
498 # quick exit on sys.std[in|out] close
499 # quick exit on sys.std[in|out] close
499 break
500 break
500 if self.autoindent:
501 if self.autoindent:
501 self.rl_do_indent = False
502 self.rl_do_indent = False
502
503
503 except KeyboardInterrupt:
504 except KeyboardInterrupt:
504 #double-guard against keyboardinterrupts during kbdint handling
505 #double-guard against keyboardinterrupts during kbdint handling
505 try:
506 try:
506 self.write('\nKeyboardInterrupt\n')
507 self.write('\nKeyboardInterrupt\n')
507 source_raw = self.input_splitter.source_raw_reset()[1]
508 source_raw = self.input_splitter.source_raw_reset()[1]
508 hlen_b4_cell = \
509 hlen_b4_cell = \
509 self._replace_rlhist_multiline(source_raw, hlen_b4_cell)
510 self._replace_rlhist_multiline(source_raw, hlen_b4_cell)
510 more = False
511 more = False
511 except KeyboardInterrupt:
512 except KeyboardInterrupt:
512 pass
513 pass
513 except EOFError:
514 except EOFError:
514 if self.autoindent:
515 if self.autoindent:
515 self.rl_do_indent = False
516 self.rl_do_indent = False
516 if self.has_readline:
517 if self.has_readline:
517 self.readline_startup_hook(None)
518 self.readline_startup_hook(None)
518 self.write('\n')
519 self.write('\n')
519 self.exit()
520 self.exit()
520 except bdb.BdbQuit:
521 except bdb.BdbQuit:
521 warn('The Python debugger has exited with a BdbQuit exception.\n'
522 warn('The Python debugger has exited with a BdbQuit exception.\n'
522 'Because of how pdb handles the stack, it is impossible\n'
523 'Because of how pdb handles the stack, it is impossible\n'
523 'for IPython to properly format this particular exception.\n'
524 'for IPython to properly format this particular exception.\n'
524 'IPython will resume normal operation.')
525 'IPython will resume normal operation.')
525 except:
526 except:
526 # exceptions here are VERY RARE, but they can be triggered
527 # exceptions here are VERY RARE, but they can be triggered
527 # asynchronously by signal handlers, for example.
528 # asynchronously by signal handlers, for example.
528 self.showtraceback()
529 self.showtraceback()
529 else:
530 else:
530 self.input_splitter.push(line)
531 self.input_splitter.push(line)
531 more = self.input_splitter.push_accepts_more()
532 more = self.input_splitter.push_accepts_more()
532 if (self.SyntaxTB.last_syntax_error and
533 if (self.SyntaxTB.last_syntax_error and
533 self.autoedit_syntax):
534 self.autoedit_syntax):
534 self.edit_syntax_error()
535 self.edit_syntax_error()
535 if not more:
536 if not more:
536 source_raw = self.input_splitter.source_raw_reset()[1]
537 source_raw = self.input_splitter.source_raw_reset()[1]
537 self.run_cell(source_raw, store_history=True)
538 self.run_cell(source_raw, store_history=True)
538 hlen_b4_cell = \
539 hlen_b4_cell = \
539 self._replace_rlhist_multiline(source_raw, hlen_b4_cell)
540 self._replace_rlhist_multiline(source_raw, hlen_b4_cell)
540
541
541 # Turn off the exit flag, so the mainloop can be restarted if desired
542 # Turn off the exit flag, so the mainloop can be restarted if desired
542 self.exit_now = False
543 self.exit_now = False
543
544
544 def raw_input(self, prompt=''):
545 def raw_input(self, prompt=''):
545 """Write a prompt and read a line.
546 """Write a prompt and read a line.
546
547
547 The returned line does not include the trailing newline.
548 The returned line does not include the trailing newline.
548 When the user enters the EOF key sequence, EOFError is raised.
549 When the user enters the EOF key sequence, EOFError is raised.
549
550
550 Optional inputs:
551 Optional inputs:
551
552
552 - prompt(''): a string to be printed to prompt the user.
553 - prompt(''): a string to be printed to prompt the user.
553
554
554 - continue_prompt(False): whether this line is the first one or a
555 - continue_prompt(False): whether this line is the first one or a
555 continuation in a sequence of inputs.
556 continuation in a sequence of inputs.
556 """
557 """
557 # Code run by the user may have modified the readline completer state.
558 # Code run by the user may have modified the readline completer state.
558 # We must ensure that our completer is back in place.
559 # We must ensure that our completer is back in place.
559
560
560 if self.has_readline:
561 if self.has_readline:
561 self.set_readline_completer()
562 self.set_readline_completer()
562
563
563 try:
564 try:
564 line = py3compat.str_to_unicode(self.raw_input_original(prompt))
565 line = py3compat.str_to_unicode(self.raw_input_original(prompt))
565 except ValueError:
566 except ValueError:
566 warn("\n********\nYou or a %run:ed script called sys.stdin.close()"
567 warn("\n********\nYou or a %run:ed script called sys.stdin.close()"
567 " or sys.stdout.close()!\nExiting IPython!")
568 " or sys.stdout.close()!\nExiting IPython!")
568 self.ask_exit()
569 self.ask_exit()
569 return ""
570 return ""
570
571
571 # Try to be reasonably smart about not re-indenting pasted input more
572 # Try to be reasonably smart about not re-indenting pasted input more
572 # than necessary. We do this by trimming out the auto-indent initial
573 # than necessary. We do this by trimming out the auto-indent initial
573 # spaces, if the user's actual input started itself with whitespace.
574 # spaces, if the user's actual input started itself with whitespace.
574 if self.autoindent:
575 if self.autoindent:
575 if num_ini_spaces(line) > self.indent_current_nsp:
576 if num_ini_spaces(line) > self.indent_current_nsp:
576 line = line[self.indent_current_nsp:]
577 line = line[self.indent_current_nsp:]
577 self.indent_current_nsp = 0
578 self.indent_current_nsp = 0
578
579
579 return line
580 return line
580
581
581 #-------------------------------------------------------------------------
582 #-------------------------------------------------------------------------
582 # Methods to support auto-editing of SyntaxErrors.
583 # Methods to support auto-editing of SyntaxErrors.
583 #-------------------------------------------------------------------------
584 #-------------------------------------------------------------------------
584
585
585 def edit_syntax_error(self):
586 def edit_syntax_error(self):
586 """The bottom half of the syntax error handler called in the main loop.
587 """The bottom half of the syntax error handler called in the main loop.
587
588
588 Loop until syntax error is fixed or user cancels.
589 Loop until syntax error is fixed or user cancels.
589 """
590 """
590
591
591 while self.SyntaxTB.last_syntax_error:
592 while self.SyntaxTB.last_syntax_error:
592 # copy and clear last_syntax_error
593 # copy and clear last_syntax_error
593 err = self.SyntaxTB.clear_err_state()
594 err = self.SyntaxTB.clear_err_state()
594 if not self._should_recompile(err):
595 if not self._should_recompile(err):
595 return
596 return
596 try:
597 try:
597 # may set last_syntax_error again if a SyntaxError is raised
598 # may set last_syntax_error again if a SyntaxError is raised
598 self.safe_execfile(err.filename,self.user_ns)
599 self.safe_execfile(err.filename,self.user_ns)
599 except:
600 except:
600 self.showtraceback()
601 self.showtraceback()
601 else:
602 else:
602 try:
603 try:
603 f = open(err.filename)
604 f = open(err.filename)
604 try:
605 try:
605 # This should be inside a display_trap block and I
606 # This should be inside a display_trap block and I
606 # think it is.
607 # think it is.
607 sys.displayhook(f.read())
608 sys.displayhook(f.read())
608 finally:
609 finally:
609 f.close()
610 f.close()
610 except:
611 except:
611 self.showtraceback()
612 self.showtraceback()
612
613
613 def _should_recompile(self,e):
614 def _should_recompile(self,e):
614 """Utility routine for edit_syntax_error"""
615 """Utility routine for edit_syntax_error"""
615
616
616 if e.filename in ('<ipython console>','<input>','<string>',
617 if e.filename in ('<ipython console>','<input>','<string>',
617 '<console>','<BackgroundJob compilation>',
618 '<console>','<BackgroundJob compilation>',
618 None):
619 None):
619
620
620 return False
621 return False
621 try:
622 try:
622 if (self.autoedit_syntax and
623 if (self.autoedit_syntax and
623 not self.ask_yes_no('Return to editor to correct syntax error? '
624 not self.ask_yes_no('Return to editor to correct syntax error? '
624 '[Y/n] ','y')):
625 '[Y/n] ','y')):
625 return False
626 return False
626 except EOFError:
627 except EOFError:
627 return False
628 return False
628
629
629 def int0(x):
630 def int0(x):
630 try:
631 try:
631 return int(x)
632 return int(x)
632 except TypeError:
633 except TypeError:
633 return 0
634 return 0
634 # always pass integer line and offset values to editor hook
635 # always pass integer line and offset values to editor hook
635 try:
636 try:
636 self.hooks.fix_error_editor(e.filename,
637 self.hooks.fix_error_editor(e.filename,
637 int0(e.lineno),int0(e.offset),e.msg)
638 int0(e.lineno),int0(e.offset),e.msg)
638 except TryNext:
639 except TryNext:
639 warn('Could not open editor')
640 warn('Could not open editor')
640 return False
641 return False
641 return True
642 return True
642
643
643 #-------------------------------------------------------------------------
644 #-------------------------------------------------------------------------
644 # Things related to exiting
645 # Things related to exiting
645 #-------------------------------------------------------------------------
646 #-------------------------------------------------------------------------
646
647
647 def ask_exit(self):
648 def ask_exit(self):
648 """ Ask the shell to exit. Can be overiden and used as a callback. """
649 """ Ask the shell to exit. Can be overiden and used as a callback. """
649 self.exit_now = True
650 self.exit_now = True
650
651
651 def exit(self):
652 def exit(self):
652 """Handle interactive exit.
653 """Handle interactive exit.
653
654
654 This method calls the ask_exit callback."""
655 This method calls the ask_exit callback."""
655 if self.confirm_exit:
656 if self.confirm_exit:
656 if self.ask_yes_no('Do you really want to exit ([y]/n)?','y'):
657 if self.ask_yes_no('Do you really want to exit ([y]/n)?','y'):
657 self.ask_exit()
658 self.ask_exit()
658 else:
659 else:
659 self.ask_exit()
660 self.ask_exit()
660
661
661 #-------------------------------------------------------------------------
662 #-------------------------------------------------------------------------
662 # Things related to magics
663 # Things related to magics
663 #-------------------------------------------------------------------------
664 #-------------------------------------------------------------------------
664
665
665 def init_magics(self):
666 def init_magics(self):
666 super(TerminalInteractiveShell, self).init_magics()
667 super(TerminalInteractiveShell, self).init_magics()
667 self.define_magic('autoindent', magic_autoindent)
668 self.register_magics(TerminalMagics)
668 self.define_magic('cpaste', magic_cpaste)
669 self.define_magic('paste', magic_paste)
670 try:
671 magic_cls
672 except NameError:
673 pass
674 else:
675 self.define_magic('cls', magic_cls)
676
669
677 def showindentationerror(self):
670 def showindentationerror(self):
678 super(TerminalInteractiveShell, self).showindentationerror()
671 super(TerminalInteractiveShell, self).showindentationerror()
679 print("If you want to paste code into IPython, try the "
672 print("If you want to paste code into IPython, try the "
680 "%paste and %cpaste magic functions.")
673 "%paste and %cpaste magic functions.")
681
674
682
675
683 InteractiveShellABC.register(TerminalInteractiveShell)
676 InteractiveShellABC.register(TerminalInteractiveShell)
General Comments 0
You need to be logged in to leave comments. Login now