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