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